[x265] [PATCH] Add dynamic rate-control reconfiguration
Aarthi Priya Thirumalai
aarthi at multicorewareinc.com
Thu Apr 6 10:05:55 CEST 2017
On Tue, Apr 4, 2017 at 6:34 PM, <aruna at multicorewareinc.com> wrote:
> # HG changeset patch
> # User Aruna Matheswaran <aruna at multicorewareinc.com>
> # Date 1487757265 -19800
> # Wed Feb 22 15:24:25 2017 +0530
> # Node ID 576ad673d9b352c45853b7ffeeacce7d23268bb8
> # Parent 08a05ca9fd16c9f5efb1ce4d8389bda8a63f5f7d
> Add dynamic rate-control reconfiguration
>
> diff -r 08a05ca9fd16 -r 576ad673d9b3 source/common/frame.cpp
> --- a/source/common/frame.cpp Mon Mar 27 12:35:20 2017 +0530
> +++ b/source/common/frame.cpp Wed Feb 22 15:24:25 2017 +0530
> @@ -47,6 +47,7 @@
> memset(&m_lowres, 0, sizeof(m_lowres));
> m_rcData = NULL;
> m_encodeStartTime = 0;
> + m_reconfigureRc = false;
> }
>
> bool Frame::create(x265_param *param, float* quantOffsets)
> diff -r 08a05ca9fd16 -r 576ad673d9b3 source/common/frame.h
> --- a/source/common/frame.h Mon Mar 27 12:35:20 2017 +0530
> +++ b/source/common/frame.h Wed Feb 22 15:24:25 2017 +0530
> @@ -84,6 +84,7 @@
> Lowres m_lowres;
> bool m_lowresInit; // lowres init complete
> (pre-analysis)
> bool m_bChromaExtended; // orig chroma planes
> motion extended for weight analysis
> + bool m_reconfigureRc;
>
> float* m_quantOffsets; // points to
> quantOffsets in x265_picture
> x265_sei m_userSEI;
> diff -r 08a05ca9fd16 -r 576ad673d9b3 source/encoder/api.cpp
> --- a/source/encoder/api.cpp Mon Mar 27 12:35:20 2017 +0530
> +++ b/source/encoder/api.cpp Wed Feb 22 15:24:25 2017 +0530
> @@ -171,7 +171,7 @@
>
> x265_param save;
> Encoder* encoder = static_cast<Encoder*>(enc);
> - if (encoder->m_reconfigure) /* Reconfigure in progress */
> + if (encoder->m_reconfigure || encoder->m_reconfigureRc) /*
> Reconfigure in progress */
> return 1;
> memcpy(&save, encoder->m_latestParam, sizeof(x265_param));
> int ret = encoder->reconfigureParam(encoder->m_latestParam,
> param_in);
> @@ -197,7 +197,22 @@
> return -1;
> }
> }
> - encoder->m_reconfigure = true;
> + if (encoder->m_reconfigureRc)
> + {
> + VPS saveVPS;
> + memcpy(&saveVPS.ptl, &encoder->m_vps.ptl,
> sizeof(saveVPS.ptl));
> + determineLevel(*encoder->m_latestParam, encoder->m_vps);
> + if (saveVPS.ptl.profileIdc != encoder->m_vps.ptl.profileIdc
> || saveVPS.ptl.levelIdc != encoder->m_vps.ptl.levelIdc
> + || saveVPS.ptl.tierFlag != encoder->m_vps.ptl.tierFlag)
> + {
> + x265_log(encoder->m_param, X265_LOG_WARNING,
> "Profile/Level/Tier has changed from %d/%d/%s to %d/%d/%s.Cannot
> reconfigure rate-control.\n",
> + saveVPS.ptl.profileIdc, saveVPS.ptl.levelIdc,
> saveVPS.ptl.tierFlag ? "High" : "Main", encoder->m_vps.ptl.profileIdc,
> + encoder->m_vps.ptl.levelIdc,
> encoder->m_vps.ptl.tierFlag ? "High" : "Main");
> + encoder->m_reconfigureRc = false;
> + }
> + }
> + else
> + encoder->m_reconfigure = true;
>
why set only m_reconfigure as true, where are you setting m_reconfigureRc
to true?
> encoder->printReconfigureParams();
> }
> return ret;
> diff -r 08a05ca9fd16 -r 576ad673d9b3 source/encoder/encoder.cpp
> --- a/source/encoder/encoder.cpp Mon Mar 27 12:35:20 2017 +0530
> +++ b/source/encoder/encoder.cpp Wed Feb 22 15:24:25 2017 +0530
> @@ -56,6 +56,7 @@
> {
> m_aborted = false;
> m_reconfigure = false;
> + m_reconfigureRc = false;
> m_encodedFrameNum = 0;
> m_pocLast = -1;
> m_curEncoder = 0;
> @@ -607,7 +608,7 @@
> {
> inFrame = new Frame;
> inFrame->m_encodeStartTime = x265_mdate();
> - x265_param* p = m_reconfigure ? m_latestParam : m_param;
>
no need for this change - when reconfigureRc is true, m_reconfigure will
also be true..so dont need to change these
> + x265_param* p = (m_reconfigure || m_reconfigureRc) ?
> m_latestParam : m_param;
> if (inFrame->create(p, pic_in->quantOffsets))
> {
> /* the first PicYuv created is asked to generate the CU
> and block unit offset
> @@ -674,7 +675,7 @@
> inFrame->m_userData = pic_in->userData;
> inFrame->m_pts = pic_in->pts;
> inFrame->m_forceqp = pic_in->forceqp;
> - inFrame->m_param = m_reconfigure ? m_latestParam : m_param;
>
same as above. for any reconfigure, set m_reconfigure to true,
additionally, set m_reconfigureRc to true for
Rate control reconfigure changes. no need for the above change then
> + inFrame->m_param = (m_reconfigure || m_reconfigureRc) ?
> m_latestParam : m_param;
>
> if (pic_in->userSEI.numPayloads)
> {
> @@ -740,6 +741,8 @@
> inFrame->m_lowres.bScenecut = !!inFrame->m_analysisData.
> bScenecut;
> inFrame->m_lowres.satdCost = inFrame->m_analysisData.
> satdCost;
> }
> + if (m_reconfigureRc)
> + inFrame->m_reconfigureRc = true;
>
> m_lookahead->addPicture(*inFrame, sliceType);
> m_numDelayedPic++;
> @@ -940,6 +943,15 @@
> if (m_param->rc.bStatRead)
> readAnalysis2PassFile(&frameEnc->m_analysis2Pass,
> frameEnc->m_poc, frameEnc->m_lowres.sliceType);
> }
> +
> + if (frameEnc->m_reconfigureRc && m_reconfigureRc)
> + {
> + memcpy(m_param, m_latestParam, sizeof(x265_param));
> + m_rateControl->reconfigureRC();
> + m_reconfigureRc = false;
> + }
> + if (frameEnc->m_reconfigureRc && !m_reconfigureRc)
> + frameEnc->m_reconfigureRc = false;
> if (curEncoder->m_reconfigure)
> {
> /* One round robin cycle of FE reconfigure is complete */
> @@ -1090,6 +1102,25 @@
> encParam->bIntraInBFrames = param->bIntraInBFrames;
> if (param->scalingLists && !encParam->scalingLists)
> encParam->scalingLists = strdup(param->scalingLists);
>
Can you turn vbv off in reconfigure, if it was ON to beign with? need that
check as well
> + /* VBV can't be turned ON if it wasn't ON to begin with */
> + if (param->rc.vbvMaxBitrate > 0 && param->rc.vbvBufferSize > 0 &&
> + encParam->rc.vbvMaxBitrate > 0 && encParam->rc.vbvBufferSize > 0)
> + {
> + m_reconfigureRc |= encParam->rc.vbvMaxBitrate !=
> param->rc.vbvMaxBitrate;
> + m_reconfigureRc |= encParam->rc.vbvBufferSize !=
> param->rc.vbvBufferSize;
> + if (m_reconfigureRc && m_param->bEmitHRDSEI)
> + x265_log(m_param, X265_LOG_WARNING, "VBV parameters cannot be
> changed when HRD is in use.\n");
> + else
> + {
> + encParam->rc.vbvMaxBitrate = param->rc.vbvMaxBitrate;
> + encParam->rc.vbvBufferSize = param->rc.vbvBufferSize;
+ }
> + }
> + m_reconfigureRc |= encParam->rc.bitrate != param->rc.bitrate;
> + encParam->rc.bitrate = param->rc.bitrate;
> + m_reconfigureRc |= encParam->rc.rfConstant != param->rc.rfConstant;
> + encParam->rc.rfConstant = param->rc.rfConstant;
> +
> /* To add: Loop Filter/deblocking controls, transform skip, signhide
> require PPS to be resent */
> /* To add: SAO, temporal MVP, AMP, TU depths require SPS to be
> resent, at every CVS boundary */
> return x265_check_params(encParam);
> @@ -3090,7 +3121,7 @@
>
> void Encoder::printReconfigureParams()
> {
> - if (!m_reconfigure)
> + if (!(m_reconfigure || m_reconfigureRc))
> return;
> x265_param* oldParam = m_param;
> x265_param* newParam = m_latestParam;
> @@ -3112,6 +3143,10 @@
> TOOLCMP(oldParam->maxNumMergeCand, newParam->maxNumMergeCand,
> "max-merge=%d to %d\n");
> TOOLCMP(oldParam->bIntraInBFrames, newParam->bIntraInBFrames,
> "b-intra=%d to %d\n");
> TOOLCMP(oldParam->scalingLists, newParam->scalingLists,
> "scalinglists=%s to %s\n");
> + TOOLCMP(oldParam->rc.vbvMaxBitrate, newParam->rc.vbvMaxBitrate,
> "vbv-maxrate=%d to %d\n");
> + TOOLCMP(oldParam->rc.vbvBufferSize, newParam->rc.vbvBufferSize,
> "vbv-bufsize=%d to %d\n");
> + TOOLCMP(oldParam->rc.bitrate, newParam->rc.bitrate, "bitrate=%d to
> %d\n");
> + TOOLCMP(oldParam->rc.rfConstant, newParam->rc.rfConstant, "crf=%f to
> %f\n");
> }
>
> bool Encoder::computeSPSRPSIndex()
> diff -r 08a05ca9fd16 -r 576ad673d9b3 source/encoder/encoder.h
> --- a/source/encoder/encoder.h Mon Mar 27 12:35:20 2017 +0530
> +++ b/source/encoder/encoder.h Wed Feb 22 15:24:25 2017 +0530
> @@ -153,6 +153,7 @@
> bool m_bZeroLatency; // x265_encoder_encode()
> returns NALs for the input picture, zero lag
> bool m_aborted; // fatal error detected
> bool m_reconfigure; // Encoder reconfigure in
> progress
> + bool m_reconfigureRc;
>
> /* Begin intra refresh when one not in progress or else begin one as
> soon as the current
> * one is done. Requires bIntraRefresh to be set.*/
> diff -r 08a05ca9fd16 -r 576ad673d9b3 source/encoder/ratecontrol.cpp
> --- a/source/encoder/ratecontrol.cpp Mon Mar 27 12:35:20 2017 +0530
> +++ b/source/encoder/ratecontrol.cpp Wed Feb 22 15:24:25 2017 +0530
> @@ -683,6 +683,56 @@
> return true;
> }
>
> +void RateControl::reconfigureRC()
> +{
> + if (m_isVbv)
> + {
> + m_param->rc.vbvBufferSize = x265_clip3(0, 2000000,
> m_param->rc.vbvBufferSize);
> + m_param->rc.vbvMaxBitrate = x265_clip3(0, 2000000,
> m_param->rc.vbvMaxBitrate);
> + if (m_param->rc.vbvMaxBitrate < m_param->rc.bitrate &&
> + m_param->rc.rateControlMode == X265_RC_ABR)
> + {
> + x265_log(m_param, X265_LOG_WARNING, "max bitrate less than
> average bitrate, assuming CBR\n");
> + m_param->rc.bitrate = m_param->rc.vbvMaxBitrate;
> + }
> +
> + if (m_param->rc.vbvBufferSize < (int)(m_param->rc.vbvMaxBitrate
> / m_fps))
> + {
> + m_param->rc.vbvBufferSize = (int)(m_param->rc.vbvMaxBitrate
> / m_fps);
> + x265_log(m_param, X265_LOG_WARNING, "VBV buffer size cannot
> be smaller than one frame, using %d kbit\n",
> + m_param->rc.vbvBufferSize);
> + }
> + int vbvBufferSize = m_param->rc.vbvBufferSize * 1000;
> + int vbvMaxBitrate = m_param->rc.vbvMaxBitrate * 1000;
> + m_bufferRate = vbvMaxBitrate / m_fps;
> + m_vbvMaxRate = vbvMaxBitrate;
> + m_bufferSize = vbvBufferSize;
> + m_singleFrameVbv = m_bufferRate * 1.1 > m_bufferSize;
> + }
> + if (m_param->rc.rateControlMode == X265_RC_CRF)
> + {
> + #define CRF_INIT_QP (int)m_param->rc.rfConstant
> + m_param->rc.bitrate = 0;
> + double baseCplx = m_ncu * (m_param->bframes ? 120 : 80);
> + double mbtree_offset = m_param->rc.cuTree ? (1.0 -
> m_param->rc.qCompress) * 13.5 : 0;
> + m_rateFactorConstant = pow(baseCplx, 1 - m_qCompress) /
> + x265_qp2qScale(m_param->rc.rfConstant + mbtree_offset);
> + if (m_param->rc.rfConstantMax)
> + {
> + m_rateFactorMaxIncrement = m_param->rc.rfConstantMax -
> m_param->rc.rfConstant;
> + if (m_rateFactorMaxIncrement <= 0)
> + {
> + x265_log(m_param, X265_LOG_WARNING, "CRF max must be
> greater than CRF\n");
> + m_rateFactorMaxIncrement = 0;
> + }
> + }
> + if (m_param->rc.rfConstantMin)
> + m_rateFactorMaxDecrement = m_param->rc.rfConstant -
> m_param->rc.rfConstantMin;
> + }
> + m_bitrate = m_param->rc.bitrate * 1000;
> +}
> +
> +
> void RateControl::initHRD(SPS& sps)
> {
> int vbvBufferSize = m_param->rc.vbvBufferSize * 1000;
> diff -r 08a05ca9fd16 -r 576ad673d9b3 source/encoder/ratecontrol.h
> --- a/source/encoder/ratecontrol.h Mon Mar 27 12:35:20 2017 +0530
> +++ b/source/encoder/ratecontrol.h Wed Feb 22 15:24:25 2017 +0530
> @@ -234,6 +234,7 @@
> RateControl(x265_param& p);
> bool init(const SPS& sps);
> void initHRD(SPS& sps);
> + void reconfigureRC();
>
> void setFinalFrameCount(int count);
> void terminate(); /* un-block all waiting functions so
> encoder may close */
> _______________________________________________
> x265-devel mailing list
> x265-devel at videolan.org
> https://mailman.videolan.org/listinfo/x265-devel
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mailman.videolan.org/pipermail/x265-devel/attachments/20170406/a100e997/attachment-0001.html>
More information about the x265-devel
mailing list