On Wed, 2022-11-02 at 16:11 +0800, wenbin.chen-at-intel....@ffmpeg.org wrote: > From: Wenbin Chen <wenbin.c...@intel.com> > > Add skip_frame support to qsvenc. Use per-frame metadata > "qsv_skip_frame" to control it. skip_frame option defines the behavior > of qsv_skip_frame. > no_skip: Frame skipping is disabled. > insert_dummy: Encoder inserts into bitstream frame where all macroblocks > are encoded as skipped. > insert_nothing: Similar to insert_dummy, but encoder inserts nothing. > The skipped frames are still used in brc. For example, gop still include > skipped frames, and the frames after skipped frames will be larger in > size. > brc_only: skip_frame metadata indicates the number of missed frames > before the current frame. > > Signed-off-by: Wenbin Chen <wenbin.c...@intel.com> > --- > doc/encoders.texi | 36 ++++++++++++++++++++++++++++++++++++ > libavcodec/qsvenc.c | 36 ++++++++++++++++++++++++++++++++++++ > libavcodec/qsvenc.h | 13 +++++++++++++ > libavcodec/qsvenc_h264.c | 1 + > libavcodec/qsvenc_hevc.c | 1 + > 5 files changed, 87 insertions(+) > > diff --git a/doc/encoders.texi b/doc/encoders.texi > index 53dd02fd28..59f39d18f6 100644 > --- a/doc/encoders.texi > +++ b/doc/encoders.texi > @@ -3564,6 +3564,24 @@ bitrate, @var{target_bitrate}, within the accuracy > range @var{avbr_accuracy}, > after a @var{avbr_Convergence} period. This method does not follow HRD and > the > instant bitrate is not capped or padded. > > +@item @var{skip_frame} > +Use per-frame metadata "qsv_skip_frame" to skip frame when encoding. This > option > +defines the usage of this metadata. > +@table @samp > +@item no_skip > +Frame skipping is disabled. > +@item insert_dummy > +Encoder inserts into bitstream frame where all macroblocks are encoded as > +skipped. > +@item insert_nothing > +Similar to insert_dummy, but encoder inserts nothing into bitstream. The > skipped > +frames are still used in brc. For example, gop still include skipped frames, > and > +the frames after skipped frames will be larger in size. > +@item brc_only > +skip_frame metadata indicates the number of missed frames before the current > +frame. > +@end table > + > @end table > > @subsection HEVC Options > @@ -3742,6 +3760,24 @@ bitrate, @var{target_bitrate}, within the accuracy > range @var{avbr_accuracy}, > after a @var{avbr_Convergence} period. This method does not follow HRD and > the > instant bitrate is not capped or padded. > > +@item @var{skip_frame} > +Use per-frame metadata "qsv_skip_frame" to skip frame when encoding. This > option > +defines the usage of this metadata. > +@table @samp > +@item no_skip > +Frame skipping is disabled. > +@item insert_dummy > +Encoder inserts into bitstream frame where all macroblocks are encoded as > +skipped. > +@item insert_nothing > +Similar to insert_dummy, but encoder inserts nothing into bitstream. The > skipped > +frames are still used in brc. For example, gop still include skipped frames, > and > +the frames after skipped frames will be larger in size. > +@item brc_only > +skip_frame metadata indicates the number of missed frames before the current > +frame. > +@end table > + > @end table > > @subsection MPEG2 Options > diff --git a/libavcodec/qsvenc.c b/libavcodec/qsvenc.c > index 0db774ea63..4bfa65c575 100644 > --- a/libavcodec/qsvenc.c > +++ b/libavcodec/qsvenc.c > @@ -329,6 +329,22 @@ static void dump_video_param(AVCodecContext *avctx, > QSVEncContext *q, > "MinQPI: %"PRIu8"; MaxQPI: %"PRIu8"; MinQPP: %"PRIu8"; MaxQPP: > %"PRIu8"; MinQPB: %"PRIu8"; MaxQPB: %"PRIu8"\n", > co2->MinQPI, co2->MaxQPI, co2->MinQPP, co2->MaxQPP, co2- > >MinQPB, co2->MaxQPB); > av_log(avctx, AV_LOG_VERBOSE, "DisableDeblockingIdc: %"PRIu32" \n", > co2->DisableDeblockingIdc); > + > + switch (co2->SkipFrame) { > + case MFX_SKIPFRAME_NO_SKIP: > + av_log(avctx, AV_LOG_VERBOSE, "SkipFrame: no_skip\n"); > + break; > + case MFX_SKIPFRAME_INSERT_DUMMY: > + av_log(avctx, AV_LOG_VERBOSE, "SkipFrame: insert_dummy\n"); > + break; > + case MFX_SKIPFRAME_INSERT_NOTHING: > + av_log(avctx, AV_LOG_VERBOSE, "SkipFrame: insert_nothing\n"); > + break; > + case MFX_SKIPFRAME_BRC_ONLY: > + av_log(avctx, AV_LOG_VERBOSE, "SkipFrame: brc_only\n"); > + break; > + default: break; > + } > } > > if (co3) { > @@ -991,6 +1007,8 @@ static int init_video_param(AVCodecContext *avctx, > QSVEncContext *q) > q->old_max_qp_b = q->max_qp_b; > if (q->mbbrc >= 0) > q->extco2.MBBRC = q->mbbrc ? MFX_CODINGOPTION_ON : > MFX_CODINGOPTION_OFF; > + if (q->skip_frame >= 0) > + q->extco2.SkipFrame = q->skip_frame; > > q->extco2.Header.BufferId = MFX_EXTBUFF_CODING_OPTION2; > q->extco2.Header.BufferSz = sizeof(q->extco2); > @@ -1911,6 +1929,19 @@ static int set_roi_encode_ctrl(AVCodecContext *avctx, > const AVFrame *frame, > return 0; > } > > +static void set_skip_frame_encode_ctrl(AVCodecContext *avctx, const AVFrame > *frame, > + mfxEncodeCtrl *enc_ctrl) > +{ > + AVDictionaryEntry* skip_frame_dict = NULL; > + if (!frame->metadata) > + return; > + skip_frame_dict = av_dict_get(frame->metadata, "qsv_skip_frame", NULL, > 0); > + if (!skip_frame_dict) > + return; > + enc_ctrl->SkipFrame = strtol(skip_frame_dict->value, NULL, 10); > + return; > +} > + > static int update_qp(AVCodecContext *avctx, QSVEncContext *q) > { > int updated = 0, new_qp = 0; > @@ -2282,6 +2313,11 @@ static int encode_frame(AVCodecContext *avctx, > QSVEncContext *q, > if (ret < 0) > goto free; > } > + if ((avctx->codec_id == AV_CODEC_ID_H264 || > + avctx->codec_id == AV_CODEC_ID_H265) && > + q->skip_frame != MFX_SKIPFRAME_NO_SKIP && > + enc_ctrl && QSV_RUNTIME_VERSION_ATLEAST(q->ver, 1, 13)) > + set_skip_frame_encode_ctrl(avctx, frame, enc_ctrl); > > pkt.sync = av_mallocz(sizeof(*pkt.sync)); > if (!pkt.sync) > diff --git a/libavcodec/qsvenc.h b/libavcodec/qsvenc.h > index eb79db9871..d46575ef78 100644 > --- a/libavcodec/qsvenc.h > +++ b/libavcodec/qsvenc.h > @@ -127,6 +127,18 @@ > { "avbr_accuracy", "Accuracy of the AVBR ratecontrol (unit of tenth of > percent)", OFFSET(qsv.avbr_accuracy), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, > UINT16_MAX, VE }, \ > { "avbr_convergence", "Convergence of the AVBR ratecontrol (unit of 100 > frames)", OFFSET(qsv.avbr_convergence), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, > UINT16_MAX, VE }, > > +#define QSV_OPTION_SKIP_FRAME \ > +{ "skip_frame", "Allow frame skipping", > OFFSET(qsv.skip_frame), AV_OPT_TYPE_INT, { .i64 = MFX_SKIPFRAME_NO_SKIP }, \ > + MFX_SKIPFRAME_NO_SKIP, MFX_SKIPFRAME_BRC_ONLY, VE, "skip_frame" }, \ > +{ "no_skip", "Frame skipping is disabled", \ > + 0, AV_OPT_TYPE_CONST, { .i64 = MFX_SKIPFRAME_NO_SKIP }, .flags > = VE, "skip_frame" }, \ > +{ "insert_dummy", "Encoder inserts into bitstream frame where all > macroblocks are encoded as skipped", \ > + 0, AV_OPT_TYPE_CONST, { .i64 = MFX_SKIPFRAME_INSERT_DUMMY }, .flags > = VE, "skip_frame" }, \ > +{ "insert_nothing", "Encoder inserts nothing into > bitstream", \ > + 0, AV_OPT_TYPE_CONST, { .i64 = MFX_SKIPFRAME_INSERT_NOTHING }, .flags > = VE, "skip_frame" }, \ > +{ "brc_only", "skip_frame metadata indicates the number of missed > frames before the current frame", \ > + 0, AV_OPT_TYPE_CONST, { .i64 = MFX_SKIPFRAME_BRC_ONLY }, .flags > = VE, "skip_frame" }, > + > extern const AVCodecHWConfigInternal *const ff_qsv_enc_hw_configs[]; > > typedef int SetEncodeCtrlCB (AVCodecContext *avctx, > @@ -285,6 +297,7 @@ typedef struct QSVEncContext { > int old_rc_max_rate; > // This is used for SEI Timing reset > int old_pic_timing_sei; > + int skip_frame; > } QSVEncContext; > > int ff_qsv_enc_init(AVCodecContext *avctx, QSVEncContext *q); > diff --git a/libavcodec/qsvenc_h264.c b/libavcodec/qsvenc_h264.c > index 11aaabbd1b..0ff7356346 100644 > --- a/libavcodec/qsvenc_h264.c > +++ b/libavcodec/qsvenc_h264.c > @@ -116,6 +116,7 @@ static const AVOption options[] = { > QSV_OPTION_MAX_MIN_QP > QSV_OPTION_SCENARIO > QSV_OPTION_AVBR > + QSV_OPTION_SKIP_FRAME > > { "cavlc", "Enable > CAVLC", OFFSET(qsv.cavlc), AV_OPT_TYPE_BOOL > , { .i64 = 0 }, 0, 1, VE }, > #if QSV_HAVE_VCM > diff --git a/libavcodec/qsvenc_hevc.c b/libavcodec/qsvenc_hevc.c > index 28d2cfcae1..95cf417f67 100644 > --- a/libavcodec/qsvenc_hevc.c > +++ b/libavcodec/qsvenc_hevc.c > @@ -317,6 +317,7 @@ static const AVOption options[] = { > QSV_OPTION_ADAPTIVE_B > QSV_OPTION_SCENARIO > QSV_OPTION_AVBR > + QSV_OPTION_SKIP_FRAME > > { "idr_interval", "Distance (in I-frames) between IDR frames", > OFFSET(qsv.idr_interval), AV_OPT_TYPE_INT, { .i64 = 0 }, -1, INT_MAX, VE, > "idr_interval" }, > { "begin_only", "Output an IDR-frame only at the beginning of the > stream", 0, AV_OPT_TYPE_CONST, { .i64 = -1 }, 0, 0, VE, "idr_interval" },
Applied, thx -Haihao _______________________________________________ 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".