[FFmpeg-devel] [PATCH 19/27] cbs_av1: Support manipulating HDR CLL and MDCV metadata
Mark Thompson
sw at jkqxz.net
Fri Jan 1 23:35:29 EET 2021
---
libavcodec/cbs_av1.c | 95 ++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 95 insertions(+)
diff --git a/libavcodec/cbs_av1.c b/libavcodec/cbs_av1.c
index 3bca121fba..2b5fad69e9 100644
--- a/libavcodec/cbs_av1.c
+++ b/libavcodec/cbs_av1.c
@@ -17,6 +17,7 @@
*/
#include "libavutil/avassert.h"
+#include "libavutil/mastering_display_metadata.h"
#include "libavutil/pixfmt.h"
#include "cbs.h"
@@ -1285,6 +1286,10 @@ static uint64_t cbs_av1_find_metadata_type(enum CBSMetadataType type)
enum CBSMetadataType cbs_type;
uint64_t av1_type;
} map[] = {
+ { CBS_METADATA_CONTENT_LIGHT_LEVEL,
+ AV1_METADATA_TYPE_HDR_CLL },
+ { CBS_METADATA_MASTERING_DISPLAY,
+ AV1_METADATA_TYPE_HDR_MDCV },
};
for (int i = 0; i < FF_ARRAY_ELEMS(map); i++) {
@@ -1321,6 +1326,13 @@ static int cbs_av1_remove_metadata(CodedBitstreamContext *ctx,
return 0;
}
+static uint32_t rescale_clip(AVRational value, uint32_t scale,
+ uint32_t bits)
+{
+ int64_t scaled = av_rescale(scale, value.num, value.den);
+ return av_clip64(scaled, 0, INT64_C(1) << bits);
+}
+
static int cbs_av1_insert_metadata(CodedBitstreamContext *ctx,
CodedBitstreamFragment *tu,
enum CBSMetadataType type,
@@ -1347,6 +1359,51 @@ static int cbs_av1_insert_metadata(CodedBitstreamContext *ctx,
obu->obu.metadata.metadata_type = metadata_type;
switch (metadata_type) {
+ case AV1_METADATA_TYPE_HDR_CLL:
+ {
+ const AVContentLightMetadata *clm = data;
+ AV1RawMetadataHDRCLL *cll =
+ &obu->obu.metadata.metadata.hdr_cll;
+
+ cll->max_cll = av_clip_uintp2(clm->MaxCLL, 16);
+ cll->max_fall = av_clip_uintp2(clm->MaxFALL, 16);
+ }
+ break;
+ case AV1_METADATA_TYPE_HDR_MDCV:
+ {
+ const AVMasteringDisplayMetadata *mdm = data;
+ AV1RawMetadataHDRMDCV *mdcv =
+ &obu->obu.metadata.metadata.hdr_mdcv;
+
+ if (mdm->has_primaries) {
+ for (int i = 0; i < 3; i++) {
+ mdcv->primary_chromaticity_x[i] =
+ rescale_clip(mdm->display_primaries[i][0],
+ 1 << 16, 16);
+ mdcv->primary_chromaticity_y[i] =
+ rescale_clip(mdm->display_primaries[i][1],
+ 1 << 16, 16);
+ }
+
+ mdcv->white_point_chromaticity_x =
+ rescale_clip(mdm->white_point[0], 1 << 16, 16);
+ mdcv->white_point_chromaticity_y =
+ rescale_clip(mdm->white_point[1], 1 << 16, 16);
+ }
+
+ if (mdm->has_luminance) {
+ uint32_t value;
+ value = rescale_clip(mdm->max_luminance, 1 << 8, 32);
+ mdcv->luminance_max = value;
+ av_log(ctx->log_ctx, AV_LOG_ERROR, "mdcv->luminance_max = %d, %d\n",
+ mdcv->luminance_max, value);
+ mdcv->luminance_min =
+ rescale_clip(mdm->min_luminance, 1 << 14, 32);
+ av_log(ctx->log_ctx, AV_LOG_ERROR, "mdcv->luminance_min = %d\n",
+ mdcv->luminance_min);
+ }
+ }
+ break;
default:
av_assert0(0);
}
@@ -1381,6 +1438,44 @@ static int cbs_av1_extract_metadata(CodedBitstreamContext *ctx,
}
switch (metadata_type) {
+ case AV1_METADATA_TYPE_HDR_CLL:
+ {
+ AVContentLightMetadata *clm = data;
+ const AV1RawMetadataHDRCLL *cll =
+ &obu->obu.metadata.metadata.hdr_cll;
+
+ clm->MaxCLL = cll->max_cll;
+ clm->MaxFALL = cll->max_fall;
+ }
+ break;
+ case AV1_METADATA_TYPE_HDR_MDCV:
+ {
+ AVMasteringDisplayMetadata *mdm = data;
+ const AV1RawMetadataHDRMDCV *mdcv =
+ &obu->obu.metadata.metadata.hdr_mdcv;
+
+ for (int i = 0; i < 3; i++) {
+ mdm->display_primaries[i][0] =
+ av_make_q(mdcv->primary_chromaticity_x[i], 1 << 16);
+ mdm->display_primaries[i][1] =
+ av_make_q(mdcv->primary_chromaticity_y[i], 1 << 16);
+ }
+
+ mdm->white_point[0] =
+ av_make_q(mdcv->white_point_chromaticity_x, 1 << 16);
+ mdm->white_point[1] =
+ av_make_q(mdcv->white_point_chromaticity_y, 1 << 16);
+
+ mdm->max_luminance =
+ av_make_q(mdcv->luminance_max, 1 << 8);
+ mdm->min_luminance =
+ av_make_q(mdcv->luminance_min, 1 << 14);
+
+ // The standard doesn't allow partially-filled MDCV blocks, so
+ // if the metadata appears it must be complete.
+ mdm->has_primaries = mdm->has_luminance = 1;
+ }
+ break;
default:
av_assert0(0);
}
--
2.29.2
More information about the ffmpeg-devel
mailing list