Git Inbox Mirror of the ffmpeg-devel mailing list - see https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
 help / color / mirror / Atom feed
From: "Xiang, Haihao" <haihao.xiang-at-intel.com@ffmpeg.org>
To: ffmpeg-devel@ffmpeg.org
Cc: Haihao Xiang <haihao.xiang@intel.com>
Subject: [FFmpeg-devel] [PATCH 2/2] lavc/qsvenc_{h264, hevc}: import user data unregistered SEIs if available
Date: Wed,  8 Feb 2023 14:26:19 +0800
Message-ID: <20230208062619.19496-2-haihao.xiang@intel.com> (raw)
In-Reply-To: <20230208062619.19496-1-haihao.xiang@intel.com>

From: Haihao Xiang <haihao.xiang@intel.com>

option udu_sei is added, user should set udu_sei to true|on|1 if user
data unregistered SEI is expected.

Verify user data unregistered SEI with commands below:
$ ffmpeg -y -f lavfi -i testsrc -vf "format=nv12" -c:v libx264 -frames:v 1
a.h264
$ ffmpeg -y -init_hw_device qsv -i a.h264 -c:v hevc_qsv -udu_sei 1 b.h265
$ ffmpeg -y -init_hw_device qsv -i a.h264 -c:v hevc_qsv -udu_sei 0 c.h265

$ ffmpeg -i b.h265 -vf showinfo -f null -
$ ffmpeg -i c.h265 -vf showinfo -f null -

Signed-off-by: Haihao Xiang <haihao.xiang@intel.com>
---
 doc/encoders.texi        |  6 +++++
 libavcodec/qsvenc.c      | 47 ++++++++++++++++++++++++++++++++++++++++
 libavcodec/qsvenc.h      |  1 +
 libavcodec/qsvenc_h264.c |  1 +
 libavcodec/qsvenc_hevc.c |  1 +
 5 files changed, 56 insertions(+)

diff --git a/doc/encoders.texi b/doc/encoders.texi
index 727f12a59d..a9972d8b9c 100644
--- a/doc/encoders.texi
+++ b/doc/encoders.texi
@@ -3582,6 +3582,9 @@ skip_frame metadata indicates the number of missed frames before the current
 frame.
 @end table
 
+@item udu_sei @var{boolean}
+Import user data unregistered SEI if available into output. Default is 0 (off).
+
 @end table
 
 @subsection HEVC Options
@@ -3787,6 +3790,9 @@ skip_frame metadata indicates the number of missed frames before the current
 frame.
 @end table
 
+@item udu_sei @var{boolean}
+Import user data unregistered SEI if available into output. Default is 0 (off).
+
 @end table
 
 @subsection MPEG2 Options
diff --git a/libavcodec/qsvenc.c b/libavcodec/qsvenc.c
index 2f0e94a914..c0c40e706f 100644
--- a/libavcodec/qsvenc.c
+++ b/libavcodec/qsvenc.c
@@ -2046,6 +2046,49 @@ static void set_skip_frame_encode_ctrl(AVCodecContext *avctx, const AVFrame *fra
     return;
 }
 
