---------- Forwarded message --------- From: Liwei Wang <[email protected]> Date: Sun, Sep 26, 2021 at 11:44 AM Subject: Re: [x265] [PATCH] encoding only the focused frames in the crf 2 pass To: Dakshinya T R S <[email protected]> Cc: Mahesh Pittala <[email protected]>
On Fri, Sep 24, 2021 at 1:34 PM Dakshinya T R S < [email protected]> wrote: > From d4ac086b18c41e6d146cd70524c581138b1186ec Mon Sep 17 00:00:00 2001 > From: lwWang <[email protected]> > Date: Wed, 15 Sep 2021 10:39:51 +0800 > Subject: [PATCH 1/2] encoding only the focused frames in the crf 2 pass > > --- > source/common/frame.h | 1 + > source/common/framedata.cpp | 2 +- > source/common/param.cpp | 1 + > source/encoder/encoder.cpp | 1 + > source/encoder/ratecontrol.cpp | 240 ++++++++++++++++++--------------- > source/encoder/ratecontrol.h | 3 + > source/x265.h | 3 + > 7 files changed, 138 insertions(+), 113 deletions(-) > > diff --git a/source/common/frame.h b/source/common/frame.h > index dc5bbacf7..ac1185e81 100644 > --- a/source/common/frame.h > +++ b/source/common/frame.h > @@ -70,6 +70,7 @@ struct RcStats > double count[4]; > double offset[4]; > double bufferFillFinal; > + int64_t currentSatd; > }; > > class Frame > diff --git a/source/common/framedata.cpp b/source/common/framedata.cpp > index c77b017a8..70af8a248 100644 > --- a/source/common/framedata.cpp > +++ b/source/common/framedata.cpp > @@ -62,7 +62,7 @@ bool FrameData::create(const x265_param& param, const > SPS& sps, int csp) > } > else > return false; > - CHECKED_MALLOC_ZERO(m_cuStat, RCStatCU, sps.numCUsInFrame); > + CHECKED_MALLOC_ZERO(m_cuStat, RCStatCU, sps.numCUsInFrame + 1); > [AM] What is the significance of this additional memory? *[LW] to fix the random crush issue(heap corruption)* > CHECKED_MALLOC(m_rowStat, RCStatRow, sps.numCuInHeight); > reinit(sps); > > diff --git a/source/common/param.cpp b/source/common/param.cpp > index 6751e0aa7..2c1583d93 100755 > --- a/source/common/param.cpp > +++ b/source/common/param.cpp > @@ -282,6 +282,7 @@ void x265_param_default(x265_param* param) > param->rc.bStatRead = 0; > param->rc.bStatWrite = 0; > param->rc.statFileName = NULL; > + param->rc.bEncFocusedFramesOnly = 0; > param->rc.complexityBlur = 20; > param->rc.qblur = 0.5; > param->rc.zoneCount = 0; > diff --git a/source/encoder/encoder.cpp b/source/encoder/encoder.cpp > index dee8fd85d..cc014a740 100644 > --- a/source/encoder/encoder.cpp > +++ b/source/encoder/encoder.cpp > @@ -2249,6 +2249,7 @@ int Encoder::encode(const x265_picture* pic_in, > x265_picture* pic_out) > outFrame->m_rcData->iCuCount = > outFrame->m_encData->m_frameStats.percent8x8Intra * m_rateControl->m_ncu; > outFrame->m_rcData->pCuCount = > outFrame->m_encData->m_frameStats.percent8x8Inter * m_rateControl->m_ncu; > outFrame->m_rcData->skipCuCount = > outFrame->m_encData->m_frameStats.percent8x8Skip * m_rateControl->m_ncu; > + outFrame->m_rcData->currentSatd = > curEncoder->m_rce.coeffBits; > } > > /* Allow this frame to be recycled if no frame encoders are > using it for reference */ > diff --git a/source/encoder/ratecontrol.cpp > b/source/encoder/ratecontrol.cpp > index a4756de39..2c211022d 100644 > --- a/source/encoder/ratecontrol.cpp > +++ b/source/encoder/ratecontrol.cpp > @@ -1002,123 +1002,106 @@ bool RateControl::initPass2() > uint64_t allAvailableBits = uint64_t(m_param->rc.bitrate * 1000. * > m_numEntries * m_frameDuration); > int startIndex, framesCount, endIndex; > int fps = X265_MIN(m_param->keyframeMax, (int)(m_fps + 0.5)); > + int distance = fps << 1; > + distance = distance > m_param->keyframeMax ? (m_param->keyframeMax << > 1) : m_param->keyframeMax; > startIndex = endIndex = framesCount = 0; > - int diffQp = 0; > double targetBits = 0; > double expectedBits = 0; > - for (startIndex = m_start, endIndex = m_start; endIndex < > m_numEntries; endIndex++) > + double targetBits2 = 0; > + double expectedBits2 = 0; > + double cpxSum = 0; > + double cpxSum2 = 0; > + > + if (m_param->rc.rateControlMode == X265_RC_ABR) > { > - allConstBits += m_rce2Pass[endIndex].miscBits; > - allCodedBits += m_rce2Pass[endIndex].coeffBits + > m_rce2Pass[endIndex].mvBits; > - if (m_param->rc.rateControlMode == X265_RC_CRF) > + for (startIndex = m_start, endIndex = m_start; endIndex < > m_numEntries; endIndex++) > { > - framesCount = endIndex - startIndex + 1; > - diffQp += int (m_rce2Pass[endIndex].qpaRc - > m_rce2Pass[endIndex].qpNoVbv); > - if (framesCount > fps) > - diffQp -= int (m_rce2Pass[endIndex - fps].qpaRc - > m_rce2Pass[endIndex - fps].qpNoVbv); > - if (framesCount >= fps) > - { > - if (diffQp >= 1) > - { > - if (!m_isQpModified && endIndex > fps) > - { > - double factor = 2; > - double step = 0; > - if (endIndex + fps >= m_numEntries) > - { > - m_start = endIndex - (endIndex % fps); > - return true; > - } > - for (int start = endIndex + 1; start <= endIndex > + fps && start < m_numEntries; start++) > - { > - RateControlEntry *rce = &m_rce2Pass[start]; > - targetBits += qScale2bits(rce, > x265_qp2qScale(rce->qpNoVbv)); > - expectedBits += qScale2bits(rce, rce->qScale); > - } > - if (expectedBits < 0.95 * targetBits) > - { > - m_isQpModified = true; > - m_isGopReEncoded = true; > - while (endIndex + fps < m_numEntries) > - { > - step = pow(2, factor / 6.0); > - expectedBits = 0; > - for (int start = endIndex + 1; start <= > endIndex + fps; start++) > - { > - RateControlEntry *rce = > &m_rce2Pass[start]; > - rce->newQScale = rce->qScale / step; > - X265_CHECK(rce->newQScale >= 0, "new > Qscale is negative\n"); > - expectedBits += qScale2bits(rce, > rce->newQScale); > - rce->newQp = > x265_qScale2qp(rce->newQScale); > - } > - if (expectedBits >= targetBits && step > > 1) > - factor *= 0.90; > - else > - break; > - } > - > - if (m_isVbv && endIndex + fps < m_numEntries) > - if (!vbv2Pass((uint64_t)targetBits, > endIndex + fps, endIndex + 1)) > - return false; > - > - targetBits = 0; > - expectedBits = 0; > - > - for (int start = endIndex - fps + 1; start <= > endIndex; start++) > - { > - RateControlEntry *rce = > &m_rce2Pass[start]; > - targetBits += qScale2bits(rce, > x265_qp2qScale(rce->qpNoVbv)); > - } > - while (1) > - { > - step = pow(2, factor / 6.0); > - expectedBits = 0; > - for (int start = endIndex - fps + 1; > start <= endIndex; start++) > - { > - RateControlEntry *rce = > &m_rce2Pass[start]; > - rce->newQScale = rce->qScale * step; > - X265_CHECK(rce->newQScale >= 0, "new > Qscale is negative\n"); > - expectedBits += qScale2bits(rce, > rce->newQScale); > - rce->newQp = > x265_qScale2qp(rce->newQScale); > - } > - if (expectedBits > targetBits && step > 1) > - factor *= 1.1; > - else > - break; > - } > - if (m_isVbv) > - if (!vbv2Pass((uint64_t)targetBits, > endIndex, endIndex - fps + 1)) > - return false; > - diffQp = 0; > - m_reencode = endIndex - fps + 1; > - endIndex = endIndex + fps; > - startIndex = endIndex + 1; > - m_start = startIndex; > - targetBits = expectedBits = 0; > - } > - else > - targetBits = expectedBits = 0; > - } > - } > - else > - m_isQpModified = false; > - } > + allConstBits += m_rce2Pass[endIndex].miscBits; > + allCodedBits += m_rce2Pass[endIndex].coeffBits + > m_rce2Pass[endIndex].mvBits; > } > - } > > - if (m_param->rc.rateControlMode == X265_RC_ABR) > - { > if (allAvailableBits < allConstBits) > { > x265_log(m_param, X265_LOG_ERROR, "requested bitrate is too > low. estimated minimum is %d kbps\n", > - (int)(allConstBits * m_fps / framesCount * 1000.)); > + (int)(allConstBits * m_fps / framesCount * 1000.)); > return false; > } > if (!analyseABR2Pass(allAvailableBits)) > return false; > + > + return true; > + } > + > + if (m_param->rc.rateControlMode != X265_RC_CRF) > + { > [AM] This condition will never hit. Please clarify why this is required. *[LW] Yeah, you're right. It will never hit. I will remove this check.Thanks* > + return true; > } > > - m_start = X265_MAX(m_start, endIndex - fps); > + if (m_isQpModified) > + { > [AM] This condition will always hit. Please clarify why this check is required. *[LW] m_isQpModified may be false. And in the uhdkit, the cappedvbr would modify its value.* [AM] Please include a conformance check in Encoder::configure() to disable m_param->rc.bEncFocusedFramesOnly if either bStatRead or CRF is disabled. [*LW] OK. I will add it. By the way, **bEncFocusedFramesOnly has been set to be false by default in the x265_param_default()* [AM] Update X265_BUILD, add help document, and add an entry for the new param in info SEI. Is this a param?API only option? If so, clarify that in the document. Else, add a test CLI. *[LW] OK. However, **bEncFocusedFramesOnly would only be used together with cappedvbr in uhdkit. It could not be used alone in x25. So maybe it is better to move it from the x265_param to the encoder or rateontrol?* > /* temporally blur quants */ > double qblur; > On Fri, Sep 24, 2021 at 5:02 PM Dakshinya T R S < [email protected]> wrote: > > > ---------- Forwarded message --------- > From: Aruna Matheswaran <[email protected]> > Date: Fri, Sep 24, 2021 at 2:26 PM > Subject: Re: [x265] [PATCH] encoding only the focused frames in the crf 2 > pass > To: Development for x265 <[email protected]> > > > > > On Fri, Sep 24, 2021 at 1:34 PM Dakshinya T R S < > [email protected]> wrote: > >> From d4ac086b18c41e6d146cd70524c581138b1186ec Mon Sep 17 00:00:00 2001 >> From: lwWang <[email protected]> >> Date: Wed, 15 Sep 2021 10:39:51 +0800 >> Subject: [PATCH 1/2] encoding only the focused frames in the crf 2 pass >> >> --- >> source/common/frame.h | 1 + >> source/common/framedata.cpp | 2 +- >> source/common/param.cpp | 1 + >> source/encoder/encoder.cpp | 1 + >> source/encoder/ratecontrol.cpp | 240 ++++++++++++++++++--------------- >> source/encoder/ratecontrol.h | 3 + >> source/x265.h | 3 + >> 7 files changed, 138 insertions(+), 113 deletions(-) >> >> diff --git a/source/common/frame.h b/source/common/frame.h >> index dc5bbacf7..ac1185e81 100644 >> --- a/source/common/frame.h >> +++ b/source/common/frame.h >> @@ -70,6 +70,7 @@ struct RcStats >> double count[4]; >> double offset[4]; >> double bufferFillFinal; >> + int64_t currentSatd; >> }; >> >> class Frame >> diff --git a/source/common/framedata.cpp b/source/common/framedata.cpp >> index c77b017a8..70af8a248 100644 >> --- a/source/common/framedata.cpp >> +++ b/source/common/framedata.cpp >> @@ -62,7 +62,7 @@ bool FrameData::create(const x265_param& param, const >> SPS& sps, int csp) >> } >> else >> return false; >> - CHECKED_MALLOC_ZERO(m_cuStat, RCStatCU, sps.numCUsInFrame); >> + CHECKED_MALLOC_ZERO(m_cuStat, RCStatCU, sps.numCUsInFrame + 1); >> > [AM] What is the significance of this additional memory? > >> CHECKED_MALLOC(m_rowStat, RCStatRow, sps.numCuInHeight); >> reinit(sps); >> >> diff --git a/source/common/param.cpp b/source/common/param.cpp >> index 6751e0aa7..2c1583d93 100755 >> --- a/source/common/param.cpp >> +++ b/source/common/param.cpp >> @@ -282,6 +282,7 @@ void x265_param_default(x265_param* param) >> param->rc.bStatRead = 0; >> param->rc.bStatWrite = 0; >> param->rc.statFileName = NULL; >> + param->rc.bEncFocusedFramesOnly = 0; >> param->rc.complexityBlur = 20; >> param->rc.qblur = 0.5; >> param->rc.zoneCount = 0; >> diff --git a/source/encoder/encoder.cpp b/source/encoder/encoder.cpp >> index dee8fd85d..cc014a740 100644 >> --- a/source/encoder/encoder.cpp >> +++ b/source/encoder/encoder.cpp >> @@ -2249,6 +2249,7 @@ int Encoder::encode(const x265_picture* pic_in, >> x265_picture* pic_out) >> outFrame->m_rcData->iCuCount = >> outFrame->m_encData->m_frameStats.percent8x8Intra * m_rateControl->m_ncu; >> outFrame->m_rcData->pCuCount = >> outFrame->m_encData->m_frameStats.percent8x8Inter * m_rateControl->m_ncu; >> outFrame->m_rcData->skipCuCount = >> outFrame->m_encData->m_frameStats.percent8x8Skip * m_rateControl->m_ncu; >> + outFrame->m_rcData->currentSatd = >> curEncoder->m_rce.coeffBits; >> } >> >> /* Allow this frame to be recycled if no frame encoders are >> using it for reference */ >> diff --git a/source/encoder/ratecontrol.cpp >> b/source/encoder/ratecontrol.cpp >> index a4756de39..2c211022d 100644 >> --- a/source/encoder/ratecontrol.cpp >> +++ b/source/encoder/ratecontrol.cpp >> @@ -1002,123 +1002,106 @@ bool RateControl::initPass2() >> uint64_t allAvailableBits = uint64_t(m_param->rc.bitrate * 1000. * >> m_numEntries * m_frameDuration); >> int startIndex, framesCount, endIndex; >> int fps = X265_MIN(m_param->keyframeMax, (int)(m_fps + 0.5)); >> + int distance = fps << 1; >> + distance = distance > m_param->keyframeMax ? (m_param->keyframeMax >> << 1) : m_param->keyframeMax; >> startIndex = endIndex = framesCount = 0; >> - int diffQp = 0; >> double targetBits = 0; >> double expectedBits = 0; >> - for (startIndex = m_start, endIndex = m_start; endIndex < >> m_numEntries; endIndex++) >> + double targetBits2 = 0; >> + double expectedBits2 = 0; >> + double cpxSum = 0; >> + double cpxSum2 = 0; >> + >> + if (m_param->rc.rateControlMode == X265_RC_ABR) >> { >> - allConstBits += m_rce2Pass[endIndex].miscBits; >> - allCodedBits += m_rce2Pass[endIndex].coeffBits + >> m_rce2Pass[endIndex].mvBits; >> - if (m_param->rc.rateControlMode == X265_RC_CRF) >> + for (startIndex = m_start, endIndex = m_start; endIndex < >> m_numEntries; endIndex++) >> { >> - framesCount = endIndex - startIndex + 1; >> - diffQp += int (m_rce2Pass[endIndex].qpaRc - >> m_rce2Pass[endIndex].qpNoVbv); >> - if (framesCount > fps) >> - diffQp -= int (m_rce2Pass[endIndex - fps].qpaRc - >> m_rce2Pass[endIndex - fps].qpNoVbv); >> - if (framesCount >= fps) >> - { >> - if (diffQp >= 1) >> - { >> - if (!m_isQpModified && endIndex > fps) >> - { >> - double factor = 2; >> - double step = 0; >> - if (endIndex + fps >= m_numEntries) >> - { >> - m_start = endIndex - (endIndex % fps); >> - return true; >> - } >> - for (int start = endIndex + 1; start <= endIndex >> + fps && start < m_numEntries; start++) >> - { >> - RateControlEntry *rce = &m_rce2Pass[start]; >> - targetBits += qScale2bits(rce, >> x265_qp2qScale(rce->qpNoVbv)); >> - expectedBits += qScale2bits(rce, >> rce->qScale); >> - } >> - if (expectedBits < 0.95 * targetBits) >> - { >> - m_isQpModified = true; >> - m_isGopReEncoded = true; >> - while (endIndex + fps < m_numEntries) >> - { >> - step = pow(2, factor / 6.0); >> - expectedBits = 0; >> - for (int start = endIndex + 1; start <= >> endIndex + fps; start++) >> - { >> - RateControlEntry *rce = >> &m_rce2Pass[start]; >> - rce->newQScale = rce->qScale / step; >> - X265_CHECK(rce->newQScale >= 0, "new >> Qscale is negative\n"); >> - expectedBits += qScale2bits(rce, >> rce->newQScale); >> - rce->newQp = >> x265_qScale2qp(rce->newQScale); >> - } >> - if (expectedBits >= targetBits && step > >> 1) >> - factor *= 0.90; >> - else >> - break; >> - } >> - >> - if (m_isVbv && endIndex + fps < m_numEntries) >> - if (!vbv2Pass((uint64_t)targetBits, >> endIndex + fps, endIndex + 1)) >> - return false; >> - >> - targetBits = 0; >> - expectedBits = 0; >> - >> - for (int start = endIndex - fps + 1; start >> <= endIndex; start++) >> - { >> - RateControlEntry *rce = >> &m_rce2Pass[start]; >> - targetBits += qScale2bits(rce, >> x265_qp2qScale(rce->qpNoVbv)); >> - } >> - while (1) >> - { >> - step = pow(2, factor / 6.0); >> - expectedBits = 0; >> - for (int start = endIndex - fps + 1; >> start <= endIndex; start++) >> - { >> - RateControlEntry *rce = >> &m_rce2Pass[start]; >> - rce->newQScale = rce->qScale * step; >> - X265_CHECK(rce->newQScale >= 0, "new >> Qscale is negative\n"); >> - expectedBits += qScale2bits(rce, >> rce->newQScale); >> - rce->newQp = >> x265_qScale2qp(rce->newQScale); >> - } >> - if (expectedBits > targetBits && step > >> 1) >> - factor *= 1.1; >> - else >> - break; >> - } >> - if (m_isVbv) >> - if (!vbv2Pass((uint64_t)targetBits, >> endIndex, endIndex - fps + 1)) >> - return false; >> - diffQp = 0; >> - m_reencode = endIndex - fps + 1; >> - endIndex = endIndex + fps; >> - startIndex = endIndex + 1; >> - m_start = startIndex; >> - targetBits = expectedBits = 0; >> - } >> - else >> - targetBits = expectedBits = 0; >> - } >> - } >> - else >> - m_isQpModified = false; >> - } >> + allConstBits += m_rce2Pass[endIndex].miscBits; >> + allCodedBits += m_rce2Pass[endIndex].coeffBits + >> m_rce2Pass[endIndex].mvBits; >> } >> - } >> >> - if (m_param->rc.rateControlMode == X265_RC_ABR) >> - { >> if (allAvailableBits < allConstBits) >> { >> x265_log(m_param, X265_LOG_ERROR, "requested bitrate is too >> low. estimated minimum is %d kbps\n", >> - (int)(allConstBits * m_fps / framesCount * 1000.)); >> + (int)(allConstBits * m_fps / framesCount * 1000.)); >> return false; >> } >> if (!analyseABR2Pass(allAvailableBits)) >> return false; >> + >> + return true; >> + } >> + >> + if (m_param->rc.rateControlMode != X265_RC_CRF) >> + { >> > [AM] This condition will never hit. Please clarify why this is required. > >> + return true; >> } >> > >> - m_start = X265_MAX(m_start, endIndex - fps); >> + if (m_isQpModified) >> + { >> > [AM] This condition will always hit. Please clarify why this check is > required. > >> + return true; >> + } >> + >> + if (m_start + (fps << 1) > m_numEntries) >> + { >> + return true; >> + } >> + >> + for (startIndex = m_start, endIndex = m_numEntries - 1; startIndex < >> endIndex; startIndex++, endIndex--) >> + { >> + cpxSum += m_rce2Pass[startIndex].qScale / >> m_rce2Pass[startIndex].coeffBits; >> + cpxSum2 += m_rce2Pass[endIndex].qScale / >> m_rce2Pass[endIndex].coeffBits; >> + >> + RateControlEntry *rce = &m_rce2Pass[startIndex]; >> + targetBits += qScale2bits(rce, x265_qp2qScale(rce->qpNoVbv)); >> + expectedBits += qScale2bits(rce, rce->qScale); >> + >> + rce = &m_rce2Pass[endIndex]; >> + targetBits2 += qScale2bits(rce, x265_qp2qScale(rce->qpNoVbv)); >> + expectedBits2 += qScale2bits(rce, rce->qScale); >> + } >> + >> + if (expectedBits < 0.95 * targetBits || expectedBits2 < 0.95 * >> targetBits2) >> + { >> + if (cpxSum / cpxSum2 < 0.95 || cpxSum2 / cpxSum < 0.95) >> + { >> + m_isQpModified = true; >> + m_isGopReEncoded = true; >> + >> + m_shortTermCplxSum = 0; >> + m_shortTermCplxCount = 0; >> + m_framesDone = m_start; >> + >> + for (startIndex = m_start; startIndex < m_numEntries; >> startIndex++) >> + { >> + m_shortTermCplxSum *= 0.5; >> + m_shortTermCplxCount *= 0.5; >> + m_shortTermCplxSum += m_rce2Pass[startIndex].currentSatd >> / (CLIP_DURATION(m_frameDuration) / BASE_FRAME_DURATION); >> + m_shortTermCplxCount++; >> + } >> + >> + m_bufferFill = m_rce2Pass[m_start - 1].bufferFill; >> + m_bufferFillFinal = m_rce2Pass[m_start - 1].bufferFillFinal; >> + m_bufferFillActual = m_rce2Pass[m_start - >> 1].bufferFillActual; >> + >> + m_reencode = m_start; >> + m_start = m_numEntries; >> + } >> + else >> + { >> + >> + m_isQpModified = false; >> + m_isGopReEncoded = false; >> + } >> + } >> + else >> + { >> + >> + m_isQpModified = false; >> + m_isGopReEncoded = false; >> + } >> + >> + m_start = X265_MAX(m_start, m_numEntries - distance + >> m_param->keyframeMax); >> >> return true; >> } >> @@ -1391,15 +1374,47 @@ int RateControl::rateControlStart(Frame* >> curFrame, RateControlEntry* rce, Encode >> rce->frameSizeMaximum *= m_param->maxAUSizeFactor; >> } >> } >> + >> + ///< regenerate the qp >> if (!m_isAbr && m_2pass && m_param->rc.rateControlMode == >> X265_RC_CRF) >> { >> - rce->qpPrev = x265_qScale2qp(rce->qScale); >> - rce->qScale = rce->newQScale; >> - rce->qpaRc = curEncData.m_avgQpRc = curEncData.m_avgQpAq = >> x265_qScale2qp(rce->newQScale); >> - m_qp = int(rce->qpaRc + 0.5); >> - rce->frameSizePlanned = qScale2bits(rce, rce->qScale); >> - m_framesDone++; >> - return m_qp; >> + if (!m_param->rc.bEncFocusedFramesOnly) >> + { >> + rce->qpPrev = x265_qScale2qp(rce->qScale); >> + rce->qScale = rce->newQScale; >> + rce->qpaRc = curEncData.m_avgQpRc = curEncData.m_avgQpAq = >> x265_qScale2qp(rce->newQScale); >> + m_qp = int(rce->qpaRc + 0.5); >> + rce->frameSizePlanned = qScale2bits(rce, rce->qScale); >> + m_framesDone++; >> + return m_qp; >> + } >> + else >> + { >> + int index = m_encOrder[rce->poc]; >> + index++; >> + double totalDuration = m_frameDuration; >> + for (int j = 0; totalDuration < 1.0 && index < m_numEntries; >> j++) >> + { >> + switch (m_rce2Pass[index].sliceType) >> + { >> + case B_SLICE: >> + curFrame->m_lowres.plannedType[j] = >> m_rce2Pass[index].keptAsRef ? X265_TYPE_BREF : X265_TYPE_B; >> + break; >> + case P_SLICE: >> + curFrame->m_lowres.plannedType[j] = X265_TYPE_P; >> + break; >> + case I_SLICE: >> + curFrame->m_lowres.plannedType[j] = >> m_param->bOpenGOP ? X265_TYPE_I : X265_TYPE_IDR; >> + break; >> + default: >> + break; >> + } >> + >> + curFrame->m_lowres.plannedSatd[j] = >> m_rce2Pass[index].currentSatd; >> + totalDuration += m_frameDuration; >> + index++; >> + } >> + } >> } >> >> if (m_isAbr || m_2pass) // ABR,CRF >> @@ -1890,7 +1905,7 @@ double RateControl::rateEstimateQscale(Frame* >> curFrame, RateControlEntry *rce) >> qScale = x265_clip3(lqmin, lqmax, qScale); >> } >> >> - if (!m_2pass || m_param->bliveVBV2pass) >> + if (!m_2pass || m_param->bliveVBV2pass || (m_2pass && >> m_param->rc.rateControlMode == X265_RC_CRF && >> m_param->rc.bEncFocusedFramesOnly)) >> { >> /* clip qp to permissible range after vbv-lookahead >> estimation to avoid possible >> * mispredictions by initial frame size predictors */ >> @@ -1927,7 +1942,7 @@ double RateControl::rateEstimateQscale(Frame* >> curFrame, RateControlEntry *rce) >> else >> { >> double abrBuffer = 2 * m_rateTolerance * m_bitrate; >> - if (m_2pass) >> + if (m_2pass && (m_param->rc.rateControlMode != X265_RC_CRF || >> !m_param->rc.bEncFocusedFramesOnly)) >> { >> > [AM] Please include a conformance check in Encoder::configure() to disable > m_param->rc.bEncFocusedFramesOnly if either bStatRead or CRF is disabled. > >> double lmin = m_lmin[m_sliceType]; >> double lmax = m_lmax[m_sliceType]; >> @@ -2828,7 +2843,7 @@ int RateControl::rateControlEnd(Frame* curFrame, >> int64_t bits, RateControlEntry* >> >> if (m_param->rc.aqMode || m_isVbv || m_param->bAQMotion || >> bEnableDistOffset) >> { >> - if (m_isVbv && !(m_2pass && m_param->rc.rateControlMode == >> X265_RC_CRF)) >> + if (m_isVbv && !(m_2pass && m_param->rc.rateControlMode == >> X265_RC_CRF && !m_param->rc.bEncFocusedFramesOnly)) >> { >> double avgQpRc = 0; >> /* determine avg QP decided by VBV rate control */ >> @@ -2862,8 +2877,9 @@ int RateControl::rateControlEnd(Frame* curFrame, >> int64_t bits, RateControlEntry* >> if (m_param->rc.rateControlMode == X265_RC_CRF) >> { >> double crfVal, qpRef = curEncData.m_avgQpRc; >> + >> bool is2passCrfChange = false; >> - if (m_2pass) >> + if (m_2pass && !m_param->rc.bEncFocusedFramesOnly) >> { >> if (fabs(curEncData.m_avgQpRc - rce->qpPrev) > 0.1) >> { >> diff --git a/source/encoder/ratecontrol.h b/source/encoder/ratecontrol.h >> index 996465eeb..204bd71e1 100644 >> --- a/source/encoder/ratecontrol.h >> +++ b/source/encoder/ratecontrol.h >> @@ -73,6 +73,7 @@ struct RateControlEntry >> Predictor rowPreds[3][2]; >> Predictor* rowPred[2]; >> >> + int64_t currentSatd; >> int64_t lastSatd; /* Contains the picture cost of the previous >> frame, required for resetAbr and VBV */ >> int64_t leadingNoBSatd; >> int64_t rowTotalBits; /* update cplxrsum and totalbits at the end >> of 2 rows */ >> @@ -87,6 +88,8 @@ struct RateControlEntry >> double rowCplxrSum; >> double qpNoVbv; >> double bufferFill; >> + double bufferFillFinal; >> + double bufferFillActual; >> double targetFill; >> bool vbvEndAdj; >> double frameDuration; >> diff --git a/source/x265.h b/source/x265.h >> index 3f3133536..6bb893c98 100644 >> --- a/source/x265.h >> +++ b/source/x265.h >> @@ -1443,6 +1443,9 @@ typedef struct x265_param >> * encoder will default to using x265_2pass.log */ >> const char* statFileName; >> >> + /* if only the focused frames would be re-encode or not */ >> + int bEncFocusedFramesOnly; >> + >> > [AM] Update X265_BUILD, add help document, and add an entry for the new > param in info SEI. > Is this a param?API only option? If so, clarify that in the document. > Else, add a test CLI. > >> /* temporally blur quants */ >> double qblur; >> >> -- >> 2.22.0.windows.1 >> >> _______________________________________________ >> x265-devel mailing list >> [email protected] >> https://mailman.videolan.org/listinfo/x265-devel >> > > > -- > Regards, > *Aruna Matheswaran,* > Video Codec Engineer, > Media & AI analytics BU, > > > > _______________________________________________ > x265-devel mailing list > [email protected] > https://mailman.videolan.org/listinfo/x265-devel >
_______________________________________________ x265-devel mailing list [email protected] https://mailman.videolan.org/listinfo/x265-devel
