PR #25606 opened by Kacper Michajłow (kasper93)
URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/25606
Patch URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/25606.patch

```fate-samples
hevc/dovi-p4-nodm.hevc
hevc/dovi-p8-nodm.hevc
```



From 8bedf287f5117ee13b6e5343da7edca2f37515c5 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Kacper=20Michaj=C5=82ow?= <[email protected]>
Date: Fri, 30 Oct 2026 08:05:07 +0100
Subject: [PATCH 1/3] avcodec/dovi_rpu: fix the default YCC to RGB matrix and
 offsets

The defaults of an RPU without display management metadata had the two
chroma coefficients of the green row with the wrong sign and the offsets
as 1/4 and 2, where ETSI GS CCM 001 clause 6.2.2 gives -1754 and -4383
and the offsets 1/16 and 1/2.
---
 libavcodec/dovi_rpu.c | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/libavcodec/dovi_rpu.c b/libavcodec/dovi_rpu.c
index f19c1922f16..99765b9f773 100644
--- a/libavcodec/dovi_rpu.c
+++ b/libavcodec/dovi_rpu.c
@@ -99,16 +99,16 @@ const AVDOVIColorMetadata ff_dovi_color_default = {
         {     0, 8192 },
         { 14742, 8192 },
         {  9575, 8192 },
-        {  1754, 8192 },
-        {  4383, 8192 },
+        { -1754, 8192 },
+        { -4383, 8192 },
         {  9575, 8192 },
         { 17372, 8192 },
         {     0, 8192 },
     },
     .ycc_to_rgb_offset = {
-        { 1, 4 },
-        { 2, 1 },
-        { 2, 1 },
+        { 1, 16 },
+        { 1,  2 },
+        { 1,  2 },
     },
     .rgb_to_lms_matrix = {
         {  5845, 16384 },
-- 
2.54.0


From 4490f67015d39132467ab102e5b6f08ca717866a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Kacper=20Michaj=C5=82ow?= <[email protected]>
Date: Fri, 30 Oct 2026 08:06:54 +0100
Subject: [PATCH 2/3] avcodec/dovi_rpu: default to the display management
 metadata of a PQ signal

An RPU without display management metadata took the defaults of the
14-bit gamma signal of profile 4, so a PQ stream without the block was
reported as a 14-bit gamma signal, and the encoder omitted the block only
for that metadata. Take table 3 of ETSI GS CCM 001, a PQ signal of 12
bits, for the 10 and 12-bit compositions, and keep the gamma signal for
the 14-bit ones, which clause 5.4.3.3 reserves for a base layer in
BT.1886.
---
 libavcodec/dovi_rpu.c    | 43 ++++++++++++++++++++++++++++++++++++++++
 libavcodec/dovi_rpu.h    | 12 ++++++++++-
 libavcodec/dovi_rpudec.c |  2 +-
 libavcodec/dovi_rpuenc.c |  4 ++--
 4 files changed, 57 insertions(+), 4 deletions(-)

diff --git a/libavcodec/dovi_rpu.c b/libavcodec/dovi_rpu.c
index 99765b9f773..9fd4e3ccae4 100644
--- a/libavcodec/dovi_rpu.c
+++ b/libavcodec/dovi_rpu.c
@@ -92,6 +92,49 @@ int ff_dovi_guess_profile_hevc(const AVDOVIRpuDataHeader 
*hdr)
 }
 
 const AVDOVIColorMetadata ff_dovi_color_default = {
+    .dm_metadata_id     = 0,
+    .scene_refresh_flag = 0,
+    .ycc_to_rgb_matrix = {
+        {  9575, 8192 },
+        {     0, 8192 },
+        { 14742, 8192 },
+        {  9575, 8192 },
+        { -1754, 8192 },
+        { -4383, 8192 },
+        {  9575, 8192 },
+        { 17372, 8192 },
+        {     0, 8192 },
+    },
+    .ycc_to_rgb_offset = {
+        { 1, 16 },
+        { 1,  2 },
+        { 1,  2 },
+    },
+    .rgb_to_lms_matrix = {
+        {  5845, 16384 },
+        {  9702, 16384 },
+        {   837, 16384 },
+        {  2568, 16384 },
+        { 12256, 16384 },
+        {  1561, 16384 },
+        {     0, 16384 },
+        {   679, 16384 },
+        { 15705, 16384 },
+    },
+    .signal_eotf            = 0xFFFF,
+    .signal_eotf_param0     = 0,
+    .signal_eotf_param1     = 0,
+    .signal_eotf_param2     = 0,
+    .signal_bit_depth       = 12,
+    .signal_color_space     = 0,
+    .signal_chroma_format   = 0,
+    .signal_full_range_flag = 1,
+    .source_min_pq          = 62,
+    .source_max_pq          = 3696,
+    .source_diagonal        = 42,
+};
+
+const AVDOVIColorMetadata ff_dovi_color_default_bt1886 = {
     .dm_metadata_id     = 0,
     .scene_refresh_flag = 0,
     .ycc_to_rgb_matrix = {
diff --git a/libavcodec/dovi_rpu.h b/libavcodec/dovi_rpu.h
index 1b74983205d..8e60636dd29 100644
--- a/libavcodec/dovi_rpu.h
+++ b/libavcodec/dovi_rpu.h
@@ -191,8 +191,18 @@ enum {
  */
 int ff_dovi_guess_profile_hevc(const AVDOVIRpuDataHeader *hdr);
 
-/* Default values for AVDOVIColorMetadata */
+/* Default values for AVDOVIColorMetadata, of a PQ signal (ETSI GS CCM 001
+ * table 3) and of the 14-bit gamma signal composed from a base layer in
+ * BT.1886 (clause 5.4.3.3) */
 extern const AVDOVIColorMetadata ff_dovi_color_default;
+extern const AVDOVIColorMetadata ff_dovi_color_default_bt1886;
+
+static inline const AVDOVIColorMetadata *
+ff_dovi_default_color(const AVDOVIRpuDataHeader *hdr)
+{
+    return hdr->vdr_bit_depth == 14 ? &ff_dovi_color_default_bt1886
+                                    : &ff_dovi_color_default;
+}
 
 static inline int ff_dovi_rpu_extension_is_static(int level)
 {
diff --git a/libavcodec/dovi_rpudec.c b/libavcodec/dovi_rpudec.c
index 79717f605f6..8d69401b59f 100644
--- a/libavcodec/dovi_rpudec.c
+++ b/libavcodec/dovi_rpudec.c
@@ -721,7 +721,7 @@ int ff_dovi_rpu_parse(DOVIContext *s, const uint8_t *rpu, 
size_t rpu_size,
             }
         }
     } else {
-        s->color = &ff_dovi_color_default;
+        s->color = ff_dovi_default_color(hdr);
         av_refstruct_unref(&s->ext_blocks);
     }
 
diff --git a/libavcodec/dovi_rpuenc.c b/libavcodec/dovi_rpuenc.c
index 4bd87f496fe..f674e6bb49a 100644
--- a/libavcodec/dovi_rpuenc.c
+++ b/libavcodec/dovi_rpuenc.c
@@ -726,7 +726,7 @@ int ff_dovi_rpu_generate(DOVIContext *s, const 
AVDOVIMetadata *metadata,
             return AVERROR(ENOMEM);
     }
 
-    vdr_dm_metadata_present = !!memcmp(color, &ff_dovi_color_default, 
sizeof(*color));
+    vdr_dm_metadata_present = !!memcmp(color, ff_dovi_default_color(hdr), 
sizeof(*color));
     if (metadata->num_ext_blocks)
         vdr_dm_metadata_present = 1;
 
@@ -954,7 +954,7 @@ int ff_dovi_rpu_generate(DOVIContext *s, const 
AVDOVIMetadata *metadata,
             }
         }
     } else {
-        s->color = &ff_dovi_color_default;
+        s->color = ff_dovi_default_color(hdr);
         av_refstruct_unref(&s->ext_blocks);
     }
 
