On Mon, Aug 11, 2025 at 1:57 PM Maryla Ustarroz-Calonge <mar...@google.com> wrote: > > Signed-off-by: Maryla Ustarroz-Calonge <mar...@google.com> > --- > Changelog | 1 + > libavcodec/libaomdec.c | 63 ++++++++++++++++++++++++++++++++++++++++++ > libavcodec/libaomenc.c | 55 ++++++++++++++++++++++++++++++++++++ > libavcodec/version.h | 2 +- > 4 files changed, 120 insertions(+), 1 deletion(-) > > diff --git a/Changelog b/Changelog > index 0b0e6ecbf4..6bca37a594 100644 > --- a/Changelog > +++ b/Changelog > @@ -37,6 +37,7 @@ version 8.0: > - ProRes RAW decoder > - ProRes RAW Vulkan hwaccel > - ffprobe -codec option > +- HDR10+ metadata passthrough when decoding/encoding with libaom-av1 > > > version 7.1: > diff --git a/libavcodec/libaomdec.c b/libavcodec/libaomdec.c > index 69eec8b089..cf5986baf4 100644 > --- a/libavcodec/libaomdec.c > +++ b/libavcodec/libaomdec.c > @@ -28,11 +28,14 @@ > > #include "libavutil/common.h" > #include "libavutil/cpu.h" > +#include "libavutil/hdr_dynamic_metadata.h" > #include "libavutil/imgutils.h" > > #include "avcodec.h" > +#include "bytestream.h" > #include "codec_internal.h" > #include "decode.h" > +#include "itut35.h" > #include "libaom.h" > #include "profiles.h" > > @@ -137,6 +140,61 @@ static int set_pix_fmt(AVCodecContext *avctx, struct > aom_image *img) > } > } > > +static int decode_metadata_itu_t_t35(AVFrame *frame, > + const uint8_t *buffer, size_t > buffer_size) > +{ > + if (buffer_size < 6) > + return AVERROR(EINVAL); > + > + GetByteContext bc; > + bytestream2_init(&bc, buffer, buffer_size); > + > + const int country_code = bytestream2_get_byteu(&bc); > + const int provider_code = bytestream2_get_be16u(&bc); > + const int provider_oriented_code = bytestream2_get_be16u(&bc); > + const int application_identifier = bytestream2_get_byteu(&bc); > + > + // See "HDR10+ AV1 Metadata Handling Specification" v1.0.1, Section 2.1. > + if (country_code == ITU_T_T35_COUNTRY_CODE_US > + && provider_code == ITU_T_T35_PROVIDER_CODE_SAMSUNG > + && provider_oriented_code == 0x0001 > + && application_identifier == 0x04) { > + // HDR10+ > + AVDynamicHDRPlus *hdr_plus = > av_dynamic_hdr_plus_create_side_data(frame); > + if (!hdr_plus) > + return AVERROR(ENOMEM); > + > + int res = av_dynamic_hdr_plus_from_t35(hdr_plus, bc.buffer, > + > bytestream2_get_bytes_left(&bc)); > + if (res < 0) > + return res; > + } > + > + return 0; > +} > + > +static int decode_metadata(AVFrame *frame, const struct aom_image *img) > +{ > + const size_t num_metadata = aom_img_num_metadata(img); > + for (size_t i = 0; i < num_metadata; ++i) { > + const aom_metadata_t *metadata = aom_img_get_metadata(img, i); > + if (!metadata) > + continue; > + > + switch (metadata->type) { > + case OBU_METADATA_TYPE_ITUT_T35: { > + int res = decode_metadata_itu_t_t35(frame, metadata->payload, > metadata->sz); > + if (res < 0) > + return res; > + break; > + } > + default: > + break; > + } > + } > + return 0; > +} > + > static int aom_decode(AVCodecContext *avctx, AVFrame *picture, > int *got_frame, AVPacket *avpkt) > { > @@ -215,6 +273,11 @@ static int aom_decode(AVCodecContext *avctx, AVFrame > *picture, > av_image_copy(picture->data, picture->linesize, planes, > stride, avctx->pix_fmt, img->d_w, img->d_h); > } > + ret = decode_metadata(picture, img); > + if (ret < 0) { > + av_log(avctx, AV_LOG_ERROR, "Failed to decode metadata\n"); > + return ret; > + } > *got_frame = 1; > } > return avpkt->size; > diff --git a/libavcodec/libaomenc.c b/libavcodec/libaomenc.c > index 46f8d60e46..5d265a54d1 100644 > --- a/libavcodec/libaomenc.c > +++ b/libavcodec/libaomenc.c > @@ -33,6 +33,7 @@ > #include "libavutil/base64.h" > #include "libavutil/common.h" > #include "libavutil/cpu.h" > +#include "libavutil/hdr_dynamic_metadata.h" > #include "libavutil/imgutils.h" > #include "libavutil/mathematics.h" > #include "libavutil/mem.h" > @@ -42,10 +43,12 @@ > #include "av1.h" > #include "avcodec.h" > #include "bsf.h" > +#include "bytestream.h" > #include "codec_internal.h" > #include "dovi_rpu.h" > #include "encode.h" > #include "internal.h" > +#include "itut35.h" > #include "libaom.h" > #include "packet_internal.h" > #include "profiles.h" > @@ -328,6 +331,53 @@ static av_cold int codecctl_int(AVCodecContext *avctx, > return 0; > } > > +static int add_hdr_plus(AVCodecContext *avctx, struct aom_image *img, const > AVFrame *frame) > +{ > + // Check for HDR10+ > + AVFrameSideData *side_data = > + av_frame_get_side_data(frame, AV_FRAME_DATA_DYNAMIC_HDR_PLUS); > + if (!side_data) > + return 0; > + > + size_t payload_size; > + AVDynamicHDRPlus *hdr_plus = (AVDynamicHDRPlus *)side_data->buf->data; > + int res = av_dynamic_hdr_plus_to_t35(hdr_plus, NULL, &payload_size); > + if (res < 0) { > + log_encoder_error(avctx, "Error finding the size of HDR10+"); > + return res; > + } > + > + uint8_t *hdr_plus_buf; > + // Extra bytes for the country code, provider code, provider oriented > code and app id. > + const size_t hdr_plus_buf_size = payload_size + 6; > + hdr_plus_buf = av_malloc(hdr_plus_buf_size); > + if (!hdr_plus_buf) > + return AVERROR(ENOMEM); > + > + uint8_t *payload = hdr_plus_buf; > + // See "HDR10+ AV1 Metadata Handling Specification" v1.0.1, Section 2.1. > + bytestream_put_byte(&payload, ITU_T_T35_COUNTRY_CODE_US); > + bytestream_put_be16(&payload, ITU_T_T35_PROVIDER_CODE_SAMSUNG); > + bytestream_put_be16(&payload, 0x0001); // provider_oriented_code > + bytestream_put_byte(&payload, 0x04); // application_identifier > + > + res = av_dynamic_hdr_plus_to_t35(hdr_plus, &payload, &payload_size); > + if (res < 0) { > + av_free(hdr_plus_buf); > + log_encoder_error(avctx, "Error encoding HDR10+ from side data"); > + return res; > + } > + > + res = aom_img_add_metadata(img, OBU_METADATA_TYPE_ITUT_T35, > + hdr_plus_buf, hdr_plus_buf_size, > AOM_MIF_ANY_FRAME); > + av_free(hdr_plus_buf); > + if (res < 0) { > + log_encoder_error(avctx, "Error adding HDR10+ to aom_img"); > + return res; > + } > + return 0; > +} > + > #if defined(AOM_CTRL_AV1E_GET_NUM_OPERATING_POINTS) && \ > defined(AOM_CTRL_AV1E_GET_SEQ_LEVEL_IDX) && \ > defined(AOM_CTRL_AV1E_GET_TARGET_SEQ_LEVEL_IDX) > @@ -1234,6 +1284,7 @@ static int aom_encode(AVCodecContext *avctx, AVPacket > *pkt, > > if (frame) { > rawimg = &ctx->rawimg; > + aom_img_remove_metadata(rawimg); > rawimg->planes[AOM_PLANE_Y] = frame->data[0]; > rawimg->planes[AOM_PLANE_U] = frame->data[1]; > rawimg->planes[AOM_PLANE_V] = frame->data[2]; > @@ -1284,6 +1335,10 @@ static int aom_encode(AVCodecContext *avctx, AVPacket > *pkt, > > if (frame->pict_type == AV_PICTURE_TYPE_I) > flags |= AOM_EFLAG_FORCE_KF; > + > + res = add_hdr_plus(avctx, rawimg, frame); > + if (res < 0) > + return res; > } > > res = aom_codec_encode(&ctx->encoder, rawimg, timestamp, duration, > flags); > diff --git a/libavcodec/version.h b/libavcodec/version.h > index da2264a097..2e28c23410 100644 > --- a/libavcodec/version.h > +++ b/libavcodec/version.h > @@ -30,7 +30,7 @@ > #include "version_major.h" > > #define LIBAVCODEC_VERSION_MINOR 12 > -#define LIBAVCODEC_VERSION_MICRO 100 > +#define LIBAVCODEC_VERSION_MICRO 101 > > #define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \ > LIBAVCODEC_VERSION_MINOR, \ > -- > 2.50.1.703.g449372360f-goog >
Note this is mostly a rebase of v2, due to changes in version.h and also the renaming of ITU_T_T35_PROVIDER_CODE_SMTPE to ITU_T_T35_PROVIDER_CODE_SAMSUNG. It also fixes a minor style issue. _______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".