Pushed to master. On Fri, Jul 3, 2020 at 8:10 PM Niranjan Bala <niran...@multicorewareinc.com> wrote:
> From b64252405aa3160461f77e576864518aebaf5a24 Mon Sep 17 00:00:00 2001 > From: Niranjan <niran...@multicorewareinc.com> > Date: Wed, 1 Jul 2020 21:23:42 +0530 > Subject: [PATCH] Improve: Scenecut Aware Frame Quantizer Selection > > This patch does the following: > 1)Reduce bits for frames before the scenecut > 2)Refactor Scenecut Aware Frame Quantizer Selection > 3)Add option "--qp-delta-nonref" to set offset for > non-referenced inter frames(optional). > 4)Enables Scenecut Aware Frame Quantizer Selection > to run only with pass 2 > --- > doc/reST/cli.rst | 20 +++-- > source/CMakeLists.txt | 2 +- > source/common/frame.cpp | 1 + > source/common/frame.h | 2 + > source/common/param.cpp | 22 +++-- > source/encoder/encoder.cpp | 37 ++++++++- > source/encoder/ratecontrol.cpp | 126 +++++++++++++++++++---------- > source/encoder/ratecontrol.h | 4 +- > source/test/rate-control-tests.txt | 2 + > source/test/regression-tests.txt | 1 - > source/x265.h | 14 +++- > source/x265cli.cpp | 3 +- > source/x265cli.h | 3 +- > 13 files changed, 169 insertions(+), 68 deletions(-) > > diff --git a/doc/reST/cli.rst b/doc/reST/cli.rst > index 3b8a6e2e6..458b3a836 100644 > --- a/doc/reST/cli.rst > +++ b/doc/reST/cli.rst > @@ -1948,10 +1948,11 @@ Quality, rate control and rate distortion options > > .. option:: --scenecut-aware-qp, --no-scenecut-aware-qp > > - Enables a ratecontrol algorithm for reducing the bits spent on the > inter-frames > - within the :option:`--scenecut-window` after a scenecut by increasing > their QP > - without any deterioration in visual quality. It also increases the > quality of > - scenecut I-Frames by reducing their QP. Default disabled. > + It reduces the bits spent on the inter-frames within the > :option:`--scenecut-window` > + before and after a scenecut by increasing their QP in ratecontrol > pass2 algorithm > + without any deterioration in visual quality. If a scenecut falls > within the window, > + the QP of the inter-frames after this scenecut will not be modified. > + :option:`--scenecut-aware-qp` works only with --pass 2. Default > disabled. > > .. option:: --scenecut-window <integer> > > @@ -1961,12 +1962,21 @@ Quality, rate control and rate distortion options > > **Range of values:** 0 to 1000 > > -.. option:: --max-qp-delta <integer> > +.. option:: --qp-delta-ref <double> > > The offset by which QP is incremented for inter-frames > when :option:`--scenecut-aware-qp` is enabled. Default 5. > > **Range of values:** 0 to 10 > + > +.. option:: --qp-delta-nonref <double> > + > + The offset by which QP is incremented for non-referenced > + inter-frames when :option:`--scenecut-aware-qp` is enabled. > + The offset is computed from :option:`--qp-delta-ref` when it > + is not explicitly specified. > + > + **Range of values:** 0 to 10 > > Quantization Options > ==================== > diff --git a/source/CMakeLists.txt b/source/CMakeLists.txt > index ce127ce75..1d1f8cacf 100644 > --- a/source/CMakeLists.txt > +++ b/source/CMakeLists.txt > @@ -29,7 +29,7 @@ option(NATIVE_BUILD "Target the build CPU" OFF) > option(STATIC_LINK_CRT "Statically link C runtime for release builds" OFF) > mark_as_advanced(FPROFILE_USE FPROFILE_GENERATE NATIVE_BUILD) > # X265_BUILD must be incremented each time the public API is changed > -set(X265_BUILD 194) > +set(X265_BUILD 195) > configure_file("${PROJECT_SOURCE_DIR}/x265.def.in" > "${PROJECT_BINARY_DIR}/x265.def") > configure_file("${PROJECT_SOURCE_DIR}/x265_config.h.in" > diff --git a/source/common/frame.cpp b/source/common/frame.cpp > index 8940cea8c..255882a9d 100644 > --- a/source/common/frame.cpp > +++ b/source/common/frame.cpp > @@ -63,6 +63,7 @@ Frame::Frame() > m_thetaPic = NULL; > m_edgeBitPlane = NULL; > m_edgeBitPic = NULL; > + m_isInsideWindow = 0; > } > > bool Frame::create(x265_param *param, float* quantOffsets) > diff --git a/source/common/frame.h b/source/common/frame.h > index d96c1eeb2..dc5bbacf7 100644 > --- a/source/common/frame.h > +++ b/source/common/frame.h > @@ -141,6 +141,8 @@ public: > pixel* m_edgeBitPlane; > pixel* m_edgeBitPic; > > + int m_isInsideWindow; > + > Frame(); > > bool create(x265_param *param, float* quantOffsets); > diff --git a/source/common/param.cpp b/source/common/param.cpp > index 8c0498efc..dc9d23cdd 100644 > --- a/source/common/param.cpp > +++ b/source/common/param.cpp > @@ -180,7 +180,8 @@ void x265_param_default(x265_param* param) > param->bEnableFades = 0; > param->bEnableSceneCutAwareQp = 0; > param->scenecutWindow = 500; > - param->maxQpDelta = 5; > + param->refQpDelta = 5; > + param->nonRefQpDelta = param->refQpDelta + (SLICE_TYPE_DELTA * > param->refQpDelta); > > /* Intra Coding Tools */ > param->bEnableConstrainedIntra = 0; > @@ -1342,7 +1343,8 @@ int x265_param_parse(x265_param* p, const char* > name, const char* value) > OPT("fades") p->bEnableFades = atobool(value); > OPT("scenecut-aware-qp") p->bEnableSceneCutAwareQp = > atobool(value); > OPT("scenecut-window") p->scenecutWindow = atoi(value); > - OPT("max-qp-delta") p->maxQpDelta = atoi(value); > + OPT("qp-delta-ref") p->refQpDelta = atoi(value); > + OPT("qp-delta-nonref") p->nonRefQpDelta = atoi(value); > OPT("field") p->bField = atobool( value ); > OPT("cll") p->bEmitCLL = atobool(value); > OPT("frame-dup") p->bEnableFrameDuplication = atobool(value); > @@ -1768,10 +1770,17 @@ int x265_check_params(x265_param* param) > } > CHECK(param->selectiveSAO < 0 || param->selectiveSAO > 4, > "Invalid SAO tune level. Value must be between 0 and 4 > (inclusive)"); > + if (param->bEnableSceneCutAwareQp && !param->rc.bStatRead) > + { > + param->bEnableSceneCutAwareQp = 0; > + x265_log(param, X265_LOG_WARNING, "Disabling Scenecut Aware Frame > Quantizer Selection since it works only in pass 2\n"); > + } > CHECK(param->scenecutWindow < 0 || param->scenecutWindow > 1000, > "Invalid scenecut Window duration. Value must be between 0 and > 1000(inclusive)"); > - CHECK(param->maxQpDelta < 0 || param->maxQpDelta > 10, > - "Invalid maxQpDelta value. Value must be between 0 and 10 > (inclusive)"); > + CHECK(param->refQpDelta < 0 || param->refQpDelta > 10, > + "Invalid refQpDelta value. Value must be between 0 and 10 > (inclusive)"); > + CHECK(param->nonRefQpDelta < 0 || param->nonRefQpDelta > 10, > + "Invalid nonRefQpDelta value. Value must be between 0 and 10 > (inclusive)"); > for(int level = 0; level < 3; level++) > CHECK(param->hmeRange[level] < 0 || param->hmeRange[level] >= > 32768, > "Search Range for HME levels must be between 0 and 32768"); > @@ -2219,7 +2228,7 @@ char *x265_param2string(x265_param* p, int padx, int > pady) > s += sprintf(s, " qp-adaptation-range=%.2f", p->rc.qpAdaptationRange); > BOOL(p->bEnableSceneCutAwareQp, "scenecut-aware-qp"); > if (p->bEnableSceneCutAwareQp) > - s += sprintf(s, " scenecut-window=%d max-qp-delta=%d", > p->scenecutWindow, p->maxQpDelta); > + s += sprintf(s, " scenecut-window=%d qp-delta-ref=%f > qp-delta-nonref=%f", p->scenecutWindow, p->refQpDelta, p->nonRefQpDelta); > s += sprintf(s, "conformance-window-offsets right=%d bottom=%d", > p->confWinRightOffset, p->confWinBottomOffset); > s += sprintf(s, " decoder-max-rate=%d", p->decoderVbvMaxRate); > #undef BOOL > @@ -2571,7 +2580,8 @@ void x265_copy_params(x265_param* dst, x265_param* > src) > dst->bEnableFades = src->bEnableFades; > dst->bEnableSceneCutAwareQp = src->bEnableSceneCutAwareQp; > dst->scenecutWindow = src->scenecutWindow; > - dst->maxQpDelta = src->maxQpDelta; > + dst->refQpDelta = src->refQpDelta; > + dst->nonRefQpDelta = src->nonRefQpDelta; > dst->bField = src->bField; > > dst->confWinRightOffset = src->confWinRightOffset; > diff --git a/source/encoder/encoder.cpp b/source/encoder/encoder.cpp > index af5e7712f..cf7bfb98d 100644 > --- a/source/encoder/encoder.cpp > +++ b/source/encoder/encoder.cpp > @@ -1793,6 +1793,7 @@ int Encoder::encode(const x265_picture* pic_in, > x265_picture* pic_out) > inFrame->m_lowres.bScenecut = false; > inFrame->m_lowres.satdCost = (int64_t)-1; > inFrame->m_lowresInit = false; > + inFrame->m_isInsideWindow = 0; > } > > /* Copy input picture into a Frame and PicYuv, send to lookahead > */ > @@ -1808,6 +1809,23 @@ int Encoder::encode(const x265_picture* pic_in, > x265_picture* pic_out) > if (m_param->radl && m_param->keyframeMax != > m_param->keyframeMin) > inFrame->m_lowres.m_bIsHardScenecut = isHardSC; > } > + > + if (m_param->bEnableSceneCutAwareQp && m_param->rc.bStatRead) > + { > + RateControlEntry * rcEntry = NULL; > + rcEntry = &(m_rateControl->m_rce2Pass[inFrame->m_poc]); > + if(rcEntry->scenecut) > + { > + int backwardWindow = X265_MIN(int((p->fpsNum / > p->fpsDenom) / 10), p->lookaheadDepth); > + for (int i = 1; i <= backwardWindow; i++) > + { > + int frameNum = inFrame->m_poc - i; > + Frame * frame = > m_lookahead->m_inputQueue.getPOC(frameNum); > + if (frame) > + frame->m_isInsideWindow = BACKWARD_WINDOW; > + } > + } > + } > if (m_param->bHistBasedSceneCut && m_param->analysisSave) > { > memcpy(inFrame->m_analysisData.edgeHist, m_curEdgeHist, > EDGE_BINS * sizeof(int32_t)); > @@ -2224,8 +2242,23 @@ int Encoder::encode(const x265_picture* pic_in, > x265_picture* pic_out) > frameEnc = m_lookahead->getDecidedPicture(); > if (frameEnc && !pass && (!m_param->chunkEnd || > (m_encodedFrameNum < m_param->chunkEnd))) > { > - if (m_param->bEnableSceneCutAwareQp && > frameEnc->m_lowres.bScenecut) > - m_rateControl->m_lastScenecut = frameEnc->m_poc; > + if (m_param->bEnableSceneCutAwareQp && m_param->rc.bStatRead) > + { > + RateControlEntry * rcEntry; > + rcEntry = &(m_rateControl->m_rce2Pass[frameEnc->m_poc]); > + > + if (rcEntry->scenecut) > + { > + if (m_rateControl->m_lastScenecut == -1) > + m_rateControl->m_lastScenecut = frameEnc->m_poc; > + else > + { > + int maxWindowSize = int((m_param->scenecutWindow > / 1000.0) * (m_param->fpsNum / m_param->fpsDenom) + 0.5); > + if (frameEnc->m_poc > > (m_rateControl->m_lastScenecut + maxWindowSize)) > + m_rateControl->m_lastScenecut = > frameEnc->m_poc; > + } > + } > + } > > if (m_param->analysisMultiPassRefine || > m_param->analysisMultiPassDistortion) > { > diff --git a/source/encoder/ratecontrol.cpp > b/source/encoder/ratecontrol.cpp > index 33e5a35a1..32b24c23c 100644 > --- a/source/encoder/ratecontrol.cpp > +++ b/source/encoder/ratecontrol.cpp > @@ -580,7 +580,7 @@ bool RateControl::init(const SPS& sps) > double totalQpAq = 0; > for (int i = 0; i < m_numEntries; i++) > { > - RateControlEntry *rce; > + RateControlEntry *rce, *rcePocOrder; > int frameNumber; > int encodeOrder; > char picType; > @@ -597,13 +597,16 @@ bool RateControl::init(const SPS& sps) > return false; > } > rce = &m_rce2Pass[encodeOrder]; > + rcePocOrder = &m_rce2Pass[frameNumber]; > m_encOrder[frameNumber] = encodeOrder; > if (!m_param->bMultiPassOptRPS) > { > - e += sscanf(p, " in:%*d out:%*d type:%c q:%lf > q-aq:%lf q-noVbv:%lf q-Rceq:%lf tex:%d mv:%d misc:%d icu:%lf pcu:%lf > scu:%lf", > + int scenecut = 0; > + e += sscanf(p, " in:%*d out:%*d type:%c q:%lf > q-aq:%lf q-noVbv:%lf q-Rceq:%lf tex:%d mv:%d misc:%d icu:%lf pcu:%lf > scu:%lf sc:%d", > &picType, &qpRc, &qpAq, &qNoVbv, &qRceq, > &rce->coeffBits, > &rce->mvBits, &rce->miscBits, &rce->iCuCount, > &rce->pCuCount, > - &rce->skipCuCount); > + &rce->skipCuCount, &scenecut); > + rcePocOrder->scenecut = scenecut != 0; > } > else > { > @@ -1311,7 +1314,8 @@ int RateControl::rateControlStart(Frame* curFrame, > RateControlEntry* rce, Encode > copyRceData(rce, &m_rce2Pass[index]); > } > rce->isActive = true; > - rce->scenecut = false; > + if (!m_param->rc.bStatRead) > + rce->scenecut = false; > rce->isFadeEnd = curFrame->m_lowres.bIsFadeEnd; > bool isRefFrameScenecut = m_sliceType!= I_SLICE && > m_curSlice->m_refFrameList[0][0]->m_lowres.bScenecut; > m_isFirstMiniGop = m_sliceType == I_SLICE ? true : m_isFirstMiniGop; > @@ -1856,11 +1860,12 @@ double RateControl::rateEstimateQscale(Frame* > curFrame, RateControlEntry *rce) > { > double lqmin = m_lmin[m_sliceType]; > double lqmax = m_lmax[m_sliceType]; > - qScale = scenecutAwareQp(curFrame, qScale); > + qScale = scenecutAwareMasking(curFrame, qScale); > qScale = x265_clip3(lqmin, lqmax, qScale); > q = x265_qScale2qp(qScale); > rce->qpNoVbv = q; > } > + > if (m_isVbv) > { > lmin = m_lastQScaleFor[P_SLICE] / m_lstep; > @@ -1971,6 +1976,16 @@ double RateControl::rateEstimateQscale(Frame* > curFrame, RateControlEntry *rce) > m_avgPFrameQp = (m_avgPFrameQp + rce->qpNoVbv) / 2; > } > > + /* Scenecut Aware QP offsets*/ > + if (m_param->bEnableSceneCutAwareQp) > + { > + double qmin = m_lmin[m_sliceType]; > + double qmax = m_lmax[m_sliceType]; > + q = scenecutAwareMasking(curFrame, q); > + q = x265_clip3(qmin, qmax, q); > + rce->qpNoVbv = x265_qScale2qp(q); > + } > + > if (m_isVbv) > { > /* Do not overflow vbv */ > @@ -2120,13 +2135,12 @@ double RateControl::rateEstimateQscale(Frame* > curFrame, RateControlEntry *rce) > { > double qmin = m_lmin[m_sliceType]; > double qmax = m_lmax[m_sliceType]; > - q = scenecutAwareQp(curFrame, q); > + q = scenecutAwareMasking(curFrame, q); > q = x265_clip3(qmin, qmax, q); > rce->qpNoVbv = x265_qScale2qp(q); > } > q = clipQscale(curFrame, rce, q); > > - > if (m_2pass) > rce->frameSizePlanned = qScale2bits(rce, q); > else > @@ -2964,7 +2978,7 @@ int RateControl::writeRateControlFrameStats(Frame* > curFrame, RateControlEntry* r > if (!curEncData.m_param->bMultiPassOptRPS) > { > if (fprintf(m_statFileOut, > - "in:%d out:%d type:%c q:%.2f q-aq:%.2f q-noVbv:%.2f > q-Rceq:%.2f tex:%d mv:%d misc:%d icu:%.2f pcu:%.2f scu:%.2f ;\n", > + "in:%d out:%d type:%c q:%.2f q-aq:%.2f q-noVbv:%.2f > q-Rceq:%.2f tex:%d mv:%d misc:%d icu:%.2f pcu:%.2f scu:%.2f sc:%d ;\n", > rce->poc, rce->encodeOrder, > cType, curEncData.m_avgQpRc, curEncData.m_avgQpAq, > rce->qpNoVbv, rce->qRceq, > @@ -2973,7 +2987,8 @@ int RateControl::writeRateControlFrameStats(Frame* > curFrame, RateControlEntry* r > curFrame->m_encData->m_frameStats.miscBits, > curFrame->m_encData->m_frameStats.percent8x8Intra * m_ncu, > curFrame->m_encData->m_frameStats.percent8x8Inter * m_ncu, > - curFrame->m_encData->m_frameStats.percent8x8Skip * m_ncu) < > 0) > + curFrame->m_encData->m_frameStats.percent8x8Skip * m_ncu, > + curFrame->m_lowres.bScenecut) < 0) > goto writeFailure; > } > else > @@ -3150,52 +3165,75 @@ void RateControl::splitbUsed(char bused[], > RateControlEntry *rce) > } > } > > -double RateControl::scenecutAwareQp(Frame* curFrame, double q) > +double RateControl::scenecutAwareMasking(Frame* curFrame, double q) > { > double qp = x265_qScale2qp(q); > uint32_t maxWindowSize = uint32_t((m_param->scenecutWindow / 1000.0) > * (m_param->fpsNum / m_param->fpsDenom) + 0.5); > uint32_t windowSize = maxWindowSize / 3; > int lastScenecut = m_top->m_rateControl->m_lastScenecut; > int lastIFrame = m_top->m_rateControl->m_lastScenecutAwareIFrame; > - double maxQpDelta = double(m_param->maxQpDelta); > - double iSliceDelta = double(I_SLICE_DELTA); > - double sliceTypeDelta = SLICE_TYPE_DELTA * maxQpDelta; > - double window2Delta = WINDOW2_DELTA * maxQpDelta; > - double window3Delta = WINDOW3_DELTA * maxQpDelta; > + double refQpDelta = double(m_param->refQpDelta); > + double nonRefQpDelta = double(m_param->nonRefQpDelta); > + double sliceTypeDelta = SLICE_TYPE_DELTA * refQpDelta; > + double window2Delta = WINDOW2_DELTA * refQpDelta; > + double window3Delta = WINDOW3_DELTA * refQpDelta; > > - bool isFrameInsideWindow = curFrame->m_poc > lastScenecut && > curFrame->m_poc <= (lastScenecut + int(maxWindowSize)); > - > - if (isFrameInsideWindow && > IS_X265_TYPE_I(curFrame->m_lowres.sliceType)) > - { > - m_top->m_rateControl->m_lastScenecutAwareIFrame = curFrame->m_poc; > - } > - else if (isFrameInsideWindow && (curFrame->m_lowres.sliceType == > X265_TYPE_P)) > + if (curFrame->m_poc > lastScenecut && curFrame->m_poc <= > (lastScenecut + int(maxWindowSize))) > + curFrame->m_isInsideWindow = FORWARD_WINDOW; > + if (curFrame->m_isInsideWindow == FORWARD_WINDOW) > { > - if (!(lastIFrame > lastScenecut && lastIFrame <= (lastScenecut + > int(maxWindowSize)) > - && curFrame->m_poc > lastIFrame)) > + if (IS_X265_TYPE_I(curFrame->m_lowres.sliceType) || > curFrame->m_lowres.bScenecut) > { > - qp += maxQpDelta - sliceTypeDelta; > - if (((curFrame->m_poc) > (lastScenecut + int(windowSize))) && > ((curFrame->m_poc) <= (lastScenecut + 2 * int(windowSize)))) > - qp -= window2Delta; > - else if (curFrame->m_poc > lastScenecut + 2 * int(windowSize)) > - qp -= window3Delta; > + m_top->m_rateControl->m_lastScenecutAwareIFrame = > curFrame->m_poc; > } > - } > - else if (isFrameInsideWindow && > IS_X265_TYPE_B(curFrame->m_lowres.sliceType)) > - { > - if (!(lastIFrame > lastScenecut && lastIFrame <= (lastScenecut + > int(maxWindowSize)) > - && curFrame->m_poc > lastIFrame)) > + else if (curFrame->m_lowres.sliceType == X265_TYPE_P) > + { > + if (!(lastIFrame > lastScenecut && lastIFrame <= > (lastScenecut + int(maxWindowSize)) > + && curFrame->m_poc >= lastIFrame)) > + { > + qp += refQpDelta - sliceTypeDelta; > + if (((curFrame->m_poc) > (lastScenecut + > int(windowSize))) && ((curFrame->m_poc) <= (lastScenecut + 2 * > int(windowSize)))) > + qp -= window2Delta; > + else if (curFrame->m_poc > lastScenecut + 2 * > int(windowSize)) > + qp -= window3Delta; > + } > + } > + else if (curFrame->m_lowres.sliceType == X265_TYPE_BREF) > { > - qp += maxQpDelta; > - if (curFrame->m_lowres.sliceType == X265_TYPE_B) > - qp += sliceTypeDelta; > - if (((curFrame->m_poc) > (lastScenecut + int(windowSize))) && > ((curFrame->m_poc) <= (lastScenecut + 2 * int(windowSize)))) > - qp -= window2Delta; > - else if (curFrame->m_poc > lastScenecut + 2 * int(windowSize)) > - qp -= window3Delta; > + if (!(lastIFrame > lastScenecut && lastIFrame <= > (lastScenecut + int(maxWindowSize)) > + && curFrame->m_poc >= lastIFrame)) > + { > + qp += refQpDelta; > + if (((curFrame->m_poc) > (lastScenecut + > int(windowSize))) && ((curFrame->m_poc) <= (lastScenecut + 2 * > int(windowSize)))) > + qp -= window2Delta; > + else if (curFrame->m_poc > lastScenecut + 2 * > int(windowSize)) > + qp -= window3Delta; > + } > + } > + else if (curFrame->m_lowres.sliceType == X265_TYPE_B) > + { > + if (!(lastIFrame > lastScenecut && lastIFrame <= > (lastScenecut + int(maxWindowSize)) > + && curFrame->m_poc >= lastIFrame)) > + { > + qp += nonRefQpDelta; > + if (((curFrame->m_poc) > (lastScenecut + > int(windowSize))) && ((curFrame->m_poc) <= (lastScenecut + 2 * > int(windowSize)))) > + qp -= window2Delta; > + else if (curFrame->m_poc > lastScenecut + 2 * > int(windowSize)) > + qp -= window3Delta; > + } > } > } > - if (IS_X265_TYPE_I(curFrame->m_lowres.sliceType) && > curFrame->m_lowres.bScenecut) > - qp = qp - iSliceDelta; > - return x265_qp2qScale(qp); > + else if (curFrame->m_isInsideWindow == BACKWARD_WINDOW) > + { > + refQpDelta -= window3Delta; > + nonRefQpDelta -= window3Delta; > + if (curFrame->m_lowres.sliceType == X265_TYPE_P) > + qp += refQpDelta - sliceTypeDelta; > + else if (curFrame->m_lowres.sliceType == X265_TYPE_BREF) > + qp += refQpDelta; > + else if (curFrame->m_lowres.sliceType == X265_TYPE_B) > + qp += nonRefQpDelta; > + } > + > + return x265_qp2qScale(qp); > } > diff --git a/source/encoder/ratecontrol.h b/source/encoder/ratecontrol.h > index 118191bbf..809e0c620 100644 > --- a/source/encoder/ratecontrol.h > +++ b/source/encoder/ratecontrol.h > @@ -47,8 +47,6 @@ struct SPS; > #define CLIP_DURATION(f) x265_clip3(MIN_FRAME_DURATION, > MAX_FRAME_DURATION, f) > > /*Scenecut Aware QP*/ > -#define I_SLICE_DELTA 2 /* Subtracted from base QP for the > scenecut I frames*/ > -#define SLICE_TYPE_DELTA 0.3 /* The offset decremented or > incremented for P-frames or b-frames respectively*/ > #define WINDOW1_DELTA 0 /* The offset for the frames coming > in the window-1*/ > #define WINDOW2_DELTA 0.3 /* The offset for the frames coming > in the window-2*/ > #define WINDOW3_DELTA 0.6 /* The offset for the frames coming > in the window-3*/ > @@ -271,7 +269,7 @@ public: > int writeRateControlFrameStats(Frame* curFrame, RateControlEntry* > rce); > bool initPass2(); > > - double scenecutAwareQp(Frame* curFrame, double q); > + double scenecutAwareMasking(Frame* curFrame, double q); > > protected: > > diff --git a/source/test/rate-control-tests.txt > b/source/test/rate-control-tests.txt > index 5b1f9992a..eed92f809 100644 > --- a/source/test/rate-control-tests.txt > +++ b/source/test/rate-control-tests.txt > @@ -44,6 +44,8 @@ CrowdRun_1920x1080_50_10bit_422.yuv,--preset superfast > --bitrate 2500 --pass 1 - > RaceHorses_416x240_30_10bit.yuv,--preset medium --crf 26 --vbv-maxrate > 1000 --vbv-bufsize 1000 --pass 1::--preset fast --bitrate 1000 > --vbv-maxrate 1000 --vbv-bufsize 700 --pass 3 -F4::--preset slow --bitrate > 500 --vbv-maxrate 500 --vbv-bufsize 700 --pass 2 -F4 > sita_1920x1080_30.yuv, --preset ultrafast --crf 20 --no-cutree --keyint > 50 --min-keyint 50 --no-open-gop --pass 1 --vbv-bufsize 7000 --vbv-maxrate > 5000:: --preset ultrafast --crf 20 --no-cutree --keyint 50 --min-keyint 50 > --no-open-gop --pass 2 --vbv-bufsize 7000 --vbv-maxrate 5000 > --repeat-headers > sita_1920x1080_30.yuv, --preset medium --crf 20 --no-cutree --keyint 50 > --min-keyint 50 --no-open-gop --pass 1 --vbv-bufsize 7000 --vbv-maxrate > 5000 --repeat-headers --multi-pass-opt-rps:: --preset medium --crf 20 > --no-cutree --keyint 50 --min-keyint 50 --no-open-gop --pass 2 > --vbv-bufsize 7000 --vbv-maxrate 5000 --repeat-headers --multi-pass-opt-rps > +sintel_trailer_2k_1920x1080_24.yuv,--preset medium --bitrate 6000 > --no-cutree --aq-mode 0 --pass 1::--preset medium --bitrate 6000 > --no-cutree --aq-mode 0 --pass 2 --scenecut-aware-qp > +sintel_trailer_2k_1920x1080_24.yuv,--preset medium --bitrate 6000 > --no-cutree --aq-mode 0 --hist-scenecut --pass 1::--preset medium --bitrate > 6000 --no-cutree --aq-mode 0 --hist-scenecut --pass 2 --scenecut-aware-qp > --qp-delta-nonref 8 > > # multi-pass rate control and analysis > ducks_take_off_1080p50.y4m,--bitrate 6000 --pass 1 > --multi-pass-opt-analysis --hash 1 --ssim --psnr:: --bitrate 6000 --pass > 2 --multi-pass-opt-analysis --hash 1 --ssim --psnr > diff --git a/source/test/regression-tests.txt > b/source/test/regression-tests.txt > index 97e6e5b11..22673d469 100644 > --- a/source/test/regression-tests.txt > +++ b/source/test/regression-tests.txt > @@ -158,7 +158,6 @@ ducks_take_off_420_720p50.y4m,--preset medium > --aq-mode 4 --crf 22 --no-cutree > ducks_take_off_420_1_720p50.y4m,--preset medium --selective-sao 4 --sao > --crf 20 > Traffic_4096x2048_30p.y4m, --preset medium --frame-dup --dup-threshold 60 > --hrd --bitrate 10000 --vbv-bufsize 15000 --vbv-maxrate 12000 > Kimono1_1920x1080_24_400.yuv,--preset superfast --qp 28 --zones 0,139,q=32 > -Island_960x540_24.yuv,--no-cutree --aq-mode 0 --bitrate 6000 > --scenecut-aware-qp > sintel_trailer_2k_1920x1080_24.yuv, --preset medium --hist-scenecut > --hist-threshold 0.02 --frame-dup --dup-threshold 60 --hrd --bitrate 10000 > --vbv-bufsize 15000 --vbv-maxrate 12000 > sintel_trailer_2k_1920x1080_24.yuv, --preset medium --hist-scenecut > --hist-threshold 0.02 > sintel_trailer_2k_1920x1080_24.yuv, --preset ultrafast --hist-scenecut > --hist-threshold 0.02 > diff --git a/source/x265.h b/source/x265.h > index 32feb2bca..0ffa600b0 100644 > --- a/source/x265.h > +++ b/source/x265.h > @@ -607,6 +607,10 @@ typedef enum > #define X265_ANALYSIS_SAVE 1 > #define X265_ANALYSIS_LOAD 2 > > +#define SLICE_TYPE_DELTA 0.3 /* The offset decremented or > incremented for P-frames or b-frames respectively*/ > +#define BACKWARD_WINDOW 1 /* Scenecut window before a scenecut */ > +#define FORWARD_WINDOW 2 /* Scenecut window after a scenecut */ > + > typedef struct x265_cli_csp > { > int planes; > @@ -1843,9 +1847,8 @@ typedef struct x265_param > Default 1 (Enabled). API only. */ > int bResetZoneConfig; > > - /* Enables a ratecontrol algorithm for reducing the bits spent on the > inter-frames > - * within the scenecutWindow after a scenecut by increasing their QP > without > - * any deterioration in visual quality. It also increases the quality > of scenecut I-Frames by reducing their QP. > + /* It reduces the bits spent on the inter-frames within the > scenecutWindow before and after a scenecut > + * by increasing their QP in ratecontrol pass2 algorithm without any > deterioration in visual quality. > * Default is disabled. */ > int bEnableSceneCutAwareQp; > > @@ -1855,7 +1858,10 @@ typedef struct x265_param > > /* The offset by which QP is incremented for inter-frames when > bEnableSceneCutAwareQp is set. > * Default is +5. */ > - int maxQpDelta; > + double refQpDelta; > + > + /* The offset by which QP is incremented for non-referenced > inter-frames when bEnableSceneCutAwareQp is set. */ > + double nonRefQpDelta; > > /* A genuine threshold used for histogram based scene cut detection. > * This threshold determines whether a frame is a scenecut or not > diff --git a/source/x265cli.cpp b/source/x265cli.cpp > index b53dc2b0b..b198e55c2 100644 > --- a/source/x265cli.cpp > +++ b/source/x265cli.cpp > @@ -179,7 +179,8 @@ namespace X265_NS { > H0(" --[no-]fades Enable detection and > handling of fade-in regions. Default %s\n", OPT(param->bEnableFades)); > H1(" --[no-]scenecut-aware-qp Enable increasing QP for > frames inside the scenecut window after scenecut. Default %s\n", > OPT(param->bEnableSceneCutAwareQp)); > H1(" --scenecut-window <0..1000> QP incremental duration(in > milliseconds) when scenecut-aware-qp is enabled. Default %d\n", > param->scenecutWindow); > - H1(" --max-qp-delta <0..10> QP offset to increment with > base QP for inter-frames. Default %d\n", param->maxQpDelta); > + H1(" --qp-delta-ref <0..10> QP offset to increment with > base QP for inter-frames. Default %f\n", param->refQpDelta); > + H1(" --qp-delta-nonref <0..10> QP offset to increment with > base QP for non-referenced inter-frames. Default %f\n", > param->nonRefQpDelta); > H0(" --radl <integer> Number of RADL pictures > allowed in front of IDR. Default %d\n", param->radl); > H0(" --intra-refresh Use Periodic Intra Refresh > instead of IDR frames\n"); > H0(" --rc-lookahead <integer> Number of frames for > frame-type lookahead (determines encoder latency) Default %d\n", > param->lookaheadDepth); > diff --git a/source/x265cli.h b/source/x265cli.h > index 08f5d3d9e..311f06935 100644 > --- a/source/x265cli.h > +++ b/source/x265cli.h > @@ -151,7 +151,8 @@ static const struct option long_options[] = > { "scenecut-aware-qp", no_argument, NULL, 0 }, > { "no-scenecut-aware-qp", no_argument, NULL, 0 }, > { "scenecut-window",required_argument, NULL, 0 }, > - { "max-qp-delta", required_argument, NULL, 0 }, > + { "qp-delta-ref", required_argument, NULL, 0 }, > + { "qp-delta-nonref",required_argument, NULL, 0 }, > { "radl", required_argument, NULL, 0 }, > { "ctu-info", required_argument, NULL, 0 }, > { "intra-refresh", no_argument, NULL, 0 }, > -- > 2.18.0.windows.1 > > > Thanks & Regards > *Niranjan Kumar B* > Video Codec Engineer > Media & AI Analytics > +91 958 511 1449 > <https://multicorewareinc.com/> > >> _______________________________________________ > x265-devel mailing list > x265-devel@videolan.org > https://mailman.videolan.org/listinfo/x265-devel > -- Regards, *Aruna Matheswaran,* Video Codec Engineer, Media & AI analytics BU,
_______________________________________________ x265-devel mailing list x265-devel@videolan.org https://mailman.videolan.org/listinfo/x265-devel