-- 
2.54.0


From 6f9278f278c55f67490bc01e51b54a36243b944a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Kacper=20Michaj=C5=82ow?= <[email protected]>
Date: Fri, 30 Oct 2026 08:35:07 +0100
Subject: [PATCH 3/3] fate/hevc: test Dolby Vision RPUs without display
 management metadata

One frame with a 12-bit and one with a 14-bit RPU without the block,
probed for the defaults the decoder fills in.
---
 tests/fate/hevc.mak                |   4 +
 tests/ref/fate/hevc-dv-rpu-nodm-p4 | 123 +++++++++++++++++++++++++++
 tests/ref/fate/hevc-dv-rpu-nodm-p8 | 129 +++++++++++++++++++++++++++++
 3 files changed, 256 insertions(+)
 create mode 100644 tests/ref/fate/hevc-dv-rpu-nodm-p4
 create mode 100644 tests/ref/fate/hevc-dv-rpu-nodm-p8

diff --git a/tests/fate/hevc.mak b/tests/fate/hevc.mak
index b39358167ee..387155b4143 100644
--- a/tests/fate/hevc.mak
+++ b/tests/fate/hevc.mak
@@ -291,6 +291,10 @@ FATE_HEVC_FFPROBE-$(call PARSERDEMDEC, HEVC, HEVC, HEVC) 
+= fate-hevc-hdr-vivid-
 fate-hevc-dv-rpu: CMD = probeframes -show_entries frame=side_data_list 
