@@ -8,6 +8,7 @@ goog.provide('shaka.util.Mp4Generator');
88
99goog . require ( 'goog.asserts' ) ;
1010goog . require ( 'shaka.device.DeviceFactory' ) ;
11+ goog . require ( 'shaka.util.BufferUtils' ) ;
1112goog . require ( 'shaka.util.Lazy' ) ;
1213goog . require ( 'shaka.util.ManifestParserUtils' ) ;
1314goog . require ( 'shaka.util.Uint8ArrayUtils' ) ;
@@ -673,11 +674,38 @@ shaka.util.Mp4Generator = class {
673674 * @return {!Uint8Array }
674675 */
675676 segmentData ( ) {
676- const segmentDataArray = [ ] ;
677+ const Mp4Generator = shaka . util . Mp4Generator ;
678+ const boxHeaderSize = Mp4Generator . BOX_HEADER_SIZE_ ;
679+ // Assemble whole segment into one allocation
680+ const streams = [ ] ;
681+ // Running sum of bytes needed for the final segment buffer.
682+ let total = 0 ;
677683 for ( const streamInfo of this . streamInfos_ ) {
678- segmentDataArray . push ( this . moof_ ( streamInfo ) , this . mdat_ ( streamInfo ) ) ;
684+ const moof = this . moof_ ( streamInfo ) ;
685+ const samples = streamInfo . data ? streamInfo . data . samples : [ ] ;
686+ // Sum of sample byte lengths for this stream's mdat payload.
687+ let mdatPayload = 0 ;
688+ for ( const sample of samples ) {
689+ mdatPayload += sample . data . byteLength ;
690+ }
691+ const mdatSize = boxHeaderSize + mdatPayload ;
692+ streams . push ( { moof, samples, mdatSize} ) ;
693+ total += moof . byteLength + mdatSize ;
694+ }
695+ const result = shaka . util . BufferUtils . toUint8 ( new ArrayBuffer ( total ) ) ;
696+ // Current byte position in the output buffer.
697+ let offset = 0 ;
698+ for ( const { moof, samples, mdatSize} of streams ) {
699+ result . set ( moof , offset ) ;
700+ offset += moof . byteLength ;
701+ this . writeUint32_ ( result , mdatSize , offset ) ;
702+ result . set ( Mp4Generator . MDAT_TYPE_ . value ( ) , offset + 4 ) ;
703+ offset += boxHeaderSize ;
704+ for ( const sample of samples ) {
705+ result . set ( sample . data , offset ) ;
706+ offset += sample . data . byteLength ;
707+ }
679708 }
680- const result = shaka . util . Uint8ArrayUtils . concat ( ...segmentDataArray ) ;
681709 return result ;
682710 }
683711
@@ -849,20 +877,6 @@ shaka.util.Mp4Generator = class {
849877 return box ;
850878 }
851879
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-
866880 /**
867881 * @param {!Uint8Array } bytes
868882 * @param {number } value
@@ -1002,6 +1016,13 @@ shaka.util.Mp4Generator.BOX_TYPES_ = new Map();
10021016 */
10031017shaka . util . Mp4Generator . BOX_HEADER_SIZE_ = 8 ;
10041018
1019+ /**
1020+ * 'mdat' box-type bytes (ASCII).
1021+ * @private {!shaka.util.Lazy<!Uint8Array>}
1022+ */
1023+ shaka . util . Mp4Generator . MDAT_TYPE_ =
1024+ new shaka . util . Lazy ( ( ) => new Uint8Array ( [ 0x6d , 0x64 , 0x61 , 0x74 ] ) ) ;
1025+
10051026/**
10061027 * Template MVHD (version 1, 112 bytes).
10071028 * Dynamic fields: timescale [20], upperDur [24], lowerDur [28].
0 commit comments