[FFmpeg-devel] [PATCH v2 17/18] vaapi_encode_h264: Support HDR metadata
Mark Thompson
sw at jkqxz.net
Sun Feb 21 21:51:24 EET 2021
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
More information about the ffmpeg-devel
mailing list