-select_streams 0 -read_intervals "%+\#2" $(TARGET_SAMPLES)/hevc/dv84.mov
 FATE_HEVC_FFPROBE-$(call DEMDEC, MOV, HEVC) += fate-hevc-dv-rpu
 
+fate-hevc-dv-rpu-nodm-p8: CMD = probeframes -show_entries frame=side_data_list 
$(TARGET_SAMPLES)/hevc/dovi-p8-nodm.hevc
+fate-hevc-dv-rpu-nodm-p4: CMD = probeframes -show_entries frame=side_data_list 
$(TARGET_SAMPLES)/hevc/dovi-p4-nodm.hevc
+FATE_HEVC_FFPROBE-$(call PARSERDEMDEC, HEVC, HEVC, HEVC) += 
fate-hevc-dv-rpu-nodm-p8 fate-hevc-dv-rpu-nodm-p4
+
 fate-hevc-two-first-slice: CMD = threads=2 framemd5 -i 
$(TARGET_SAMPLES)/hevc/two_first_slice.mp4 -sws_flags bitexact -t 00:02.00 -an
 FATE_HEVC-$(call FRAMEMD5, MOV, HEVC) += fate-hevc-two-first-slice
 
diff --git a/tests/ref/fate/hevc-dv-rpu-nodm-p4 
b/tests/ref/fate/hevc-dv-rpu-nodm-p4
new file mode 100644
index 00000000000..d479aba46e3
--- /dev/null
+++ b/tests/ref/fate/hevc-dv-rpu-nodm-p4
@@ -0,0 +1,123 @@
+[FRAME]
+[SIDE_DATA]
+side_data_type=Dolby Vision RPU Data
+[/SIDE_DATA]
+[SIDE_DATA]
+side_data_type=Dolby Vision Metadata
+rpu_type=2
+rpu_format=18
+vdr_rpu_profile=1
+vdr_rpu_level=0
+chroma_resampling_explicit_filter_flag=0
+coef_data_type=0
+coef_log2_denom=23
+vdr_rpu_normalized_idc=1
+bl_video_full_range_flag=0
+bl_bit_depth=10
+el_bit_depth=10
+vdr_bit_depth=14
+spatial_resampling_filter_flag=0
+el_spatial_resampling_filter_flag=1
+disable_residual_flag=0
+vdr_rpu_id=0
+mapping_color_space=0
+mapping_chroma_format_idc=0
+nlq_method_idc=0
+nlq_method_idc_name=linear_dz
+num_x_partitions=1
+num_y_partitions=1
+[COMPONENT]
+pivots=0 127 254 381 508 635 762 1023
+[PIECE]
+mapping_idc=0
+mapping_idc_name=polynomial
+poly_order=2
+poly_coef=213062 5891559 -17445672
+[/PIECE]
+[PIECE]
+mapping_idc=0
+mapping_idc_name=polynomial
+poly_order=2
+poly_coef=413068 2125125 -79688
+[/PIECE]
+[PIECE]
+mapping_idc=0
+mapping_idc_name=polynomial
+poly_order=2
+poly_coef=496486 1440069 1326334
+[/PIECE]
+[PIECE]
+mapping_idc=0
+mapping_idc_name=polynomial
+poly_order=2
+poly_coef=981073 -1216757 4966557
+[/PIECE]
+[PIECE]
+mapping_idc=0
+mapping_idc_name=polynomial
+poly_order=2
+poly_coef=3366544 -9995684 12969922
+[/PIECE]
+[PIECE]
+mapping_idc=0
+mapping_idc_name=polynomial
+poly_order=2
+poly_coef=10689129 -31143132 28030074
+[/PIECE]
+[PIECE]
+mapping_idc=0
+mapping_idc_name=polynomial
+poly_order=1
+poly_coef=3035779 0
+[/PIECE]
+nlq_offset=222
+vdr_in_max=2541417
+linear_deadzone_slope=3172
+linear_deadzone_threshold=0
+[/COMPONENT]
+[COMPONENT]
+pivots=0 1023
+[PIECE]
+mapping_idc=1
+mapping_idc_name=mmr
+mmr_order=3
+mmr_constant=16449274
+mmr_coef=4103435 -44190260 -28549000 -10285070 -10368700 22808488 25116122 
-545273 72049280 39815660 4575146 8341101 -24908494 -45741684 -1383188 
-41706216 -22319822 12513032 -173411 0 0
+[/PIECE]
+nlq_offset=456
+vdr_in_max=233999
+linear_deadzone_slope=1271
+linear_deadzone_threshold=0
+[/COMPONENT]
+[COMPONENT]
+pivots=0 1023
+[PIECE]
+mapping_idc=1
+mapping_idc_name=mmr
+mmr_order=3
+mmr_constant=-34580828
+mmr_coef=7098579 115975488 89402904 -10084052 -11819902 -152075520 15231387 
-2935989 -110839976 -61692752 2647022 5633932 143070384 16789862 1574340 
46978764 19447978 -7298183 -6733614 0 0
+[/PIECE]
+nlq_offset=474
+vdr_in_max=200689
+linear_deadzone_slope=1270
+linear_deadzone_threshold=0
+[/COMPONENT]
+dm_metadata_id=0
+scene_refresh_flag=0
+ycc_to_rgb_matrix=9575/8192 0/8192 14742/8192 9575/8192 -1754/8192 -4383/8192 
9575/8192 17372/8192 0/8192
+ycc_to_rgb_offset=1/16 1/2 1/2
+rgb_to_lms_matrix=5845/16384 9702/16384 837/16384 2568/16384 12256/16384 
1561/16384 0/16384 679/16384 15705/16384
+signal_eotf=39322
+signal_eotf_param0=15867
+signal_eotf_param1=228
+signal_eotf_param2=1383604
+signal_bit_depth=14
+signal_color_space=0
+signal_chroma_format=0
+signal_full_range_flag=1
+source_min_pq=62
+source_max_pq=3696
+source_diagonal=42
+[/SIDE_DATA]
+[/FRAME]
diff --git a/tests/ref/fate/hevc-dv-rpu-nodm-p8 
b/tests/ref/fate/hevc-dv-rpu-nodm-p8
new file mode 100644
index 00000000000..12163fe6655
--- /dev/null
+++ b/tests/ref/fate/hevc-dv-rpu-nodm-p8
@@ -0,0 +1,129 @@
+[FRAME]
+[SIDE_DATA]
+side_data_type=Dolby Vision RPU Data
+[/SIDE_DATA]
+[SIDE_DATA]
+side_data_type=Dolby Vision Metadata
+rpu_type=2
+rpu_format=18
+vdr_rpu_profile=1
+vdr_rpu_level=0
+chroma_resampling_explicit_filter_flag=0
+coef_data_type=0
+coef_log2_denom=23
+vdr_rpu_normalized_idc=1
+bl_video_full_range_flag=0
+bl_bit_depth=10
+el_bit_depth=10
+vdr_bit_depth=12
+spatial_resampling_filter_flag=0
+el_spatial_resampling_filter_flag=1
+disable_residual_flag=0
+vdr_rpu_id=0
+mapping_color_space=0
+mapping_chroma_format_idc=0
+nlq_method_idc=0
+nlq_method_idc_name=linear_dz
+num_x_partitions=1
+num_y_partitions=1
+[COMPONENT]
+pivots=0 128 256 384 512 640 768 896 1023
+[PIECE]
+mapping_idc=0
+mapping_idc_name=polynomial
+poly_order=1
+poly_coef=0 8388608
+[/PIECE]
+[PIECE]
+mapping_idc=0
+mapping_idc_name=polynomial
+poly_order=1
+poly_coef=0 8388608
+[/PIECE]
+[PIECE]
+mapping_idc=0
+mapping_idc_name=polynomial
+poly_order=1
+poly_coef=0 8388608
+[/PIECE]
+[PIECE]
+mapping_idc=0
+mapping_idc_name=polynomial
+poly_order=1
+poly_coef=0 8388608
+[/PIECE]
+[PIECE]
+mapping_idc=0
+mapping_idc_name=polynomial
+poly_order=1
+poly_coef=0 8388608
+[/PIECE]
+[PIECE]
+mapping_idc=0
+mapping_idc_name=polynomial
+poly_order=1
+poly_coef=0 8388608
+[/PIECE]
+[PIECE]
+mapping_idc=0
+mapping_idc_name=polynomial
+poly_order=1
+poly_coef=0 8388608
+[/PIECE]
+[PIECE]
+mapping_idc=0
+mapping_idc_name=polynomial
+poly_order=1
+poly_coef=0 8388608
+[/PIECE]
+nlq_offset=512
+vdr_in_max=1048576
+linear_deadzone_slope=2048
+linear_deadzone_threshold=0
+[/COMPONENT]
+[COMPONENT]
+pivots=0 1023
+[PIECE]
+mapping_idc=1
+mapping_idc_name=mmr
+mmr_order=3
+mmr_constant=1531801
+mmr_coef=11492892 8537460 -1042134 -30398922 29816652 -16552261 7603182 
-68950248 591318 1579150 1071993 -2837853 27827992 -6300769 5340337 -1778050 
1839703 -8308845 10291805 15925644 0
+[/PIECE]
+nlq_offset=512
+vdr_in_max=1048576
+linear_deadzone_slope=2048
+linear_deadzone_threshold=0
+[/COMPONENT]
+[COMPONENT]
+pivots=0 1023
+[PIECE]
+mapping_idc=1
+mapping_idc_name=mmr
+mmr_order=3
+mmr_constant=-1494901
+mmr_coef=3017344 3764755 13577232 -14286250 4264498 607605 4095404 -5763423 
-853472 -5786657 2792002 5753012 -2115534 -5883643 8417115 -1996323 -9181184 
13601885 -9651483 8353145 0
+[/PIECE]
+nlq_offset=512
+vdr_in_max=1048576
+linear_deadzone_slope=2048
+linear_deadzone_threshold=0
+[/COMPONENT]
+dm_metadata_id=0
+scene_refresh_flag=0
+ycc_to_rgb_matrix=9575/8192 0/8192 14742/8192 9575/8192 -1754/8192 -4383/8192 
9575/8192 17372/8192 0/8192
+ycc_to_rgb_offset=1/16 1/2 1/2
+rgb_to_lms_matrix=5845/16384 9702/16384 837/16384 2568/16384 12256/16384 
1561/16384 0/16384 679/16384 15705/16384
+signal_eotf=65535
+signal_eotf_param0=0
+signal_eotf_param1=0
+signal_eotf_param2=0
+signal_bit_depth=12
+signal_color_space=0
+signal_chroma_format=0
+signal_full_range_flag=1
+source_min_pq=62
+source_max_pq=3696
+source_diagonal=42
+[/SIDE_DATA]
+[/FRAME]
-- 
2.54.0

_______________________________________________
ffmpeg-devel mailing list -- [email protected]
To unsubscribe send an email to [email protected]

Reply via email to