mirror of
https://github.com/FFmpeg/FFmpeg.git
synced 2025-01-29 22:00:58 +02:00
lavc/qsvenc: enable QVBR mode
QVBR mode is to use the variable bitrate control algorithm with constant quality. mfxExtCodingOption3 should be supported to enable QVBR mode. It is neccesary to specify a max_rate for QVBR, else it may be ICQ mode. Example usage: ffmpeg -hwaccel qsv -c:v h264_qsv -i input.mp4 -c:v h264_qsv -global_quality 25 -maxrate 2M test_qvbr.mp4 -v verbose Clip QVBR quality range to be [0, 51] as Mark's commments. It is similar to qp range of CQP but possibly should be updated when VP8/VP9 encoding can be supported. Reviewed-by: Mark Thompson <sw@jkqxz.net> Signed-off-by: Zhong Li <zhong.li@intel.com>
This commit is contained in:
parent
3224d6691c
commit
74cf2dc3ac
@ -136,6 +136,9 @@ static void dump_video_param(AVCodecContext *avctx, QSVEncContext *q,
|
||||
#if QSV_HAVE_CO2
|
||||
mfxExtCodingOption2 *co2 = (mfxExtCodingOption2*)coding_opts[1];
|
||||
#endif
|
||||
#if QSV_HAVE_CO3
|
||||
mfxExtCodingOption3 *co3 = (mfxExtCodingOption3*)coding_opts[2];
|
||||
#endif
|
||||
|
||||
av_log(avctx, AV_LOG_VERBOSE, "profile: %s; level: %"PRIu16"\n",
|
||||
print_profile(info->CodecProfile), info->CodecLevel);
|
||||
@ -190,7 +193,12 @@ static void dump_video_param(AVCodecContext *avctx, QSVEncContext *q,
|
||||
info->ICQQuality, co2->LookAheadDepth);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if QSV_HAVE_QVBR
|
||||
else if (info->RateControlMethod == MFX_RATECONTROL_QVBR) {
|
||||
av_log(avctx, AV_LOG_VERBOSE, "QVBRQuality: %"PRIu16"\n",
|
||||
co3->QVBRQuality);
|
||||
}
|
||||
#endif
|
||||
av_log(avctx, AV_LOG_VERBOSE, "NumSlice: %"PRIu16"; NumRefFrame: %"PRIu16"\n",
|
||||
info->NumSlice, info->NumRefFrame);
|
||||
av_log(avctx, AV_LOG_VERBOSE, "RateDistortionOpt: %s\n",
|
||||
@ -330,7 +338,7 @@ static int select_rc_mode(AVCodecContext *avctx, QSVEncContext *q)
|
||||
}
|
||||
#endif
|
||||
#if QSV_HAVE_ICQ
|
||||
else if (avctx->global_quality > 0) {
|
||||
else if (avctx->global_quality > 0 && !avctx->rc_max_rate) {
|
||||
rc_mode = MFX_RATECONTROL_ICQ;
|
||||
rc_desc = "intelligent constant quality (ICQ)";
|
||||
}
|
||||
@ -344,6 +352,12 @@ static int select_rc_mode(AVCodecContext *avctx, QSVEncContext *q)
|
||||
rc_mode = MFX_RATECONTROL_AVBR;
|
||||
rc_desc = "average variable bitrate (AVBR)";
|
||||
}
|
||||
#endif
|
||||
#if QSV_HAVE_QVBR
|
||||
else if (avctx->global_quality > 0) {
|
||||
rc_mode = MFX_RATECONTROL_QVBR;
|
||||
rc_desc = "constant quality with VBR algorithm (QVBR)";
|
||||
}
|
||||
#endif
|
||||
else {
|
||||
rc_mode = MFX_RATECONTROL_VBR;
|
||||
@ -567,12 +581,19 @@ static int init_video_param(AVCodecContext *avctx, QSVEncContext *q)
|
||||
case MFX_RATECONTROL_VBR:
|
||||
#if QSV_HAVE_VCM
|
||||
case MFX_RATECONTROL_VCM:
|
||||
#endif
|
||||
#if QSV_HAVE_QVBR
|
||||
case MFX_RATECONTROL_QVBR:
|
||||
#endif
|
||||
q->param.mfx.BufferSizeInKB = buffer_size_in_kilobytes / brc_param_multiplier;
|
||||
q->param.mfx.InitialDelayInKB = initial_delay_in_kilobytes / brc_param_multiplier;
|
||||
q->param.mfx.TargetKbps = target_bitrate_kbps / brc_param_multiplier;
|
||||
q->param.mfx.MaxKbps = max_bitrate_kbps / brc_param_multiplier;
|
||||
q->param.mfx.BRCParamMultiplier = brc_param_multiplier;
|
||||
#if QSV_HAVE_QVBR
|
||||
if (q->param.mfx.RateControlMethod == MFX_RATECONTROL_QVBR)
|
||||
q->extco3.QVBRQuality = av_clip(avctx->global_quality, 0, 51);
|
||||
#endif
|
||||
break;
|
||||
case MFX_RATECONTROL_CQP:
|
||||
quant = avctx->global_quality / FF_QP2LAMBDA;
|
||||
@ -718,6 +739,11 @@ FF_ENABLE_DEPRECATION_WARNINGS
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#if QSV_HAVE_CO3
|
||||
q->extco3.Header.BufferId = MFX_EXTBUFF_CODING_OPTION3;
|
||||
q->extco3.Header.BufferSz = sizeof(q->extco3);
|
||||
q->extparam_internal[q->nb_extparam_internal++] = (mfxExtBuffer *)&q->extco3;
|
||||
#endif
|
||||
}
|
||||
|
||||
if (!check_enc_param(avctx,q)) {
|
||||
@ -772,12 +798,21 @@ static int qsv_retrieve_enc_params(AVCodecContext *avctx, QSVEncContext *q)
|
||||
.Header.BufferSz = sizeof(co2),
|
||||
};
|
||||
#endif
|
||||
#if QSV_HAVE_CO3
|
||||
mfxExtCodingOption3 co3 = {
|
||||
.Header.BufferId = MFX_EXTBUFF_CODING_OPTION3,
|
||||
.Header.BufferSz = sizeof(co3),
|
||||
};
|
||||
#endif
|
||||
|
||||
mfxExtBuffer *ext_buffers[] = {
|
||||
(mfxExtBuffer*)&extradata,
|
||||
(mfxExtBuffer*)&co,
|
||||
#if QSV_HAVE_CO2
|
||||
(mfxExtBuffer*)&co2,
|
||||
#endif
|
||||
#if QSV_HAVE_CO3
|
||||
(mfxExtBuffer*)&co3,
|
||||
#endif
|
||||
};
|
||||
|
||||
|
@ -56,7 +56,7 @@
|
||||
#define QSV_HAVE_AVBR 0
|
||||
#define QSV_HAVE_ICQ QSV_VERSION_ATLEAST(1, 28)
|
||||
#define QSV_HAVE_VCM 0
|
||||
#define QSV_HAVE_QVBR 0
|
||||
#define QSV_HAVE_QVBR QSV_VERSION_ATLEAST(1, 28)
|
||||
#define QSV_HAVE_MF QSV_VERSION_ATLEAST(1, 25)
|
||||
#endif
|
||||
|
||||
@ -111,6 +111,9 @@ typedef struct QSVEncContext {
|
||||
#if QSV_HAVE_CO2
|
||||
mfxExtCodingOption2 extco2;
|
||||
#endif
|
||||
#if QSV_HAVE_CO3
|
||||
mfxExtCodingOption3 extco3;
|
||||
#endif
|
||||
#if QSV_HAVE_MF
|
||||
mfxExtMultiFrameParam extmfp;
|
||||
mfxExtMultiFrameControl extmfc;
|
||||
@ -119,7 +122,7 @@ typedef struct QSVEncContext {
|
||||
mfxFrameSurface1 **opaque_surfaces;
|
||||
AVBufferRef *opaque_alloc_buf;
|
||||
|
||||
mfxExtBuffer *extparam_internal[2 + QSV_HAVE_CO2 + (QSV_HAVE_MF * 2)];
|
||||
mfxExtBuffer *extparam_internal[2 + QSV_HAVE_CO2 + QSV_HAVE_CO3 + (QSV_HAVE_MF * 2)];
|
||||
int nb_extparam_internal;
|
||||
|
||||
mfxExtBuffer **extparam;
|
||||
|
Loading…
x
Reference in New Issue
Block a user