[x265] [PATCH] dqp: add logic to encode DQP at depth zero and above as well
gopu at multicorewareinc.com
gopu at multicorewareinc.com
Thu Mar 5 08:33:30 CET 2015
# HG changeset patch
# User Gopu Govindaswamy <gopu at multicorewareinc.com>
# Date 1425540797 -19800
# Thu Mar 05 13:03:17 2015 +0530
# Node ID ce2bd9e51497631f038110c227e164fe0ffcb5bf
# Parent ea9bdb10353fcb06cea1045ba0186c22c448df63
dqp: add logic to encode DQP at depth zero and above as well
Added the logic to check dqp for all sub-CU level
checkDQP function moved into base class search
diff -r ea9bdb10353f -r ce2bd9e51497 source/encoder/analysis.cpp
--- a/source/encoder/analysis.cpp Wed Mar 04 13:20:55 2015 +0530
+++ b/source/encoder/analysis.cpp Thu Mar 05 13:03:17 2015 +0530
@@ -312,11 +312,11 @@
addSplitFlagCost(*splitPred, cuGeom.depth);
else
updateModeCost(*splitPred);
+
+ checkDQPForSplitPred(splitPred->cu, cuGeom);
checkBestMode(*splitPred, depth);
}
- checkDQP(md.bestMode->cu, cuGeom);
-
/* Copy best data to encData CTU and recon */
md.bestMode->cu.copyToPic(depth);
if (md.bestMode != &md.pred[PRED_SPLIT])
@@ -711,6 +711,7 @@
else
updateModeCost(*splitPred);
+ checkDQPForSplitPred(splitPred->cu, cuGeom);
checkBestMode(*splitPred, depth);
}
@@ -724,8 +725,6 @@
cuStat.avgCost[depth] = (temp + md.bestMode->rdCost) / cuStat.count[depth];
}
- checkDQP(md.bestMode->cu, cuGeom);
-
/* Copy best data to encData CTU and recon */
md.bestMode->cu.copyToPic(depth);
if (md.bestMode != &md.pred[PRED_SPLIT])
@@ -996,8 +995,9 @@
checkBestMode(*splitPred, cuGeom.depth);
else if (splitPred->sa8dCost < md.bestMode->sa8dCost)
md.bestMode = splitPred;
+
+ checkDQPForSplitPred(md.bestMode->cu, cuGeom);
}
-
if (mightNotSplit)
{
/* early-out statistics */
@@ -1008,8 +1008,6 @@
cuStat.avgCost[depth] = (temp + md.bestMode->rdCost) / cuStat.count[depth];
}
- checkDQP(md.bestMode->cu, cuGeom);
-
/* Copy best data to encData CTU and recon */
md.bestMode->cu.copyToPic(depth);
if (md.bestMode != &md.pred[PRED_SPLIT] && m_param->rdLevel)
@@ -1184,11 +1182,10 @@
else
updateModeCost(*splitPred);
+ checkDQPForSplitPred(splitPred->cu, cuGeom);
checkBestMode(*splitPred, depth);
}
- checkDQP(md.bestMode->cu, cuGeom);
-
/* Copy best data to encData CTU and recon */
md.bestMode->cu.copyToPic(depth);
if (md.bestMode != &md.pred[PRED_SPLIT])
@@ -1296,6 +1293,7 @@
bestPred->cu.setPUMv(1, candMvField[bestSadCand][1].mv, 0, 0);
bestPred->cu.setPURefIdx(0, (int8_t)candMvField[bestSadCand][0].refIdx, 0, 0);
bestPred->cu.setPURefIdx(1, (int8_t)candMvField[bestSadCand][1].refIdx, 0, 0);
+ checkDQP(bestPred->cu, cuGeom);
}
/* sets md.bestMode if a valid merge candidate is found, else leaves it NULL */
@@ -1432,6 +1430,7 @@
if (m_param->analysisMode == X265_ANALYSIS_SAVE)
*m_reuseBestMergeCand = bestPred->cu.m_mvpIdx[0][0];
}
+ checkDQP(bestPred->cu, cuGeom);
}
void Analysis::checkInter_rd0_4(Mode& interMode, const CUGeom& cuGeom, PartSize partSize)
@@ -1759,7 +1758,6 @@
predV, predYuv.m_csize);
}
- checkDQP(cu, cuGeom);
cu.updatePic(cuGeom.depth);
}
@@ -1788,34 +1786,6 @@
}
}
-void Analysis::checkDQP(CUData& cu, const CUGeom& cuGeom)
-{
- if (m_slice->m_pps->bUseDQP && cuGeom.depth <= m_slice->m_pps->maxCuDQPDepth)
- {
- if (cu.m_cuDepth[0] > cuGeom.depth) // detect splits
- {
- bool hasResidual = false;
- for (uint32_t absPartIdx = 0; absPartIdx < cu.m_numPartitions; absPartIdx++)
- {
- if (cu.getQtRootCbf(absPartIdx))
- {
- hasResidual = true;
- break;
- }
- }
- if (hasResidual)
- cu.setQPSubCUs(cu.getRefQP(0), 0, cuGeom.depth);
- else
- cu.setQPSubParts(cu.getRefQP(0), 0, cuGeom.depth);
- }
- else
- {
- if (!cu.getCbf(0, TEXT_LUMA, 0) && !cu.getCbf(0, TEXT_CHROMA_U, 0) && !cu.getCbf(0, TEXT_CHROMA_V, 0))
- cu.setQPSubParts(cu.getRefQP(0), 0, cuGeom.depth);
- }
- }
-}
-
uint32_t Analysis::topSkipMinDepth(const CUData& parentCTU, const CUGeom& cuGeom)
{
/* Do not attempt to code a block larger than the largest block in the
diff -r ea9bdb10353f -r ce2bd9e51497 source/encoder/analysis.h
--- a/source/encoder/analysis.h Wed Mar 04 13:20:55 2015 +0530
+++ b/source/encoder/analysis.h Thu Mar 05 13:03:17 2015 +0530
@@ -132,9 +132,6 @@
/* add the RD cost of coding a split flag (0 or 1) to the given mode */
void addSplitFlagCost(Mode& mode, uint32_t depth);
- /* update CBF flags and QP values to be internally consistent */
- void checkDQP(CUData& cu, const CUGeom& cuGeom);
-
/* work-avoidance heuristics for RD levels < 5 */
uint32_t topSkipMinDepth(const CUData& parentCTU, const CUGeom& cuGeom);
bool recursionDepthCheck(const CUData& parentCTU, const CUGeom& cuGeom, const Mode& bestMode);
diff -r ea9bdb10353f -r ce2bd9e51497 source/encoder/search.cpp
--- a/source/encoder/search.cpp Wed Mar 04 13:20:55 2015 +0530
+++ b/source/encoder/search.cpp Thu Mar 05 13:03:17 2015 +0530
@@ -1184,8 +1184,8 @@
const Yuv* fencYuv = intraMode.fencYuv;
intraMode.psyEnergy = m_rdCost.psyCost(cuGeom.log2CUSize - 2, fencYuv->m_buf[0], fencYuv->m_size, intraMode.reconYuv.m_buf[0], intraMode.reconYuv.m_size);
}
-
updateModeCost(intraMode);
+ checkDQP(cu, cuGeom);
}
/* Note that this function does not save the best intra prediction, it must
@@ -1404,6 +1404,7 @@
m_entropyCoder.store(intraMode.contexts);
updateModeCost(intraMode);
+ checkDQP(intraMode.cu, cuGeom);
}
uint32_t Search::estIntraPredQT(Mode &intraMode, const CUGeom& cuGeom, const uint32_t depthRange[2], uint8_t* sharedModes)
@@ -2627,6 +2628,7 @@
interMode.coeffBits = coeffBits;
interMode.mvBits = bits - coeffBits;
updateModeCost(interMode);
+ checkDQP(interMode.cu, cuGeom);
}
void Search::residualTransformQuantInter(Mode& mode, const CUGeom& cuGeom, uint32_t absPartIdx, uint32_t tuDepth, const uint32_t depthRange[2])
@@ -3444,3 +3446,49 @@
candModeList[maxIndex] = mode;
}
}
+
+void Search::checkDQP(CUData& cu, const CUGeom& cuGeom)
+{
+ if (cu.m_slice->m_pps->bUseDQP && cuGeom.depth <= cu.m_slice->m_pps->maxCuDQPDepth)
+ {
+ if (cu.getQtRootCbf(0))
+ {
+ /* When analysing RDO with DQP bits, the entropy encoder should add the cost of DQP bits here
+ * i.e Encode QP */
+ }
+ else
+ {
+ cu.setQPSubParts(cu.getRefQP(0), 0, cuGeom.depth);
+ }
+ }
+}
+
+void Search::checkDQPForSplitPred(CUData& cu, const CUGeom& cuGeom)
+{
+ if ((cuGeom.depth == cu.m_slice->m_pps->maxCuDQPDepth) && cu.m_slice->m_pps->bUseDQP)
+ {
+ bool hasResidual = false;
+
+ /* Check if any sub-CU has a non-zero QP */
+ for (uint32_t blkIdx = 0; blkIdx < cuGeom.numPartitions; blkIdx++)
+ {
+ if (cu.getQtRootCbf(blkIdx))
+ {
+ hasResidual = true;
+ break;
+ }
+ }
+ if (hasResidual)
+ {
+ /* TODO: Encode QP, and recalculate RD cost of splitPred */
+ /* For all zero CBF sub-CUs, reset QP to RefQP (so that deltaQP is not signalled).
+ When the non-zero CBF sub-CU is found, stop */
+ bool ret = false;
+ ret = cu.setQPSubCUs(cu.getRefQP(0), 0, cuGeom.depth);
+ X265_CHECK(ret, "set sub QP CU failed\n");
+ }
+ else
+ /* No residual within this CU or subCU, so reset QP to RefQP */
+ cu.setQPSubParts(cu.getRefQP(0), 0, cuGeom.depth);
+ }
+}
diff -r ea9bdb10353f -r ce2bd9e51497 source/encoder/search.h
--- a/source/encoder/search.h Wed Mar 04 13:20:55 2015 +0530
+++ b/source/encoder/search.h Thu Mar 05 13:03:17 2015 +0530
@@ -281,6 +281,10 @@
// pick be chroma mode from available using just sa8d costs
void getBestIntraModeChroma(Mode& intraMode, const CUGeom& cuGeom);
+ /* update CBF flags and QP values to be internally consistent */
+ void checkDQP(CUData& cu, const CUGeom& cuGeom);
+ void checkDQPForSplitPred(CUData& cu, const CUGeom& cuGeom);
+
class PME : public BondedTaskGroup
{
public:
More information about the x265-devel
mailing list