diff --git a/packager/app/muxer_flags.cc b/packager/app/muxer_flags.cc index 0fcd349258..4c31fbdb00 100644 --- a/packager/app/muxer_flags.cc +++ b/packager/app/muxer_flags.cc @@ -41,3 +41,6 @@ DEFINE_string(temp_dir, "", "Specify a directory in which to store temporary (intermediate) " " files. Used only if single_segment=true."); +DEFINE_bool(mp4_include_pssh_in_stream, + true, + "MP4 only: include pssh in the encrypted stream."); diff --git a/packager/app/muxer_flags.h b/packager/app/muxer_flags.h index 650e4601e0..608529a351 100644 --- a/packager/app/muxer_flags.h +++ b/packager/app/muxer_flags.h @@ -18,5 +18,6 @@ DECLARE_double(fragment_duration); DECLARE_bool(fragment_sap_aligned); DECLARE_int32(num_subsegments_per_sidx); DECLARE_string(temp_dir); +DECLARE_bool(mp4_include_pssh_in_stream); #endif // APP_MUXER_FLAGS_H_ diff --git a/packager/app/packager_util.cc b/packager/app/packager_util.cc index 177d4ad182..0c538c417d 100644 --- a/packager/app/packager_util.cc +++ b/packager/app/packager_util.cc @@ -193,6 +193,7 @@ EncryptionOptions GetEncryptionOptions() { MuxerOptions GetMuxerOptions() { MuxerOptions muxer_options; muxer_options.num_subsegments_per_sidx = FLAGS_num_subsegments_per_sidx; + muxer_options.mp4_include_pssh_in_stream = FLAGS_mp4_include_pssh_in_stream; if (FLAGS_mp4_use_decoding_timestamp_in_timeline) { LOG(WARNING) << "Flag --mp4_use_decoding_timestamp_in_timeline is set. " "Note that it is a temporary hack to workaround Chromium " diff --git a/packager/app/test/packager_test.py b/packager/app/test/packager_test.py index dbc5191b34..71f5441554 100755 --- a/packager/app/test/packager_test.py +++ b/packager/app/test/packager_test.py @@ -187,6 +187,16 @@ class PackagerAppTest(unittest.TestCase): self._VerifyDecryption(self.output[0], 'bear-640x360-a-golden.mp4') self._VerifyDecryption(self.output[1], 'bear-640x360-v-golden.mp4') + def testPackageWithEncryptionAndNoPsshInStream(self): + self.packager.Package( + self._GetStreams(['audio', 'video']), + self._GetFlags(encryption=True, include_pssh_in_stream=False)) + self._DiffGold(self.output[0], 'bear-640x360-a-cenc-no-pssh-golden.mp4') + self._DiffGold(self.output[1], 'bear-640x360-v-cenc-no-pssh-golden.mp4') + self._DiffGold(self.mpd_output, 'bear-640x360-av-cenc-no-pssh-golden.mpd') + self._VerifyDecryption(self.output[0], 'bear-640x360-a-golden.mp4') + self._VerifyDecryption(self.output[1], 'bear-640x360-v-golden.mp4') + def testPackageWithEncryptionCbc1(self): self.packager.Package( self._GetStreams(['audio', 'video']), @@ -432,6 +442,19 @@ class PackagerAppTest(unittest.TestCase): self._DiffLiveMpdGold(self.mpd_output, 'bear-640x360-av-live-cenc-rotation-golden.mpd') + def testPackageWithLiveProfileAndKeyRotationAndNoPsshInStream(self): + self.packager.Package( + self._GetStreams(['audio', 'video'], live=True), + self._GetFlags( + encryption=True, key_rotation=True, include_pssh_in_stream=False)) + self._DiffLiveGold(self.output[0], + 'bear-640x360-a-live-cenc-rotation-no-pssh-golden') + self._DiffLiveGold(self.output[1], + 'bear-640x360-v-live-cenc-rotation-no-pssh-golden') + self._DiffLiveMpdGold( + self.mpd_output, + 'bear-640x360-av-live-cenc-rotation-no-pssh-golden.mpd') + def testPackageWithLiveProfileAndKeyRotationAndNonDashIfIop(self): self.packager.Package( self._GetStreams(['audio', 'video'], live=True), @@ -550,6 +573,7 @@ class PackagerAppTest(unittest.TestCase): random_iv=False, widevine_encryption=False, key_rotation=False, + include_pssh_in_stream=True, dash_if_iop=True, output_media_info=False, output_hls=False, @@ -587,6 +611,9 @@ class PackagerAppTest(unittest.TestCase): if key_rotation: flags.append('--crypto_period_duration=1') + if not include_pssh_in_stream: + flags.append('--mp4_include_pssh_in_stream=false') + if not dash_if_iop: flags.append('--generate_dash_if_iop_compliant_mpd=false') if output_media_info: diff --git a/packager/app/test/testdata/bear-320x240-opus-cenc-golden.mp4 b/packager/app/test/testdata/bear-320x240-opus-cenc-golden.mp4 index 913f861695..3522370065 100644 Binary files a/packager/app/test/testdata/bear-320x240-opus-cenc-golden.mp4 and b/packager/app/test/testdata/bear-320x240-opus-cenc-golden.mp4 differ diff --git a/packager/app/test/testdata/bear-320x240-opus-golden.mp4 b/packager/app/test/testdata/bear-320x240-opus-golden.mp4 index a37c02d73d..54a091c00c 100644 Binary files a/packager/app/test/testdata/bear-320x240-opus-golden.mp4 and b/packager/app/test/testdata/bear-320x240-opus-golden.mp4 differ diff --git a/packager/app/test/testdata/bear-320x240-opus-vp9-cenc-golden.mpd b/packager/app/test/testdata/bear-320x240-opus-vp9-cenc-golden.mpd index 576e963532..95bb75d440 100644 --- a/packager/app/test/testdata/bear-320x240-opus-vp9-cenc-golden.mpd +++ b/packager/app/test/testdata/bear-320x240-opus-vp9-cenc-golden.mpd @@ -7,11 +7,11 @@ AAAANHBzc2gBAAAAEHfv7MCyTQKs4zweUuL7SwAAAAExMjM0NTY3ODkwMTIzNDU2AAAAAA== - + output_audio.mp4 - - + + @@ -20,10 +20,10 @@ AAAANHBzc2gBAAAAEHfv7MCyTQKs4zweUuL7SwAAAAExMjM0NTY3ODkwMTIzNDU2AAAAAA== - + output_video.mp4 - - + + diff --git a/packager/app/test/testdata/bear-320x240-vp9-cenc-golden.mp4 b/packager/app/test/testdata/bear-320x240-vp9-cenc-golden.mp4 index afaf011f5d..32e9992269 100644 Binary files a/packager/app/test/testdata/bear-320x240-vp9-cenc-golden.mp4 and b/packager/app/test/testdata/bear-320x240-vp9-cenc-golden.mp4 differ diff --git a/packager/app/test/testdata/bear-320x240-vp9-golden.mp4 b/packager/app/test/testdata/bear-320x240-vp9-golden.mp4 index a229300ecf..9c5af5948a 100644 Binary files a/packager/app/test/testdata/bear-320x240-vp9-golden.mp4 and b/packager/app/test/testdata/bear-320x240-vp9-golden.mp4 differ diff --git a/packager/app/test/testdata/bear-640x360-a-cbc1-golden.mp4 b/packager/app/test/testdata/bear-640x360-a-cbc1-golden.mp4 index 626fab7cc9..4425400231 100644 Binary files a/packager/app/test/testdata/bear-640x360-a-cbc1-golden.mp4 and b/packager/app/test/testdata/bear-640x360-a-cbc1-golden.mp4 differ diff --git a/packager/app/test/testdata/bear-640x360-a-cbcs-golden.mp4 b/packager/app/test/testdata/bear-640x360-a-cbcs-golden.mp4 index d155296c3b..54071c85a3 100644 Binary files a/packager/app/test/testdata/bear-640x360-a-cbcs-golden.mp4 and b/packager/app/test/testdata/bear-640x360-a-cbcs-golden.mp4 differ diff --git a/packager/app/test/testdata/bear-640x360-a-cenc-golden.mp4 b/packager/app/test/testdata/bear-640x360-a-cenc-golden.mp4 index a1192dce82..e072c4019c 100644 Binary files a/packager/app/test/testdata/bear-640x360-a-cenc-golden.mp4 and b/packager/app/test/testdata/bear-640x360-a-cenc-golden.mp4 differ diff --git a/packager/app/test/testdata/bear-640x360-a-cenc-golden.mp4.media_info b/packager/app/test/testdata/bear-640x360-a-cenc-golden.mp4.media_info index 3510bbf031..3244f9075d 100644 --- a/packager/app/test/testdata/bear-640x360-a-cenc-golden.mp4.media_info +++ b/packager/app/test/testdata/bear-640x360-a-cenc-golden.mp4.media_info @@ -1,4 +1,4 @@ -bandwidth: 129139 +bandwidth: 129162 audio_info { codec: "mp4a.40.2" sampling_frequency: 44100 @@ -8,11 +8,11 @@ audio_info { } init_range { begin: 0 - end: 958 + end: 966 } index_range { - begin: 959 - end: 1026 + begin: 967 + end: 1034 } media_file_name: "place_holder" media_duration_seconds: 2.7631745 diff --git a/packager/app/test/testdata/bear-640x360-a-cenc-no-pssh-golden.mp4 b/packager/app/test/testdata/bear-640x360-a-cenc-no-pssh-golden.mp4 new file mode 100644 index 0000000000..d7fc496a8f Binary files /dev/null and b/packager/app/test/testdata/bear-640x360-a-cenc-no-pssh-golden.mp4 differ diff --git a/packager/app/test/testdata/bear-640x360-a-cens-golden.mp4 b/packager/app/test/testdata/bear-640x360-a-cens-golden.mp4 index 897dbd4b5a..b51c81193c 100644 Binary files a/packager/app/test/testdata/bear-640x360-a-cens-golden.mp4 and b/packager/app/test/testdata/bear-640x360-a-cens-golden.mp4 differ diff --git a/packager/app/test/testdata/bear-640x360-a-golden.mp4 b/packager/app/test/testdata/bear-640x360-a-golden.mp4 index e1e27bde3a..d58886f965 100644 Binary files a/packager/app/test/testdata/bear-640x360-a-golden.mp4 and b/packager/app/test/testdata/bear-640x360-a-golden.mp4 differ diff --git a/packager/app/test/testdata/bear-640x360-a-live-cenc-golden-1.m4s b/packager/app/test/testdata/bear-640x360-a-live-cenc-golden-1.m4s index 04852faa99..f336d41dd2 100644 Binary files a/packager/app/test/testdata/bear-640x360-a-live-cenc-golden-1.m4s and b/packager/app/test/testdata/bear-640x360-a-live-cenc-golden-1.m4s differ diff --git a/packager/app/test/testdata/bear-640x360-a-live-cenc-golden-2.m4s b/packager/app/test/testdata/bear-640x360-a-live-cenc-golden-2.m4s index ac2742b0cb..e285304cbf 100644 Binary files a/packager/app/test/testdata/bear-640x360-a-live-cenc-golden-2.m4s and b/packager/app/test/testdata/bear-640x360-a-live-cenc-golden-2.m4s differ diff --git a/packager/app/test/testdata/bear-640x360-a-live-cenc-golden-3.m4s b/packager/app/test/testdata/bear-640x360-a-live-cenc-golden-3.m4s index e5295affc5..f197652913 100644 Binary files a/packager/app/test/testdata/bear-640x360-a-live-cenc-golden-3.m4s and b/packager/app/test/testdata/bear-640x360-a-live-cenc-golden-3.m4s differ diff --git a/packager/app/test/testdata/bear-640x360-a-live-cenc-golden-init.mp4 b/packager/app/test/testdata/bear-640x360-a-live-cenc-golden-init.mp4 index 2b347d1361..5b8b64992e 100644 Binary files a/packager/app/test/testdata/bear-640x360-a-live-cenc-golden-init.mp4 and b/packager/app/test/testdata/bear-640x360-a-live-cenc-golden-init.mp4 differ diff --git a/packager/app/test/testdata/bear-640x360-a-live-cenc-rotation-golden-1.m4s b/packager/app/test/testdata/bear-640x360-a-live-cenc-rotation-golden-1.m4s index 83e0dd46b0..50e3c1afc8 100644 Binary files a/packager/app/test/testdata/bear-640x360-a-live-cenc-rotation-golden-1.m4s and b/packager/app/test/testdata/bear-640x360-a-live-cenc-rotation-golden-1.m4s differ diff --git a/packager/app/test/testdata/bear-640x360-a-live-cenc-rotation-golden-2.m4s b/packager/app/test/testdata/bear-640x360-a-live-cenc-rotation-golden-2.m4s index 057782c951..460c2cda59 100644 Binary files a/packager/app/test/testdata/bear-640x360-a-live-cenc-rotation-golden-2.m4s and b/packager/app/test/testdata/bear-640x360-a-live-cenc-rotation-golden-2.m4s differ diff --git a/packager/app/test/testdata/bear-640x360-a-live-cenc-rotation-golden-3.m4s b/packager/app/test/testdata/bear-640x360-a-live-cenc-rotation-golden-3.m4s index cc56e2ad51..ec6f85f521 100644 Binary files a/packager/app/test/testdata/bear-640x360-a-live-cenc-rotation-golden-3.m4s and b/packager/app/test/testdata/bear-640x360-a-live-cenc-rotation-golden-3.m4s differ diff --git a/packager/app/test/testdata/bear-640x360-a-live-cenc-rotation-golden-init.mp4 b/packager/app/test/testdata/bear-640x360-a-live-cenc-rotation-golden-init.mp4 index 9d5c06a43d..1b003c389d 100644 Binary files a/packager/app/test/testdata/bear-640x360-a-live-cenc-rotation-golden-init.mp4 and b/packager/app/test/testdata/bear-640x360-a-live-cenc-rotation-golden-init.mp4 differ diff --git a/packager/app/test/testdata/bear-640x360-a-live-cenc-rotation-no-pssh-golden-1.m4s b/packager/app/test/testdata/bear-640x360-a-live-cenc-rotation-no-pssh-golden-1.m4s new file mode 100644 index 0000000000..f336d41dd2 Binary files /dev/null and b/packager/app/test/testdata/bear-640x360-a-live-cenc-rotation-no-pssh-golden-1.m4s differ diff --git a/packager/app/test/testdata/bear-640x360-a-live-cenc-rotation-no-pssh-golden-2.m4s b/packager/app/test/testdata/bear-640x360-a-live-cenc-rotation-no-pssh-golden-2.m4s new file mode 100644 index 0000000000..39468e7e43 Binary files /dev/null and b/packager/app/test/testdata/bear-640x360-a-live-cenc-rotation-no-pssh-golden-2.m4s differ diff --git a/packager/app/test/testdata/bear-640x360-a-live-cenc-rotation-no-pssh-golden-3.m4s b/packager/app/test/testdata/bear-640x360-a-live-cenc-rotation-no-pssh-golden-3.m4s new file mode 100644 index 0000000000..e179f1c7e3 Binary files /dev/null and b/packager/app/test/testdata/bear-640x360-a-live-cenc-rotation-no-pssh-golden-3.m4s differ diff --git a/packager/app/test/testdata/bear-640x360-a-live-cenc-rotation-no-pssh-golden-init.mp4 b/packager/app/test/testdata/bear-640x360-a-live-cenc-rotation-no-pssh-golden-init.mp4 new file mode 100644 index 0000000000..1b003c389d Binary files /dev/null and b/packager/app/test/testdata/bear-640x360-a-live-cenc-rotation-no-pssh-golden-init.mp4 differ diff --git a/packager/app/test/testdata/bear-640x360-a-live-golden-1.m4s b/packager/app/test/testdata/bear-640x360-a-live-golden-1.m4s index 6c7f6ed426..c4b4ac03d9 100644 Binary files a/packager/app/test/testdata/bear-640x360-a-live-golden-1.m4s and b/packager/app/test/testdata/bear-640x360-a-live-golden-1.m4s differ diff --git a/packager/app/test/testdata/bear-640x360-a-live-golden-2.m4s b/packager/app/test/testdata/bear-640x360-a-live-golden-2.m4s index 8871a6a0d9..8504387c99 100644 Binary files a/packager/app/test/testdata/bear-640x360-a-live-golden-2.m4s and b/packager/app/test/testdata/bear-640x360-a-live-golden-2.m4s differ diff --git a/packager/app/test/testdata/bear-640x360-a-live-golden-3.m4s b/packager/app/test/testdata/bear-640x360-a-live-golden-3.m4s index 76937b2cb9..99af31e503 100644 Binary files a/packager/app/test/testdata/bear-640x360-a-live-golden-3.m4s and b/packager/app/test/testdata/bear-640x360-a-live-golden-3.m4s differ diff --git a/packager/app/test/testdata/bear-640x360-a-live-golden-init.mp4 b/packager/app/test/testdata/bear-640x360-a-live-golden-init.mp4 index 25022c72d1..a703e29da8 100644 Binary files a/packager/app/test/testdata/bear-640x360-a-live-golden-init.mp4 and b/packager/app/test/testdata/bear-640x360-a-live-golden-init.mp4 differ diff --git a/packager/app/test/testdata/bear-640x360-a-por-BR-golden.mp4 b/packager/app/test/testdata/bear-640x360-a-por-BR-golden.mp4 index e2b16076c3..a68f12768a 100644 Binary files a/packager/app/test/testdata/bear-640x360-a-por-BR-golden.mp4 and b/packager/app/test/testdata/bear-640x360-a-por-BR-golden.mp4 differ diff --git a/packager/app/test/testdata/bear-640x360-a-por-golden.mp4 b/packager/app/test/testdata/bear-640x360-a-por-golden.mp4 index e2b16076c3..a68f12768a 100644 Binary files a/packager/app/test/testdata/bear-640x360-a-por-golden.mp4 and b/packager/app/test/testdata/bear-640x360-a-por-golden.mp4 differ diff --git a/packager/app/test/testdata/bear-640x360-av-cbc1-golden.mpd b/packager/app/test/testdata/bear-640x360-av-cbc1-golden.mpd index 9ec1f841c3..e79e6ef92f 100644 --- a/packager/app/test/testdata/bear-640x360-av-cbc1-golden.mpd +++ b/packager/app/test/testdata/bear-640x360-av-cbc1-golden.mpd @@ -7,10 +7,10 @@ AAAANHBzc2gBAAAAEHfv7MCyTQKs4zweUuL7SwAAAAExMjM0NTY3ODkwMTIzNDU2AAAAAA== - + output_video.mp4 - - + + @@ -19,11 +19,11 @@ AAAANHBzc2gBAAAAEHfv7MCyTQKs4zweUuL7SwAAAAExMjM0NTY3ODkwMTIzNDU2AAAAAA== - + output_audio.mp4 - - + + diff --git a/packager/app/test/testdata/bear-640x360-av-cbcs-golden.mpd b/packager/app/test/testdata/bear-640x360-av-cbcs-golden.mpd index 1e6f53721f..6349663e85 100644 --- a/packager/app/test/testdata/bear-640x360-av-cbcs-golden.mpd +++ b/packager/app/test/testdata/bear-640x360-av-cbcs-golden.mpd @@ -7,10 +7,10 @@ AAAANHBzc2gBAAAAEHfv7MCyTQKs4zweUuL7SwAAAAExMjM0NTY3ODkwMTIzNDU2AAAAAA== - + output_video.mp4 - - + + @@ -19,11 +19,11 @@ AAAANHBzc2gBAAAAEHfv7MCyTQKs4zweUuL7SwAAAAExMjM0NTY3ODkwMTIzNDU2AAAAAA== - + output_audio.mp4 - - + + diff --git a/packager/app/test/testdata/bear-640x360-av-cenc-golden.mpd b/packager/app/test/testdata/bear-640x360-av-cenc-golden.mpd index dee44d5362..e87441b29e 100644 --- a/packager/app/test/testdata/bear-640x360-av-cenc-golden.mpd +++ b/packager/app/test/testdata/bear-640x360-av-cenc-golden.mpd @@ -7,10 +7,10 @@ AAAANHBzc2gBAAAAEHfv7MCyTQKs4zweUuL7SwAAAAExMjM0NTY3ODkwMTIzNDU2AAAAAA== - + output_video.mp4 - - + + @@ -19,11 +19,11 @@ AAAANHBzc2gBAAAAEHfv7MCyTQKs4zweUuL7SwAAAAExMjM0NTY3ODkwMTIzNDU2AAAAAA== - + output_audio.mp4 - - + + diff --git a/packager/app/test/testdata/bear-640x360-av-cenc-no-pssh-golden.mpd b/packager/app/test/testdata/bear-640x360-av-cenc-no-pssh-golden.mpd new file mode 100644 index 0000000000..950b78976f --- /dev/null +++ b/packager/app/test/testdata/bear-640x360-av-cenc-no-pssh-golden.mpd @@ -0,0 +1,31 @@ + + + + + + + + AAAANHBzc2gBAAAAEHfv7MCyTQKs4zweUuL7SwAAAAExMjM0NTY3ODkwMTIzNDU2AAAAAA== + + + output_video.mp4 + + + + + + + + + AAAANHBzc2gBAAAAEHfv7MCyTQKs4zweUuL7SwAAAAExMjM0NTY3ODkwMTIzNDU2AAAAAA== + + + + output_audio.mp4 + + + + + + + diff --git a/packager/app/test/testdata/bear-640x360-av-cenc-non-iop-golden.mpd b/packager/app/test/testdata/bear-640x360-av-cenc-non-iop-golden.mpd index a8feca0925..8e38072ee0 100644 --- a/packager/app/test/testdata/bear-640x360-av-cenc-non-iop-golden.mpd +++ b/packager/app/test/testdata/bear-640x360-av-cenc-non-iop-golden.mpd @@ -3,27 +3,27 @@ - + AAAANHBzc2gBAAAAEHfv7MCyTQKs4zweUuL7SwAAAAExMjM0NTY3ODkwMTIzNDU2AAAAAA== output_video.mp4 - - + + - + AAAANHBzc2gBAAAAEHfv7MCyTQKs4zweUuL7SwAAAAExMjM0NTY3ODkwMTIzNDU2AAAAAA== output_audio.mp4 - - + + diff --git a/packager/app/test/testdata/bear-640x360-av-cens-golden.mpd b/packager/app/test/testdata/bear-640x360-av-cens-golden.mpd index d7254c5b27..edc1461ce1 100644 --- a/packager/app/test/testdata/bear-640x360-av-cens-golden.mpd +++ b/packager/app/test/testdata/bear-640x360-av-cens-golden.mpd @@ -7,10 +7,10 @@ AAAANHBzc2gBAAAAEHfv7MCyTQKs4zweUuL7SwAAAAExMjM0NTY3ODkwMTIzNDU2AAAAAA== - + output_video.mp4 - - + + @@ -19,11 +19,11 @@ AAAANHBzc2gBAAAAEHfv7MCyTQKs4zweUuL7SwAAAAExMjM0NTY3ODkwMTIzNDU2AAAAAA== - + output_audio.mp4 - - + + diff --git a/packager/app/test/testdata/bear-640x360-av-golden.mpd b/packager/app/test/testdata/bear-640x360-av-golden.mpd index 1b22d067cc..dfa8debf37 100644 --- a/packager/app/test/testdata/bear-640x360-av-golden.mpd +++ b/packager/app/test/testdata/bear-640x360-av-golden.mpd @@ -3,19 +3,19 @@ - + output_video.mp4 - - + + - + output_audio.mp4 - - + + diff --git a/packager/app/test/testdata/bear-640x360-av-live-cenc-golden.mpd b/packager/app/test/testdata/bear-640x360-av-live-cenc-golden.mpd index 7518715304..b904b4dde3 100644 --- a/packager/app/test/testdata/bear-640x360-av-live-cenc-golden.mpd +++ b/packager/app/test/testdata/bear-640x360-av-live-cenc-golden.mpd @@ -7,7 +7,7 @@ AAAANHBzc2gBAAAAEHfv7MCyTQKs4zweUuL7SwAAAAExMjM0NTY3ODkwMTIzNDU2AAAAAA== - + @@ -21,7 +21,7 @@ AAAANHBzc2gBAAAAEHfv7MCyTQKs4zweUuL7SwAAAAExMjM0NTY3ODkwMTIzNDU2AAAAAA== - + diff --git a/packager/app/test/testdata/bear-640x360-av-live-cenc-non-iop-golden.mpd b/packager/app/test/testdata/bear-640x360-av-live-cenc-non-iop-golden.mpd index e3768f912d..7358bb9452 100644 --- a/packager/app/test/testdata/bear-640x360-av-live-cenc-non-iop-golden.mpd +++ b/packager/app/test/testdata/bear-640x360-av-live-cenc-non-iop-golden.mpd @@ -3,7 +3,7 @@ - + AAAANHBzc2gBAAAAEHfv7MCyTQKs4zweUuL7SwAAAAExMjM0NTY3ODkwMTIzNDU2AAAAAA== @@ -17,7 +17,7 @@ - + diff --git a/packager/app/test/testdata/bear-640x360-av-live-cenc-rotation-golden.mpd b/packager/app/test/testdata/bear-640x360-av-live-cenc-rotation-golden.mpd index 07b81749c6..b0dbafdd3b 100644 --- a/packager/app/test/testdata/bear-640x360-av-live-cenc-rotation-golden.mpd +++ b/packager/app/test/testdata/bear-640x360-av-live-cenc-rotation-golden.mpd @@ -5,7 +5,7 @@ - + @@ -17,7 +17,7 @@ - + diff --git a/packager/app/test/testdata/bear-640x360-av-live-cenc-rotation-no-pssh-golden.mpd b/packager/app/test/testdata/bear-640x360-av-live-cenc-rotation-no-pssh-golden.mpd new file mode 100644 index 0000000000..fd2258b125 --- /dev/null +++ b/packager/app/test/testdata/bear-640x360-av-live-cenc-rotation-no-pssh-golden.mpd @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/packager/app/test/testdata/bear-640x360-av-live-cenc-rotation-non-iop-golden.mpd b/packager/app/test/testdata/bear-640x360-av-live-cenc-rotation-non-iop-golden.mpd index 4adc7ed781..53338d584b 100644 --- a/packager/app/test/testdata/bear-640x360-av-live-cenc-rotation-non-iop-golden.mpd +++ b/packager/app/test/testdata/bear-640x360-av-live-cenc-rotation-non-iop-golden.mpd @@ -3,7 +3,7 @@ - + @@ -15,7 +15,7 @@ - + diff --git a/packager/app/test/testdata/bear-640x360-av-live-golden.mpd b/packager/app/test/testdata/bear-640x360-av-live-golden.mpd index 125a7785a5..4faf8e66e8 100644 --- a/packager/app/test/testdata/bear-640x360-av-live-golden.mpd +++ b/packager/app/test/testdata/bear-640x360-av-live-golden.mpd @@ -3,7 +3,7 @@ - + @@ -13,7 +13,7 @@ - + diff --git a/packager/app/test/testdata/bear-640x360-av-live-static-golden.mpd b/packager/app/test/testdata/bear-640x360-av-live-static-golden.mpd index dfe32584f7..c5bc3d7bde 100644 --- a/packager/app/test/testdata/bear-640x360-av-live-static-golden.mpd +++ b/packager/app/test/testdata/bear-640x360-av-live-static-golden.mpd @@ -3,7 +3,7 @@ - + @@ -13,7 +13,7 @@ - + diff --git a/packager/app/test/testdata/bear-640x360-av-por-BR-golden.mpd b/packager/app/test/testdata/bear-640x360-av-por-BR-golden.mpd index 30687a598c..fde8124b13 100644 --- a/packager/app/test/testdata/bear-640x360-av-por-BR-golden.mpd +++ b/packager/app/test/testdata/bear-640x360-av-por-BR-golden.mpd @@ -3,19 +3,19 @@ - + output_video.mp4 - - + + - + output_audio.mp4 - - + + diff --git a/packager/app/test/testdata/bear-640x360-av-por-golden.mpd b/packager/app/test/testdata/bear-640x360-av-por-golden.mpd index 30687a598c..fde8124b13 100644 --- a/packager/app/test/testdata/bear-640x360-av-por-golden.mpd +++ b/packager/app/test/testdata/bear-640x360-av-por-golden.mpd @@ -3,19 +3,19 @@ - + output_video.mp4 - - + + - + output_audio.mp4 - - + + diff --git a/packager/app/test/testdata/bear-640x360-avt-golden.mpd b/packager/app/test/testdata/bear-640x360-avt-golden.mpd index 3a247b791a..46380e8396 100644 --- a/packager/app/test/testdata/bear-640x360-avt-golden.mpd +++ b/packager/app/test/testdata/bear-640x360-avt-golden.mpd @@ -8,19 +8,19 @@ - + output_video.mp4 - - + + - + output_audio.mp4 - - + + diff --git a/packager/app/test/testdata/bear-640x360-hevc-cenc-golden.mp4 b/packager/app/test/testdata/bear-640x360-hevc-cenc-golden.mp4 index 13e09541d0..ca1335d15e 100644 Binary files a/packager/app/test/testdata/bear-640x360-hevc-cenc-golden.mp4 and b/packager/app/test/testdata/bear-640x360-hevc-cenc-golden.mp4 differ diff --git a/packager/app/test/testdata/bear-640x360-hevc-cenc-golden.mpd b/packager/app/test/testdata/bear-640x360-hevc-cenc-golden.mpd index 0382a2a785..09fc89ed78 100644 --- a/packager/app/test/testdata/bear-640x360-hevc-cenc-golden.mpd +++ b/packager/app/test/testdata/bear-640x360-hevc-cenc-golden.mpd @@ -7,10 +7,10 @@ AAAANHBzc2gBAAAAEHfv7MCyTQKs4zweUuL7SwAAAAExMjM0NTY3ODkwMTIzNDU2AAAAAA== - + output_video.mp4 - - + + diff --git a/packager/app/test/testdata/bear-640x360-hevc-golden.mp4 b/packager/app/test/testdata/bear-640x360-hevc-golden.mp4 index 2a2f319c75..69170b8652 100644 Binary files a/packager/app/test/testdata/bear-640x360-hevc-golden.mp4 and b/packager/app/test/testdata/bear-640x360-hevc-golden.mp4 differ diff --git a/packager/app/test/testdata/bear-640x360-v-cbc1-golden.mp4 b/packager/app/test/testdata/bear-640x360-v-cbc1-golden.mp4 index 363097dac1..52993506af 100644 Binary files a/packager/app/test/testdata/bear-640x360-v-cbc1-golden.mp4 and b/packager/app/test/testdata/bear-640x360-v-cbc1-golden.mp4 differ diff --git a/packager/app/test/testdata/bear-640x360-v-cbcs-golden.mp4 b/packager/app/test/testdata/bear-640x360-v-cbcs-golden.mp4 index 235101a4b2..8bc2ea5aec 100644 Binary files a/packager/app/test/testdata/bear-640x360-v-cbcs-golden.mp4 and b/packager/app/test/testdata/bear-640x360-v-cbcs-golden.mp4 differ diff --git a/packager/app/test/testdata/bear-640x360-v-cenc-golden.mp4 b/packager/app/test/testdata/bear-640x360-v-cenc-golden.mp4 index 9b75ee0e42..7573a77be8 100644 Binary files a/packager/app/test/testdata/bear-640x360-v-cenc-golden.mp4 and b/packager/app/test/testdata/bear-640x360-v-cenc-golden.mp4 differ diff --git a/packager/app/test/testdata/bear-640x360-v-cenc-golden.mp4.media_info b/packager/app/test/testdata/bear-640x360-v-cenc-golden.mp4.media_info index fc9e2d2d9b..942ad37375 100644 --- a/packager/app/test/testdata/bear-640x360-v-cenc-golden.mp4.media_info +++ b/packager/app/test/testdata/bear-640x360-v-cenc-golden.mp4.media_info @@ -1,4 +1,4 @@ -bandwidth: 885567 +bandwidth: 885590 video_info { codec: "avc1.64001e" width: 640 @@ -11,11 +11,11 @@ video_info { } init_range { begin: 0 - end: 1082 + end: 1090 } index_range { - begin: 1083 - end: 1150 + begin: 1091 + end: 1158 } media_file_name: "place_holder" media_duration_seconds: 2.7360666 diff --git a/packager/app/test/testdata/bear-640x360-v-cenc-no-pssh-golden.mp4 b/packager/app/test/testdata/bear-640x360-v-cenc-no-pssh-golden.mp4 new file mode 100644 index 0000000000..69b13ea7c5 Binary files /dev/null and b/packager/app/test/testdata/bear-640x360-v-cenc-no-pssh-golden.mp4 differ diff --git a/packager/app/test/testdata/bear-640x360-v-cens-golden.mp4 b/packager/app/test/testdata/bear-640x360-v-cens-golden.mp4 index f0e5832eb2..2f4f828aa0 100644 Binary files a/packager/app/test/testdata/bear-640x360-v-cens-golden.mp4 and b/packager/app/test/testdata/bear-640x360-v-cens-golden.mp4 differ diff --git a/packager/app/test/testdata/bear-640x360-v-golden.mp4 b/packager/app/test/testdata/bear-640x360-v-golden.mp4 index f399c0c0d5..a4315c32cb 100644 Binary files a/packager/app/test/testdata/bear-640x360-v-golden.mp4 and b/packager/app/test/testdata/bear-640x360-v-golden.mp4 differ diff --git a/packager/app/test/testdata/bear-640x360-v-golden.mpd b/packager/app/test/testdata/bear-640x360-v-golden.mpd index ff72edae50..c78e29d393 100644 --- a/packager/app/test/testdata/bear-640x360-v-golden.mpd +++ b/packager/app/test/testdata/bear-640x360-v-golden.mpd @@ -3,10 +3,10 @@ - + output_0.mp4 - - + + diff --git a/packager/app/test/testdata/bear-640x360-v-live-cenc-golden-1.m4s b/packager/app/test/testdata/bear-640x360-v-live-cenc-golden-1.m4s index ccd7275418..c8e0ec8cfa 100644 Binary files a/packager/app/test/testdata/bear-640x360-v-live-cenc-golden-1.m4s and b/packager/app/test/testdata/bear-640x360-v-live-cenc-golden-1.m4s differ diff --git a/packager/app/test/testdata/bear-640x360-v-live-cenc-golden-2.m4s b/packager/app/test/testdata/bear-640x360-v-live-cenc-golden-2.m4s index 4139342010..0643459854 100644 Binary files a/packager/app/test/testdata/bear-640x360-v-live-cenc-golden-2.m4s and b/packager/app/test/testdata/bear-640x360-v-live-cenc-golden-2.m4s differ diff --git a/packager/app/test/testdata/bear-640x360-v-live-cenc-golden-3.m4s b/packager/app/test/testdata/bear-640x360-v-live-cenc-golden-3.m4s index 1ace57b8d7..c14b44bcf0 100644 Binary files a/packager/app/test/testdata/bear-640x360-v-live-cenc-golden-3.m4s and b/packager/app/test/testdata/bear-640x360-v-live-cenc-golden-3.m4s differ diff --git a/packager/app/test/testdata/bear-640x360-v-live-cenc-golden-init.mp4 b/packager/app/test/testdata/bear-640x360-v-live-cenc-golden-init.mp4 index bb28541bdc..08e6c418ad 100644 Binary files a/packager/app/test/testdata/bear-640x360-v-live-cenc-golden-init.mp4 and b/packager/app/test/testdata/bear-640x360-v-live-cenc-golden-init.mp4 differ diff --git a/packager/app/test/testdata/bear-640x360-v-live-cenc-rotation-golden-1.m4s b/packager/app/test/testdata/bear-640x360-v-live-cenc-rotation-golden-1.m4s index 51af483cb6..5ff1a7ced3 100644 Binary files a/packager/app/test/testdata/bear-640x360-v-live-cenc-rotation-golden-1.m4s and b/packager/app/test/testdata/bear-640x360-v-live-cenc-rotation-golden-1.m4s differ diff --git a/packager/app/test/testdata/bear-640x360-v-live-cenc-rotation-golden-2.m4s b/packager/app/test/testdata/bear-640x360-v-live-cenc-rotation-golden-2.m4s index d488ecd050..f39ee26d7e 100644 Binary files a/packager/app/test/testdata/bear-640x360-v-live-cenc-rotation-golden-2.m4s and b/packager/app/test/testdata/bear-640x360-v-live-cenc-rotation-golden-2.m4s differ diff --git a/packager/app/test/testdata/bear-640x360-v-live-cenc-rotation-golden-3.m4s b/packager/app/test/testdata/bear-640x360-v-live-cenc-rotation-golden-3.m4s index f9d475d4a8..4a91b498a4 100644 Binary files a/packager/app/test/testdata/bear-640x360-v-live-cenc-rotation-golden-3.m4s and b/packager/app/test/testdata/bear-640x360-v-live-cenc-rotation-golden-3.m4s differ diff --git a/packager/app/test/testdata/bear-640x360-v-live-cenc-rotation-golden-init.mp4 b/packager/app/test/testdata/bear-640x360-v-live-cenc-rotation-golden-init.mp4 index 3ca04d061a..c3a9ab7a21 100644 Binary files a/packager/app/test/testdata/bear-640x360-v-live-cenc-rotation-golden-init.mp4 and b/packager/app/test/testdata/bear-640x360-v-live-cenc-rotation-golden-init.mp4 differ diff --git a/packager/app/test/testdata/bear-640x360-v-live-cenc-rotation-no-pssh-golden-1.m4s b/packager/app/test/testdata/bear-640x360-v-live-cenc-rotation-no-pssh-golden-1.m4s new file mode 100644 index 0000000000..c8e0ec8cfa Binary files /dev/null and b/packager/app/test/testdata/bear-640x360-v-live-cenc-rotation-no-pssh-golden-1.m4s differ diff --git a/packager/app/test/testdata/bear-640x360-v-live-cenc-rotation-no-pssh-golden-2.m4s b/packager/app/test/testdata/bear-640x360-v-live-cenc-rotation-no-pssh-golden-2.m4s new file mode 100644 index 0000000000..954d3fffbd Binary files /dev/null and b/packager/app/test/testdata/bear-640x360-v-live-cenc-rotation-no-pssh-golden-2.m4s differ diff --git a/packager/app/test/testdata/bear-640x360-v-live-cenc-rotation-no-pssh-golden-3.m4s b/packager/app/test/testdata/bear-640x360-v-live-cenc-rotation-no-pssh-golden-3.m4s new file mode 100644 index 0000000000..ef6de1a4b8 Binary files /dev/null and b/packager/app/test/testdata/bear-640x360-v-live-cenc-rotation-no-pssh-golden-3.m4s differ diff --git a/packager/app/test/testdata/bear-640x360-v-live-cenc-rotation-no-pssh-golden-init.mp4 b/packager/app/test/testdata/bear-640x360-v-live-cenc-rotation-no-pssh-golden-init.mp4 new file mode 100644 index 0000000000..c3a9ab7a21 Binary files /dev/null and b/packager/app/test/testdata/bear-640x360-v-live-cenc-rotation-no-pssh-golden-init.mp4 differ diff --git a/packager/app/test/testdata/bear-640x360-v-live-golden-1.m4s b/packager/app/test/testdata/bear-640x360-v-live-golden-1.m4s index fce03f2646..e8a21a613c 100644 Binary files a/packager/app/test/testdata/bear-640x360-v-live-golden-1.m4s and b/packager/app/test/testdata/bear-640x360-v-live-golden-1.m4s differ diff --git a/packager/app/test/testdata/bear-640x360-v-live-golden-2.m4s b/packager/app/test/testdata/bear-640x360-v-live-golden-2.m4s index 92e49e7076..311f93260e 100644 Binary files a/packager/app/test/testdata/bear-640x360-v-live-golden-2.m4s and b/packager/app/test/testdata/bear-640x360-v-live-golden-2.m4s differ diff --git a/packager/app/test/testdata/bear-640x360-v-live-golden-3.m4s b/packager/app/test/testdata/bear-640x360-v-live-golden-3.m4s index 54a382befd..71e371e17a 100644 Binary files a/packager/app/test/testdata/bear-640x360-v-live-golden-3.m4s and b/packager/app/test/testdata/bear-640x360-v-live-golden-3.m4s differ diff --git a/packager/app/test/testdata/bear-640x360-v-live-golden-init.mp4 b/packager/app/test/testdata/bear-640x360-v-live-golden-init.mp4 index 1726955b76..b183dc5d1c 100644 Binary files a/packager/app/test/testdata/bear-640x360-v-live-golden-init.mp4 and b/packager/app/test/testdata/bear-640x360-v-live-golden-init.mp4 differ diff --git a/packager/app/test/testdata/bear-640x360-vp8-cenc-golden.mp4 b/packager/app/test/testdata/bear-640x360-vp8-cenc-golden.mp4 index 6f7bb1256a..81c04f212c 100644 Binary files a/packager/app/test/testdata/bear-640x360-vp8-cenc-golden.mp4 and b/packager/app/test/testdata/bear-640x360-vp8-cenc-golden.mp4 differ diff --git a/packager/app/test/testdata/bear-640x360-vp8-cenc-golden.mpd b/packager/app/test/testdata/bear-640x360-vp8-cenc-golden.mpd index 8f7f6e2517..893418c5f6 100644 --- a/packager/app/test/testdata/bear-640x360-vp8-cenc-golden.mpd +++ b/packager/app/test/testdata/bear-640x360-vp8-cenc-golden.mpd @@ -7,10 +7,10 @@ AAAANHBzc2gBAAAAEHfv7MCyTQKs4zweUuL7SwAAAAExMjM0NTY3ODkwMTIzNDU2AAAAAA== - + output_video.mp4 - - + + diff --git a/packager/app/test/testdata/bear-640x360-vp8-golden.mp4 b/packager/app/test/testdata/bear-640x360-vp8-golden.mp4 index dabfead815..3c7843fb39 100644 Binary files a/packager/app/test/testdata/bear-640x360-vp8-golden.mp4 and b/packager/app/test/testdata/bear-640x360-vp8-golden.mp4 differ diff --git a/packager/media/base/fixed_key_source.cc b/packager/media/base/fixed_key_source.cc index fcc1b116b1..64918372f2 100644 --- a/packager/media/base/fixed_key_source.cc +++ b/packager/media/base/fixed_key_source.cc @@ -103,6 +103,11 @@ std::unique_ptr FixedKeySource::CreateFromHexStrings( if (!base::HexStringToBytes(key_hex, &encryption_key->key)) { LOG(ERROR) << "Cannot parse key_hex " << key_hex; return std::unique_ptr(); + } else if (encryption_key->key.size() != 16) { + // CENC only supports AES-128, i.e. 16 bytes. + LOG(ERROR) << "Invalid key size '" << encryption_key->key.size() + << "', must be 16 bytes."; + return std::unique_ptr(); } std::vector pssh_boxes; diff --git a/packager/media/base/fourccs.h b/packager/media/base/fourccs.h index 153949739d..a999a5e058 100644 --- a/packager/media/base/fourccs.h +++ b/packager/media/base/fourccs.h @@ -32,6 +32,8 @@ enum FourCC : uint32_t { FOURCC_cenc = 0x63656e63, FOURCC_cens = 0x63656e73, FOURCC_co64 = 0x636f3634, + FOURCC_cmfc = 0x636d6663, + FOURCC_cmfs = 0x636d6673, FOURCC_ctim = 0x6374696d, FOURCC_ctts = 0x63747473, FOURCC_dOps = 0x644f7073, @@ -63,6 +65,8 @@ enum FourCC : uint32_t { FOURCC_hvcC = 0x68766343, FOURCC_iden = 0x6964656e, FOURCC_iso6 = 0x69736f36, + FOURCC_iso8 = 0x69736f38, + FOURCC_isom = 0x69736f6d, FOURCC_iods = 0x696f6473, FOURCC_mdat = 0x6d646174, FOURCC_mdhd = 0x6d646864, diff --git a/packager/media/base/muxer_options.h b/packager/media/base/muxer_options.h index 11e37a88d1..640a0942f1 100644 --- a/packager/media/base/muxer_options.h +++ b/packager/media/base/muxer_options.h @@ -50,6 +50,12 @@ struct MuxerOptions { /// User-specified bit rate for the media stream. If zero, the muxer will /// attempt to estimate. uint32_t bandwidth = 0; + + // MP4 only: include pssh in the encrypted stream. CMAF recommends carrying + // license acquisition information in the manifest and not duplicate the + // information in the stream. (This is not a hard requirement so we are still + // CMAF compatible even if pssh is included in the stream.) + bool mp4_include_pssh_in_stream = true; }; } // namespace media diff --git a/packager/media/crypto/encryption_handler.cc b/packager/media/crypto/encryption_handler.cc index 41471e248f..8dbc43c579 100644 --- a/packager/media/crypto/encryption_handler.cc +++ b/packager/media/crypto/encryption_handler.cc @@ -463,8 +463,12 @@ bool EncryptionHandler::EncryptNalFrame(MediaSample* sample, // ISO/IEC 23001-7:2016 10.2 'cbc1' 10.3 'cens' // The BytesOfProtectedData size SHALL be a multiple of 16 bytes to // avoid partial blocks in Subsamples. + // CMAF requires 'cenc' scheme BytesOfProtectedData SHALL be a multiple + // of 16 bytes; while 'cbcs' scheme BytesOfProtectedData SHALL start on + // the first byte of video data following the slice header. if (encryption_options_.protection_scheme == FOURCC_cbc1 || - encryption_options_.protection_scheme == FOURCC_cens) { + encryption_options_.protection_scheme == FOURCC_cens || + encryption_options_.protection_scheme == FOURCC_cenc) { const uint16_t misalign_bytes = cipher_bytes % kCencBlockSize; current_clear_bytes += misalign_bytes; cipher_bytes -= misalign_bytes; diff --git a/packager/media/crypto/encryption_handler_unittest.cc b/packager/media/crypto/encryption_handler_unittest.cc index 9341ab2f49..f5c07e6bea 100644 --- a/packager/media/crypto/encryption_handler_unittest.cc +++ b/packager/media/crypto/encryption_handler_unittest.cc @@ -237,7 +237,8 @@ class EncryptionHandlerEncryptionTest subsamples.emplace_back(static_cast(kSubsampleSize3), 0u); } else { if (codec_ == kCodecVP9 || protection_scheme_ == FOURCC_cbc1 || - protection_scheme_ == FOURCC_cens) { + protection_scheme_ == FOURCC_cens || + protection_scheme_ == FOURCC_cenc) { // Align the encrypted bytes to multiple of 16 bytes. subsamples.emplace_back(static_cast(kAlignedClearSize1), static_cast(kAlignedCipherSize1)); diff --git a/packager/media/formats/mp4/box_definitions.cc b/packager/media/formats/mp4/box_definitions.cc index 37a1eb6e95..95ff6e2e34 100644 --- a/packager/media/formats/mp4/box_definitions.cc +++ b/packager/media/formats/mp4/box_definitions.cc @@ -562,7 +562,7 @@ TrackHeader::TrackHeader() volume(-1), width(0), height(0) { - flags = kTrackEnabled | kTrackInMovie; + flags = kTrackEnabled | kTrackInMovie | kTrackInPreview; } TrackHeader::~TrackHeader() {} FourCC TrackHeader::BoxType() const { return FOURCC_tkhd; } @@ -2219,16 +2219,17 @@ bool Movie::ReadWriteInternal(BoxBuffer* buffer) { RCHECK(ReadWriteHeaderInternal(buffer) && buffer->PrepareChildren() && buffer->ReadWriteChild(&header) && - buffer->TryReadWriteChild(&metadata) && - buffer->TryReadWriteChild(&extends)); + buffer->TryReadWriteChild(&metadata)); if (buffer->Reading()) { BoxReader* reader = buffer->reader(); DCHECK(reader); RCHECK(reader->ReadChildren(&tracks) && + reader->TryReadChild(&extends) && reader->TryReadChildren(&pssh)); } else { for (uint32_t i = 0; i < tracks.size(); ++i) RCHECK(buffer->ReadWriteChild(&tracks[i])); + RCHECK(buffer->TryReadWriteChild(&extends)); for (uint32_t i = 0; i < pssh.size(); ++i) RCHECK(buffer->ReadWriteChild(&pssh[i])); } diff --git a/packager/media/formats/mp4/mp4_muxer.cc b/packager/media/formats/mp4/mp4_muxer.cc index af10f4a06f..6f03533f9a 100644 --- a/packager/media/formats/mp4/mp4_muxer.cc +++ b/packager/media/formats/mp4/mp4_muxer.cc @@ -115,15 +115,27 @@ Status MP4Muxer::InitializeMuxer() { std::unique_ptr ftyp(new FileType); std::unique_ptr moov(new Movie); - ftyp->major_brand = FOURCC_dash; - ftyp->compatible_brands.push_back(FOURCC_iso6); + ftyp->major_brand = FOURCC_isom; + ftyp->compatible_brands.push_back(FOURCC_iso8); ftyp->compatible_brands.push_back(FOURCC_mp41); - if (streams().size() == 1 && streams()[0]->stream_type() == kStreamVideo) { - const FourCC codec_fourcc = CodecToFourCC( - streams()[0]->codec(), static_cast(streams()[0].get()) - ->h26x_stream_format()); - if (codec_fourcc != FOURCC_NULL) - ftyp->compatible_brands.push_back(codec_fourcc); + ftyp->compatible_brands.push_back(FOURCC_dash); + + if (streams().size() == 1) { + FourCC codec_fourcc = FOURCC_NULL; + if (streams()[0]->stream_type() == kStreamVideo) { + codec_fourcc = + CodecToFourCC(streams()[0]->codec(), + static_cast(streams()[0].get()) + ->h26x_stream_format()); + if (codec_fourcc != FOURCC_NULL) + ftyp->compatible_brands.push_back(codec_fourcc); + } + + // CMAF allows only one track/stream per file. + // CMAF requires single initialization switching for AVC3/HEV1, which is not + // supported yet. + if (codec_fourcc != FOURCC_avc3 && codec_fourcc != FOURCC_hev1) + ftyp->compatible_brands.push_back(FOURCC_cmfc); } moov->header.creation_time = IsoTimeNow(); @@ -160,7 +172,7 @@ Status MP4Muxer::InitializeMuxer() { << streams()[i]->stream_type(); } - if (streams()[i]->is_encrypted()) { + if (streams()[i]->is_encrypted() && options().mp4_include_pssh_in_stream) { const auto& key_system_info = streams()[i]->encryption_config().key_system_info; moov->pssh.resize(key_system_info.size()); diff --git a/packager/media/formats/mp4/multi_segment_segmenter.cc b/packager/media/formats/mp4/multi_segment_segmenter.cc index 0ddff48301..8bb00532ef 100644 --- a/packager/media/formats/mp4/multi_segment_segmenter.cc +++ b/packager/media/formats/mp4/multi_segment_segmenter.cc @@ -30,6 +30,9 @@ MultiSegmentSegmenter::MultiSegmentSegmenter(const MuxerOptions& options, // Use the same brands for styp as ftyp. styp_->major_brand = Segmenter::ftyp()->major_brand; styp_->compatible_brands = Segmenter::ftyp()->compatible_brands; + // Replace 'cmfc' with 'cmfs' for CMAF segments compatibility. + std::replace(styp_->compatible_brands.begin(), styp_->compatible_brands.end(), + FOURCC_cmfc, FOURCC_cmfs); } MultiSegmentSegmenter::~MultiSegmentSegmenter() {} diff --git a/packager/media/formats/mp4/segmenter.cc b/packager/media/formats/mp4/segmenter.cc index f76d166073..9dd804c42b 100644 --- a/packager/media/formats/mp4/segmenter.cc +++ b/packager/media/formats/mp4/segmenter.cc @@ -42,11 +42,7 @@ Segmenter::Segmenter(const MuxerOptions& options, moov_(std::move(moov)), moof_(new MovieFragment()), fragment_buffer_(new BufferWriter()), - sidx_(new SegmentIndex()), - progress_listener_(NULL), - progress_target_(0), - accumulated_progress_(0), - sample_duration_(0u) {} + sidx_(new SegmentIndex()) {} Segmenter::~Segmenter() {} @@ -61,6 +57,7 @@ Status Segmenter::Initialize( moof_->tracks.resize(streams.size()); fragmenters_.resize(streams.size()); + stream_durations_.resize(streams.size()); for (uint32_t i = 0; i < streams.size(); ++i) { moof_->tracks[i].header.track_id = i + 1; @@ -101,20 +98,17 @@ Status Segmenter::Initialize( } Status Segmenter::Finalize() { - // Set tracks and moov durations. - // Note that the updated moov box will be written to output file for VOD case - // only. - for (std::vector::iterator track = moov_->tracks.begin(); - track != moov_->tracks.end(); - ++track) { - track->header.duration = Rescale(track->media.header.duration, - track->media.header.timescale, - moov_->header.timescale); - if (track->header.duration > moov_->header.duration) - moov_->header.duration = track->header.duration; + // Set movie duration. Note that the duration in mvhd, tkhd, mdhd should not + // be touched, i.e. kept at 0. The updated moov box will be written to output + // file for VOD case only. + moov_->extends.header.fragment_duration = 0; + for (size_t i = 0; i < stream_durations_.size(); ++i) { + uint64_t duration = + Rescale(stream_durations_[i], moov_->tracks[i].media.header.timescale, + moov_->header.timescale); + if (duration > moov_->extends.header.fragment_duration) + moov_->extends.header.fragment_duration = duration; } - moov_->extends.header.fragment_duration = moov_->header.duration; - return DoFinalize(); } @@ -139,7 +133,7 @@ Status Segmenter::AddSample(size_t stream_id, if (sample_duration_ == 0) sample_duration_ = sample->duration(); - moov_->tracks[stream_id].media.header.duration += sample->duration(); + stream_durations_[stream_id] += sample->duration(); return Status::OK; } @@ -220,12 +214,12 @@ uint32_t Segmenter::GetReferenceTimeScale() const { } double Segmenter::GetDuration() const { - if (moov_->header.timescale == 0) { + uint64_t duration = moov_->extends.header.fragment_duration; + if (duration == 0) { // Handling the case where this is not properly initialized. return 0.0; } - - return static_cast(moov_->header.duration) / moov_->header.timescale; + return static_cast(duration) / moov_->header.timescale; } void Segmenter::UpdateProgress(uint64_t progress) { @@ -258,11 +252,16 @@ void Segmenter::FinalizeFragmentForKeyRotation( size_t stream_id, bool fragment_encrypted, const EncryptionConfig& encryption_config) { - const std::vector& system_info = - encryption_config.key_system_info; - moof_->pssh.resize(system_info.size()); - for (size_t i = 0; i < system_info.size(); i++) - moof_->pssh[i].raw_box = system_info[i].CreateBox(); + if (options_.mp4_include_pssh_in_stream) { + const std::vector& system_info = + encryption_config.key_system_info; + moof_->pssh.resize(system_info.size()); + for (size_t i = 0; i < system_info.size(); i++) + moof_->pssh[i].raw_box = system_info[i].CreateBox(); + } else { + LOG(WARNING) + << "Key rotation and no pssh in stream may not work well together."; + } // Skip the following steps if the current fragment is not going to be // encrypted. 'pssh' box needs to be included in the fragment, which is diff --git a/packager/media/formats/mp4/segmenter.h b/packager/media/formats/mp4/segmenter.h index 27c7459811..9956414c15 100644 --- a/packager/media/formats/mp4/segmenter.h +++ b/packager/media/formats/mp4/segmenter.h @@ -127,11 +127,12 @@ class Segmenter { std::unique_ptr fragment_buffer_; std::unique_ptr sidx_; std::vector> fragmenters_; - MuxerListener* muxer_listener_; - ProgressListener* progress_listener_; - uint64_t progress_target_; - uint64_t accumulated_progress_; - uint32_t sample_duration_; + MuxerListener* muxer_listener_ = nullptr; + ProgressListener* progress_listener_ = nullptr; + uint64_t progress_target_ = 0u; + uint64_t accumulated_progress_ = 0u; + uint32_t sample_duration_ = 0u; + std::vector stream_durations_; DISALLOW_COPY_AND_ASSIGN(Segmenter); };