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]