+static int set_udu_encode_ctrl(AVCodecContext *avctx,  QSVEncContext *q,
+                               const AVFrame *frame, mfxEncodeCtrl *enc_ctrl)
+{
+    if (!frame || !q->udu_sei)
+        return 0;
+
+    for (int i = 0; i < frame->nb_side_data && enc_ctrl->NumPayload < QSV_MAX_ENC_PAYLOAD; i++) {
+        AVFrameSideData *sd = NULL;
+        mfxPayload *payload = NULL;
+        mfxU8* sei_data;
+        int j;
+
+        sd = frame->side_data[i];
+        if (sd->type != AV_FRAME_DATA_SEI_UNREGISTERED)
+            continue;
+
+        /* SEI type: 1 byte, SEI size: sd->size / 255 + 1 bytes, SEI data: sd->size bytes */
+        payload = av_malloc(sizeof(*payload) + sd->size / 255 + 2 + sd->size);
+        if (!payload)
+            return AVERROR(ENOMEM);
+
+        memset(payload, 0, sizeof(*payload));
+        sei_data = (mfxU8 *)(payload + 1);
+        // SEI header
+        sei_data[0] = 5;
+        for (j = 0; j < sd->size / 255; j++)
+            sei_data[j + 1] = 0xff;
+        sei_data[j + 1] = sd->size % 255;
+        // SEI data
+        memcpy(&sei_data[sd->size / 255 + 2], sd->data, sd->size);
+
+        payload->BufSize = sd->size + sd->size / 255 + 2;
+        payload->NumBit = payload->BufSize * 8;
+        payload->Type = 5;
+        payload->Data = sei_data;
+
+        enc_ctrl->Payload[enc_ctrl->NumPayload] = payload;
+        enc_ctrl->NumPayload++;
+    }
+
+    return 0;
+}
+
 static int update_qp(AVCodecContext *avctx, QSVEncContext *q)
 {
     int updated = 0, new_qp = 0;
@@ -2416,6 +2459,10 @@ static int encode_frame(AVCodecContext *avctx, QSVEncContext *q,
         ret = set_roi_encode_ctrl(avctx, frame, enc_ctrl);
         if (ret < 0)
             goto free;
+
+        ret = set_udu_encode_ctrl(avctx, q, frame, enc_ctrl);
+        if (ret < 0)
+            goto free;
     }
     if ((avctx->codec_id == AV_CODEC_ID_H264 ||
          avctx->codec_id == AV_CODEC_ID_H265) &&
diff --git a/libavcodec/qsvenc.h b/libavcodec/qsvenc.h
index 4a6fa2caed..5b66d31053 100644
--- a/libavcodec/qsvenc.h
+++ b/libavcodec/qsvenc.h
@@ -255,6 +255,7 @@ typedef struct QSVEncContext {
     int transform_skip;
 
     int a53_cc;
+    int udu_sei;
 
 #if QSV_HAVE_MF
     int mfmode;
diff --git a/libavcodec/qsvenc_h264.c b/libavcodec/qsvenc_h264.c
index 071a9a79e9..31de8d7073 100644
--- a/libavcodec/qsvenc_h264.c
+++ b/libavcodec/qsvenc_h264.c
@@ -166,6 +166,7 @@ static const AVOption options[] = {
 #endif
 
     { "repeat_pps", "repeat pps for every frame", OFFSET(qsv.repeat_pps), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, VE },
+    { "udu_sei",    "Use user data unregistered SEI if available", OFFSET(qsv.udu_sei), AV_OPT_TYPE_BOOL,   { .i64 = 0 }, 0, 1, VE },
 
     { NULL },
 };
diff --git a/libavcodec/qsvenc_hevc.c b/libavcodec/qsvenc_hevc.c
index 5e23ca9647..5941c332cf 100644
--- a/libavcodec/qsvenc_hevc.c
+++ b/libavcodec/qsvenc_hevc.c
@@ -362,6 +362,7 @@ static const AVOption options[] = {
     { "int_ref_cycle_size", "Number of frames in the intra refresh cycle",       OFFSET(qsv.int_ref_cycle_size),      AV_OPT_TYPE_INT, { .i64 = -1 },               -1, UINT16_MAX, VE },
     { "int_ref_qp_delta",   "QP difference for the refresh MBs",                 OFFSET(qsv.int_ref_qp_delta),        AV_OPT_TYPE_INT, { .i64 = INT16_MIN }, INT16_MIN,  INT16_MAX, VE },
     { "int_ref_cycle_dist",   "Distance between the beginnings of the intra-refresh cycles in frames",  OFFSET(qsv.int_ref_cycle_dist),      AV_OPT_TYPE_INT, { .i64 = -1 }, -1, INT16_MAX, VE },
+    { "udu_sei",    "Use user data unregistered SEI if available", OFFSET(qsv.udu_sei), AV_OPT_TYPE_BOOL,   { .i64 = 0 }, 0, 1, VE },
 
     { NULL },
 };
-- 
2.17.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-request@ffmpeg.org with subject "unsubscribe".

      reply	other threads:[~2023-02-08  6:26 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-02-08  6:26 [FFmpeg-devel] [PATCH 1/2] lavc/qsvenc: enlarge the maximum number of mfxPayload on mfxEncodeCtrl Xiang, Haihao
2023-02-08  6:26 ` Xiang, Haihao [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20230208062619.19496-2-haihao.xiang@intel.com \
    --to=haihao.xiang-at-intel.com@ffmpeg.org \
    --cc=ffmpeg-devel@ffmpeg.org \
    --cc=haihao.xiang@intel.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link

Git Inbox Mirror of the ffmpeg-devel mailing list - see https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

This inbox may be cloned and mirrored by anyone:

	git clone --mirror https://master.gitmailbox.com/ffmpegdev/0 ffmpegdev/git/0.git

	# If you have public-inbox 1.1+ installed, you may
	# initialize and index your mirror using the following commands:
	public-inbox-init -V2 ffmpegdev ffmpegdev/ https://master.gitmailbox.com/ffmpegdev \
		ffmpegdev@gitmailbox.com
	public-inbox-index ffmpegdev

Example config snippet for mirrors.


AGPL code for this site: git clone https://public-inbox.org/public-inbox.git