aboutsummaryrefslogtreecommitdiff
path: root/libavcodec/qsvenc.c
diff options
context:
space:
mode:
authorZhong Li2019-01-23 19:16:17 +0800
committerZhong Li2019-01-25 16:53:27 +0800
commit74cf2dc3ac405c5e55b7ecd4d17b40e26d59eb84 (patch)
tree44dd369aad5ac5034a18fef803ae2b4acfd10da4 /libavcodec/qsvenc.c
parent3224d6691cdc59ef0d31cdb35efac27494ff515b (diff)
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>
Diffstat (limited to 'libavcodec/qsvenc.c')
-rw-r--r--libavcodec/qsvenc.c39
1 files changed, 37 insertions, 2 deletions
diff --git a/libavcodec/qsvenc.c b/libavcodec/qsvenc.c
index ba9bcf16d7..5aa020d47b 100644
--- a/libavcodec/qsvenc.c
+++ b/libavcodec/qsvenc.c
@@ -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)";
}
@@ -345,6 +353,12 @@ static int select_rc_mode(AVCodecContext *avctx, QSVEncContext *q)
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;
rc_desc = "variable bitrate (VBR)";
@@ -568,11 +582,18 @@ static int init_video_param(AVCodecContext *avctx, QSVEncContext *q)
#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,6 +798,12 @@ 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,
@@ -779,6 +811,9 @@ static int qsv_retrieve_enc_params(AVCodecContext *avctx, QSVEncContext *q)
#if QSV_HAVE_CO2
(mfxExtBuffer*)&co2,
#endif
+#if QSV_HAVE_CO3
+ (mfxExtBuffer*)&co3,
+#endif
};
int need_pps = avctx->codec_id != AV_CODEC_ID_MPEG2VIDEO;