From 8465f5f020b5c6152d24107a6d164301e05c3176 Mon Sep 17 00:00:00 2001 From: sr90 Date: Fri, 8 Sep 2023 14:41:41 -0700 Subject: [PATCH] feat(DASH): Add video transfer characteristics. (#1210) This PR is related to https://github.com/shaka-project/shaka-packager/issues/1035 --- .../output.mpd | 1 + .../output.mpd | 2 ++ .../testdata/hdr10-with-encryption/output.mpd | 1 + packager/mpd/base/adaptation_set.cc | 8 ++++++++ packager/mpd/base/adaptation_set.h | 14 ++++++++++++++ packager/mpd/base/mpd_utils.cc | 11 +++++++++++ packager/mpd/base/mpd_utils.h | 1 + packager/mpd/base/period.cc | 16 ++++++++++++++++ 8 files changed, 54 insertions(+) diff --git a/packager/app/test/testdata/dolby-vision-profile-5-with-encryption/output.mpd b/packager/app/test/testdata/dolby-vision-profile-5-with-encryption/output.mpd index b81c94aa08b..9f02235c0b7 100644 --- a/packager/app/test/testdata/dolby-vision-profile-5-with-encryption/output.mpd +++ b/packager/app/test/testdata/dolby-vision-profile-5-with-encryption/output.mpd @@ -3,6 +3,7 @@ + AAAANHBzc2gBAAAAEHfv7MCyTQKs4zweUuL7SwAAAAExMjM0NTY3ODkwMTIzNDU2AAAAAA== diff --git a/packager/app/test/testdata/dolby-vision-profile-8-with-encryption/output.mpd b/packager/app/test/testdata/dolby-vision-profile-8-with-encryption/output.mpd index 0950e11dcd9..04c010c0081 100644 --- a/packager/app/test/testdata/dolby-vision-profile-8-with-encryption/output.mpd +++ b/packager/app/test/testdata/dolby-vision-profile-8-with-encryption/output.mpd @@ -3,6 +3,7 @@ + AAAANHBzc2gBAAAAEHfv7MCyTQKs4zweUuL7SwAAAAExMjM0NTY3ODkwMTIzNDU2AAAAAA== @@ -15,6 +16,7 @@ + AAAANHBzc2gBAAAAEHfv7MCyTQKs4zweUuL7SwAAAAExMjM0NTY3ODkwMTIzNDU2AAAAAA== diff --git a/packager/app/test/testdata/hdr10-with-encryption/output.mpd b/packager/app/test/testdata/hdr10-with-encryption/output.mpd index 9fd7a8654ae..56001f85c7a 100644 --- a/packager/app/test/testdata/hdr10-with-encryption/output.mpd +++ b/packager/app/test/testdata/hdr10-with-encryption/output.mpd @@ -3,6 +3,7 @@ + AAAANHBzc2gBAAAAEHfv7MCyTQKs4zweUuL7SwAAAAExMjM0NTY3ODkwMTIzNDU2AAAAAA== diff --git a/packager/mpd/base/adaptation_set.cc b/packager/mpd/base/adaptation_set.cc index 1f3cbe1d822..5720cf5edfa 100644 --- a/packager/mpd/base/adaptation_set.cc +++ b/packager/mpd/base/adaptation_set.cc @@ -290,6 +290,14 @@ base::Optional AdaptationSet::GetXml() { } } + // https://dashif.org/docs/DASH-IF-IOP-v4.3.pdf - 4.2.5.1 + if (IsVideo() && transfer_characteristics_ > 0 && + !adaptation_set.AddSupplementalProperty( + "urn:mpeg:mpegB:cicp:TransferCharacteristics", + std::to_string(transfer_characteristics_))) { + return base::nullopt; + } + // Note: must be checked before checking segments_aligned_ (below). So that // segments_aligned_ is set before checking below. if (mpd_options_.mpd_type == MpdType::kStatic) { diff --git a/packager/mpd/base/adaptation_set.h b/packager/mpd/base/adaptation_set.h index dd9fa3942d7..d6ebc624a61 100644 --- a/packager/mpd/base/adaptation_set.h +++ b/packager/mpd/base/adaptation_set.h @@ -180,6 +180,17 @@ class AdaptationSet { /// @param codec is the new codec to be set. void set_codec(const std::string& codec) { codec_ = codec; }; + /// @return transfer_characteristics. + const uint32_t transfer_characteristics() const { + return transfer_characteristics_; + } + + /// Set AdaptationSet's video transfer characteristics. + /// @param transfer_characteristics is the video transfer characteristics. + void set_transfer_characteristics(const uint32_t& transfer_characteristics) { + transfer_characteristics_ = transfer_characteristics; + }; + protected: /// @param language is the language of this AdaptationSet. Mainly relevant for /// audio. @@ -314,6 +325,9 @@ class AdaptationSet { // and HD videos in different AdaptationSets can share the same trick play // stream. std::vector trick_play_references_; + + // Transfer characteristics. + uint32_t transfer_characteristics_ = 0; }; } // namespace shaka diff --git a/packager/mpd/base/mpd_utils.cc b/packager/mpd/base/mpd_utils.cc index 018551a80fd..0f945f6538c 100644 --- a/packager/mpd/base/mpd_utils.cc +++ b/packager/mpd/base/mpd_utils.cc @@ -162,6 +162,17 @@ std::string GetAdaptationSetKey(const MediaInfo& media_info, if (!ignore_codec) { key.append(":"); key.append(GetBaseCodec(media_info)); + + if (GetBaseCodec(media_info).find("dvh") == 0) { + // Transfer characteristics for Dolby Vision (dvh1 or dvhe) must be PQ + // irrespective of value present in SPS VUI. + key.append(":"); + key.append(std::to_string(kTransferFunctionPQ)); + } else if (media_info.video_info().has_transfer_characteristics()) { + key.append(":"); + key.append( + std::to_string(media_info.video_info().transfer_characteristics())); + } } key.append(":"); key.append(GetLanguage(media_info)); diff --git a/packager/mpd/base/mpd_utils.h b/packager/mpd/base/mpd_utils.h index 3bad952fa22..782f6bb12ad 100644 --- a/packager/mpd/base/mpd_utils.h +++ b/packager/mpd/base/mpd_utils.h @@ -25,6 +25,7 @@ struct SegmentInfo; const char kEncryptedMp4Scheme[] = "urn:mpeg:dash:mp4protection:2011"; const char kPsshElementName[] = "cenc:pssh"; const char kMsproElementName[] = "mspr:pro"; +const uint32_t kTransferFunctionPQ = 16; bool HasVODOnlyFields(const MediaInfo& media_info); diff --git a/packager/mpd/base/period.cc b/packager/mpd/base/period.cc index e1285fdf0b1..0cb8273d03d 100644 --- a/packager/mpd/base/period.cc +++ b/packager/mpd/base/period.cc @@ -269,6 +269,22 @@ bool Period::SetNewAdaptationSetAttributes( } } + // Set transfer characteristics. + // https://dashif.org/docs/DASH-IF-IOP-v4.3.pdf - 4.2.5.1 + // ISO/IEC 23001-8 MPEG systems technologies — Part 8: Coding-independent + // code points. https://en.wikipedia.org/wiki/Coding-independent_code_points + // - Common CCIP values. + // Dolby vision: + // https://professionalsupport.dolby.com/s/article/How-to-signal-Dolby-Vision-in-MPEG-DASH + // Transfer characteristics for Dolby Vision (dvh1 or dvhe) must be PQ + // irrespective of value present in SPS VUI. + if (new_adaptation_set->codec().find("dvh") == 0) { + new_adaptation_set->set_transfer_characteristics(kTransferFunctionPQ); + } else if (media_info.video_info().has_transfer_characteristics()) { + new_adaptation_set->set_transfer_characteristics( + media_info.video_info().transfer_characteristics()); + } + } else if (media_info.has_text_info()) { // IOP requires all AdaptationSets to have (sub)segmentAlignment set to // true, so carelessly set it to true.