Skip to content

Commit 0da45dc

Browse files
committed
perf(Mp4Generator): assemble segment data in a single allocation
1 parent 5c836b1 commit 0da45dc

1 file changed

Lines changed: 36 additions & 17 deletions

File tree

lib/util/mp4_generator.js

Lines changed: 36 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -673,11 +673,38 @@ shaka.util.Mp4Generator = class {
673673
* @return {!Uint8Array}
674674
*/
675675
segmentData() {
676-
const segmentDataArray = [];
676+
const Mp4Generator = shaka.util.Mp4Generator;
677+
const HEADER = Mp4Generator.BOX_HEADER_SIZE_;
678+
// Assemble whole segment into one allocation
679+
const streams = [];
680+
// Running sum of bytes needed for the final segment buffer.
681+
let total = 0;
677682
for (const streamInfo of this.streamInfos_) {
678-
segmentDataArray.push(this.moof_(streamInfo), this.mdat_(streamInfo));
683+
const moof = this.moof_(streamInfo);
684+
const samples = streamInfo.data ? streamInfo.data.samples : [];
685+
// Sum of sample byte lengths for this stream's mdat payload.
686+
let mdatPayload = 0;
687+
for (const sample of samples) {
688+
mdatPayload += sample.data.byteLength;
689+
}
690+
const mdatSize = HEADER + mdatPayload;
691+
streams.push({moof, samples, mdatSize});
692+
total += moof.byteLength + mdatSize;
693+
}
694+
const result = new Uint8Array(total);
695+
// Current byte position in the output buffer.
696+
let offset = 0;
697+
for (const {moof, samples, mdatSize} of streams) {
698+
result.set(moof, offset);
699+
offset += moof.byteLength;
700+
this.writeUint32_(result, mdatSize, offset);
701+
result.set(Mp4Generator.MDAT_TYPE_, offset + 4);
702+
offset += HEADER;
703+
for (const sample of samples) {
704+
result.set(sample.data, offset);
705+
offset += sample.data.byteLength;
706+
}
679707
}
680-
const result = shaka.util.Uint8ArrayUtils.concat(...segmentDataArray);
681708
return result;
682709
}
683710

@@ -849,20 +876,6 @@ shaka.util.Mp4Generator = class {
849876
return box;
850877
}
851878

852-
/**
853-
* Generate a MDAT box
854-
*
855-
* @param {shaka.util.Mp4Generator.StreamInfo} streamInfo
856-
* @return {!Uint8Array}
857-
* @private
858-
*/
859-
mdat_(streamInfo) {
860-
const Mp4Generator = shaka.util.Mp4Generator;
861-
const samples = streamInfo.data ? streamInfo.data.samples : [];
862-
const allData = samples.map((sample) => sample.data);
863-
return Mp4Generator.box('mdat', ...allData);
864-
}
865-
866879
/**
867880
* @param {!Uint8Array} bytes
868881
* @param {number} value
@@ -1002,6 +1015,12 @@ shaka.util.Mp4Generator.BOX_TYPES_ = new Map();
10021015
*/
10031016
shaka.util.Mp4Generator.BOX_HEADER_SIZE_ = 8;
10041017

1018+
/**
1019+
* 'mdat' box-type bytes (ASCII).
1020+
* @private {!Uint8Array}
1021+
*/
1022+
shaka.util.Mp4Generator.MDAT_TYPE_ = new Uint8Array([0x6d, 0x64, 0x61, 0x74]);
1023+
10051024
/**
10061025
* Template MVHD (version 1, 112 bytes).
10071026
* Dynamic fields: timescale [20], upperDur [24], lowerDur [28].

0 commit comments

Comments
 (0)