diff --git a/include/packager/mpd_params.h b/include/packager/mpd_params.h index 16090634330..243c14af12b 100644 --- a/include/packager/mpd_params.h +++ b/include/packager/mpd_params.h @@ -102,6 +102,9 @@ struct MpdParams { /// and is greatly influnced by the player. /// This parameter is required by DASH-IF Low Latency standards. double target_latency_seconds = 1; + // If enabled, use EssentialProperty instead of SupplementalProperty + // for video colorimetry descriptors. + bool use_colorimetry_essential_property = false; }; } // namespace shaka diff --git a/packager/app/mpd_flags.cc b/packager/app/mpd_flags.cc index d432fd922bf..973082177f9 100644 --- a/packager/app/mpd_flags.cc +++ b/packager/app/mpd_flags.cc @@ -98,3 +98,9 @@ ABSL_FLAG( "https://shaka-project.github.io/shaka-packager/html/tutorials/low_latency.html " // clang-format on "for more information."); +ABSL_FLAG( + bool, + use_colorimetry_essential_property, + false, + "If enabled, use EssentialProperty instead of SupplementalProperty " + "for video colorimetry descriptors."); diff --git a/packager/app/mpd_flags.h b/packager/app/mpd_flags.h index b88086dbb9d..82ed4debac4 100644 --- a/packager/app/mpd_flags.h +++ b/packager/app/mpd_flags.h @@ -26,5 +26,6 @@ ABSL_DECLARE_FLAG(bool, allow_codec_switching); ABSL_DECLARE_FLAG(bool, include_mspr_pro_for_playready); ABSL_DECLARE_FLAG(bool, dash_force_segment_list); ABSL_DECLARE_FLAG(bool, low_latency_dash_mode); - +ABSL_DECLARE_FLAG(bool, use_colorimetry_essential_property); + #endif // APP_MPD_FLAGS_H_ diff --git a/packager/app/packager_main.cc b/packager/app/packager_main.cc index 7fe7b77c24a..b46b4bc0246 100644 --- a/packager/app/packager_main.cc +++ b/packager/app/packager_main.cc @@ -499,6 +499,7 @@ std::optional GetPackagingParams() { mpd_params.preserved_segments_outside_live_window = absl::GetFlag(FLAGS_preserved_segments_outside_live_window); mpd_params.use_segment_list = absl::GetFlag(FLAGS_dash_force_segment_list); + mpd_params.use_colorimetry_essential_property = absl::GetFlag(FLAGS_use_colorimetry_essential_property); if (!absl::GetFlag(FLAGS_utc_timings).empty()) { std::vector pairs = SplitStringIntoKeyValuePairs( diff --git a/packager/app/test/packager_test.py b/packager/app/test/packager_test.py index f5014cf74ca..4f32f1c7632 100755 --- a/packager/app/test/packager_test.py +++ b/packager/app/test/packager_test.py @@ -489,7 +489,8 @@ def _GetFlags(self, dash_force_segment_list=False, force_cl_index=None, start_segment_number=None, - use_dovi_supplemental_codecs=None): + use_dovi_supplemental_codecs=None, + use_colorimetry_essential_property=None): flags = ['--single_threaded'] if not strip_parameter_set_nalus: @@ -550,6 +551,9 @@ def _GetFlags(self, if use_dovi_supplemental_codecs: flags.append('--use_dovi_supplemental_codecs') + if use_colorimetry_essential_property: + flags.append('--use_colorimetry_essential_property') + if output_media_info: flags.append('--output_media_info') if output_dash: @@ -1536,6 +1540,32 @@ def testDolbyVisionProfile10UsingSupplementalCodecs(self): self.assertPackageSuccess(streams, flags) self._CheckTestResults('dolby-vision-profile-10-supplemental-codecs') + def testColorimetryEssentialProperties(self): + streams = [ + self._GetStream('video', test_file='sparks_dovi_8.mp4') + ] + flags = self._GetFlags(encryption=False, + output_dash=True, + output_hls=True, + use_dovi_supplemental_codecs=True, + use_colorimetry_essential_property=True) + + self.assertPackageSuccess(streams, flags) + self._CheckTestResults('colorimetry-essential-property') + + def testColorimetryEssentialPropertiesEncrypted(self): + streams = [ + self._GetStream('video', test_file='sparks_dovi_8.mp4') + ] + flags = self._GetFlags(encryption=True, + output_dash=True, + output_hls=True, + use_dovi_supplemental_codecs=True, + use_colorimetry_essential_property=True) + + self.assertPackageSuccess(streams, flags) + self._CheckTestResults('colorimetry-essential-property-encrypted') + def testVp8Mp4WithEncryption(self): streams = [ self._GetStream('video', diff --git a/packager/app/test/testdata/colorimetry-essential-property-encrypted/output.m3u8 b/packager/app/test/testdata/colorimetry-essential-property-encrypted/output.m3u8 new file mode 100644 index 00000000000..1ea05d3b5d7 --- /dev/null +++ b/packager/app/test/testdata/colorimetry-essential-property-encrypted/output.m3u8 @@ -0,0 +1,7 @@ +#EXTM3U +## Generated with https://github.com/shaka-project/shaka-packager version -- + +#EXT-X-INDEPENDENT-SEGMENTS + +#EXT-X-STREAM-INF:BANDWIDTH=818598,AVERAGE-BANDWIDTH=755328,CODECS="hvc1.2.4.L90.90",SUPPLEMENTAL-CODECS="dvh1.08.01/db2g",RESOLUTION=640x360,FRAME-RATE=59.940,VIDEO-RANGE=PQ,CLOSED-CAPTIONS=NONE +stream_0.m3u8 diff --git a/packager/app/test/testdata/colorimetry-essential-property-encrypted/output.mpd b/packager/app/test/testdata/colorimetry-essential-property-encrypted/output.mpd new file mode 100644 index 00000000000..002a99e36b0 --- /dev/null +++ b/packager/app/test/testdata/colorimetry-essential-property-encrypted/output.mpd @@ -0,0 +1,21 @@ + + + + + + + + + + + AAAANHBzc2gBAAAAEHfv7MCyTQKs4zweUuL7SwAAAAExMjM0NTY3ODkwMTIzNDU2AAAAAA== + + + sparks_dovi_8-video.mp4 + + + + + + + diff --git a/packager/app/test/testdata/colorimetry-essential-property-encrypted/sparks_dovi_8-video.mp4 b/packager/app/test/testdata/colorimetry-essential-property-encrypted/sparks_dovi_8-video.mp4 new file mode 100644 index 00000000000..64945106ac4 Binary files /dev/null and b/packager/app/test/testdata/colorimetry-essential-property-encrypted/sparks_dovi_8-video.mp4 differ diff --git a/packager/app/test/testdata/colorimetry-essential-property-encrypted/stream_0.m3u8 b/packager/app/test/testdata/colorimetry-essential-property-encrypted/stream_0.m3u8 new file mode 100644 index 00000000000..d605915473a --- /dev/null +++ b/packager/app/test/testdata/colorimetry-essential-property-encrypted/stream_0.m3u8 @@ -0,0 +1,19 @@ +#EXTM3U +#EXT-X-VERSION:6 +## Generated with https://github.com/shaka-project/shaka-packager version -- +#EXT-X-TARGETDURATION:3 +#EXT-X-PLAYLIST-TYPE:VOD +#EXT-X-MAP:URI="sparks_dovi_8-video.mp4",BYTERANGE="1374@0" +#EXTINF:2.002, +#EXT-X-BYTERANGE:172013@1454 +sparks_dovi_8-video.mp4 +#EXTINF:2.002, +#EXT-X-BYTERANGE:189474 +sparks_dovi_8-video.mp4 +#EXTINF:2.002, +#EXT-X-BYTERANGE:204854 +sparks_dovi_8-video.mp4 +#EXTINF:0.017, +#EXT-X-BYTERANGE:2296 +sparks_dovi_8-video.mp4 +#EXT-X-ENDLIST diff --git a/packager/app/test/testdata/colorimetry-essential-property/output.m3u8 b/packager/app/test/testdata/colorimetry-essential-property/output.m3u8 new file mode 100644 index 00000000000..c18631c4c68 --- /dev/null +++ b/packager/app/test/testdata/colorimetry-essential-property/output.m3u8 @@ -0,0 +1,7 @@ +#EXTM3U +## Generated with https://github.com/shaka-project/shaka-packager version -- + +#EXT-X-INDEPENDENT-SEGMENTS + +#EXT-X-STREAM-INF:BANDWIDTH=807837,AVERAGE-BANDWIDTH=748074,CODECS="hvc1.2.4.L90.90",SUPPLEMENTAL-CODECS="dvh1.08.01/db2g",RESOLUTION=640x360,FRAME-RATE=59.940,VIDEO-RANGE=PQ,CLOSED-CAPTIONS=NONE +stream_0.m3u8 diff --git a/packager/app/test/testdata/colorimetry-essential-property/output.mpd b/packager/app/test/testdata/colorimetry-essential-property/output.mpd new file mode 100644 index 00000000000..510d3cdb649 --- /dev/null +++ b/packager/app/test/testdata/colorimetry-essential-property/output.mpd @@ -0,0 +1,17 @@ + + + + + + + + + + sparks_dovi_8-video.mp4 + + + + + + + diff --git a/packager/app/test/testdata/colorimetry-essential-property/sparks_dovi_8-video.mp4 b/packager/app/test/testdata/colorimetry-essential-property/sparks_dovi_8-video.mp4 new file mode 100644 index 00000000000..ce05290a78d Binary files /dev/null and b/packager/app/test/testdata/colorimetry-essential-property/sparks_dovi_8-video.mp4 differ diff --git a/packager/app/test/testdata/colorimetry-essential-property/stream_0.m3u8 b/packager/app/test/testdata/colorimetry-essential-property/stream_0.m3u8 new file mode 100644 index 00000000000..6b90ac6a7e6 --- /dev/null +++ b/packager/app/test/testdata/colorimetry-essential-property/stream_0.m3u8 @@ -0,0 +1,19 @@ +#EXTM3U +#EXT-X-VERSION:6 +## Generated with https://github.com/shaka-project/shaka-packager version -- +#EXT-X-TARGETDURATION:3 +#EXT-X-PLAYLIST-TYPE:VOD +#EXT-X-MAP:URI="sparks_dovi_8-video.mp4",BYTERANGE="992@0" +#EXTINF:2.002, +#EXT-X-BYTERANGE:172013@1072 +sparks_dovi_8-video.mp4 +#EXTINF:2.002, +#EXT-X-BYTERANGE:186781 +sparks_dovi_8-video.mp4 +#EXTINF:2.002, +#EXT-X-BYTERANGE:202161 +sparks_dovi_8-video.mp4 +#EXTINF:0.017, +#EXT-X-BYTERANGE:2221 +sparks_dovi_8-video.mp4 +#EXT-X-ENDLIST diff --git a/packager/mpd/base/adaptation_set.cc b/packager/mpd/base/adaptation_set.cc index e0874cb70d5..cde27b9b927 100644 --- a/packager/mpd/base/adaptation_set.cc +++ b/packager/mpd/base/adaptation_set.cc @@ -382,28 +382,40 @@ std::optional AdaptationSet::GetXml() { } } - // https://dashif.org/docs/DASH-IF-IOP-v4.3.pdf - 4.2.5.1 - if (IsVideo() && matrix_coefficients_ > 0 && - !adaptation_set.AddSupplementalProperty( - "urn:mpeg:mpegB:cicp:MatrixCoefficients", - std::to_string(matrix_coefficients_))) { - return std::nullopt; - } + if (IsVideo()) { + + auto add_property = + mpd_options_.mpd_params.use_colorimetry_essential_property + ? &xml::AdaptationSetXmlNode::AddEssentialProperty + : &xml::AdaptationSetXmlNode::AddSupplementalProperty; + + const char kMatrixUri[] = "urn:mpeg:mpegB:cicp:MatrixCoefficients"; + const char kPrimariesUri[] = "urn:mpeg:mpegB:cicp:ColourPrimaries"; + const char kTransferUri[] = "urn:mpeg:mpegB:cicp:TransferCharacteristics"; + + // https://dashif.org/docs/DASH-IF-IOP-v4.3.pdf - 4.2.5.1 + if (matrix_coefficients_ > 0) { + if (!(adaptation_set.*add_property)( + kMatrixUri, + std::to_string(matrix_coefficients_))) + return std::nullopt; + } - // https://dashif.org/docs/DASH-IF-IOP-v4.3.pdf - 4.2.5.1 - if (IsVideo() && color_primaries_ > 0 && - !adaptation_set.AddSupplementalProperty( - "urn:mpeg:mpegB:cicp:ColourPrimaries", - std::to_string(color_primaries_))) { - return std::nullopt; - } + // https://dashif.org/docs/DASH-IF-IOP-v4.3.pdf - 4.2.5.1 + if (color_primaries_ > 0) { + if (!(adaptation_set.*add_property)( + kPrimariesUri, + std::to_string(color_primaries_))) + return std::nullopt; + } - // 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 std::nullopt; + // https://dashif.org/docs/DASH-IF-IOP-v4.3.pdf - 4.2.5.1 + if (transfer_characteristics_ > 0) { + if (!(adaptation_set.*add_property)( + kTransferUri, + std::to_string(transfer_characteristics_))) + return std::nullopt; + } } // Note: must be checked before checking segments_aligned_ (below). So that