mirror of
https://github.com/FFmpeg/FFmpeg.git
synced 2026-11-06 05:17:42 +00:00
tests/fate/libavutil: add FATE test for hdr_dynamic_metadata
Test av_dynamic_hdr_plus_alloc, av_dynamic_hdr_plus_create_side_data, av_dynamic_hdr_plus_to_t35 in all three documented modes (size query, caller-allocated, existing caller-owned buffer) including the AVERROR_BUFFER_TOO_SMALL path, and av_dynamic_hdr_plus_from_t35 as a round-trip inverse. Two HDR10+ fixtures are used. The first is a conforming ST 2094-40:2020 ApplicationVersion 1 payload: one processing window, the nine distribution maxrgb percentiles required by section 8.5.4, and neither actual-peak-luminance item nor ColorSaturationWeight, both excluded for that version by section 9.4. The second is marked in the source as deliberately non-conforming and exists only to reach the optional serializer/parser branches: a second processing window with its geometry, both actual-peak-luminance matrices, per-window tone mapping and color saturation. Every field either fixture populates is decoded and printed, so a serializer or parser that drops or corrupts a value changes the reference rather than passing a flag-only check. Also test that av_dynamic_hdr_plus_to_t35 ignores application_version and always writes the CTA-861-H value, the NULL and oversized error paths, and av_dynamic_hdr_smpte2094_app5_alloc, av_dynamic_hdr_smpte2094_app5_create_side_data and the App5 to_t35 / from_t35 round trip over four fixtures covering both early-out paths (no adaptive tone map, reference-white tone mapping) and both sides of the component mixing and gain curve selectors: per-image parameters with component mixing type 3 and explicit control point slopes, and common parameters shared from alternate 0 with a mixing type other than 3 and the pchip slope. The App5 to_t35 validation failures and the OOM paths via av_max_alloc are covered as well. Coverage for libavutil/hdr_dynamic_metadata.c: 31.02% -> 95.53% The baseline comes from the HDR10+ sample tests on a full FATE run (fate-hevc-hdr10-plus-metadata, fate-png-mdcv and the Matroska/WebM HDR10+ remux tests). Signed-off-by: marcos ashton <marcosashiglesias@gmail.com>
This commit is contained in:
1 parent
b799c7772b
commit
58c47ca583
6 files changed
+877
No files matched your search
@@ -238,6 +238,7 @@ libavutil/tests/buffer.* @MarcosAsh
|
||||
libavutil/tests/csp.* @MarcosAsh
|
||||
libavutil/tests/dovi_meta.* @MarcosAsh
|
||||
libavutil/tests/downmix_info.* @MarcosAsh
|
||||
libavutil/tests/hdr_dynamic_metadata.* @MarcosAsh
|
||||
libavutil/tests/hdr_dynamic_vivid_metadata.* @MarcosAsh
|
||||
libavutil/tests/mastering_display_metadata.* @MarcosAsh
|
||||
libavutil/tests/pixdesc.* @MarcosAsh
|
||||
@@ -250,6 +251,7 @@ tests/ref/fate/buffer @MarcosAsh
|
||||
tests/ref/fate/csp @MarcosAsh
|
||||
tests/ref/fate/dovi_meta @MarcosAsh
|
||||
tests/ref/fate/downmix_info @MarcosAsh
|
||||
tests/ref/fate/hdr_dynamic_metadata @MarcosAsh
|
||||
tests/ref/fate/hdr_dynamic_vivid_metadata @MarcosAsh
|
||||
tests/ref/fate/mastering_display_metadata @MarcosAsh
|
||||
tests/ref/fate/pixdesc @MarcosAsh
|
||||
|
||||
@@ -285,6 +285,7 @@ TESTPROGS = adler32 \
|
||||
fifo \
|
||||
film_grain_params \
|
||||
hash \
|
||||
hdr_dynamic_metadata \
|
||||
hdr_dynamic_vivid_metadata \
|
||||
hmac \
|
||||
hwdevice \
|
||||
|
||||
@@ -30,6 +30,7 @@
|
||||
/file
|
||||
/film_grain_params
|
||||
/hash
|
||||
/hdr_dynamic_metadata
|
||||
/hdr_dynamic_vivid_metadata
|
||||
/hmac
|
||||
/hwcontext_cuda
|
||||
|
||||
@@ -0,0 +1,723 @@
|
||||
/*
|
||||
* This file is part of FFmpeg.
|
||||
*
|
||||
* FFmpeg is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* FFmpeg is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with FFmpeg; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#include <limits.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "libavutil/error.h"
|
||||
#include "libavutil/frame.h"
|
||||
#include "libavutil/hdr_dynamic_metadata.h"
|
||||
#include "libavutil/mem.h"
|
||||
#include "libavutil/rational.h"
|
||||
|
||||
/* Denominators av_dynamic_hdr_plus_to_t35() quantises to. The fixtures below
|
||||
* express every rational in these terms, so a correct round trip reproduces
|
||||
* the input exactly and the decoded values printed here can be compared
|
||||
* against the fixture directly. */
|
||||
#define LUMINANCE_DEN 1
|
||||
#define PEAK_LUMINANCE_DEN 15
|
||||
#define RGB_DEN 100000
|
||||
#define FRACTION_PIXEL_DEN 1000
|
||||
#define KNEE_POINT_DEN 4095
|
||||
#define BEZIER_ANCHOR_DEN 1023
|
||||
#define SATURATION_DEN 8
|
||||
|
||||
/*
|
||||
* Printers. Every field a fixture populates is printed, so that a serializer
|
||||
* or parser which drops or corrupts a value changes the FATE reference
|
||||
* instead of silently passing a flag-only check.
|
||||
*/
|
||||
|
||||
static void print_peak_matrix(const char *label, int rows, int cols,
|
||||
const AVRational m[25][25])
|
||||
{
|
||||
printf(" %s %dx%d:", label, rows, cols);
|
||||
for (int i = 0; i < rows; i++)
|
||||
for (int j = 0; j < cols; j++)
|
||||
printf(" %d/%d", m[i][j].num, m[i][j].den);
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
static void print_window(int w, const AVHDRPlusColorTransformParams *p,
|
||||
int geometry)
|
||||
{
|
||||
printf(" window %d:\n", w);
|
||||
/* Window 0 covers the whole frame; its geometry is not serialized. */
|
||||
if (geometry) {
|
||||
printf(" corners: ul=%d/%d,%d/%d lr=%d/%d,%d/%d\n",
|
||||
p->window_upper_left_corner_x.num,
|
||||
p->window_upper_left_corner_x.den,
|
||||
p->window_upper_left_corner_y.num,
|
||||
p->window_upper_left_corner_y.den,
|
||||
p->window_lower_right_corner_x.num,
|
||||
p->window_lower_right_corner_x.den,
|
||||
p->window_lower_right_corner_y.num,
|
||||
p->window_lower_right_corner_y.den);
|
||||
printf(" ellipse: center=%u,%u rotation=%u semimajor_int=%u"
|
||||
" semimajor_ext=%u semiminor_ext=%u overlap=%u\n",
|
||||
p->center_of_ellipse_x, p->center_of_ellipse_y,
|
||||
p->rotation_angle, p->semimajor_axis_internal_ellipse,
|
||||
p->semimajor_axis_external_ellipse,
|
||||
p->semiminor_axis_external_ellipse,
|
||||
p->overlap_process_option);
|
||||
}
|
||||
printf(" maxscl: %d/%d %d/%d %d/%d average_maxrgb=%d/%d\n",
|
||||
p->maxscl[0].num, p->maxscl[0].den,
|
||||
p->maxscl[1].num, p->maxscl[1].den,
|
||||
p->maxscl[2].num, p->maxscl[2].den,
|
||||
p->average_maxrgb.num, p->average_maxrgb.den);
|
||||
printf(" distribution_maxrgb: n=%u",
|
||||
p->num_distribution_maxrgb_percentiles);
|
||||
for (int i = 0; i < p->num_distribution_maxrgb_percentiles; i++)
|
||||
printf(" %u%%=%d/%d", p->distribution_maxrgb[i].percentage,
|
||||
p->distribution_maxrgb[i].percentile.num,
|
||||
p->distribution_maxrgb[i].percentile.den);
|
||||
printf("\n fraction_bright_pixels=%d/%d\n",
|
||||
p->fraction_bright_pixels.num, p->fraction_bright_pixels.den);
|
||||
printf(" tone_mapping_flag=%u", p->tone_mapping_flag);
|
||||
if (p->tone_mapping_flag) {
|
||||
printf(" knee=%d/%d,%d/%d anchors=%u:",
|
||||
p->knee_point_x.num, p->knee_point_x.den,
|
||||
p->knee_point_y.num, p->knee_point_y.den,
|
||||
p->num_bezier_curve_anchors);
|
||||
for (int i = 0; i < p->num_bezier_curve_anchors; i++)
|
||||
printf(" %d/%d", p->bezier_curve_anchors[i].num,
|
||||
p->bezier_curve_anchors[i].den);
|
||||
}
|
||||
printf("\n color_saturation_mapping_flag=%u",
|
||||
p->color_saturation_mapping_flag);
|
||||
if (p->color_saturation_mapping_flag)
|
||||
printf(" weight=%d/%d", p->color_saturation_weight.num,
|
||||
p->color_saturation_weight.den);
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
static void print_hdr_plus(const char *label, const AVDynamicHDRPlus *s)
|
||||
{
|
||||
printf("%s:\n", label);
|
||||
printf(" application_version=%u num_windows=%u"
|
||||
" targeted_system_display_maximum_luminance=%d/%d\n",
|
||||
s->application_version, s->num_windows,
|
||||
s->targeted_system_display_maximum_luminance.num,
|
||||
s->targeted_system_display_maximum_luminance.den);
|
||||
printf(" targeted_system_display_actual_peak_luminance_flag=%u\n",
|
||||
s->targeted_system_display_actual_peak_luminance_flag);
|
||||
if (s->targeted_system_display_actual_peak_luminance_flag)
|
||||
print_peak_matrix("targeted_peak",
|
||||
s->num_rows_targeted_system_display_actual_peak_luminance,
|
||||
s->num_cols_targeted_system_display_actual_peak_luminance,
|
||||
s->targeted_system_display_actual_peak_luminance);
|
||||
printf(" mastering_display_actual_peak_luminance_flag=%u\n",
|
||||
s->mastering_display_actual_peak_luminance_flag);
|
||||
if (s->mastering_display_actual_peak_luminance_flag)
|
||||
print_peak_matrix("mastering_peak",
|
||||
s->num_rows_mastering_display_actual_peak_luminance,
|
||||
s->num_cols_mastering_display_actual_peak_luminance,
|
||||
s->mastering_display_actual_peak_luminance);
|
||||
for (int w = 0; w < s->num_windows; w++)
|
||||
print_window(w, &s->params[w], w > 0);
|
||||
}
|
||||
|
||||
static void print_app5(const char *label, const AVDynamicHDRSmpte2094App5 *s)
|
||||
{
|
||||
printf("%s:\n", label);
|
||||
printf(" application_version=%u minimum_application_version=%u\n",
|
||||
s->application_version, s->minimum_application_version);
|
||||
printf(" has_custom_hdr_reference_white_flag=%u",
|
||||
s->has_custom_hdr_reference_white_flag);
|
||||
if (s->has_custom_hdr_reference_white_flag)
|
||||
printf(" hdr_reference_white=0x%04x", s->hdr_reference_white);
|
||||
printf("\n has_adaptive_tone_map_flag=%u\n",
|
||||
s->has_adaptive_tone_map_flag);
|
||||
if (!s->has_adaptive_tone_map_flag)
|
||||
return;
|
||||
|
||||
printf(" baseline_hdr_headroom=0x%04x"
|
||||
" use_reference_white_tone_mapping_flag=%u\n",
|
||||
s->baseline_hdr_headroom, s->use_reference_white_tone_mapping_flag);
|
||||
if (s->use_reference_white_tone_mapping_flag)
|
||||
return;
|
||||
|
||||
printf(" num_alternate_images=%u chromaticities_flag=%u"
|
||||
" has_common_component_mix_params_flag=%u"
|
||||
" has_common_curve_params_flag=%u\n",
|
||||
s->num_alternate_images,
|
||||
s->gain_application_space_chromaticities_flag,
|
||||
s->has_common_component_mix_params_flag,
|
||||
s->has_common_curve_params_flag);
|
||||
if (s->gain_application_space_chromaticities_flag == 3) {
|
||||
printf(" chromaticities:");
|
||||
for (int r = 0; r < 8; r++)
|
||||
printf(" 0x%04x", s->gain_application_space_chromaticities[r]);
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
for (int a = 0; a < s->num_alternate_images; a++) {
|
||||
int n = s->gain_curve_num_control_points_minus_1[a] + 1;
|
||||
printf(" alternate %d: hdr_headroom=0x%04x component_mixing_type=%u\n",
|
||||
a, s->alternate_hdr_headrooms[a], s->component_mixing_type[a]);
|
||||
if (s->component_mixing_type[a] == 3) {
|
||||
printf(" mixing flag:coefficient:");
|
||||
for (int k = 0; k < 6; k++)
|
||||
printf(" %u:0x%04x",
|
||||
s->has_component_mixing_coefficient_flag[a][k],
|
||||
s->component_mixing_coefficient[a][k]);
|
||||
printf("\n");
|
||||
}
|
||||
printf(" curve: num_control_points=%d use_pchip_slope=%u\n", n,
|
||||
s->gain_curve_use_pchip_slope_flag[a]);
|
||||
printf(" x:");
|
||||
for (int c = 0; c < n; c++)
|
||||
printf(" 0x%04x", s->gain_curve_control_points_x[a][c]);
|
||||
printf("\n y:");
|
||||
for (int c = 0; c < n; c++)
|
||||
printf(" 0x%04x", s->gain_curve_control_points_y[a][c]);
|
||||
printf("\n");
|
||||
/* theta is only serialized when the pchip slope is not used. */
|
||||
if (!s->gain_curve_use_pchip_slope_flag[a]) {
|
||||
printf(" theta:");
|
||||
for (int c = 0; c < n; c++)
|
||||
printf(" 0x%04x", s->gain_curve_control_points_theta[a][c]);
|
||||
printf("\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Round-trip helpers: serialize, then parse back into a zeroed struct.
|
||||
*/
|
||||
|
||||
static int hdr_plus_round_trip(const AVDynamicHDRPlus *in, AVDynamicHDRPlus *out)
|
||||
{
|
||||
uint8_t *buf = NULL;
|
||||
size_t size = 0;
|
||||
int ret;
|
||||
|
||||
ret = av_dynamic_hdr_plus_to_t35(in, &buf, &size);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
memset(out, 0, sizeof(*out));
|
||||
ret = av_dynamic_hdr_plus_from_t35(out, buf, size);
|
||||
av_free(buf);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int app5_round_trip(const AVDynamicHDRSmpte2094App5 *in,
|
||||
AVDynamicHDRSmpte2094App5 *out)
|
||||
{
|
||||
uint8_t *buf = NULL;
|
||||
size_t size = 0;
|
||||
int ret;
|
||||
|
||||
ret = av_dynamic_hdr_smpte2094_app5_to_t35(in, &buf, &size);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
memset(out, 0, sizeof(*out));
|
||||
ret = av_dynamic_hdr_smpte2094_app5_from_t35(out, buf, size);
|
||||
av_free(buf);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* Fixtures.
|
||||
*/
|
||||
|
||||
/* A conforming ST 2094-40:2020 ApplicationVersion 1 payload: exactly one
|
||||
* processing window, neither actual-peak-luminance item and no
|
||||
* ColorSaturationWeight (§9.4 excludes all three for Version 1), and the nine
|
||||
* distribution maxrgb percentiles §8.5.4 requires for that version.
|
||||
* CTA-861-H fixes application_version at 1 for HDR10+ carried over T.35.
|
||||
*
|
||||
* The entries for 5% and 10% are not CFD percentile samples: §8.5.4 reserves
|
||||
* every value other than 0.00000 and 0.00255 for that pair. No other entry may
|
||||
* exceed the largest MaxSCL component either, since §8.3 takes MaxSCL over each
|
||||
* RGB component separately while §8.5.2 draws the distribution from the
|
||||
* per-pixel maximum component. */
|
||||
static void fill_hdr_plus_conforming(AVDynamicHDRPlus *s)
|
||||
{
|
||||
static const uint8_t percentages[9] = { 1, 5, 10, 25, 50, 75, 90, 95, 99 };
|
||||
static const int percentiles[9] = {
|
||||
1000, 0, 255, 25000, 50000, 75000, 90000, 95000, 99000,
|
||||
};
|
||||
|
||||
memset(s, 0, sizeof(*s));
|
||||
|
||||
s->application_version = 1;
|
||||
s->num_windows = 1;
|
||||
s->targeted_system_display_maximum_luminance =
|
||||
(AVRational){ 400, LUMINANCE_DEN };
|
||||
s->targeted_system_display_actual_peak_luminance_flag = 0;
|
||||
s->mastering_display_actual_peak_luminance_flag = 0;
|
||||
|
||||
s->params[0].maxscl[0] = (AVRational){ 50000, RGB_DEN };
|
||||
s->params[0].maxscl[1] = (AVRational){ 60000, RGB_DEN };
|
||||
s->params[0].maxscl[2] = (AVRational){ 99000, RGB_DEN };
|
||||
s->params[0].average_maxrgb = (AVRational){ 40000, RGB_DEN };
|
||||
|
||||
s->params[0].num_distribution_maxrgb_percentiles = 9;
|
||||
for (int i = 0; i < 9; i++) {
|
||||
s->params[0].distribution_maxrgb[i].percentage = percentages[i];
|
||||
s->params[0].distribution_maxrgb[i].percentile =
|
||||
(AVRational){ percentiles[i], RGB_DEN };
|
||||
}
|
||||
s->params[0].fraction_bright_pixels =
|
||||
(AVRational){ 250, FRACTION_PIXEL_DEN };
|
||||
|
||||
s->params[0].tone_mapping_flag = 1;
|
||||
s->params[0].knee_point_x = (AVRational){ 512, KNEE_POINT_DEN };
|
||||
s->params[0].knee_point_y = (AVRational){ 1024, KNEE_POINT_DEN };
|
||||
s->params[0].num_bezier_curve_anchors = 9;
|
||||
for (int i = 0; i < 9; i++)
|
||||
s->params[0].bezier_curve_anchors[i] =
|
||||
(AVRational){ 100 * (i + 1), BEZIER_ANCHOR_DEN };
|
||||
|
||||
s->params[0].color_saturation_mapping_flag = 0;
|
||||
}
|
||||
|
||||
/* Deliberately NOT a conforming Version 1 payload: it combines a second
|
||||
* processing window, both actual-peak-luminance matrices and
|
||||
* ColorSaturationWeight, all of which §9.4 excludes for Version 1. It exists
|
||||
* only to drive the optional serializer/parser branches those fields guard.
|
||||
*
|
||||
* tone_mapping_flag stays set for every window because the serializer writes
|
||||
* color_saturation_mapping_flag inside the tone-mapping block while the parser
|
||||
* reads it outside; only tone_mapping_flag=1 round-trips today. */
|
||||
static void fill_hdr_plus_synthetic(AVDynamicHDRPlus *s)
|
||||
{
|
||||
memset(s, 0, sizeof(*s));
|
||||
|
||||
s->application_version = 1;
|
||||
s->num_windows = 2;
|
||||
s->targeted_system_display_maximum_luminance =
|
||||
(AVRational){ 10000, LUMINANCE_DEN };
|
||||
|
||||
s->params[1].window_upper_left_corner_x = (AVRational){ 100, 1 };
|
||||
s->params[1].window_upper_left_corner_y = (AVRational){ 120, 1 };
|
||||
s->params[1].window_lower_right_corner_x = (AVRational){ 500, 1 };
|
||||
s->params[1].window_lower_right_corner_y = (AVRational){ 520, 1 };
|
||||
s->params[1].center_of_ellipse_x = 300;
|
||||
s->params[1].center_of_ellipse_y = 320;
|
||||
s->params[1].rotation_angle = 45;
|
||||
s->params[1].semimajor_axis_internal_ellipse = 50;
|
||||
s->params[1].semimajor_axis_external_ellipse = 100;
|
||||
s->params[1].semiminor_axis_external_ellipse = 80;
|
||||
s->params[1].overlap_process_option = 1;
|
||||
|
||||
s->params[0].maxscl[0] = (AVRational){ 50000, RGB_DEN };
|
||||
s->params[0].maxscl[1] = (AVRational){ 60000, RGB_DEN };
|
||||
s->params[0].maxscl[2] = (AVRational){ 70000, RGB_DEN };
|
||||
s->params[0].average_maxrgb = (AVRational){ 40000, RGB_DEN };
|
||||
s->params[0].num_distribution_maxrgb_percentiles = 2;
|
||||
s->params[0].distribution_maxrgb[0].percentage = 50;
|
||||
s->params[0].distribution_maxrgb[0].percentile =
|
||||
(AVRational){ 30000, RGB_DEN };
|
||||
s->params[0].distribution_maxrgb[1].percentage = 99;
|
||||
s->params[0].distribution_maxrgb[1].percentile =
|
||||
(AVRational){ 90000, RGB_DEN };
|
||||
s->params[0].fraction_bright_pixels =
|
||||
(AVRational){ 250, FRACTION_PIXEL_DEN };
|
||||
|
||||
s->params[1].maxscl[0] = (AVRational){ 20000, RGB_DEN };
|
||||
s->params[1].maxscl[1] = (AVRational){ 30000, RGB_DEN };
|
||||
s->params[1].maxscl[2] = (AVRational){ 40000, RGB_DEN };
|
||||
s->params[1].average_maxrgb = (AVRational){ 25000, RGB_DEN };
|
||||
s->params[1].num_distribution_maxrgb_percentiles = 1;
|
||||
s->params[1].distribution_maxrgb[0].percentage = 25;
|
||||
s->params[1].distribution_maxrgb[0].percentile =
|
||||
(AVRational){ 12500, RGB_DEN };
|
||||
s->params[1].fraction_bright_pixels =
|
||||
(AVRational){ 100, FRACTION_PIXEL_DEN };
|
||||
|
||||
s->targeted_system_display_actual_peak_luminance_flag = 1;
|
||||
s->num_rows_targeted_system_display_actual_peak_luminance = 2;
|
||||
s->num_cols_targeted_system_display_actual_peak_luminance = 3;
|
||||
for (int i = 0; i < 2; i++)
|
||||
for (int j = 0; j < 3; j++)
|
||||
s->targeted_system_display_actual_peak_luminance[i][j] =
|
||||
(AVRational){ i * 3 + j, PEAK_LUMINANCE_DEN };
|
||||
|
||||
s->mastering_display_actual_peak_luminance_flag = 1;
|
||||
s->num_rows_mastering_display_actual_peak_luminance = 3;
|
||||
s->num_cols_mastering_display_actual_peak_luminance = 2;
|
||||
for (int i = 0; i < 3; i++)
|
||||
for (int j = 0; j < 2; j++)
|
||||
s->mastering_display_actual_peak_luminance[i][j] =
|
||||
(AVRational){ 15 - (i * 2 + j), PEAK_LUMINANCE_DEN };
|
||||
|
||||
for (int w = 0; w < 2; w++) {
|
||||
s->params[w].tone_mapping_flag = 1;
|
||||
s->params[w].knee_point_x = (AVRational){ 500 + w, KNEE_POINT_DEN };
|
||||
s->params[w].knee_point_y = (AVRational){ 800 + w, KNEE_POINT_DEN };
|
||||
s->params[w].num_bezier_curve_anchors = 3;
|
||||
s->params[w].bezier_curve_anchors[0] =
|
||||
(AVRational){ 100 + w, BEZIER_ANCHOR_DEN };
|
||||
s->params[w].bezier_curve_anchors[1] =
|
||||
(AVRational){ 500 + w, BEZIER_ANCHOR_DEN };
|
||||
s->params[w].bezier_curve_anchors[2] =
|
||||
(AVRational){ 900 + w, BEZIER_ANCHOR_DEN };
|
||||
s->params[w].color_saturation_mapping_flag = 1;
|
||||
s->params[w].color_saturation_weight =
|
||||
(AVRational){ 8 + w, SATURATION_DEN };
|
||||
}
|
||||
}
|
||||
|
||||
static void test_hdr_plus(void)
|
||||
{
|
||||
AVDynamicHDRPlus *hdr, *hdr_rt;
|
||||
AVFrame *frame;
|
||||
size_t size = 0, required = 0;
|
||||
uint8_t *buf = NULL;
|
||||
int ret;
|
||||
|
||||
printf("=== AVDynamicHDRPlus ===\n");
|
||||
|
||||
printf("Testing av_dynamic_hdr_plus_alloc()\n");
|
||||
hdr = av_dynamic_hdr_plus_alloc(&size);
|
||||
printf("alloc: %s size>0=%s\n", hdr ? "OK" : "FAIL",
|
||||
size > 0 ? "yes" : "no");
|
||||
av_freep(&hdr);
|
||||
|
||||
hdr = av_dynamic_hdr_plus_alloc(NULL);
|
||||
printf("alloc (no size): %s\n", hdr ? "OK" : "FAIL");
|
||||
av_freep(&hdr);
|
||||
|
||||
printf("\nTesting av_dynamic_hdr_plus_create_side_data()\n");
|
||||
frame = av_frame_alloc();
|
||||
if (frame) {
|
||||
hdr = av_dynamic_hdr_plus_create_side_data(frame);
|
||||
printf("create_side_data: %s\n", hdr ? "OK" : "FAIL");
|
||||
av_frame_free(&frame);
|
||||
}
|
||||
|
||||
hdr = av_dynamic_hdr_plus_alloc(NULL);
|
||||
hdr_rt = av_dynamic_hdr_plus_alloc(NULL);
|
||||
if (!hdr || !hdr_rt) {
|
||||
av_freep(&hdr);
|
||||
av_freep(&hdr_rt);
|
||||
return;
|
||||
}
|
||||
fill_hdr_plus_conforming(hdr);
|
||||
|
||||
/* Size-query mode: data=NULL, size receives the required byte count. */
|
||||
printf("\nTesting av_dynamic_hdr_plus_to_t35() size query\n");
|
||||
required = 0;
|
||||
ret = av_dynamic_hdr_plus_to_t35(hdr, NULL, &required);
|
||||
printf("size query: ret=%d required>0=%s\n", ret,
|
||||
required > 0 ? "yes" : "no");
|
||||
|
||||
/* Allocation mode: *data=NULL, the function allocates the buffer. */
|
||||
printf("\nTesting av_dynamic_hdr_plus_to_t35() allocation\n");
|
||||
buf = NULL;
|
||||
size = 0;
|
||||
ret = av_dynamic_hdr_plus_to_t35(hdr, &buf, &size);
|
||||
printf("alloc mode: ret=%d size_match=%s\n", ret,
|
||||
size == required ? "yes" : "no");
|
||||
av_freep(&buf);
|
||||
|
||||
/* Existing-buffer mode: a caller-owned buffer is filled in place. */
|
||||
printf("\nTesting av_dynamic_hdr_plus_to_t35() existing buffer\n");
|
||||
buf = av_malloc(required);
|
||||
if (buf) {
|
||||
uint8_t *orig = buf;
|
||||
size = required;
|
||||
ret = av_dynamic_hdr_plus_to_t35(hdr, &buf, &size);
|
||||
printf("existing buf: ret=%d same_pointer=%s size_match=%s\n", ret,
|
||||
buf == orig ? "yes" : "no",
|
||||
size == required ? "yes" : "no");
|
||||
av_freep(&buf);
|
||||
}
|
||||
|
||||
/* Buffer-too-small: caller-owned buffer shorter than required. */
|
||||
printf("\nTesting av_dynamic_hdr_plus_to_t35() buffer too small\n");
|
||||
if (required > 1) {
|
||||
buf = av_malloc(required - 1);
|
||||
if (buf) {
|
||||
size = required - 1;
|
||||
ret = av_dynamic_hdr_plus_to_t35(hdr, &buf, &size);
|
||||
printf("too small: ret==AVERROR_BUFFER_TOO_SMALL=%s\n",
|
||||
ret == AVERROR_BUFFER_TOO_SMALL ? "yes" : "no");
|
||||
av_freep(&buf);
|
||||
}
|
||||
}
|
||||
|
||||
printf("\nTesting round trip, conforming ST 2094-40 Version 1 payload\n");
|
||||
ret = hdr_plus_round_trip(hdr, hdr_rt);
|
||||
printf("round trip: ret=%d\n", ret);
|
||||
if (ret >= 0)
|
||||
print_hdr_plus("decoded", hdr_rt);
|
||||
|
||||
/* to_t35() ignores application_version and always writes the CTA-861-H
|
||||
* value, so the parsed field does not echo an out-of-range input. */
|
||||
printf("\nTesting that to_t35() overrides application_version\n");
|
||||
hdr->application_version = 7;
|
||||
ret = hdr_plus_round_trip(hdr, hdr_rt);
|
||||
printf("input=7 ret=%d decoded application_version=%u\n", ret,
|
||||
hdr_rt->application_version);
|
||||
hdr->application_version = 1;
|
||||
|
||||
printf("\nTesting round trip, synthetic payload (branch coverage only)\n");
|
||||
fill_hdr_plus_synthetic(hdr);
|
||||
ret = hdr_plus_round_trip(hdr, hdr_rt);
|
||||
printf("round trip: ret=%d\n", ret);
|
||||
if (ret >= 0)
|
||||
print_hdr_plus("decoded", hdr_rt);
|
||||
|
||||
printf("\nTesting error paths\n");
|
||||
buf = NULL;
|
||||
size = 0;
|
||||
ret = av_dynamic_hdr_plus_to_t35(NULL, &buf, &size);
|
||||
printf("to_t35 NULL s: ret==AVERROR(EINVAL)=%s\n",
|
||||
ret == AVERROR(EINVAL) ? "yes" : "no");
|
||||
|
||||
ret = av_dynamic_hdr_plus_to_t35(hdr, NULL, NULL);
|
||||
printf("to_t35 no data no size: ret==AVERROR(EINVAL)=%s\n",
|
||||
ret == AVERROR(EINVAL) ? "yes" : "no");
|
||||
|
||||
ret = av_dynamic_hdr_plus_from_t35(NULL, (const uint8_t *)"", 0);
|
||||
printf("from_t35 NULL s: ret==AVERROR(EINVAL)=%s\n",
|
||||
ret == AVERROR(EINVAL) ? "yes" : "no");
|
||||
|
||||
{
|
||||
/* Oversized input is rejected before parsing. */
|
||||
size_t big = AV_HDR_PLUS_MAX_PAYLOAD_SIZE + 1;
|
||||
uint8_t *oversized = av_mallocz(big);
|
||||
if (oversized) {
|
||||
ret = av_dynamic_hdr_plus_from_t35(hdr_rt, oversized, big);
|
||||
printf("from_t35 oversized: ret==AVERROR(EINVAL)=%s\n",
|
||||
ret == AVERROR(EINVAL) ? "yes" : "no");
|
||||
av_free(oversized);
|
||||
}
|
||||
}
|
||||
|
||||
av_freep(&hdr);
|
||||
av_freep(&hdr_rt);
|
||||
|
||||
printf("\nTesting OOM path\n");
|
||||
av_max_alloc(1);
|
||||
hdr = av_dynamic_hdr_plus_alloc(&size);
|
||||
printf("alloc OOM: %s\n", hdr ? "FAIL" : "OK");
|
||||
av_max_alloc(INT_MAX);
|
||||
av_freep(&hdr);
|
||||
}
|
||||
|
||||
/* Table C.2 early-out: no adaptive tone map, custom reference white only. */
|
||||
static void fill_app5_minimal(AVDynamicHDRSmpte2094App5 *s)
|
||||
{
|
||||
memset(s, 0, sizeof(*s));
|
||||
s->application_version = 1;
|
||||
s->minimum_application_version = 0;
|
||||
s->has_custom_hdr_reference_white_flag = 1;
|
||||
s->hdr_reference_white = 0x0203;
|
||||
s->has_adaptive_tone_map_flag = 0;
|
||||
}
|
||||
|
||||
/* Table C.3 early-out: reference-white tone mapping, no alternate images. */
|
||||
static void fill_app5_reference_white(AVDynamicHDRSmpte2094App5 *s)
|
||||
{
|
||||
memset(s, 0, sizeof(*s));
|
||||
s->application_version = 2;
|
||||
s->has_adaptive_tone_map_flag = 1;
|
||||
s->baseline_hdr_headroom = 0x0abc;
|
||||
s->use_reference_white_tone_mapping_flag = 1;
|
||||
}
|
||||
|
||||
/* Per-image parameters: explicit gain application space chromaticities,
|
||||
* component mixing type 3 with a mix of present and absent coefficients, and
|
||||
* explicit control point slopes (theta). */
|
||||
static void fill_app5_per_image(AVDynamicHDRSmpte2094App5 *s)
|
||||
{
|
||||
memset(s, 0, sizeof(*s));
|
||||
s->application_version = 1;
|
||||
s->has_adaptive_tone_map_flag = 1;
|
||||
s->baseline_hdr_headroom = 0x0abc;
|
||||
s->num_alternate_images = 2;
|
||||
s->gain_application_space_chromaticities_flag = 3;
|
||||
for (int r = 0; r < 8; r++)
|
||||
s->gain_application_space_chromaticities[r] = 100 * (r + 1);
|
||||
s->has_common_component_mix_params_flag = 0;
|
||||
s->has_common_curve_params_flag = 0;
|
||||
for (int a = 0; a < 2; a++) {
|
||||
s->alternate_hdr_headrooms[a] = 0x0100 + a;
|
||||
s->component_mixing_type[a] = 3;
|
||||
for (int k = 0; k < 6; k++) {
|
||||
s->has_component_mixing_coefficient_flag[a][k] = k & 1;
|
||||
s->component_mixing_coefficient[a][k] = 0x1000 + 0x10 * a + k;
|
||||
}
|
||||
s->gain_curve_num_control_points_minus_1[a] = 1;
|
||||
s->gain_curve_use_pchip_slope_flag[a] = 0;
|
||||
for (int c = 0; c < 2; c++) {
|
||||
s->gain_curve_control_points_x[a][c] = 0x2000 + 0x10 * a + c;
|
||||
s->gain_curve_control_points_y[a][c] = 0x3000 + 0x10 * a + c;
|
||||
s->gain_curve_control_points_theta[a][c] = 0x4000 + 0x10 * a + c;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* The complementary selectors: no explicit chromaticities, a component mixing
|
||||
* type other than 3, mixing and curve parameters shared from alternate 0, and
|
||||
* the pchip slope, which omits theta from the payload.
|
||||
*
|
||||
* The common_* flags make the parser copy alternate 0's parameters to the
|
||||
* other alternates, so the fixture sets them identically everywhere; only
|
||||
* alternate_hdr_headrooms and the y control points stay per-image. */
|
||||
static void fill_app5_common(AVDynamicHDRSmpte2094App5 *s)
|
||||
{
|
||||
memset(s, 0, sizeof(*s));
|
||||
s->application_version = 1;
|
||||
s->has_adaptive_tone_map_flag = 1;
|
||||
s->baseline_hdr_headroom = 0x0def;
|
||||
s->num_alternate_images = 3;
|
||||
s->gain_application_space_chromaticities_flag = 0;
|
||||
s->has_common_component_mix_params_flag = 1;
|
||||
s->has_common_curve_params_flag = 1;
|
||||
for (int a = 0; a < 3; a++) {
|
||||
s->alternate_hdr_headrooms[a] = 0x0200 + a;
|
||||
s->component_mixing_type[a] = 1;
|
||||
s->gain_curve_num_control_points_minus_1[a] = 2;
|
||||
s->gain_curve_use_pchip_slope_flag[a] = 1;
|
||||
for (int c = 0; c < 3; c++) {
|
||||
s->gain_curve_control_points_x[a][c] = 0x5000 + c;
|
||||
s->gain_curve_control_points_y[a][c] = 0x6000 + 0x10 * a + c;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void test_app5(void)
|
||||
{
|
||||
AVDynamicHDRSmpte2094App5 *app5, *app5_rt;
|
||||
AVFrame *frame;
|
||||
size_t size = 0, required = 0;
|
||||
uint8_t *buf = NULL;
|
||||
int ret;
|
||||
|
||||
printf("\n=== AVDynamicHDRSmpte2094App5 ===\n");
|
||||
printf("Testing av_dynamic_hdr_smpte2094_app5_alloc()\n");
|
||||
app5 = av_dynamic_hdr_smpte2094_app5_alloc(&size);
|
||||
printf("alloc: %s size>0=%s\n", app5 ? "OK" : "FAIL",
|
||||
size > 0 ? "yes" : "no");
|
||||
av_freep(&app5);
|
||||
|
||||
printf("\nTesting av_dynamic_hdr_smpte2094_app5_create_side_data()\n");
|
||||
frame = av_frame_alloc();
|
||||
if (frame) {
|
||||
app5 = av_dynamic_hdr_smpte2094_app5_create_side_data(frame);
|
||||
printf("create_side_data: %s\n", app5 ? "OK" : "FAIL");
|
||||
av_frame_free(&frame);
|
||||
}
|
||||
|
||||
app5 = av_dynamic_hdr_smpte2094_app5_alloc(NULL);
|
||||
app5_rt = av_dynamic_hdr_smpte2094_app5_alloc(NULL);
|
||||
if (!app5 || !app5_rt) {
|
||||
av_freep(&app5);
|
||||
av_freep(&app5_rt);
|
||||
return;
|
||||
}
|
||||
fill_app5_minimal(app5);
|
||||
|
||||
printf("\nTesting av_dynamic_hdr_smpte2094_app5_to_t35()\n");
|
||||
required = 0;
|
||||
ret = av_dynamic_hdr_smpte2094_app5_to_t35(app5, NULL, &required);
|
||||
printf("size query: ret=%d required>0=%s\n", ret,
|
||||
required > 0 ? "yes" : "no");
|
||||
|
||||
buf = NULL;
|
||||
size = 0;
|
||||
ret = av_dynamic_hdr_smpte2094_app5_to_t35(app5, &buf, &size);
|
||||
printf("alloc mode: ret=%d size_match=%s\n", ret,
|
||||
size == required ? "yes" : "no");
|
||||
av_freep(&buf);
|
||||
|
||||
printf("\nTesting round trip, no adaptive tone map\n");
|
||||
ret = app5_round_trip(app5, app5_rt);
|
||||
printf("round trip: ret=%d\n", ret);
|
||||
if (ret >= 0)
|
||||
print_app5("decoded", app5_rt);
|
||||
|
||||
printf("\nTesting round trip, reference-white tone mapping\n");
|
||||
fill_app5_reference_white(app5);
|
||||
ret = app5_round_trip(app5, app5_rt);
|
||||
printf("round trip: ret=%d\n", ret);
|
||||
if (ret >= 0)
|
||||
print_app5("decoded", app5_rt);
|
||||
|
||||
printf("\nTesting round trip, per-image mixing and curve parameters\n");
|
||||
fill_app5_per_image(app5);
|
||||
ret = app5_round_trip(app5, app5_rt);
|
||||
printf("round trip: ret=%d\n", ret);
|
||||
if (ret >= 0)
|
||||
print_app5("decoded", app5_rt);
|
||||
|
||||
printf("\nTesting round trip, common mixing and curve parameters\n");
|
||||
fill_app5_common(app5);
|
||||
ret = app5_round_trip(app5, app5_rt);
|
||||
printf("round trip: ret=%d\n", ret);
|
||||
if (ret >= 0)
|
||||
print_app5("decoded", app5_rt);
|
||||
|
||||
printf("\nTesting error paths\n");
|
||||
buf = NULL;
|
||||
size = 0;
|
||||
ret = av_dynamic_hdr_smpte2094_app5_to_t35(NULL, &buf, &size);
|
||||
printf("to_t35 NULL s: ret==AVERROR(EINVAL)=%s\n",
|
||||
ret == AVERROR(EINVAL) ? "yes" : "no");
|
||||
|
||||
ret = av_dynamic_hdr_smpte2094_app5_from_t35(NULL, (const uint8_t *)"", 0);
|
||||
printf("from_t35 NULL s: ret==AVERROR(EINVAL)=%s\n",
|
||||
ret == AVERROR(EINVAL) ? "yes" : "no");
|
||||
|
||||
/* application_version does not fit the 3-bit field. */
|
||||
app5->application_version = 8;
|
||||
ret = av_dynamic_hdr_smpte2094_app5_to_t35(app5, NULL, &size);
|
||||
printf("to_t35 invalid application_version: ret==AVERROR_INVALIDDATA=%s\n",
|
||||
ret == AVERROR_INVALIDDATA ? "yes" : "no");
|
||||
app5->application_version = 1;
|
||||
|
||||
/* minimum_application_version above the documented maximum. */
|
||||
app5->minimum_application_version = 3;
|
||||
ret = av_dynamic_hdr_smpte2094_app5_to_t35(app5, NULL, &size);
|
||||
printf("to_t35 invalid minimum_application_version:"
|
||||
" ret==AVERROR_INVALIDDATA=%s\n",
|
||||
ret == AVERROR_INVALIDDATA ? "yes" : "no");
|
||||
app5->minimum_application_version = 0;
|
||||
|
||||
/* More alternate images than the 3-bit count admits. */
|
||||
app5->num_alternate_images = 5;
|
||||
ret = av_dynamic_hdr_smpte2094_app5_to_t35(app5, NULL, &size);
|
||||
printf("to_t35 too many alternate images: ret==AVERROR_INVALIDDATA=%s\n",
|
||||
ret == AVERROR_INVALIDDATA ? "yes" : "no");
|
||||
|
||||
av_freep(&app5);
|
||||
av_freep(&app5_rt);
|
||||
|
||||
printf("\nTesting OOM path\n");
|
||||
av_max_alloc(1);
|
||||
app5 = av_dynamic_hdr_smpte2094_app5_alloc(&size);
|
||||
printf("alloc OOM: %s\n", app5 ? "FAIL" : "OK");
|
||||
av_max_alloc(INT_MAX);
|
||||
av_freep(&app5);
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
test_hdr_plus();
|
||||
test_app5();
|
||||
return 0;
|
||||
}
|
||||
@@ -119,6 +119,10 @@ FATE_LIBAVUTIL += fate-hash
|
||||
fate-hash: libavutil/tests/hash$(EXESUF)
|
||||
fate-hash: CMD = run libavutil/tests/hash$(EXESUF)
|
||||
|
||||
FATE_LIBAVUTIL += fate-hdr_dynamic_metadata
|
||||
fate-hdr_dynamic_metadata: libavutil/tests/hdr_dynamic_metadata$(EXESUF)
|
||||
fate-hdr_dynamic_metadata: CMD = run libavutil/tests/hdr_dynamic_metadata$(EXESUF)
|
||||
|
||||
FATE_LIBAVUTIL += fate-hdr_dynamic_vivid_metadata
|
||||
fate-hdr_dynamic_vivid_metadata: libavutil/tests/hdr_dynamic_vivid_metadata$(EXESUF)
|
||||
fate-hdr_dynamic_vivid_metadata: CMD = run libavutil/tests/hdr_dynamic_vivid_metadata$(EXESUF)
|
||||
|
||||
@@ -0,0 +1,146 @@
|
||||
=== AVDynamicHDRPlus ===
|
||||
Testing av_dynamic_hdr_plus_alloc()
|
||||
alloc: OK size>0=yes
|
||||
alloc (no size): OK
|
||||
|
||||
Testing av_dynamic_hdr_plus_create_side_data()
|
||||
create_side_data: OK
|
||||
|
||||
Testing av_dynamic_hdr_plus_to_t35() size query
|
||||
size query: ret=0 required>0=yes
|
||||
|
||||
Testing av_dynamic_hdr_plus_to_t35() allocation
|
||||
alloc mode: ret=0 size_match=yes
|
||||
|
||||
Testing av_dynamic_hdr_plus_to_t35() existing buffer
|
||||
existing buf: ret=0 same_pointer=yes size_match=yes
|
||||
|
||||
Testing av_dynamic_hdr_plus_to_t35() buffer too small
|
||||
too small: ret==AVERROR_BUFFER_TOO_SMALL=yes
|
||||
|
||||
Testing round trip, conforming ST 2094-40 Version 1 payload
|
||||
round trip: ret=0
|
||||
decoded:
|
||||
application_version=1 num_windows=1 targeted_system_display_maximum_luminance=400/1
|
||||
targeted_system_display_actual_peak_luminance_flag=0
|
||||
mastering_display_actual_peak_luminance_flag=0
|
||||
window 0:
|
||||
maxscl: 50000/100000 60000/100000 99000/100000 average_maxrgb=40000/100000
|
||||
distribution_maxrgb: n=9 1%=1000/100000 5%=0/100000 10%=255/100000 25%=25000/100000 50%=50000/100000 75%=75000/100000 90%=90000/100000 95%=95000/100000 99%=99000/100000
|
||||
fraction_bright_pixels=250/1000
|
||||
tone_mapping_flag=1 knee=512/4095,1024/4095 anchors=9: 100/1023 200/1023 300/1023 400/1023 500/1023 600/1023 700/1023 800/1023 900/1023
|
||||
color_saturation_mapping_flag=0
|
||||
|
||||
Testing that to_t35() overrides application_version
|
||||
input=7 ret=0 decoded application_version=1
|
||||
|
||||
Testing round trip, synthetic payload (branch coverage only)
|
||||
round trip: ret=0
|
||||
decoded:
|
||||
application_version=1 num_windows=2 targeted_system_display_maximum_luminance=10000/1
|
||||
targeted_system_display_actual_peak_luminance_flag=1
|
||||
targeted_peak 2x3: 0/15 1/15 2/15 3/15 4/15 5/15
|
||||
mastering_display_actual_peak_luminance_flag=1
|
||||
mastering_peak 3x2: 15/15 14/15 13/15 12/15 11/15 10/15
|
||||
window 0:
|
||||
maxscl: 50000/100000 60000/100000 70000/100000 average_maxrgb=40000/100000
|
||||
distribution_maxrgb: n=2 50%=30000/100000 99%=90000/100000
|
||||
fraction_bright_pixels=250/1000
|
||||
tone_mapping_flag=1 knee=500/4095,800/4095 anchors=3: 100/1023 500/1023 900/1023
|
||||
color_saturation_mapping_flag=1 weight=8/8
|
||||
window 1:
|
||||
corners: ul=100/1,120/1 lr=500/1,520/1
|
||||
ellipse: center=300,320 rotation=45 semimajor_int=50 semimajor_ext=100 semiminor_ext=80 overlap=1
|
||||
maxscl: 20000/100000 30000/100000 40000/100000 average_maxrgb=25000/100000
|
||||
distribution_maxrgb: n=1 25%=12500/100000
|
||||
fraction_bright_pixels=100/1000
|
||||
tone_mapping_flag=1 knee=501/4095,801/4095 anchors=3: 101/1023 501/1023 901/1023
|
||||
color_saturation_mapping_flag=1 weight=9/8
|
||||
|
||||
Testing error paths
|
||||
to_t35 NULL s: ret==AVERROR(EINVAL)=yes
|
||||
to_t35 no data no size: ret==AVERROR(EINVAL)=yes
|
||||
from_t35 NULL s: ret==AVERROR(EINVAL)=yes
|
||||
from_t35 oversized: ret==AVERROR(EINVAL)=yes
|
||||
|
||||
Testing OOM path
|
||||
alloc OOM: OK
|
||||
|
||||
=== AVDynamicHDRSmpte2094App5 ===
|
||||
Testing av_dynamic_hdr_smpte2094_app5_alloc()
|
||||
alloc: OK size>0=yes
|
||||
|
||||
Testing av_dynamic_hdr_smpte2094_app5_create_side_data()
|
||||
create_side_data: OK
|
||||
|
||||
Testing av_dynamic_hdr_smpte2094_app5_to_t35()
|
||||
size query: ret=0 required>0=yes
|
||||
alloc mode: ret=0 size_match=yes
|
||||
|
||||
Testing round trip, no adaptive tone map
|
||||
round trip: ret=0
|
||||
decoded:
|
||||
application_version=1 minimum_application_version=0
|
||||
has_custom_hdr_reference_white_flag=1 hdr_reference_white=0x0203
|
||||
has_adaptive_tone_map_flag=0
|
||||
|
||||
Testing round trip, reference-white tone mapping
|
||||
round trip: ret=0
|
||||
decoded:
|
||||
application_version=2 minimum_application_version=0
|
||||
has_custom_hdr_reference_white_flag=0
|
||||
has_adaptive_tone_map_flag=1
|
||||
baseline_hdr_headroom=0x0abc use_reference_white_tone_mapping_flag=1
|
||||
|
||||
Testing round trip, per-image mixing and curve parameters
|
||||
round trip: ret=0
|
||||
decoded:
|
||||
application_version=1 minimum_application_version=0
|
||||
has_custom_hdr_reference_white_flag=0
|
||||
has_adaptive_tone_map_flag=1
|
||||
baseline_hdr_headroom=0x0abc use_reference_white_tone_mapping_flag=0
|
||||
num_alternate_images=2 chromaticities_flag=3 has_common_component_mix_params_flag=0 has_common_curve_params_flag=0
|
||||
chromaticities: 0x0064 0x00c8 0x012c 0x0190 0x01f4 0x0258 0x02bc 0x0320
|
||||
alternate 0: hdr_headroom=0x0100 component_mixing_type=3
|
||||
mixing flag:coefficient: 0:0x0000 1:0x1001 0:0x0000 1:0x1003 0:0x0000 1:0x1005
|
||||
curve: num_control_points=2 use_pchip_slope=0
|
||||
x: 0x2000 0x2001
|
||||
y: 0x3000 0x3001
|
||||
theta: 0x4000 0x4001
|
||||
alternate 1: hdr_headroom=0x0101 component_mixing_type=3
|
||||
mixing flag:coefficient: 0:0x0000 1:0x1011 0:0x0000 1:0x1013 0:0x0000 1:0x1015
|
||||
curve: num_control_points=2 use_pchip_slope=0
|
||||
x: 0x2010 0x2011
|
||||
y: 0x3010 0x3011
|
||||
theta: 0x4010 0x4011
|
||||
|
||||
Testing round trip, common mixing and curve parameters
|
||||
round trip: ret=0
|
||||
decoded:
|
||||
application_version=1 minimum_application_version=0
|
||||
has_custom_hdr_reference_white_flag=0
|
||||
has_adaptive_tone_map_flag=1
|
||||
baseline_hdr_headroom=0x0def use_reference_white_tone_mapping_flag=0
|
||||
num_alternate_images=3 chromaticities_flag=0 has_common_component_mix_params_flag=1 has_common_curve_params_flag=1
|
||||
alternate 0: hdr_headroom=0x0200 component_mixing_type=1
|
||||
curve: num_control_points=3 use_pchip_slope=1
|
||||
x: 0x5000 0x5001 0x5002
|
||||
y: 0x6000 0x6001 0x6002
|
||||
alternate 1: hdr_headroom=0x0201 component_mixing_type=1
|
||||
curve: num_control_points=3 use_pchip_slope=1
|
||||
x: 0x5000 0x5001 0x5002
|
||||
y: 0x6010 0x6011 0x6012
|
||||
alternate 2: hdr_headroom=0x0202 component_mixing_type=1
|
||||
curve: num_control_points=3 use_pchip_slope=1
|
||||
x: 0x5000 0x5001 0x5002
|
||||
y: 0x6020 0x6021 0x6022
|
||||
|
||||
Testing error paths
|
||||
to_t35 NULL s: ret==AVERROR(EINVAL)=yes
|
||||
from_t35 NULL s: ret==AVERROR(EINVAL)=yes
|
||||
to_t35 invalid application_version: ret==AVERROR_INVALIDDATA=yes
|
||||
to_t35 invalid minimum_application_version: ret==AVERROR_INVALIDDATA=yes
|
||||
to_t35 too many alternate images: ret==AVERROR_INVALIDDATA=yes
|
||||
|
||||
Testing OOM path
|
||||
alloc OOM: OK
|
||||
Reference in new issue
Block a user