[FFmpeg-devel] [PATCH 3/3] lavc/qsvenc_hevc: accept HDR metadata if have

2022-10-17 Thread haihao . xiang-at-intel . com
From: Haihao Xiang 

The SDK may accept HDR metadata via mfxEncodeCtrl::ExtParam

Signed-off-by: Haihao Xiang 
---
 libavcodec/qsvenc_hevc.c | 80 
 1 file changed, 80 insertions(+)

diff --git a/libavcodec/qsvenc_hevc.c b/libavcodec/qsvenc_hevc.c
index 2a3f34b915..28d2cfcae1 100644
--- a/libavcodec/qsvenc_hevc.c
+++ b/libavcodec/qsvenc_hevc.c
@@ -26,6 +26,7 @@
 
 #include "libavutil/common.h"
 #include "libavutil/opt.h"
+#include "libavutil/mastering_display_metadata.h"
 
 #include "avcodec.h"
 #include "bytestream.h"
@@ -160,6 +161,83 @@ static int generate_fake_vps(QSVEncContext *q, 
AVCodecContext *avctx)
 return 0;
 }
 
+static int qsv_hevc_set_encode_ctrl(AVCodecContext *avctx,
+const AVFrame *frame, mfxEncodeCtrl 
*enc_ctrl)
+{
+QSVHEVCEncContext *q = avctx->priv_data;
+AVFrameSideData *sd;
+
+if (!frame || !QSV_RUNTIME_VERSION_ATLEAST(q->qsv.ver, 1, 25))
+return 0;
+
+sd = av_frame_get_side_data(frame, 
AV_FRAME_DATA_MASTERING_DISPLAY_METADATA);
+if (sd) {
+AVMasteringDisplayMetadata *mdm = (AVMasteringDisplayMetadata 
*)sd->data;
+
+// SEI is needed when both the primaries and luminance are set
+if (mdm->has_primaries && mdm->has_luminance) {
+const int mapping[3] = {1, 2, 0};
+const int chroma_den = 5;
+const int luma_den   = 1;
+int i;
+mfxExtMasteringDisplayColourVolume *mdcv = 
av_mallocz(sizeof(mfxExtMasteringDisplayColourVolume));
+
+if (!mdcv)
+return AVERROR(ENOMEM);
+
+mdcv->Header.BufferId = 
MFX_EXTBUFF_MASTERING_DISPLAY_COLOUR_VOLUME;
+mdcv->Header.BufferSz = sizeof(*mdcv);
+
+for (i = 0; i < 3; i++) {
+const int j = mapping[i];
+
+mdcv->DisplayPrimariesX[i] =
+FFMIN(lrint(chroma_den *
+av_q2d(mdm->display_primaries[j][0])),
+  chroma_den);
+mdcv->DisplayPrimariesY[i] =
+FFMIN(lrint(chroma_den *
+av_q2d(mdm->display_primaries[j][1])),
+  chroma_den);
+}
+
+mdcv->WhitePointX =
+FFMIN(lrint(chroma_den * av_q2d(mdm->white_point[0])),
+  chroma_den);
+mdcv->WhitePointY =
+FFMIN(lrint(chroma_den * av_q2d(mdm->white_point[1])),
+  chroma_den);
+
+mdcv->MaxDisplayMasteringLuminance =
+lrint(luma_den * av_q2d(mdm->max_luminance));
+mdcv->MinDisplayMasteringLuminance =
+FFMIN(lrint(luma_den * av_q2d(mdm->min_luminance)),
+  mdcv->MaxDisplayMasteringLuminance);
+
+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(mfxExtContentLightLevelInfo));
+
+if (!clli)
+return AVERROR(ENOMEM);
+
+clli->Header.BufferId = MFX_EXTBUFF_CONTENT_LIGHT_LEVEL_INFO;
+clli->Header.BufferSz = sizeof(*clli);
+
+clli->MaxContentLightLevel  = FFMIN(clm->MaxCLL,  65535);
+clli->MaxPicAverageLightLevel   = FFMIN(clm->MaxFALL, 65535);
+
+enc_ctrl->ExtParam[enc_ctrl->NumExtParam++] = (mfxExtBuffer *)clli;
+}
+
+return 0;
+}
+
 static av_cold int qsv_enc_init(AVCodecContext *avctx)
 {
 QSVHEVCEncContext *q = avctx->priv_data;
@@ -189,6 +267,8 @@ static av_cold int qsv_enc_init(AVCodecContext *avctx)
 // HEVC and H264 meaning of the value is shifted by 1, make it consistent
 q->qsv.idr_interval++;
 
+q->qsv.set_encode_ctrl_cb = qsv_hevc_set_encode_ctrl;
+
 ret = ff_qsv_enc_init(avctx, >qsv);
 if (ret < 0)
 return ret;
-- 
2.25.1

___
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".


[FFmpeg-devel] [PATCH 2/3] lavc/qsvenc: enlarge the maximum number of ExtParam buffers on mfxEncodeCtrl

2022-10-17 Thread haihao . xiang-at-intel . com
From: Haihao Xiang 

The next commit and other commits in future will use more ExtParam
buffers.

And combine 2 free functions into single one

Signed-off-by: Haihao Xiang 
---
 libavcodec/qsv_internal.h |  2 +-
 libavcodec/qsvenc.c   | 27 ---
 2 files changed, 9 insertions(+), 20 deletions(-)

diff --git a/libavcodec/qsv_internal.h b/libavcodec/qsv_internal.h
index 768f707ffa..5119ef4dff 100644
--- a/libavcodec/qsv_internal.h
+++ b/libavcodec/qsv_internal.h
@@ -51,7 +51,7 @@
 #define ASYNC_DEPTH_DEFAULT 4   // internal parallelism
 
 #define QSV_MAX_ENC_PAYLOAD 2   // # of mfxEncodeCtrl payloads supported
-#define QSV_MAX_ENC_EXTPARAM 2
+#define QSV_MAX_ENC_EXTPARAM 8  // # of mfxEncodeCtrl extparam supported
 
 #define QSV_MAX_ROI_NUM 256
 
diff --git a/libavcodec/qsvenc.c b/libavcodec/qsvenc.c
index 19fe6e59a2..690a076016 100644
--- a/libavcodec/qsvenc.c
+++ b/libavcodec/qsvenc.c
@@ -1434,25 +1434,16 @@ int ff_qsv_enc_init(AVCodecContext *avctx, 
QSVEncContext *q)
 return 0;
 }
 
