From 0a2b43939c8ceb5f8220c7ab962ea914b9e71d16 Mon Sep 17 00:00:00 2001 From: KongQun Yang Date: Tue, 14 May 2019 22:54:28 -0700 Subject: [PATCH] [HLS] Replace hev1 in codec with hvc1 and avc3 with avc1 And also dvhe with dvh1. Apple's specification does not recommend video formats with the parameter sets stored in the samples. It also fails mediastreamvalidator checks and some Apple devices / platforms refused to play. See https://apple.co/30n90DC 1.10. Replaced with the corresponding formats with the parameter sets stored in the sample descriptions instead. Fixes #587. Change-Id: Ic5d3f6fde115b1d09d1dcac32cef5fe0ad246aa0 --- packager/hls/base/media_playlist.cc | 25 ++++++++++++++++- packager/hls/base/media_playlist_unittest.cc | 28 ++++++++++++++++++++ 2 files changed, 52 insertions(+), 1 deletion(-) diff --git a/packager/hls/base/media_playlist.cc b/packager/hls/base/media_playlist.cc index c25c8845aa..215baa6bf9 100644 --- a/packager/hls/base/media_playlist.cc +++ b/packager/hls/base/media_playlist.cc @@ -37,6 +37,29 @@ uint32_t GetTimeScale(const MediaInfo& media_info) { return 0u; } +std::string AdjustVideoCodec(const std::string& codec) { + // Apple does not like video formats with the parameter sets stored in the + // samples. It also fails mediastreamvalidator checks and some Apple devices / + // platforms refused to play. + // See https://apple.co/30n90DC 1.10 and + // https://github.com/google/shaka-packager/issues/587#issuecomment-489182182. + // Replaced with the corresponding formats with the parameter sets stored in + // the sample descriptions instead. + std::string adjusted_codec = codec; + std::string fourcc = codec.substr(0, 4); + if (fourcc == "avc3") + adjusted_codec = "avc1" + codec.substr(4); + else if (fourcc == "hev1") + adjusted_codec = "hvc1" + codec.substr(4); + else if (fourcc == "dvhe") + adjusted_codec = "dvh1" + codec.substr(4); + if (adjusted_codec != codec) { + VLOG(1) << "Adusting video codec string from " << codec << " to " + << adjusted_codec; + } + return adjusted_codec; +} + // Duplicated from MpdUtils because: // 1. MpdUtils header depends on libxml header, which is not in the deps here // 2. GetLanguage depends on MediaInfo from packager/mpd/ @@ -349,7 +372,7 @@ bool MediaPlaylist::SetMediaInfo(const MediaInfo& media_info) { if (media_info.has_video_info()) { stream_type_ = MediaPlaylistStreamType::kVideo; - codec_ = media_info.video_info().codec(); + codec_ = AdjustVideoCodec(media_info.video_info().codec()); } else if (media_info.has_audio_info()) { stream_type_ = MediaPlaylistStreamType::kAudio; codec_ = media_info.audio_info().codec(); diff --git a/packager/hls/base/media_playlist_unittest.cc b/packager/hls/base/media_playlist_unittest.cc index 74100ec6cd..46f00e678a 100644 --- a/packager/hls/base/media_playlist_unittest.cc +++ b/packager/hls/base/media_playlist_unittest.cc @@ -20,6 +20,8 @@ namespace hls { using ::testing::_; using ::testing::ElementsAreArray; using ::testing::ReturnArg; +using ::testing::Values; +using ::testing::WithParamInterface; namespace { @@ -1012,5 +1014,31 @@ TEST_F(MediaPlaylistDeleteSegmentsTest, ManySegments) { kStringPrintTemplate, last_available_segment_index - 1))); } +class MediaPlaylistCodecTest + : public MediaPlaylistTest, + public WithParamInterface> {}; + +TEST_P(MediaPlaylistCodecTest, AdjustVideoCodec) { + std::string input_codec, expected_output_codec; + std::tie(input_codec, expected_output_codec) = GetParam(); + + valid_video_media_info_.mutable_video_info()->set_codec(input_codec); + ASSERT_TRUE(media_playlist_->SetMediaInfo(valid_video_media_info_)); + ASSERT_EQ(media_playlist_->codec(), expected_output_codec); +} + +INSTANTIATE_TEST_CASE_P( + Codecs, + MediaPlaylistCodecTest, + Values(std::make_pair("avc1.4d401e", "avc1.4d401e"), + // Replace avc3 with avc1. + std::make_pair("avc3.4d401e", "avc1.4d401e"), + std::make_pair("hvc1.2.4.L63.90", "hvc1.2.4.L63.90"), + // Replace hev1 with hvc1. + std::make_pair("hev1.2.4.L63.90", "hvc1.2.4.L63.90"), + std::make_pair("dvh1.2.4.L63.90", "dvh1.2.4.L63.90"), + // Replace dvhe with dvh1. + std::make_pair("dvhe.2.4.L63.90", "dvh1.2.4.L63.90"))); + } // namespace hls } // namespace shaka