diff --git a/packager/app/test/packager_test.py b/packager/app/test/packager_test.py index 399837e441..c7c5c0ad1f 100755 --- a/packager/app/test/packager_test.py +++ b/packager/app/test/packager_test.py @@ -354,6 +354,34 @@ class PackagerAppTest(unittest.TestCase): self._VerifyDecryption(self.output[0], 'bear-320x240-opus-golden.mp4') self._VerifyDecryption(self.output[1], 'bear-320x240-vp9-golden.mp4') + def testPackageWvmInput(self): + self.packager.Package( + self._GetStreams( + ['0', '1', '2', '3'], test_files=['bear-multi-configs.wvm']), + self._GetFlags( + decryption=True, encryption_key='9248d245390e0a49d483ba9b43fc69c3')) + # Output timescale is 90000. + self._DiffGold(self.output[0], 'bear-320x180-v-wvm-golden.mp4') + self._DiffGold(self.output[1], 'bear-320x180-a-wvm-golden.mp4') + self._DiffGold(self.output[2], 'bear-640x360-v-wvm-golden.mp4') + self._DiffGold(self.output[3], 'bear-640x360-a-wvm-golden.mp4') + self._DiffGold(self.mpd_output, 'bear-wvm-golden.mpd') + + def testPackageWvmInputWithoutStrippingParameterSetNalus(self): + self.packager.Package( + self._GetStreams( + ['0', '1', '2', '3'], test_files=['bear-multi-configs.wvm']), + self._GetFlags( + strip_parameter_set_nalus=False, + decryption=True, + encryption_key='9248d245390e0a49d483ba9b43fc69c3')) + # Output timescale is 90000. + self._DiffGold(self.output[0], 'bear-320x180-avc3-wvm-golden.mp4') + self._DiffGold(self.output[1], 'bear-320x180-a-wvm-golden.mp4') + self._DiffGold(self.output[2], 'bear-640x360-avc3-wvm-golden.mp4') + self._DiffGold(self.output[3], 'bear-640x360-a-wvm-golden.mp4') + self._DiffGold(self.mpd_output, 'bear-avc3-wvm-golden.mpd') + def testPackageWithEncryptionAndRandomIv(self): self.packager.Package( self._GetStreams(['audio', 'video']), @@ -582,6 +610,7 @@ class PackagerAppTest(unittest.TestCase): return 'mp4' def _GetFlags(self, + strip_parameter_set_nalus=True, encryption=False, protection_scheme=None, vp9_subsample_encryption=True, @@ -598,6 +627,10 @@ class PackagerAppTest(unittest.TestCase): generate_static_mpd=False, use_fake_clock=True): flags = [] + + if not strip_parameter_set_nalus: + flags += ['--strip_parameter_set_nalus=false'] + if widevine_encryption: widevine_server_url = ('https://license.uat.widevine.com/cenc' '/getcontentkey/widevine_test') @@ -624,7 +657,7 @@ class PackagerAppTest(unittest.TestCase): if decryption: flags += ['--enable_fixed_key_decryption', '--key_id=31323334353637383930313233343536', - '--key=32333435363738393021323334353637'] + '--key=' + encryption_key] if key_rotation: flags.append('--crypto_period_duration=1') diff --git a/packager/app/test/testdata/bear-320x180-a-wvm-golden.mp4 b/packager/app/test/testdata/bear-320x180-a-wvm-golden.mp4 new file mode 100644 index 0000000000..1de4b6a9e8 Binary files /dev/null and b/packager/app/test/testdata/bear-320x180-a-wvm-golden.mp4 differ diff --git a/packager/app/test/testdata/bear-320x180-avc3-wvm-golden.mp4 b/packager/app/test/testdata/bear-320x180-avc3-wvm-golden.mp4 new file mode 100644 index 0000000000..5dfff29f96 Binary files /dev/null and b/packager/app/test/testdata/bear-320x180-avc3-wvm-golden.mp4 differ diff --git a/packager/app/test/testdata/bear-320x180-v-wvm-golden.mp4 b/packager/app/test/testdata/bear-320x180-v-wvm-golden.mp4 new file mode 100644 index 0000000000..9e3752e3b3 Binary files /dev/null and b/packager/app/test/testdata/bear-320x180-v-wvm-golden.mp4 differ diff --git a/packager/app/test/testdata/bear-640x360-a-wvm-golden.mp4 b/packager/app/test/testdata/bear-640x360-a-wvm-golden.mp4 new file mode 100644 index 0000000000..d7a846f1b8 Binary files /dev/null and b/packager/app/test/testdata/bear-640x360-a-wvm-golden.mp4 differ diff --git a/packager/app/test/testdata/bear-640x360-avc3-wvm-golden.mp4 b/packager/app/test/testdata/bear-640x360-avc3-wvm-golden.mp4 new file mode 100644 index 0000000000..1c0e5237cf Binary files /dev/null and b/packager/app/test/testdata/bear-640x360-avc3-wvm-golden.mp4 differ diff --git a/packager/app/test/testdata/bear-640x360-v-wvm-golden.mp4 b/packager/app/test/testdata/bear-640x360-v-wvm-golden.mp4 new file mode 100644 index 0000000000..ba70a00d9b Binary files /dev/null and b/packager/app/test/testdata/bear-640x360-v-wvm-golden.mp4 differ diff --git a/packager/app/test/testdata/bear-640x360-vp9-fullsample-dec-golden.webm b/packager/app/test/testdata/bear-640x360-vp9-fullsample-dec-golden.webm deleted file mode 100644 index ae1c97b480..0000000000 Binary files a/packager/app/test/testdata/bear-640x360-vp9-fullsample-dec-golden.webm and /dev/null differ diff --git a/packager/app/test/testdata/bear-avc3-wvm-golden.mpd b/packager/app/test/testdata/bear-avc3-wvm-golden.mpd new file mode 100644 index 0000000000..34da6e83fc --- /dev/null +++ b/packager/app/test/testdata/bear-avc3-wvm-golden.mpd @@ -0,0 +1,36 @@ + + + + + + + output_0.mp4 + + + + + + output_2.mp4 + + + + + + + + + output_1.mp4 + + + + + + + output_3.mp4 + + + + + + + diff --git a/packager/app/test/testdata/bear-wvm-golden.mpd b/packager/app/test/testdata/bear-wvm-golden.mpd new file mode 100644 index 0000000000..e14c797b8e --- /dev/null +++ b/packager/app/test/testdata/bear-wvm-golden.mpd @@ -0,0 +1,36 @@ + + + + + + + output_0.mp4 + + + + + + output_2.mp4 + + + + + + + + + output_1.mp4 + + + + + + + output_3.mp4 + + + + + + + diff --git a/packager/media/codecs/avc_decoder_configuration_record.cc b/packager/media/codecs/avc_decoder_configuration_record.cc index 5233b031c6..b8503c348a 100644 --- a/packager/media/codecs/avc_decoder_configuration_record.cc +++ b/packager/media/codecs/avc_decoder_configuration_record.cc @@ -88,18 +88,21 @@ bool AVCDecoderConfigurationRecord::ParseInternal() { return true; } -std::string AVCDecoderConfigurationRecord::GetCodecString() const { - return GetCodecString(profile_indication_, profile_compatibility_, - avc_level_); +std::string AVCDecoderConfigurationRecord::GetCodecString( + FourCC codec_fourcc) const { + return GetCodecString(codec_fourcc, profile_indication_, + profile_compatibility_, avc_level_); } std::string AVCDecoderConfigurationRecord::GetCodecString( + FourCC codec_fourcc, uint8_t profile_indication, uint8_t profile_compatibility, uint8_t avc_level) { const uint8_t bytes[] = {profile_indication, profile_compatibility, avc_level}; - return "avc1." + base::ToLowerASCII(base::HexEncode(bytes, arraysize(bytes))); + return FourCCToString(codec_fourcc) + "." + + base::ToLowerASCII(base::HexEncode(bytes, arraysize(bytes))); } } // namespace media diff --git a/packager/media/codecs/avc_decoder_configuration_record.h b/packager/media/codecs/avc_decoder_configuration_record.h index ab53af66b3..91a4419c14 100644 --- a/packager/media/codecs/avc_decoder_configuration_record.h +++ b/packager/media/codecs/avc_decoder_configuration_record.h @@ -12,6 +12,7 @@ #include #include "packager/base/macros.h" +#include "packager/media/base/fourccs.h" #include "packager/media/codecs/decoder_configuration_record.h" namespace shaka { @@ -24,7 +25,7 @@ class AVCDecoderConfigurationRecord : public DecoderConfigurationRecord { ~AVCDecoderConfigurationRecord() override; /// @return The codec string. - std::string GetCodecString() const; + std::string GetCodecString(FourCC codec_fourcc) const; uint8_t version() const { return version_; } uint8_t profile_indication() const { return profile_indication_; } @@ -37,7 +38,8 @@ class AVCDecoderConfigurationRecord : public DecoderConfigurationRecord { /// Static version of GetCodecString. /// @return The codec string. - static std::string GetCodecString(uint8_t profile_indication, + static std::string GetCodecString(FourCC codec_fourcc, + uint8_t profile_indication, uint8_t profile_compatibility, uint8_t avc_level); diff --git a/packager/media/codecs/avc_decoder_configuration_record_unittest.cc b/packager/media/codecs/avc_decoder_configuration_record_unittest.cc index e00f60b986..4816aad618 100644 --- a/packager/media/codecs/avc_decoder_configuration_record_unittest.cc +++ b/packager/media/codecs/avc_decoder_configuration_record_unittest.cc @@ -32,7 +32,8 @@ TEST(AVCDecoderConfigurationRecordTest, Success) { EXPECT_EQ(8u, avc_config.pixel_width()); EXPECT_EQ(9u, avc_config.pixel_height()); - EXPECT_EQ("avc1.64001e", avc_config.GetCodecString()); + EXPECT_EQ("avc1.64001e", avc_config.GetCodecString(FOURCC_avc1)); + EXPECT_EQ("avc3.64001e", avc_config.GetCodecString(FOURCC_avc3)); } TEST(AVCDecoderConfigurationRecordTest, FailsOnInvalidNaluLengthSize) { @@ -56,8 +57,8 @@ TEST(AVCDecoderConfigurationRecordTest, FailOnInsufficientData) { } TEST(AVCDecoderConfigurationRecordTest, GetCodecString) { - EXPECT_EQ("avc1.123456", - AVCDecoderConfigurationRecord::GetCodecString(0x12, 0x34, 0x56)); + EXPECT_EQ("avc1.123456", AVCDecoderConfigurationRecord::GetCodecString( + FOURCC_avc1, 0x12, 0x34, 0x56)); } } // namespace media diff --git a/packager/media/formats/mp2t/es_parser_h264.cc b/packager/media/formats/mp2t/es_parser_h264.cc index b71b958e9c..8a609a7cdd 100644 --- a/packager/media/formats/mp2t/es_parser_h264.cc +++ b/packager/media/formats/mp2t/es_parser_h264.cc @@ -148,12 +148,16 @@ bool EsParserH264::UpdateVideoDecoderConfig(int pps_id) { const uint8_t nalu_length_size = H26xByteToUnitStreamConverter::kUnitStreamNaluLengthSize; + const H26xStreamFormat stream_format = stream_converter()->stream_format(); + const FourCC codec_fourcc = + stream_format == H26xStreamFormat::kNalUnitStreamWithParameterSetNalus + ? FOURCC_avc3 + : FOURCC_avc1; last_video_decoder_config_ = std::make_shared( - pid(), kMpeg2Timescale, kInfiniteDuration, kCodecH264, - stream_converter()->stream_format(), - AVCDecoderConfigurationRecord::GetCodecString(decoder_config_record[1], - decoder_config_record[2], - decoder_config_record[3]), + pid(), kMpeg2Timescale, kInfiniteDuration, kCodecH264, stream_format, + AVCDecoderConfigurationRecord::GetCodecString( + codec_fourcc, decoder_config_record[1], decoder_config_record[2], + decoder_config_record[3]), decoder_config_record.data(), decoder_config_record.size(), coded_width, coded_height, pixel_width, pixel_height, 0, nalu_length_size, std::string(), false); diff --git a/packager/media/formats/mp4/mp4_media_parser.cc b/packager/media/formats/mp4/mp4_media_parser.cc index 1b6e93ad3c..2ee1676aae 100644 --- a/packager/media/formats/mp4/mp4_media_parser.cc +++ b/packager/media/formats/mp4/mp4_media_parser.cc @@ -520,7 +520,7 @@ bool MP4MediaParser::ParseMoov(BoxReader* reader) { LOG(ERROR) << "Failed to parse avcc."; return false; } - codec_string = avc_config.GetCodecString(); + codec_string = avc_config.GetCodecString(actual_format); nalu_length_size = avc_config.nalu_length_size(); if (coded_width != avc_config.coded_width() || diff --git a/packager/media/formats/wvm/wvm_media_parser.cc b/packager/media/formats/wvm/wvm_media_parser.cc index 83376816aa..f4214fd0ce 100644 --- a/packager/media/formats/wvm/wvm_media_parser.cc +++ b/packager/media/formats/wvm/wvm_media_parser.cc @@ -861,7 +861,13 @@ bool WvmMediaParser::Output(bool output_encrypted_sample) { return false; } } - video_stream_info->set_codec_string(avc_config.GetCodecString()); + const FourCC codec_fourcc = + byte_to_unit_stream_converter_.stream_format() == + H26xStreamFormat::kNalUnitStreamWithParameterSetNalus + ? FOURCC_avc3 + : FOURCC_avc1; + video_stream_info->set_codec_string( + avc_config.GetCodecString(codec_fourcc)); if (avc_config.pixel_width() != video_stream_info->pixel_width() || avc_config.pixel_height() != diff --git a/packager/media/formats/wvm/wvm_media_parser_unittest.cc b/packager/media/formats/wvm/wvm_media_parser_unittest.cc index 0b26519ba7..b7ddf5cc22 100644 --- a/packager/media/formats/wvm/wvm_media_parser_unittest.cc +++ b/packager/media/formats/wvm/wvm_media_parser_unittest.cc @@ -215,7 +215,7 @@ TEST_F(WvmMediaParserTest, ParseMultiConfigWvm) { EXPECT_CALL(*key_source_, GetKey(_, _)) .WillOnce(DoAll(SetArgPointee<1>(encryption_key_), Return(Status::OK))); Parse(kMultiConfigWvmFile); - EXPECT_EQ(6u, stream_map_.size()); + ASSERT_EQ(4u, stream_map_.size()); ASSERT_EQ(kStreamVideo, stream_map_[0]->stream_type()); VideoStreamInfo* video_info = reinterpret_cast( @@ -242,18 +242,6 @@ TEST_F(WvmMediaParserTest, ParseMultiConfigWvm) { EXPECT_EQ("mp4a.40.2", audio_info->codec_string()); EXPECT_EQ(2u, audio_info->num_channels()); EXPECT_EQ(44100u, audio_info->sampling_frequency()); - - ASSERT_EQ(kStreamVideo, stream_map_[4]->stream_type()); - video_info = reinterpret_cast(stream_map_[4].get()); - EXPECT_EQ("avc1.64001f", video_info->codec_string()); - EXPECT_EQ(1280u, video_info->width()); - EXPECT_EQ(720u, video_info->height()); - - ASSERT_EQ(kStreamAudio, stream_map_[5]->stream_type()); - audio_info = reinterpret_cast(stream_map_[5].get()); - EXPECT_EQ("mp4a.40.2", audio_info->codec_string()); - EXPECT_EQ(2u, audio_info->num_channels()); - EXPECT_EQ(48000u, audio_info->sampling_frequency()); } } // namespace wvm diff --git a/packager/media/test/data/bear-multi-configs.wvm b/packager/media/test/data/bear-multi-configs.wvm index a608197fae..e2551d3571 100644 Binary files a/packager/media/test/data/bear-multi-configs.wvm and b/packager/media/test/data/bear-multi-configs.wvm differ