-static void free_encoder_ctrl_payloads(mfxEncodeCtrl* enc_ctrl)
+static void free_encoder_ctrl(mfxEncodeCtrl* enc_ctrl)
 {
 if (enc_ctrl) {
-int i;
-for (i = 0; i < enc_ctrl->NumPayload && i < QSV_MAX_ENC_PAYLOAD; i++) {
+for (int i = 0; i < enc_ctrl->NumPayload && i < QSV_MAX_ENC_PAYLOAD; 
i++)
 av_freep(_ctrl->Payload[i]);
-}
-enc_ctrl->NumPayload = 0;
-}
-}
 
-static void free_encoder_ctrl_extparam(mfxEncodeCtrl* enc_ctrl)
-{
-if (enc_ctrl) {
-int i;
-for (i = 0; i < enc_ctrl->NumExtParam && i < QSV_MAX_ENC_EXTPARAM; 
i++) {
-if (enc_ctrl->ExtParam[i])
-av_freep(&(enc_ctrl->ExtParam[i]));
-}
+for (int i = 0; i < enc_ctrl->NumExtParam && i < QSV_MAX_ENC_EXTPARAM; 
i++)
+av_freep(_ctrl->ExtParam[i]);
+
+enc_ctrl->NumPayload = 0;
 enc_ctrl->NumExtParam = 0;
 }
 }
@@ -1462,8 +1453,7 @@ static void clear_unused_frames(QSVEncContext *q)
 QSVFrame *cur = q->work_frames;
 while (cur) {
 if (cur->used && !cur->surface.Data.Locked) {
-free_encoder_ctrl_payloads(>enc_ctrl);
-free_encoder_ctrl_extparam(>enc_ctrl);
+free_encoder_ctrl(>enc_ctrl);
 //do not reuse enc_ctrl from previous frame
 memset(>enc_ctrl, 0, sizeof(cur->enc_ctrl));
 cur->enc_ctrl.Payload = cur->payloads;
@@ -2231,8 +2221,7 @@ int ff_qsv_enc_close(AVCodecContext *avctx, QSVEncContext 
*q)
 while (cur) {
 q->work_frames = cur->next;
 av_frame_free(>frame);
-free_encoder_ctrl_extparam(>enc_ctrl);
-free_encoder_ctrl_payloads(>enc_ctrl);
+free_encoder_ctrl(>enc_ctrl);
 av_freep();
 cur = q->work_frames;
 }
-- 
2.25.1

___
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".


[FFmpeg-devel] [PATCH 1/3] lavc/qsvenc: fix check to avoid segfault

2022-10-17 Thread haihao . xiang-at-intel . com
From: Haihao Xiang 

Signed-off-by: Haihao Xiang 
---
 libavcodec/qsvenc.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/libavcodec/qsvenc.c b/libavcodec/qsvenc.c
index 15e6936a65..19fe6e59a2 100644
--- a/libavcodec/qsvenc.c
+++ b/libavcodec/qsvenc.c
@@ -2093,8 +2093,8 @@ static int encode_frame(AVCodecContext *avctx, 
QSVEncContext *q,
 pkt.bs->ExtParam = enc_buf;
 }
 
-if (q->set_encode_ctrl_cb) {
-q->set_encode_ctrl_cb(avctx, frame, _frame->enc_ctrl);
+if (q->set_encode_ctrl_cb && enc_ctrl) {
+q->set_encode_ctrl_cb(avctx, frame, enc_ctrl);
 }
 
 if ((avctx->codec_id == AV_CODEC_ID_H264 ||
-- 
2.25.1

___
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".