diff options
author | Haihao Xiang <haihao.xiang@intel.com> | 2024-05-22 12:16:00 +0800 |
---|---|---|
committer | Haihao Xiang <haihao.xiang@intel.com> | 2024-05-27 09:38:46 +0800 |
commit | a72e9aeabcbe04765e3340ae9e5022b46cbfff56 (patch) | |
tree | 8707616184f2e079e5398cf19c77c581225ff9f1 /libavcodec/qsvenc_av1.c | |
parent | 473e84ad62a05e83bba5e00b4073980ee171a5bd (diff) | |
download | ffmpeg-a72e9aeabcbe04765e3340ae9e5022b46cbfff56.tar.gz |
lavc/qsvenc_av1: accept HDR metadata if have
The sdk av1 encoder can accept HDR metadata via mfxEncodeCtrl::ExtParam.
Signed-off-by: Haihao Xiang <haihao.xiang@intel.com>
Diffstat (limited to 'libavcodec/qsvenc_av1.c')
-rw-r--r-- | libavcodec/qsvenc_av1.c | 73 |
1 files changed, 73 insertions, 0 deletions
diff --git a/libavcodec/qsvenc_av1.c b/libavcodec/qsvenc_av1.c index 33727bb07e..56002746b9 100644 --- a/libavcodec/qsvenc_av1.c +++ b/libavcodec/qsvenc_av1.c @@ -25,6 +25,8 @@ #include <mfxvideo.h> #include "libavutil/common.h" +#include "libavutil/mastering_display_metadata.h" +#include "libavutil/mem.h" #include "libavutil/opt.h" #include "avcodec.h" @@ -39,6 +41,75 @@ typedef struct QSVAV1EncContext { QSVEncContext qsv; } QSVAV1EncContext; +static int qsv_av1_set_encode_ctrl(AVCodecContext *avctx, + const AVFrame *frame, mfxEncodeCtrl *enc_ctrl) +{ + QSVAV1EncContext *q = avctx->priv_data; + AVFrameSideData *sd; + + if (!frame || !QSV_RUNTIME_VERSION_ATLEAST(q->qsv.ver, 2, 11)) + return 0; + + sd = av_frame_get_side_data(frame, AV_FRAME_DATA_MASTERING_DISPLAY_METADATA); + if (sd) { + AVMasteringDisplayMetadata *mdm = (AVMasteringDisplayMetadata *)sd->data; + if (mdm->has_primaries && mdm->has_luminance) { + const int chroma_den = 1 << 16; + const int max_luma_den = 1 << 8; + const int min_luma_den = 1 << 14; + mfxExtMasteringDisplayColourVolume *mdcv = av_mallocz(sizeof(*mdcv)); + if (!mdcv) + return AVERROR(ENOMEM); + + mdcv->Header.BufferId = MFX_EXTBUFF_MASTERING_DISPLAY_COLOUR_VOLUME; + mdcv->Header.BufferSz = sizeof(*mdcv); + + for (int i = 0; i < 3; i++) { + mdcv->DisplayPrimariesX[i] = + av_rescale(mdm->display_primaries[i][0].num, chroma_den, + mdm->display_primaries[i][0].den); + mdcv->DisplayPrimariesY[i] = + av_rescale(mdm->display_primaries[i][1].num, chroma_den, + mdm->display_primaries[i][1].den); + } + + mdcv->WhitePointX = + av_rescale(mdm->white_point[0].num, chroma_den, + mdm->white_point[0].den); + mdcv->WhitePointY = + av_rescale(mdm->white_point[1].num, chroma_den, + mdm->white_point[1].den); + + mdcv->MaxDisplayMasteringLuminance = + av_rescale(mdm->max_luminance.num, max_luma_den, + mdm->max_luminance.den); + mdcv->MinDisplayMasteringLuminance = + av_rescale(mdm->min_luminance.num, min_luma_den, + mdm->min_luminance.den); + + enc_ctrl->ExtParam[enc_ctrl->NumExtParam++] = (mfxExtBuffer *)mdcv; + } + } + + sd = av_frame_get_side_data(frame, AV_FRAME_DATA_CONTENT_LIGHT_LEVEL); + if (sd) { + AVContentLightMetadata *clm = (AVContentLightMetadata *)sd->data; + mfxExtContentLightLevelInfo *clli = av_mallocz(sizeof(*clli)); + if (!clli) + return AVERROR(ENOMEM); + + clli->Header.BufferId = MFX_EXTBUFF_CONTENT_LIGHT_LEVEL_INFO; + clli->Header.BufferSz = sizeof(*clli); + + clli->MaxContentLightLevel = clm->MaxCLL; + clli->MaxPicAverageLightLevel = clm->MaxFALL; + + enc_ctrl->ExtParam[enc_ctrl->NumExtParam++] = (mfxExtBuffer *)clli; + } + + return 0; +} + static av_cold int qsv_enc_init(AVCodecContext *avctx) { QSVAV1EncContext *q = avctx->priv_data; @@ -61,6 +132,8 @@ static av_cold int qsv_enc_init(AVCodecContext *avctx) return ret; } + q->qsv.set_encode_ctrl_cb = qsv_av1_set_encode_ctrl; + return ff_qsv_enc_init(avctx, &q->qsv); } |