[x265] [PATCH] vbv: enable row resets during vbv when mid-frame qp adjustemets are too high/low
aarthi at multicorewareinc.com
aarthi at multicorewareinc.com
Mon Mar 10 21:22:52 CET 2014
# HG changeset patch
# User Aarthi Thirumalai
# Date 1394482958 -19800
# Tue Mar 11 01:52:38 2014 +0530
# Node ID 6f43b3b9719208d08801f594c750939a69c8d1b8
# Parent 7f4b871d7a0ce7f8aa90b10518fd7edc5bc95261
vbv: enable row resets during vbv when mid-frame qp adjustemets are too high/low.
diff -r 7f4b871d7a0c -r 6f43b3b97192 source/common/wavefront.cpp
--- a/source/common/wavefront.cpp Tue Mar 11 01:16:28 2014 +0530
+++ b/source/common/wavefront.cpp Tue Mar 11 01:52:38 2014 +0530
@@ -32,6 +32,7 @@
bool WaveFront::init(int numRows)
{
m_numRows = numRows;
+ m_bAllRowsStop = false;
if (m_pool)
{
@@ -117,6 +118,9 @@
CTZ64(id, mask);
+ if (m_bAllRowsStop)
+ return false;
+
uint64_t newval = oldval & ~(1LL << id);
if (ATOMIC_CAS(&m_internalDependencyBitmap[w], oldval, newval) == oldval)
{
diff -r 7f4b871d7a0c -r 6f43b3b97192 source/common/wavefront.h
--- a/source/common/wavefront.h Tue Mar 11 01:16:28 2014 +0530
+++ b/source/common/wavefront.h Tue Mar 11 01:52:38 2014 +0530
@@ -53,6 +53,8 @@
public:
+ bool m_bAllRowsStop; /*flag used by FrameEncoder to pause scheduler while doing vbv row resets */
+
WaveFront(ThreadPool *pool)
: JobProvider(pool)
, m_internalDependencyBitmap(0)
diff -r 7f4b871d7a0c -r 6f43b3b97192 source/encoder/cturow.h
--- a/source/encoder/cturow.h Tue Mar 11 01:16:28 2014 +0530
+++ b/source/encoder/cturow.h Tue Mar 11 01:52:38 2014 +0530
@@ -102,6 +102,9 @@
/* count of completed CUs in this row */
volatile uint32_t m_completed;
+
+ /* flag to enable row resets in vbv */
+ bool m_isReencode;
};
}
diff -r 7f4b871d7a0c -r 6f43b3b97192 source/encoder/frameencoder.cpp
--- a/source/encoder/frameencoder.cpp Tue Mar 11 01:16:28 2014 +0530
+++ b/source/encoder/frameencoder.cpp Tue Mar 11 01:52:38 2014 +0530
@@ -929,8 +929,11 @@
m_rows[i].m_rdGoOnBinCodersCABAC.m_fracBits = 0;
m_rows[i].m_completed = 0;
m_rows[i].m_busy = false;
+ m_rows[i].m_isReencode = false;
+
+
}
-
+ m_vbvResetTriggerRow = -1;
int range = m_cfg->param->searchRange; /* fpel search */
range += 1; /* diamond search range check lag */
range += 2; /* subpel refine */
@@ -1059,8 +1062,25 @@
const uint32_t lineStartCUAddr = row * numCols;
double qpBase = m_pic->m_avgQpRc;
bool isVbv = m_cfg->param->rc.vbvBufferSize > 0 && m_cfg->param->rc.vbvMaxBitrate > 0;
+
+ //block current row if previous row is getting reencoded or prev row reference cus are not completed.
+ ScopedLock self(curRow.m_lock);
+ if (row > 0 && (m_rows[row - 1].m_isReencode || m_rows[row].m_completed < numCols - 2 && m_rows[row - 1].m_completed < m_rows[row].m_completed + 2))
+ {
+ m_rows[row].m_active = false;
+ m_rows[row].m_busy = false;
+ m_totalTime = m_totalTime + (x265_mdate() - startTime);
+ return;
+ }
for (uint32_t col = curRow.m_completed; col < numCols; col++)
{
+ //reset current row data if reencoded is turned on this row
+ if (m_rows[row].m_isReencode == true )
+ {
+ col = 0;
+ m_bAllRowsStop = false;
+ m_rows[row].m_isReencode = false;
+ }
const uint32_t cuAddr = lineStartCUAddr + col;
TComDataCU* cu = m_pic->getCU(cuAddr);
cu->initCU(m_pic, cuAddr);
@@ -1069,16 +1089,26 @@
codeRow.m_entropyCoder.resetEntropy();
TEncSbac *bufSbac = (m_cfg->param->bEnableWavefront && col == 0 && row > 0) ? &m_rows[row - 1].m_bufferSbacCoder : NULL;
- if ((uint32_t)row >= col && (row != 0) && isVbv)
- qpBase = m_pic->getCU(cuAddr - numCols + 1)->m_baseQp;
+ if(isVbv)
+ {
+ if ((uint32_t)row == 0)
+ m_pic->m_rowDiagQp[row] = m_pic->m_avgQpRc;
+
+ if ((uint32_t)row >= col && (row != 0) && m_vbvResetTriggerRow != row)
+ cu->m_baseQp = m_pic->getCU(cuAddr - numCols + 1)->m_baseQp;
+ else
+ cu->m_baseQp = m_pic->m_rowDiagQp[row];
+ }
+ else
+ cu->m_baseQp = m_pic->m_avgQpRc;
if (m_cfg->param->rc.aqMode || isVbv)
{
- int qp = calcQpForCu(m_pic, cuAddr, qpBase);
+ int qp = calcQpForCu(m_pic, cuAddr, cu->m_baseQp);
setLambda(qp, row);
qp = X265_MIN(qp, MAX_QP);
cu->setQP(0, char(qp));
- cu->m_baseQp = qpBase;
+
if (m_cfg->param->rc.aqMode)
m_pic->m_qpaAq[row] += qp;
}
@@ -1087,22 +1117,46 @@
{
// Update encoded bits, satdCost, baseQP for each CU
m_pic->m_rowDiagSatd[row] += m_pic->m_cuCostsForVbv[cuAddr];
+ m_pic->m_rowDiagIntraSatd[row] += m_pic->m_intraCuCostsForVbv[cuAddr];
m_pic->m_rowEncodedBits[row] += cu->m_totalBits;
m_pic->m_numEncodedCusPerRow[row] = cuAddr;
m_pic->m_qpaRc[row] += cu->m_baseQp;
- if ((uint32_t)row == col)
- m_pic->m_rowDiagQp[row] = qpBase;
-
// If current block is at row diagonal checkpoint, call vbv ratecontrol.
if ((uint32_t)row == col && row != 0)
{
- m_top->m_rateControl->rowDiagonalVbvRateControl(m_pic, row, &m_rce, qpBase);
+ qpBase = cu->m_baseQp;
+ int reEncode = m_top->m_rateControl->rowDiagonalVbvRateControl(m_pic, row, &m_rce, qpBase);
qpBase = Clip3((double)MIN_QP, (double)MAX_MAX_QP, qpBase);
+ m_pic->m_rowDiagQp[row] = qpBase;
+ m_pic->m_rowDiagQScale[row] = x265_qp2qScale(qpBase);
+ if (reEncode < 0)
+ {
+ m_bAllRowsStop = true;
+ m_rows[row].m_completed = 0;
+ m_rows[row].m_isReencode = true;
+ m_vbvResetTriggerRow = row;
+ for (int bottomRows = m_numRows - 1; bottomRows >= row ; bottomRows--)
+ {
+ if (bottomRows!=row)
+ {
+ //wait for each row to be idle
+ while(m_rows[bottomRows].m_active && m_rows[bottomRows].m_busy)
+ GIVE_UP_TIME();
+ }
+ m_rows[bottomRows].m_isReencode = true;
+ m_rows[bottomRows].m_completed = 0;
+ m_pic->m_qpaAq[bottomRows] = 0;
+ m_pic->m_rowEncodedBits[bottomRows] = 0;
+ m_pic->m_qpaRc[bottomRows] = 0;
+ m_pic->m_numEncodedCusPerRow[bottomRows] = 0;
+ }
+ }
}
}
// Completed CU processing
- m_rows[row].m_completed++;
+ if (!m_rows[row].m_isReencode)
+ m_rows[row].m_completed++;
if (m_rows[row].m_completed >= 2 && row < m_numRows - 1)
{
ScopedLock below(m_rows[row + 1].m_lock);
@@ -1171,6 +1225,7 @@
if (m_cfg->param->rc.vbvBufferSize > 0 && m_cfg->param->rc.vbvMaxBitrate > 0)
{
m_pic->m_cuCostsForVbv[cuAddr] += m_pic->m_lowres.lowresCostForRc[idx];
+ m_pic->m_intraCuCostsForVbv[cuAddr] += m_pic->m_lowres.intraCost[idx];
}
cnt++;
}
diff -r 7f4b871d7a0c -r 6f43b3b97192 source/encoder/frameencoder.h
--- a/source/encoder/frameencoder.h Tue Mar 11 01:16:28 2014 +0530
+++ b/source/encoder/frameencoder.h Tue Mar 11 01:52:38 2014 +0530
@@ -114,6 +114,8 @@
int m_blockRefPOC;
+ int m_vbvResetTriggerRow;
+
Event m_reconRowWait;
TEncEntropy* getEntropyCoder(int row) { return &this->m_rows[row].m_entropyCoder; }
diff -r 7f4b871d7a0c -r 6f43b3b97192 source/encoder/ratecontrol.cpp
--- a/source/encoder/ratecontrol.cpp Tue Mar 11 01:16:28 2014 +0530
+++ b/source/encoder/ratecontrol.cpp Tue Mar 11 01:52:38 2014 +0530
@@ -790,7 +790,7 @@
intraCost += pic->m_intraCuCostsForVbv[cuAddr];
}
- refQScale = row == maxRows - 1 ? refPic->m_rowDiagQScale[row] : refPic->m_rowDiagQScale[row + 1];
+ refQScale = refPic->m_rowDiagQScale[row];
}
if (picType == I_SLICE || qScale >= refQScale)
@@ -827,8 +827,6 @@
{
double qScaleVbv = x265_qp2qScale(qpVbv);
- pic->m_rowDiagQp[row] = qpVbv;
- pic->m_rowDiagQScale[row] = qScaleVbv;
double rowSatdCost = pic->m_rowDiagSatd[row];
double encodedBits = pic->m_rowEncodedBits[row];
if (row == 1)
More information about the x265-devel
mailing list