This can now be done in exactly the same way as it is for H.265. --- libavcodec/vaapi_encode_h264.c | 66 +++++++++++++++++++++++++++++++++- 1 file changed, 65 insertions(+), 1 deletion(-)
diff --git a/libavcodec/vaapi_encode_h264.c b/libavcodec/vaapi_encode_h264.c index b546ddec08..582a855586 100644 --- a/libavcodec/vaapi_encode_h264.c +++ b/libavcodec/vaapi_encode_h264.c @@ -24,11 +24,13 @@ #include "libavutil/avassert.h" #include "libavutil/common.h" #include "libavutil/internal.h" +#include "libavutil/mastering_display_metadata.h" #include "libavutil/opt.h" #include "avcodec.h" #include "cbs.h" #include "cbs_h264.h" +#include "cbs_metadata.h" #include "h264.h" #include "h264_levels.h" #include "h264_sei.h" @@ -95,6 +97,11 @@ typedef struct VAAPIEncodeH264Context { int aud_needed; int sei_needed; int sei_cbr_workaround_needed; + + int have_mastering_display; + AVMasteringDisplayMetadata mastering_display; + int have_content_light_level; + AVContentLightMetadata content_light_level; } VAAPIEncodeH264Context; @@ -241,6 +248,20 @@ static int vaapi_encode_h264_write_extra_header(AVCodecContext *avctx, if (err < 0) goto fail; } + if (priv->sei_needed & SEI_MASTERING_DISPLAY) { + err = ff_cbs_insert_metadata(priv->cbc, au, + CBS_METADATA_MASTERING_DISPLAY, + &priv->mastering_display); + if (err < 0) + goto fail; + } + if (priv->sei_needed & SEI_CONTENT_LIGHT_LEVEL) { + err = ff_cbs_insert_metadata(priv->cbc, au, + CBS_METADATA_CONTENT_LIGHT_LEVEL, + &priv->content_light_level); + if (err < 0) + goto fail; + } priv->sei_needed = 0; @@ -674,6 +695,42 @@ static int vaapi_encode_h264_init_picture_params(AVCodecContext *avctx, priv->sei_needed |= SEI_RECOVERY_POINT; } + if (priv->sei & SEI_MASTERING_DISPLAY) { + AVFrameSideData *sd = + av_frame_get_side_data(pic->input_image, + AV_FRAME_DATA_MASTERING_DISPLAY_METADATA); + + if (sd) { + av_assert0(sd->size >= sizeof(priv->mastering_display)); + priv->have_mastering_display = 1; + memcpy(&priv->mastering_display, sd->data, + sizeof(priv->mastering_display)); + } + + if (priv->have_mastering_display && + (pic->type == PICTURE_TYPE_IDR || pic->type == PICTURE_TYPE_I)) { + priv->sei_needed |= SEI_MASTERING_DISPLAY; + } + } + + if (priv->sei & SEI_CONTENT_LIGHT_LEVEL) { + AVFrameSideData *sd = + av_frame_get_side_data(pic->input_image, + AV_FRAME_DATA_CONTENT_LIGHT_LEVEL); + + if (sd) { + av_assert0(sd->size >= sizeof(priv->content_light_level)); + priv->have_mastering_display = 1; + memcpy(&priv->content_light_level, sd->data, + sizeof(priv->content_light_level)); + } + + if (priv->have_content_light_level && + (pic->type == PICTURE_TYPE_IDR || pic->type == PICTURE_TYPE_I)) { + priv->sei_needed |= SEI_CONTENT_LIGHT_LEVEL; + } + } + vpic->CurrPic = (VAPictureH264) { .picture_id = pic->recon_surface, .frame_idx = hpic->frame_num, @@ -1245,7 +1302,8 @@ static const AVOption vaapi_encode_h264_options[] = { { "sei", "Set SEI to include", OFFSET(sei), AV_OPT_TYPE_FLAGS, - { .i64 = SEI_IDENTIFIER | SEI_TIMING | SEI_RECOVERY_POINT }, + { .i64 = SEI_IDENTIFIER | SEI_TIMING | SEI_RECOVERY_POINT | + SEI_MASTERING_DISPLAY | SEI_CONTENT_LIGHT_LEVEL }, 0, INT_MAX, FLAGS, "sei" }, { "identifier", "Include encoder version identifier", 0, AV_OPT_TYPE_CONST, { .i64 = SEI_IDENTIFIER }, @@ -1256,6 +1314,12 @@ static const AVOption vaapi_encode_h264_options[] = { { "recovery_point", "Include recovery points where appropriate", 0, AV_OPT_TYPE_CONST, { .i64 = SEI_RECOVERY_POINT }, INT_MIN, INT_MAX, FLAGS, "sei" }, + { "hdr", + "Include HDR metadata (mastering display colour volume " + "and content light level information)", + 0, AV_OPT_TYPE_CONST, + { .i64 = SEI_MASTERING_DISPLAY | SEI_CONTENT_LIGHT_LEVEL }, + INT_MIN, INT_MAX, FLAGS, "sei" }, { "profile", "Set profile (profile_idc and constraint_set*_flag)", OFFSET(profile), AV_OPT_TYPE_INT, -- 2.30.0 _______________________________________________ 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".