[FFmpeg-devel] [PATCH 28/29] lavc/*dec: use side data preference for mastering display/content light metadata
Anton Khirnov
anton at khirnov.net
Mon Mar 4 15:06:43 EET 2024
---
libavcodec/av1dec.c | 46 +++++++++++---------
libavcodec/h2645_sei.c | 96 +++++++++++++++++++++++-------------------
libavcodec/libdav1d.c | 47 ++++++++++++---------
libavcodec/pngdec.c | 54 ++++++++++++++----------
libavcodec/qsvdec.c | 50 +++++++++++++---------
5 files changed, 165 insertions(+), 128 deletions(-)
diff --git a/libavcodec/av1dec.c b/libavcodec/av1dec.c
index af80ee0b17..bbb5634773 100644
--- a/libavcodec/av1dec.c
+++ b/libavcodec/av1dec.c
@@ -999,31 +999,39 @@ static int export_metadata(AVCodecContext *avctx, AVFrame *frame)
int ret = 0;
if (s->mdcv) {
- AVMasteringDisplayMetadata *mastering = av_mastering_display_metadata_create_side_data(frame);
- if (!mastering)
- return AVERROR(ENOMEM);
+ AVMasteringDisplayMetadata *mastering;
- for (int i = 0; i < 3; i++) {
- mastering->display_primaries[i][0] = av_make_q(s->mdcv->primary_chromaticity_x[i], 1 << 16);
- mastering->display_primaries[i][1] = av_make_q(s->mdcv->primary_chromaticity_y[i], 1 << 16);
+ ret = ff_decode_mastering_display_new(avctx, frame, &mastering);
+ if (ret < 0)
+ return ret;
+
+ if (mastering) {
+ for (int i = 0; i < 3; i++) {
+ mastering->display_primaries[i][0] = av_make_q(s->mdcv->primary_chromaticity_x[i], 1 << 16);
+ mastering->display_primaries[i][1] = av_make_q(s->mdcv->primary_chromaticity_y[i], 1 << 16);
+ }
+ mastering->white_point[0] = av_make_q(s->mdcv->white_point_chromaticity_x, 1 << 16);
+ mastering->white_point[1] = av_make_q(s->mdcv->white_point_chromaticity_y, 1 << 16);
+
+ mastering->max_luminance = av_make_q(s->mdcv->luminance_max, 1 << 8);
+ mastering->min_luminance = av_make_q(s->mdcv->luminance_min, 1 << 14);
+
+ mastering->has_primaries = 1;
+ mastering->has_luminance = 1;
}
- mastering->white_point[0] = av_make_q(s->mdcv->white_point_chromaticity_x, 1 << 16);
- mastering->white_point[1] = av_make_q(s->mdcv->white_point_chromaticity_y, 1 << 16);
-
- mastering->max_luminance = av_make_q(s->mdcv->luminance_max, 1 << 8);
- mastering->min_luminance = av_make_q(s->mdcv->luminance_min, 1 << 14);
-
- mastering->has_primaries = 1;
- mastering->has_luminance = 1;
}
if (s->cll) {
- AVContentLightMetadata *light = av_content_light_metadata_create_side_data(frame);
- if (!light)
- return AVERROR(ENOMEM);
+ AVContentLightMetadata *light;
- light->MaxCLL = s->cll->max_cll;
- light->MaxFALL = s->cll->max_fall;
+ ret = ff_decode_content_light_new(avctx, frame, &light);
+ if (ret < 0)
+ return ret;
+
+ if (light) {
+ light->MaxCLL = s->cll->max_cll;
+ light->MaxFALL = s->cll->max_fall;
+ }
}
while (av_fifo_read(s->itut_t35_fifo, &itut_t35, 1) >= 0) {
diff --git a/libavcodec/h2645_sei.c b/libavcodec/h2645_sei.c
index 56539608cd..a9d17cc9fd 100644
--- a/libavcodec/h2645_sei.c
+++ b/libavcodec/h2645_sei.c
@@ -516,6 +516,7 @@ int ff_h2645_sei_to_frame(AVFrame *frame, H2645SEI *sei,
int seed)
{
H2645SEIFramePacking *fp = &sei->frame_packing;
+ int ret;
if (fp->present &&
is_frame_packing_type_valid(fp->arrangement_type, codec_id) &&
@@ -710,56 +711,63 @@ int ff_h2645_sei_to_frame(AVFrame *frame, H2645SEI *sei,
const int chroma_den = 50000;
const int luma_den = 10000;
int i;
- AVMasteringDisplayMetadata *metadata =
- av_mastering_display_metadata_create_side_data(frame);
- if (!metadata)
- return AVERROR(ENOMEM);
+ AVMasteringDisplayMetadata *metadata;
- for (i = 0; i < 3; i++) {
- const int j = mapping[i];
- metadata->display_primaries[i][0].num = sei->mastering_display.display_primaries[j][0];
- metadata->display_primaries[i][0].den = chroma_den;
- metadata->display_primaries[i][1].num = sei->mastering_display.display_primaries[j][1];
- metadata->display_primaries[i][1].den = chroma_den;
+ ret = ff_decode_mastering_display_new(avctx, frame, &metadata);
+ if (ret < 0)
+ return ret;
+
+ if (metadata) {
+ for (i = 0; i < 3; i++) {
+ const int j = mapping[i];
+ metadata->display_primaries[i][0].num = sei->mastering_display.display_primaries[j][0];
+ metadata->display_primaries[i][0].den = chroma_den;
+ metadata->display_primaries[i][1].num = sei->mastering_display.display_primaries[j][1];
+ metadata->display_primaries[i][1].den = chroma_den;
+ }
+ metadata->white_point[0].num = sei->mastering_display.white_point[0];
+ metadata->white_point[0].den = chroma_den;
+ metadata->white_point[1].num = sei->mastering_display.white_point[1];
+ metadata->white_point[1].den = chroma_den;
+
+ metadata->max_luminance.num = sei->mastering_display.max_luminance;
+ metadata->max_luminance.den = luma_den;
+ metadata->min_luminance.num = sei->mastering_display.min_luminance;
+ metadata->min_luminance.den = luma_den;
+ metadata->has_luminance = 1;
+ metadata->has_primaries = 1;
+
+ av_log(avctx, AV_LOG_DEBUG, "Mastering Display Metadata:\n");
+ av_log(avctx, AV_LOG_DEBUG,
+ "r(%5.4f,%5.4f) g(%5.4f,%5.4f) b(%5.4f %5.4f) wp(%5.4f, %5.4f)\n",
+ av_q2d(metadata->display_primaries[0][0]),
+ av_q2d(metadata->display_primaries[0][1]),
+ av_q2d(metadata->display_primaries[1][0]),
+ av_q2d(metadata->display_primaries[1][1]),
+ av_q2d(metadata->display_primaries[2][0]),
+ av_q2d(metadata->display_primaries[2][1]),
+ av_q2d(metadata->white_point[0]), av_q2d(metadata->white_point[1]));
+ av_log(avctx, AV_LOG_DEBUG,
+ "min_luminance=%f, max_luminance=%f\n",
+ av_q2d(metadata->min_luminance), av_q2d(metadata->max_luminance));
}
- metadata->white_point[0].num = sei->mastering_display.white_point[0];
- metadata->white_point[0].den = chroma_den;
- metadata->white_point[1].num = sei->mastering_display.white_point[1];
- metadata->white_point[1].den = chroma_den;
-
- metadata->max_luminance.num = sei->mastering_display.max_luminance;
- metadata->max_luminance.den = luma_den;
- metadata->min_luminance.num = sei->mastering_display.min_luminance;
- metadata->min_luminance.den = luma_den;
- metadata->has_luminance = 1;
- metadata->has_primaries = 1;
-
- av_log(avctx, AV_LOG_DEBUG, "Mastering Display Metadata:\n");
- av_log(avctx, AV_LOG_DEBUG,
- "r(%5.4f,%5.4f) g(%5.4f,%5.4f) b(%5.4f %5.4f) wp(%5.4f, %5.4f)\n",
- av_q2d(metadata->display_primaries[0][0]),
- av_q2d(metadata->display_primaries[0][1]),
- av_q2d(metadata->display_primaries[1][0]),
- av_q2d(metadata->display_primaries[1][1]),
- av_q2d(metadata->display_primaries[2][0]),
- av_q2d(metadata->display_primaries[2][1]),
- av_q2d(metadata->white_point[0]), av_q2d(metadata->white_point[1]));
- av_log(avctx, AV_LOG_DEBUG,
- "min_luminance=%f, max_luminance=%f\n",
- av_q2d(metadata->min_luminance), av_q2d(metadata->max_luminance));
}
if (sei->content_light.present) {
- AVContentLightMetadata *metadata =
- av_content_light_metadata_create_side_data(frame);
- if (!metadata)
- return AVERROR(ENOMEM);
- metadata->MaxCLL = sei->content_light.max_content_light_level;
- metadata->MaxFALL = sei->content_light.max_pic_average_light_level;
+ AVContentLightMetadata *metadata;
- av_log(avctx, AV_LOG_DEBUG, "Content Light Level Metadata:\n");
- av_log(avctx, AV_LOG_DEBUG, "MaxCLL=%d, MaxFALL=%d\n",
- metadata->MaxCLL, metadata->MaxFALL);
+ ret = ff_decode_content_light_new(avctx, frame, &metadata);
+ if (ret < 0)
+ return ret;
+
+ if (metadata) {
+ metadata->MaxCLL = sei->content_light.max_content_light_level;
+ metadata->MaxFALL = sei->content_light.max_pic_average_light_level;
+
+ av_log(avctx, AV_LOG_DEBUG, "Content Light Level Metadata:\n");
+ av_log(avctx, AV_LOG_DEBUG, "MaxCLL=%d, MaxFALL=%d\n",
+ metadata->MaxCLL, metadata->MaxFALL);
+ }
}
return 0;
diff --git a/libavcodec/libdav1d.c b/libavcodec/libdav1d.c
index 3714137ed0..42d3ef00de 100644
--- a/libavcodec/libdav1d.c
+++ b/libavcodec/libdav1d.c
@@ -507,33 +507,38 @@ FF_ENABLE_DEPRECATION_WARNINGS
}
if (p->mastering_display) {
- AVMasteringDisplayMetadata *mastering = av_mastering_display_metadata_create_side_data(frame);
- if (!mastering) {
- res = AVERROR(ENOMEM);
+ AVMasteringDisplayMetadata *mastering;
+
+ res = ff_decode_mastering_display_new(c, frame, &mastering);
+ if (res < 0)
goto fail;
+
+ if (mastering) {
+ for (int i = 0; i < 3; i++) {
+ mastering->display_primaries[i][0] = av_make_q(p->mastering_display->primaries[i][0], 1 << 16);
+ mastering->display_primaries[i][1] = av_make_q(p->mastering_display->primaries[i][1], 1 << 16);
+ }
+ mastering->white_point[0] = av_make_q(p->mastering_display->white_point[0], 1 << 16);
+ mastering->white_point[1] = av_make_q(p->mastering_display->white_point[1], 1 << 16);
+
+ mastering->max_luminance = av_make_q(p->mastering_display->max_luminance, 1 << 8);
+ mastering->min_luminance = av_make_q(p->mastering_display->min_luminance, 1 << 14);
+
+ mastering->has_primaries = 1;
+ mastering->has_luminance = 1;
}
-
- for (int i = 0; i < 3; i++) {
- mastering->display_primaries[i][0] = av_make_q(p->mastering_display->primaries[i][0], 1 << 16);
- mastering->display_primaries[i][1] = av_make_q(p->mastering_display->primaries[i][1], 1 << 16);
- }
- mastering->white_point[0] = av_make_q(p->mastering_display->white_point[0], 1 << 16);
- mastering->white_point[1] = av_make_q(p->mastering_display->white_point[1], 1 << 16);
-
- mastering->max_luminance = av_make_q(p->mastering_display->max_luminance, 1 << 8);
- mastering->min_luminance = av_make_q(p->mastering_display->min_luminance, 1 << 14);
-
- mastering->has_primaries = 1;
- mastering->has_luminance = 1;
}
if (p->content_light) {
- AVContentLightMetadata *light = av_content_light_metadata_create_side_data(frame);
- if (!light) {
- res = AVERROR(ENOMEM);
+ AVContentLightMetadata *light;
+
+ res = ff_decode_content_light_new(c, frame, &light);
+ if (res < 0)
goto fail;
+
+ if (light) {
+ light->MaxCLL = p->content_light->max_content_light_level;
+ light->MaxFALL = p->content_light->max_frame_average_light_level;
}
- light->MaxCLL = p->content_light->max_content_light_level;
- light->MaxFALL = p->content_light->max_frame_average_light_level;
}
if (p->itut_t35) {
#if FF_DAV1D_VERSION_AT_LEAST(6,9)
diff --git a/libavcodec/pngdec.c b/libavcodec/pngdec.c
index 8f409c74b8..de50e6a5b6 100644
--- a/libavcodec/pngdec.c
+++ b/libavcodec/pngdec.c
@@ -746,33 +746,41 @@ static int populate_avctx_color_fields(AVCodecContext *avctx, AVFrame *frame)
avctx->bits_per_raw_sample = s->significant_bits;
if (s->have_clli) {
- AVContentLightMetadata *clli =
- av_content_light_metadata_create_side_data(frame);
- if (!clli)
- return AVERROR(ENOMEM);
- /*
- * 0.0001 divisor value
- * see: https://www.w3.org/TR/png-3/#cLLi-chunk
- */
- clli->MaxCLL = s->clli_max / 10000;
- clli->MaxFALL = s->clli_avg / 10000;
+ AVContentLightMetadata *clli;
+
+ ret = ff_decode_content_light_new(avctx, frame, &clli);
+ if (ret < 0)
+ return ret;
+
+ if (clli) {
+ /*
+ * 0.0001 divisor value
+ * see: https://www.w3.org/TR/png-3/#cLLi-chunk
+ */
+ clli->MaxCLL = s->clli_max / 10000;
+ clli->MaxFALL = s->clli_avg / 10000;
+ }
}
if (s->have_mdvc) {
- AVMasteringDisplayMetadata *mdvc =
- av_mastering_display_metadata_create_side_data(frame);
- if (!mdvc)
- return AVERROR(ENOMEM);
- mdvc->has_primaries = 1;
- for (int i = 0; i < 3; i++) {
- mdvc->display_primaries[i][0] = av_make_q(s->mdvc_primaries[i][0], 50000);
- mdvc->display_primaries[i][1] = av_make_q(s->mdvc_primaries[i][1], 50000);
+ AVMasteringDisplayMetadata *mdvc;
+
+ ret = ff_decode_mastering_display_new(avctx, frame, &mdvc);
+ if (ret < 0)
+ return ret;
+
+ if (mdvc) {
+ mdvc->has_primaries = 1;
+ for (int i = 0; i < 3; i++) {
+ mdvc->display_primaries[i][0] = av_make_q(s->mdvc_primaries[i][0], 50000);
+ mdvc->display_primaries[i][1] = av_make_q(s->mdvc_primaries[i][1], 50000);
+ }
+ mdvc->white_point[0] = av_make_q(s->mdvc_white_point[0], 50000);
+ mdvc->white_point[1] = av_make_q(s->mdvc_white_point[1], 50000);
+ mdvc->has_luminance = 1;
+ mdvc->max_luminance = av_make_q(s->mdvc_max_lum, 10000);
+ mdvc->min_luminance = av_make_q(s->mdvc_min_lum, 10000);
}
- mdvc->white_point[0] = av_make_q(s->mdvc_white_point[0], 50000);
- mdvc->white_point[1] = av_make_q(s->mdvc_white_point[1], 50000);
- mdvc->has_luminance = 1;
- mdvc->max_luminance = av_make_q(s->mdvc_max_lum, 10000);
- mdvc->min_luminance = av_make_q(s->mdvc_min_lum, 10000);
}
return 0;
diff --git a/libavcodec/qsvdec.c b/libavcodec/qsvdec.c
index d688a17c41..4f39f6942a 100644
--- a/libavcodec/qsvdec.c
+++ b/libavcodec/qsvdec.c
@@ -651,42 +651,50 @@ static int qsv_export_film_grain(AVCodecContext *avctx, mfxExtAV1FilmGrainParam
static int qsv_export_hdr_side_data(AVCodecContext *avctx, mfxExtMasteringDisplayColourVolume *mdcv,
mfxExtContentLightLevelInfo *clli, AVFrame *frame)
{
+ int ret;
+
// The SDK re-uses this flag for HDR SEI parsing
if (mdcv->InsertPayloadToggle) {
- AVMasteringDisplayMetadata *mastering = av_mastering_display_metadata_create_side_data(frame);
+ AVMasteringDisplayMetadata *mastering;
const int mapping[3] = {2, 0, 1};
const int chroma_den = 50000;
const int luma_den = 10000;
int i;
- if (!mastering)
- return AVERROR(ENOMEM);
+ ret = ff_decode_mastering_display_new(avctx, frame, &mastering);
+ if (ret < 0)
+ return ret;
- for (i = 0; i < 3; i++) {
- const int j = mapping[i];
- mastering->display_primaries[i][0] = av_make_q(mdcv->DisplayPrimariesX[j], chroma_den);
- mastering->display_primaries[i][1] = av_make_q(mdcv->DisplayPrimariesY[j], chroma_den);
+ if (mastering) {
+ for (i = 0; i < 3; i++) {
+ const int j = mapping[i];
+ mastering->display_primaries[i][0] = av_make_q(mdcv->DisplayPrimariesX[j], chroma_den);
+ mastering->display_primaries[i][1] = av_make_q(mdcv->DisplayPrimariesY[j], chroma_den);
+ }
+
+ mastering->white_point[0] = av_make_q(mdcv->WhitePointX, chroma_den);
+ mastering->white_point[1] = av_make_q(mdcv->WhitePointY, chroma_den);
+
+ mastering->max_luminance = av_make_q(mdcv->MaxDisplayMasteringLuminance, luma_den);
+ mastering->min_luminance = av_make_q(mdcv->MinDisplayMasteringLuminance, luma_den);
+
+ mastering->has_luminance = 1;
+ mastering->has_primaries = 1;
}
-
- mastering->white_point[0] = av_make_q(mdcv->WhitePointX, chroma_den);
- mastering->white_point[1] = av_make_q(mdcv->WhitePointY, chroma_den);
-
- mastering->max_luminance = av_make_q(mdcv->MaxDisplayMasteringLuminance, luma_den);
- mastering->min_luminance = av_make_q(mdcv->MinDisplayMasteringLuminance, luma_den);
-
- mastering->has_luminance = 1;
- mastering->has_primaries = 1;
}
// The SDK re-uses this flag for HDR SEI parsing
if (clli->InsertPayloadToggle) {
- AVContentLightMetadata *light = av_content_light_metadata_create_side_data(frame);
+ AVContentLightMetadata *light;
- if (!light)
- return AVERROR(ENOMEM);
+ ret = ff_decode_content_light_new(avctx, frame, &light);
+ if (ret < 0)
+ return ret;
- light->MaxCLL = clli->MaxContentLightLevel;
- light->MaxFALL = clli->MaxPicAverageLightLevel;
+ if (light) {
+ light->MaxCLL = clli->MaxContentLightLevel;
+ light->MaxFALL = clli->MaxPicAverageLightLevel;
+ }
}
return 0;
--
2.43.0
More information about the ffmpeg-devel
mailing list