[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
This commit is contained in:
KongQun Yang 2019-05-14 22:54:28 -07:00
parent adc3c804a9
commit 0a2b43939c
2 changed files with 52 additions and 1 deletions

View File

@ -37,6 +37,29 @@ uint32_t GetTimeScale(const MediaInfo& media_info) {
return 0u; 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: // Duplicated from MpdUtils because:
// 1. MpdUtils header depends on libxml header, which is not in the deps here // 1. MpdUtils header depends on libxml header, which is not in the deps here
// 2. GetLanguage depends on MediaInfo from packager/mpd/ // 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()) { if (media_info.has_video_info()) {
stream_type_ = MediaPlaylistStreamType::kVideo; stream_type_ = MediaPlaylistStreamType::kVideo;
codec_ = media_info.video_info().codec(); codec_ = AdjustVideoCodec(media_info.video_info().codec());
} else if (media_info.has_audio_info()) { } else if (media_info.has_audio_info()) {
stream_type_ = MediaPlaylistStreamType::kAudio; stream_type_ = MediaPlaylistStreamType::kAudio;
codec_ = media_info.audio_info().codec(); codec_ = media_info.audio_info().codec();

View File

@ -20,6 +20,8 @@ namespace hls {
using ::testing::_; using ::testing::_;
using ::testing::ElementsAreArray; using ::testing::ElementsAreArray;
using ::testing::ReturnArg; using ::testing::ReturnArg;
using ::testing::Values;
using ::testing::WithParamInterface;
namespace { namespace {
@ -1012,5 +1014,31 @@ TEST_F(MediaPlaylistDeleteSegmentsTest, ManySegments) {
kStringPrintTemplate, last_available_segment_index - 1))); kStringPrintTemplate, last_available_segment_index - 1)));
} }
class MediaPlaylistCodecTest
: public MediaPlaylistTest,
public WithParamInterface<std::pair<std::string, std::string>> {};
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 hls
} // namespace shaka } // namespace shaka