From aba9b897afcd53c83be9c631ac630957a27ee28d Mon Sep 17 00:00:00 2001 From: Xingzhao Yun Date: Wed, 9 Aug 2023 17:12:32 +0800 Subject: [PATCH 1/3] support Dolby Vision back compatiable signaling in HLS. --- packager/hls/base/media_playlist.cc | 20 +++++++++++++++++++- packager/hls/base/media_playlist.h | 5 +++++ packager/media/base/fourccs.h | 6 +++++- packager/media/base/video_stream_info.h | 5 +++++ 4 files changed, 34 insertions(+), 2 deletions(-) diff --git a/packager/hls/base/media_playlist.cc b/packager/hls/base/media_playlist.cc index 4016cdbcc75..6b73135bf51 100644 --- a/packager/hls/base/media_playlist.cc +++ b/packager/hls/base/media_playlist.cc @@ -344,6 +344,7 @@ MediaPlaylist::MediaPlaylist(const HlsParams& hls_params, file_name_(file_name), name_(name), group_id_(group_id), + dovi_compatible_brand_(), media_sequence_number_(hls_params_.media_sequence_number) { // When there's a forced media_sequence_number, start with discontinuity if (media_sequence_number_ > 0) @@ -380,6 +381,11 @@ bool MediaPlaylist::SetMediaInfo(const MediaInfo& media_info) { if (media_info.has_video_info()) { stream_type_ = MediaPlaylistStreamType::kVideo; codec_ = AdjustVideoCodec(media_info.video_info().codec()); + if (media_info.video_info().has_extra_decoder_config()) { + dovi_codec_ = AdjustVideoCodec(media_info.video_info().dovi_codec()); + dovi_compatible_brand_ = static_cast(media_info.video_info().dovi_compatible_brand()); + } + } else if (media_info.has_audio_info()) { stream_type_ = MediaPlaylistStreamType::kAudio; codec_ = media_info.audio_info().codec(); @@ -560,10 +566,22 @@ std::string MediaPlaylist::GetVideoRange() const { // https://tools.ietf.org/html/draft-pantos-hls-rfc8216bis-02#section-4.4.4.2 switch (media_info_.video_info().transfer_characteristics()) { case 1: + case 6: + case 13: + case 15: return "SDR"; + case 14: + // Dolby Vision profile 8.4 may have a transfer_characteristics 14, the + // actual value refers to preferred_transfer_characteristic value in SEI + // message, using compatible brand as a temp solution. + if (!dovi_codec_.empty() && dovi_compatible_brand_ == media::FOURCC_db4g) + return "HLG"; + else + return "SDR"; case 16: - case 18: return "PQ"; + case 18: + return "HLG"; default: // Leave it empty if we do not have the transfer characteristics // information. diff --git a/packager/hls/base/media_playlist.h b/packager/hls/base/media_playlist.h index 50f45f9f7e1..94936088313 100644 --- a/packager/hls/base/media_playlist.h +++ b/packager/hls/base/media_playlist.h @@ -16,6 +16,7 @@ #include "packager/hls/public/hls_params.h" #include "packager/mpd/base/bandwidth_estimator.h" #include "packager/mpd/base/media_info.pb.h" +#include "packager/media/base/fourccs.h" namespace shaka { @@ -79,6 +80,8 @@ class MediaPlaylist { const std::string& group_id() const { return group_id_; } MediaPlaylistStreamType stream_type() const { return stream_type_; } const std::string& codec() const { return codec_; } + const std::string& dovi_codec() const { return dovi_codec_; } + const media::FourCC& dovi_compatible_brand() const { return dovi_compatible_brand_; } /// For testing only. void SetStreamTypeForTesting(MediaPlaylistStreamType stream_type); @@ -258,6 +261,8 @@ class MediaPlaylist { // Whether to use byte range for SegmentInfoEntry. bool use_byte_range_ = false; std::string codec_; + std::string dovi_codec_; + media::FourCC dovi_compatible_brand_; std::string language_; std::vector characteristics_; uint32_t media_sequence_number_ = 0; diff --git a/packager/media/base/fourccs.h b/packager/media/base/fourccs.h index c721f2c81f5..19c99c282f9 100644 --- a/packager/media/base/fourccs.h +++ b/packager/media/base/fourccs.h @@ -45,7 +45,11 @@ enum FourCC : uint32_t { FOURCC_dac3 = 0x64616333, FOURCC_dac4 = 0x64616334, FOURCC_dash = 0x64617368, - FOURCC_dby1 = 0x64627931, + FOURCC_db1p = 0x64623170, // "db1p" + FOURCC_db2g = 0x64623267, // "db2g" + FOURCC_db4g = 0x64623467, // "db4g" + FOURCC_db4h = 0x64623468, // "db4h" + FOURCC_dby1 = 0x64627931, // "dby1" FOURCC_ddts = 0x64647473, FOURCC_dec3 = 0x64656333, FOURCC_dfLa = 0x64664c61, diff --git a/packager/media/base/video_stream_info.h b/packager/media/base/video_stream_info.h index 8d89d7cc845..56195adbe54 100644 --- a/packager/media/base/video_stream_info.h +++ b/packager/media/base/video_stream_info.h @@ -54,6 +54,7 @@ class VideoStreamInfo : public StreamInfo { std::unique_ptr Clone() const override; /// @} + FourCC dovi_compatible_brand() const { return dovi_compatible_brand_; } const std::vector& extra_config() const { return extra_config_; } H26xStreamFormat h26x_stream_format() const { return h26x_stream_format_; } uint16_t width() const { return width_; } @@ -70,6 +71,9 @@ class VideoStreamInfo : public StreamInfo { uint32_t playback_rate() const { return playback_rate_; } const std::vector& eme_init_data() const { return eme_init_data_; } + void set_dovi_compatible_brand(const FourCC dovi_compatible_brand) { + dovi_compatible_brand_ = dovi_compatible_brand; + } void set_extra_config(const std::vector& extra_config) { extra_config_ = extra_config; } @@ -94,6 +98,7 @@ class VideoStreamInfo : public StreamInfo { private: // Extra codec configuration in a stream of mp4 boxes. It is only applicable // to mp4 container only. It is needed by some codecs, e.g. Dolby Vision. + FourCC dovi_compatible_brand_; std::vector extra_config_; H26xStreamFormat h26x_stream_format_; uint16_t width_; From eff471224ce5d1874184359f6369f8370eef147b Mon Sep 17 00:00:00 2001 From: Xingzhao Yun Date: Wed, 9 Aug 2023 17:14:43 +0800 Subject: [PATCH 2/3] Revert "support Dolby Vision back compatiable signaling in HLS." This reverts commit aba9b897afcd53c83be9c631ac630957a27ee28d. --- packager/hls/base/media_playlist.cc | 20 +------------------- packager/hls/base/media_playlist.h | 5 ----- packager/media/base/fourccs.h | 6 +----- packager/media/base/video_stream_info.h | 5 ----- 4 files changed, 2 insertions(+), 34 deletions(-) diff --git a/packager/hls/base/media_playlist.cc b/packager/hls/base/media_playlist.cc index 6b73135bf51..4016cdbcc75 100644 --- a/packager/hls/base/media_playlist.cc +++ b/packager/hls/base/media_playlist.cc @@ -344,7 +344,6 @@ MediaPlaylist::MediaPlaylist(const HlsParams& hls_params, file_name_(file_name), name_(name), group_id_(group_id), - dovi_compatible_brand_(), media_sequence_number_(hls_params_.media_sequence_number) { // When there's a forced media_sequence_number, start with discontinuity if (media_sequence_number_ > 0) @@ -381,11 +380,6 @@ bool MediaPlaylist::SetMediaInfo(const MediaInfo& media_info) { if (media_info.has_video_info()) { stream_type_ = MediaPlaylistStreamType::kVideo; codec_ = AdjustVideoCodec(media_info.video_info().codec()); - if (media_info.video_info().has_extra_decoder_config()) { - dovi_codec_ = AdjustVideoCodec(media_info.video_info().dovi_codec()); - dovi_compatible_brand_ = static_cast(media_info.video_info().dovi_compatible_brand()); - } - } else if (media_info.has_audio_info()) { stream_type_ = MediaPlaylistStreamType::kAudio; codec_ = media_info.audio_info().codec(); @@ -566,22 +560,10 @@ std::string MediaPlaylist::GetVideoRange() const { // https://tools.ietf.org/html/draft-pantos-hls-rfc8216bis-02#section-4.4.4.2 switch (media_info_.video_info().transfer_characteristics()) { case 1: - case 6: - case 13: - case 15: return "SDR"; - case 14: - // Dolby Vision profile 8.4 may have a transfer_characteristics 14, the - // actual value refers to preferred_transfer_characteristic value in SEI - // message, using compatible brand as a temp solution. - if (!dovi_codec_.empty() && dovi_compatible_brand_ == media::FOURCC_db4g) - return "HLG"; - else - return "SDR"; case 16: - return "PQ"; case 18: - return "HLG"; + return "PQ"; default: // Leave it empty if we do not have the transfer characteristics // information. diff --git a/packager/hls/base/media_playlist.h b/packager/hls/base/media_playlist.h index 94936088313..50f45f9f7e1 100644 --- a/packager/hls/base/media_playlist.h +++ b/packager/hls/base/media_playlist.h @@ -16,7 +16,6 @@ #include "packager/hls/public/hls_params.h" #include "packager/mpd/base/bandwidth_estimator.h" #include "packager/mpd/base/media_info.pb.h" -#include "packager/media/base/fourccs.h" namespace shaka { @@ -80,8 +79,6 @@ class MediaPlaylist { const std::string& group_id() const { return group_id_; } MediaPlaylistStreamType stream_type() const { return stream_type_; } const std::string& codec() const { return codec_; } - const std::string& dovi_codec() const { return dovi_codec_; } - const media::FourCC& dovi_compatible_brand() const { return dovi_compatible_brand_; } /// For testing only. void SetStreamTypeForTesting(MediaPlaylistStreamType stream_type); @@ -261,8 +258,6 @@ class MediaPlaylist { // Whether to use byte range for SegmentInfoEntry. bool use_byte_range_ = false; std::string codec_; - std::string dovi_codec_; - media::FourCC dovi_compatible_brand_; std::string language_; std::vector characteristics_; uint32_t media_sequence_number_ = 0; diff --git a/packager/media/base/fourccs.h b/packager/media/base/fourccs.h index 19c99c282f9..c721f2c81f5 100644 --- a/packager/media/base/fourccs.h +++ b/packager/media/base/fourccs.h @@ -45,11 +45,7 @@ enum FourCC : uint32_t { FOURCC_dac3 = 0x64616333, FOURCC_dac4 = 0x64616334, FOURCC_dash = 0x64617368, - FOURCC_db1p = 0x64623170, // "db1p" - FOURCC_db2g = 0x64623267, // "db2g" - FOURCC_db4g = 0x64623467, // "db4g" - FOURCC_db4h = 0x64623468, // "db4h" - FOURCC_dby1 = 0x64627931, // "dby1" + FOURCC_dby1 = 0x64627931, FOURCC_ddts = 0x64647473, FOURCC_dec3 = 0x64656333, FOURCC_dfLa = 0x64664c61, diff --git a/packager/media/base/video_stream_info.h b/packager/media/base/video_stream_info.h index 56195adbe54..8d89d7cc845 100644 --- a/packager/media/base/video_stream_info.h +++ b/packager/media/base/video_stream_info.h @@ -54,7 +54,6 @@ class VideoStreamInfo : public StreamInfo { std::unique_ptr Clone() const override; /// @} - FourCC dovi_compatible_brand() const { return dovi_compatible_brand_; } const std::vector& extra_config() const { return extra_config_; } H26xStreamFormat h26x_stream_format() const { return h26x_stream_format_; } uint16_t width() const { return width_; } @@ -71,9 +70,6 @@ class VideoStreamInfo : public StreamInfo { uint32_t playback_rate() const { return playback_rate_; } const std::vector& eme_init_data() const { return eme_init_data_; } - void set_dovi_compatible_brand(const FourCC dovi_compatible_brand) { - dovi_compatible_brand_ = dovi_compatible_brand; - } void set_extra_config(const std::vector& extra_config) { extra_config_ = extra_config; } @@ -98,7 +94,6 @@ class VideoStreamInfo : public StreamInfo { private: // Extra codec configuration in a stream of mp4 boxes. It is only applicable // to mp4 container only. It is needed by some codecs, e.g. Dolby Vision. - FourCC dovi_compatible_brand_; std::vector extra_config_; H26xStreamFormat h26x_stream_format_; uint16_t width_; From 7719a1b30371f514b40a1d96426e0a362b124a6d Mon Sep 17 00:00:00 2001 From: Xingzhao Yun Date: Thu, 10 Aug 2023 18:37:02 +0800 Subject: [PATCH 3/3] support Dolby Vision 8.x back compatiable for HLS. --- packager/hls/base/master_playlist.cc | 10 +++++++ packager/hls/base/media_playlist.cc | 22 ++++++++++++++- packager/hls/base/media_playlist.h | 5 ++++ packager/media/base/fourccs.h | 6 ++++- packager/media/base/video_stream_info.h | 10 +++++++ .../dovi_decoder_configuration_record.cc | 24 ++++++++++++++++- .../dovi_decoder_configuration_record.h | 4 +++ .../media/event/muxer_listener_internal.cc | 2 ++ .../media/formats/mp4/mp4_media_parser.cc | 27 +++++++++++++------ packager/media/formats/mp4/mp4_muxer.cc | 12 ++++++++- packager/mpd/base/media_info.proto | 5 ++++ 11 files changed, 115 insertions(+), 12 deletions(-) diff --git a/packager/hls/base/master_playlist.cc b/packager/hls/base/master_playlist.cc index 89288027817..3531bdcd43f 100644 --- a/packager/hls/base/master_playlist.cc +++ b/packager/hls/base/master_playlist.cc @@ -225,6 +225,16 @@ void BuildStreamInfTag(const MediaPlaylist& playlist, variant.text_codecs.end()); tag.AddQuotedString("CODECS", base::JoinString(all_codecs, ",")); + if (playlist.supplemental_codec() != "" + && playlist.compatible_brand() != media::FOURCC_NULL) { + std::vector supplemental_codecs; + supplemental_codecs.push_back(playlist.supplemental_codec()); + supplemental_codecs.push_back(FourCCToString(playlist.compatible_brand())); + tag.AddQuotedString("SUPPLEMENTAL-CODECS", + base::JoinString(supplemental_codecs, "/")); + } + + uint32_t width; uint32_t height; if (playlist.GetDisplayResolution(&width, &height)) { diff --git a/packager/hls/base/media_playlist.cc b/packager/hls/base/media_playlist.cc index 4016cdbcc75..9a014343e6b 100644 --- a/packager/hls/base/media_playlist.cc +++ b/packager/hls/base/media_playlist.cc @@ -380,6 +380,14 @@ bool MediaPlaylist::SetMediaInfo(const MediaInfo& media_info) { if (media_info.has_video_info()) { stream_type_ = MediaPlaylistStreamType::kVideo; codec_ = AdjustVideoCodec(media_info.video_info().codec()); + if (media_info.video_info().has_supplemental_codec() + && media_info.video_info().has_compatible_brand()) { + supplemental_codec_ = AdjustVideoCodec( + media_info.video_info().supplemental_codec()); + compatible_brand_ = static_cast( + media_info.video_info().compatible_brand()); + } + } else if (media_info.has_audio_info()) { stream_type_ = MediaPlaylistStreamType::kAudio; codec_ = media_info.audio_info().codec(); @@ -560,10 +568,22 @@ std::string MediaPlaylist::GetVideoRange() const { // https://tools.ietf.org/html/draft-pantos-hls-rfc8216bis-02#section-4.4.4.2 switch (media_info_.video_info().transfer_characteristics()) { case 1: + case 6: + case 13: + case 15: return "SDR"; + case 14: + // Dolby Vision profile 8.4 may have a transfer_characteristics 14, the + // actual value refers to preferred_transfer_characteristic value in SEI + // message, using compatible brand as a temp solution. + if (!supplemental_codec_.empty() && compatible_brand_ == media::FOURCC_db4g) + return "HLG"; + else + return "SDR"; case 16: - case 18: return "PQ"; + case 18: + return "HLG"; default: // Leave it empty if we do not have the transfer characteristics // information. diff --git a/packager/hls/base/media_playlist.h b/packager/hls/base/media_playlist.h index 50f45f9f7e1..83832b97d78 100644 --- a/packager/hls/base/media_playlist.h +++ b/packager/hls/base/media_playlist.h @@ -16,6 +16,7 @@ #include "packager/hls/public/hls_params.h" #include "packager/mpd/base/bandwidth_estimator.h" #include "packager/mpd/base/media_info.pb.h" +#include "packager/media/base/fourccs.h" namespace shaka { @@ -79,6 +80,8 @@ class MediaPlaylist { const std::string& group_id() const { return group_id_; } MediaPlaylistStreamType stream_type() const { return stream_type_; } const std::string& codec() const { return codec_; } + const std::string& supplemental_codec() const { return supplemental_codec_; } + const media::FourCC& compatible_brand() const { return compatible_brand_; } /// For testing only. void SetStreamTypeForTesting(MediaPlaylistStreamType stream_type); @@ -258,6 +261,8 @@ class MediaPlaylist { // Whether to use byte range for SegmentInfoEntry. bool use_byte_range_ = false; std::string codec_; + std::string supplemental_codec_; + media::FourCC compatible_brand_; std::string language_; std::vector characteristics_; uint32_t media_sequence_number_ = 0; diff --git a/packager/media/base/fourccs.h b/packager/media/base/fourccs.h index c721f2c81f5..19c99c282f9 100644 --- a/packager/media/base/fourccs.h +++ b/packager/media/base/fourccs.h @@ -45,7 +45,11 @@ enum FourCC : uint32_t { FOURCC_dac3 = 0x64616333, FOURCC_dac4 = 0x64616334, FOURCC_dash = 0x64617368, - FOURCC_dby1 = 0x64627931, + FOURCC_db1p = 0x64623170, // "db1p" + FOURCC_db2g = 0x64623267, // "db2g" + FOURCC_db4g = 0x64623467, // "db4g" + FOURCC_db4h = 0x64623468, // "db4h" + FOURCC_dby1 = 0x64627931, // "dby1" FOURCC_ddts = 0x64647473, FOURCC_dec3 = 0x64656333, FOURCC_dfLa = 0x64664c61, diff --git a/packager/media/base/video_stream_info.h b/packager/media/base/video_stream_info.h index 8d89d7cc845..90c28d48078 100644 --- a/packager/media/base/video_stream_info.h +++ b/packager/media/base/video_stream_info.h @@ -54,6 +54,8 @@ class VideoStreamInfo : public StreamInfo { std::unique_ptr Clone() const override; /// @} + const std::string supplemental_codec() const { return supplemental_codec_; } + FourCC compatible_brand() const { return compatible_brand_; } const std::vector& extra_config() const { return extra_config_; } H26xStreamFormat h26x_stream_format() const { return h26x_stream_format_; } uint16_t width() const { return width_; } @@ -70,6 +72,12 @@ class VideoStreamInfo : public StreamInfo { uint32_t playback_rate() const { return playback_rate_; } const std::vector& eme_init_data() const { return eme_init_data_; } + void set_supplemental_codec(const std::string supplemental_codec) { + supplemental_codec_ = supplemental_codec; + } + void set_compatible_brand(const FourCC compatible_brand) { + compatible_brand_ = compatible_brand; + } void set_extra_config(const std::vector& extra_config) { extra_config_ = extra_config; } @@ -94,6 +102,8 @@ class VideoStreamInfo : public StreamInfo { private: // Extra codec configuration in a stream of mp4 boxes. It is only applicable // to mp4 container only. It is needed by some codecs, e.g. Dolby Vision. + std::string supplemental_codec_; + FourCC compatible_brand_; std::vector extra_config_; H26xStreamFormat h26x_stream_format_; uint16_t width_; diff --git a/packager/media/codecs/dovi_decoder_configuration_record.cc b/packager/media/codecs/dovi_decoder_configuration_record.cc index 31c56887749..64246d57d89 100644 --- a/packager/media/codecs/dovi_decoder_configuration_record.cc +++ b/packager/media/codecs/dovi_decoder_configuration_record.cc @@ -22,7 +22,8 @@ bool DOVIDecoderConfigurationRecord::Parse(const std::vector& data) { uint8_t minor_version = 0; RCHECK(reader.ReadBits(8, &major_version) && major_version == 1 && reader.ReadBits(8, &minor_version) && minor_version == 0 && - reader.ReadBits(7, &profile_) && reader.ReadBits(6, &level_)); + reader.ReadBits(7, &profile_) && reader.ReadBits(6, &level_) && + reader.SkipBits(3) && reader.ReadBits(4, &bl_signal_compatibility_id_)); return true; } @@ -34,5 +35,26 @@ std::string DOVIDecoderConfigurationRecord::GetCodecString( "%s.%02d.%02d", FourCCToString(codec_fourcc).c_str(), profile_, level_); } +FourCC DOVIDecoderConfigurationRecord::GetDoViCompatibleBrand( + const uint8_t transfer_characteristics) const { + // Dolby Vision Streams within the ISO Base Media File Format Version 2.4: + switch (bl_signal_compatibility_id_) { + case 1: + return FOURCC_db1p; + case 2: + return FOURCC_db2g; + case 4: + if (transfer_characteristics == 14) { + return FOURCC_db4g; + } + else if (transfer_characteristics == 18) { + return FOURCC_db4h; + } + default: + return FOURCC_NULL; + } + return FOURCC_NULL; +} + } // namespace media } // namespace shaka diff --git a/packager/media/codecs/dovi_decoder_configuration_record.h b/packager/media/codecs/dovi_decoder_configuration_record.h index 0dc4ebb6afc..be14e36c531 100644 --- a/packager/media/codecs/dovi_decoder_configuration_record.h +++ b/packager/media/codecs/dovi_decoder_configuration_record.h @@ -35,6 +35,9 @@ class DOVIDecoderConfigurationRecord { /// DASH and HLS manifests. std::string GetCodecString(FourCC codec_fourcc) const; + /// @return The compatiable brand in the format defined by https://mp4ra.org/#/brands. + FourCC GetDoViCompatibleBrand(const uint8_t transfer_characteristics) const; + private: DOVIDecoderConfigurationRecord(const DOVIDecoderConfigurationRecord&) = delete; @@ -42,6 +45,7 @@ class DOVIDecoderConfigurationRecord { const DOVIDecoderConfigurationRecord&) = delete; uint8_t profile_ = 0; + uint8_t bl_signal_compatibility_id_ = 0; uint8_t level_ = 0; }; diff --git a/packager/media/event/muxer_listener_internal.cc b/packager/media/event/muxer_listener_internal.cc index e71d0ec97c8..3b704131066 100644 --- a/packager/media/event/muxer_listener_internal.cc +++ b/packager/media/event/muxer_listener_internal.cc @@ -69,6 +69,8 @@ void AddVideoInfo(const VideoStreamInfo* video_stream_info, DCHECK(video_stream_info); DCHECK(media_info); MediaInfo_VideoInfo* video_info = media_info->mutable_video_info(); + video_info->set_supplemental_codec(video_stream_info->supplemental_codec()); + video_info->set_compatible_brand(video_stream_info->compatible_brand()); video_info->set_codec(video_stream_info->codec_string()); video_info->set_width(video_stream_info->width()); video_info->set_height(video_stream_info->height()); diff --git a/packager/media/formats/mp4/mp4_media_parser.cc b/packager/media/formats/mp4/mp4_media_parser.cc index 8f2b504851f..64deae47fe5 100644 --- a/packager/media/formats/mp4/mp4_media_parser.cc +++ b/packager/media/formats/mp4/mp4_media_parser.cc @@ -137,10 +137,13 @@ std::vector GetDOVIDecoderConfig( return std::vector(); } -bool UpdateCodecStringForDolbyVision( +bool UpdateDolbyVisionInfo( FourCC actual_format, const std::vector& configs, - std::string* codec_string) { + uint8_t transfer_characteristics, + std::string* codec_string, + std::string* dovi_supplemental_codec_string, + FourCC* dovi_compatible_brand) { DOVIDecoderConfigurationRecord dovi_config; if (!dovi_config.Parse(GetDOVIDecoderConfig(configs))) { LOG(ERROR) << "Failed to parse Dolby Vision decoder " @@ -155,19 +158,21 @@ bool UpdateCodecStringForDolbyVision( *codec_string = dovi_config.GetCodecString(actual_format); break; case FOURCC_hev1: - // Backward compatibility mode. Two codecs are signalled: base codec - // without Dolby Vision and HDR with Dolby Vision. - *codec_string += ";" + dovi_config.GetCodecString(FOURCC_dvhe); + // Backward compatibility mode. Use supplemental codec indicating Dolby + // Dolby Vision content. + *dovi_supplemental_codec_string = dovi_config.GetCodecString(FOURCC_dvhe); break; case FOURCC_hvc1: // See above. - *codec_string += ";" + dovi_config.GetCodecString(FOURCC_dvh1); + *dovi_supplemental_codec_string = dovi_config.GetCodecString(FOURCC_dvh1); break; default: LOG(ERROR) << "Unsupported format with extra codec " << FourCCToString(actual_format); return false; } + *dovi_compatible_brand = + dovi_config.GetDoViCompatibleBrand(transfer_characteristics); return true; } @@ -592,6 +597,8 @@ bool MP4MediaParser::ParseMoov(BoxReader* reader) { &pixel_height); } std::string codec_string; + std::string dovi_supplemental_codec_string(""); + FourCC dovi_compatible_brand = FOURCC_NULL; uint8_t nalu_length_size = 0; uint8_t transfer_characteristics = 0; @@ -676,8 +683,10 @@ bool MP4MediaParser::ParseMoov(BoxReader* reader) { if (!entry.extra_codec_configs.empty()) { // |extra_codec_configs| is present only for Dolby Vision. - if (!UpdateCodecStringForDolbyVision( - actual_format, entry.extra_codec_configs, &codec_string)) { + if (!UpdateDolbyVisionInfo(actual_format, entry.extra_codec_configs, + transfer_characteristics, &codec_string, + &dovi_supplemental_codec_string, + &dovi_compatible_brand)) { return false; } } @@ -725,6 +734,8 @@ bool MP4MediaParser::ParseMoov(BoxReader* reader) { transfer_characteristics, 0, // trick_play_factor nalu_length_size, track->media.header.language.code, is_encrypted)); + video_stream_info->set_supplemental_codec(dovi_supplemental_codec_string); + video_stream_info->set_compatible_brand(dovi_compatible_brand); video_stream_info->set_extra_config(entry.ExtraCodecConfigsAsVector()); // Set pssh raw data if it has. diff --git a/packager/media/formats/mp4/mp4_muxer.cc b/packager/media/formats/mp4/mp4_muxer.cc index 27f926d8ca2..529db42dd59 100644 --- a/packager/media/formats/mp4/mp4_muxer.cc +++ b/packager/media/formats/mp4/mp4_muxer.cc @@ -229,8 +229,18 @@ Status MP4Muxer::DelayInitializeMuxer() { ftyp->compatible_brands.push_back(codec_fourcc); // https://professional.dolby.com/siteassets/content-creation/dolby-vision-for-content-creators/dolby_vision_bitstreams_within_the_iso_base_media_file_format_dec2017.pdf - if (streams()[0].get()->codec_string().find("dvh") != std::string::npos) + std::string codec_string = + static_cast(streams()[0].get())->codec_string(); + std::string supplemental_codec_string = + static_cast(streams()[0].get())->supplemental_codec(); + if (codec_string.find("dvh") != std::string::npos || + supplemental_codec_string.find("dvh") != std::string::npos) ftyp->compatible_brands.push_back(FOURCC_dby1); + FourCC extra_brand = + static_cast(streams()[0].get()) + ->compatible_brand(); + if (extra_brand != FOURCC_NULL) + ftyp->compatible_brands.push_back(extra_brand); } // CMAF allows only one track/stream per file. diff --git a/packager/mpd/base/media_info.proto b/packager/mpd/base/media_info.proto index b626f6b32a6..99242094b8a 100644 --- a/packager/mpd/base/media_info.proto +++ b/packager/mpd/base/media_info.proto @@ -49,6 +49,11 @@ message MediaInfo { // Transfer characteristics. Useful to determine the VIDEO-RANGE for HLS, // i.e. whether it is SDR or HDR. optional uint32 transfer_characteristics = 10; + + // supplemental_codec/compatible_brand is used for SUPPLEMENTAL-CODECS for + // HLS. It's useful for Dolby Vision back compatiable content. + optional string supplemental_codec = 11; + optional uint32 compatible_brand = 12; } message AudioInfo {