[x265] [PATCH 3 of 3] vbv: calculate cuSatdCost, rowSatdCost from lowresCus
aarthi at multicorewareinc.com
aarthi at multicorewareinc.com
Sun Feb 16 19:47:41 CET 2014
# HG changeset patch
# User Aarthi Thirumalai<aarthi at multicorewareinc.com>
# Date 1392576377 -19800
# Mon Feb 17 00:16:17 2014 +0530
# Node ID 85a6960bef867b3bfdf363e3a52a035106776c9d
# Parent e7e527d13d2fdd9b08915b3245a248332df29882
vbv: calculate cuSatdCost, rowSatdCost from lowresCus.
diff -r e7e527d13d2f -r 85a6960bef86 source/encoder/frameencoder.cpp
--- a/source/encoder/frameencoder.cpp Sun Feb 16 23:31:39 2014 +0530
+++ b/source/encoder/frameencoder.cpp Mon Feb 17 00:16:17 2014 +0530
@@ -1056,6 +1056,7 @@
CTURow& codeRow = m_rows[m_cfg->param.bEnableWavefront ? row : 0];
const uint32_t numCols = m_pic->getPicSym()->getFrameWidthInCU();
const uint32_t lineStartCUAddr = row * numCols;
+ double qpBase = m_pic->m_avgQpRc;
for (uint32_t col = curRow.m_completed; col < numCols; col++)
{
const uint32_t cuAddr = lineStartCUAddr + col;
@@ -1066,14 +1067,16 @@
codeRow.m_entropyCoder.resetEntropy();
TEncSbac *bufSbac = (m_cfg->param.bEnableWavefront && col == 0 && row > 0) ? &m_rows[row - 1].m_bufferSbacCoder : NULL;
- if (m_cfg->param.rc.aqMode)
+
+ if (m_cfg->param.rc.aqMode || (m_cfg->param.rc.vbvBufferSize >0 && m_cfg->param.rc.vbvMaxBitrate > 0))
{
- int qp = calcQpForCu(m_pic, cuAddr);
+ int qp = calcQpForCu(m_pic, cuAddr , qpBase);
setLambda(qp, row);
- if (qp > MAX_QP)
- qp = MAX_QP;
- cu->setQP(0, (char)qp);
+ qp = X265_MIN(qp, MAX_QP);
+ cu->setQP(0,char(qp));
+ cu->m_baseQp = qpBase;
}
+
codeRow.processCU(cu, m_pic->getSlice(), bufSbac, m_cfg->param.bEnableWavefront && col == 1);
// TODO: Keep atomic running totals for rate control?
@@ -1127,34 +1130,40 @@
curRow.m_busy = false;
}
-int FrameEncoder::calcQpForCu(TComPic *pic, uint32_t cuAddr)
+int FrameEncoder::calcQpForCu(TComPic *pic, uint32_t cuAddr, double baseQp)
{
x265_emms();
- double qp = pic->getSlice()->m_avgQpRc;
- if (m_cfg->param.rc.aqMode)
+ double qp = baseQp;
+
+ /* Derive qpOffet for each CU by averaging offsets for all 16x16 blocks in the cu. */
+ double qp_offset = 0;
+ int maxBlockCols = (pic->getPicYuvOrg()->getWidth() + (16 - 1)) / 16;
+ int maxBlockRows = (pic->getPicYuvOrg()->getHeight() + (16 - 1)) / 16;
+ int noOfBlocks = g_maxCUWidth / 16;
+ int block_y = (cuAddr / pic->getPicSym()->getFrameWidthInCU()) * noOfBlocks;
+ int block_x = (cuAddr * noOfBlocks) - block_y * pic->getPicSym()->getFrameWidthInCU();
+
+ double *qpoffs = (pic->getSlice()->isReferenced() && m_cfg->param.rc.cuTree) ? pic->m_lowres.qpOffset : pic->m_lowres.qpAqOffset;
+ int cnt = 0, idx =0;
+ for (int h = 0; h < noOfBlocks && block_y < maxBlockRows; h++, block_y++)
{
- /* Derive qpOffet for each CU by averaging offsets for all 16x16 blocks in the cu. */
- double qp_offset = 0;
- int maxBlockCols = (pic->getPicYuvOrg()->getWidth() + (16 - 1)) / 16;
- int maxBlockRows = (pic->getPicYuvOrg()->getHeight() + (16 - 1)) / 16;
- int noOfBlocks = g_maxCUWidth / 16;
- int block_y = (cuAddr / pic->getPicSym()->getFrameWidthInCU()) * noOfBlocks;
- int block_x = (cuAddr * noOfBlocks) - block_y * pic->getPicSym()->getFrameWidthInCU();
+ for (int w = 0; w < noOfBlocks && (block_x + w) < maxBlockCols; w++)
+ {
+ idx = block_x + w + (block_y * maxBlockCols);
+ if (m_cfg->param.rc.aqMode)
+ qp_offset += qpoffs[idx];
- double *qpoffs = (pic->getSlice()->isReferenced() && m_cfg->param.rc.cuTree) ? pic->m_lowres.qpOffset : pic->m_lowres.qpAqOffset;
- int cnt = 0;
- for (int h = 0; h < noOfBlocks && block_y < maxBlockRows; h++, block_y++)
- {
- for (int w = 0; w < noOfBlocks && (block_x + w) < maxBlockCols; w++)
- {
- qp_offset += qpoffs[block_x + w + (block_y * maxBlockCols)];
- cnt++;
- }
+ if (m_cfg->param.rc.vbvBufferSize > 0 && m_cfg->param.rc.vbvMaxBitrate > 0)
+ m_pic->m_cuCostsForVbv[cuAddr] += m_pic->m_lowres.lowresCostForRc[idx];
+
+ cnt++;
}
+ }
- qp_offset /= cnt;
- qp += qp_offset;
- }
+ qp_offset /= cnt;
+ qp += qp_offset;
+
+
return Clip3(MIN_QP, MAX_MAX_QP, (int)(qp + 0.5));
}
diff -r e7e527d13d2f -r 85a6960bef86 source/encoder/frameencoder.h
--- a/source/encoder/frameencoder.h Sun Feb 16 23:31:39 2014 +0530
+++ b/source/encoder/frameencoder.h Mon Feb 17 00:16:17 2014 +0530
@@ -173,7 +173,7 @@
protected:
void determineSliceBounds();
- int calcQpForCu(TComPic *pic, uint32_t cuAddr);
+ int calcQpForCu (TComPic *pic, uint32_t cuAddr, double baseQp);
Encoder* m_top;
TEncCfg* m_cfg;
diff -r e7e527d13d2f -r 85a6960bef86 source/encoder/slicetype.cpp
--- a/source/encoder/slicetype.cpp Sun Feb 16 23:31:39 2014 +0530
+++ b/source/encoder/slicetype.cpp Mon Feb 17 00:16:17 2014 +0530
@@ -178,6 +178,26 @@
pic->m_lowres.satdCost = pic->m_lowres.costEstAq[b - p0][p1 - b];
else
pic->m_lowres.satdCost = pic->m_lowres.costEst[b - p0][p1 - b];
+
+ if (cfg->param.rc.vbvBufferSize > 0 && cfg->param.rc.vbvMaxBitrate > 0)
+ {
+ pic->m_lowres.lowresCostForRc = pic->m_lowres.lowresCosts[b - p0][p1 - b];
+ uint32_t maxBlockRows = (pic->getPicYuvOrg()->getHeight() + (16 - 1)) / 16;
+ uint32_t lowresRow = 0;
+ int lowresCol = 0;
+ for (uint32_t row = 0; row < pic->getFrameHeightInCU(); row++)
+ {
+ lowresRow = row * maxBlockRows;
+ for (uint32_t cnt = 0; cnt < maxBlockRows && lowresRow < (uint32_t)heightInCU; cnt++, lowresRow++)
+ {
+ lowresCol = lowresRow * widthInCU;
+ for (; lowresCol < widthInCU; lowresCol++)
+ {
+ pic->m_rowSatdForVbv[row] += pic->m_lowres.lowresCostForRc[lowresCol];
+ }
+ }
+ }
+ }
return pic->m_lowres.satdCost;
}
More information about the x265-devel
mailing list