From patchwork Wed Jan 23 11:16:17 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Zhong Li X-Patchwork-Id: 11838 Return-Path: X-Original-To: patchwork@ffaux-bg.ffmpeg.org Delivered-To: patchwork@ffaux-bg.ffmpeg.org Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org [79.124.17.100]) by ffaux.localdomain (Postfix) with ESMTP id C95D244CD10 for ; Wed, 23 Jan 2019 13:17:12 +0200 (EET) Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id E25BD68AC2D; Wed, 23 Jan 2019 13:17:00 +0200 (EET) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mga01.intel.com (mga01.intel.com [192.55.52.88]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 05A5468AB80 for ; Wed, 23 Jan 2019 13:16:53 +0200 (EET) X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from fmsmga005.fm.intel.com ([10.253.24.32]) by fmsmga101.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 23 Jan 2019 03:17:09 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.56,511,1539673200"; d="scan'208";a="314081814" Received: from media_ffmpeg_skl_e3.sh.intel.com ([10.239.159.38]) by fmsmga005.fm.intel.com with ESMTP; 23 Jan 2019 03:17:08 -0800 From: Zhong Li To: ffmpeg-devel@ffmpeg.org Date: Wed, 23 Jan 2019 19:16:17 +0800 Message-Id: <1548242177-15335-1-git-send-email-zhong.li@intel.com> X-Mailer: git-send-email 2.7.4 Subject: [FFmpeg-devel] [PATCH v5] lavc/qsvenc: enable QVBR mode X-BeenThere: ffmpeg-devel@ffmpeg.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: FFmpeg development discussions and patches List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Reply-To: FFmpeg development discussions and patches Cc: Zhong Li MIME-Version: 1.0 Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" QVBR mode is to use the variable bitrate control algorithm with constant quality. mfxExtCodingOption3 should be supported to enable QVBR 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 Signed-off-by: Zhong Li --- libavcodec/qsvenc.c | 39 +++++++++++++++++++++++++++++++++++++-- libavcodec/qsvenc.h | 7 +++++-- 2 files changed, 42 insertions(+), 4 deletions(-) diff --git a/libavcodec/qsvenc.c b/libavcodec/qsvenc.c index ba9bcf1..5aa020d 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; diff --git a/libavcodec/qsvenc.h b/libavcodec/qsvenc.h index 47a70a4..00afbd8 100644 --- a/libavcodec/qsvenc.h +++ b/libavcodec/qsvenc.h @@ -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;