[x265] [PATCH 2 of 3] rd level: modify mode-decision logic for rd level 0
deepthidevaki at multicorewareinc.com
deepthidevaki at multicorewareinc.com
Fri Dec 13 12:26:51 CET 2013
# HG changeset patch
# User Deepthi Devaki <deepthidevaki at multicorewareinc.com>
# Date 1386932319 -19800
# Node ID 4a547144db4800881e254b390f244b31e1cc30c6
# Parent b39b6c3301686a28843bbf29fbd1a03c3dd2a320
rd level: modify mode-decision logic for rd level 0
In rd level 0, sa8d cost used for mode decision across depths. dct,quant is not done during mode-decision and no recon is generated. Hence Intra has to use original pixels as reference. Residual encoding is done at depth 0 and Intra prediction for the best mode will be done again with recon as reference.
diff -r b39b6c330168 -r 4a547144db48 source/encoder/compress.cpp
--- a/source/encoder/compress.cpp Fri Dec 13 16:20:00 2013 +0530
+++ b/source/encoder/compress.cpp Fri Dec 13 16:28:39 2013 +0530
@@ -553,11 +553,15 @@
m_search->encodeResAndCalcRdInterCU(outBestCU, m_origYuv[depth], m_bestPredYuv[depth], m_tmpResiYuv[depth],
m_bestResiYuv[depth], m_bestRecoYuv[depth], false);
}
- else if (m_cfg->param.rdLevel <= 1)
+ else if (m_cfg->param.rdLevel == 1)
{
m_tmpResiYuv[depth]->subtract(m_origYuv[depth], m_bestPredYuv[depth], 0, outBestCU->getWidth(0));
m_search->generateCoeffRecon(outBestCU, m_origYuv[depth], m_bestPredYuv[depth], m_tmpResiYuv[depth], m_bestRecoYuv[depth], false);
}
+ else if (m_cfg->param.rdLevel == 0)
+ {
+ m_origYuv[depth]->copyPartToPartYuv(m_bestRecoYuv[depth], 0, outBestCU->getWidth(0), outBestCU->getHeight(0), true, true);
+ }
}
else
{
@@ -566,6 +570,10 @@
else if (m_cfg->param.rdLevel == 1)
{
m_search->generateCoeffRecon(outBestCU, m_origYuv[depth], m_bestPredYuv[depth], m_tmpResiYuv[depth], m_bestRecoYuv[depth], false);
+ }
+ else if (m_cfg->param.rdLevel == 0)
+ {
+ m_origYuv[depth]->copyPartToPartYuv(m_bestRecoYuv[depth], 0, outBestCU->getWidth(0), outBestCU->getHeight(0), true, true);
}
}
//Check Merge-skip
@@ -597,7 +605,7 @@
}
}
}
- else if (m_cfg->param.rdLevel <= 1)
+ else if (m_cfg->param.rdLevel == 1)
{
uint32_t threshold[4] = { 20000, 6000, 1600, 500 };
int index = 4 - g_convertToBit[outBestCU->getWidth(0)];
@@ -608,6 +616,21 @@
outBestCU = m_mergeCU[depth];
}
}
+ else if (m_cfg->param.rdLevel == 0)
+ {
+ uint32_t threshold[4] = { 20000, 6000, 1600, 500 };
+ int index = 4 - g_convertToBit[outBestCU->getWidth(0)];
+ if (m_mergeCU[depth]->m_totalDistortion < threshold[index])
+ {
+ m_mergeCU[depth]->setSkipFlagSubParts(true, 0, depth);
+ outBestCU = m_mergeCU[depth];
+ if (bestMergePred != m_bestPredYuv[depth])
+ {
+ bestMergePred->copyPartToPartYuv(m_bestPredYuv[depth], 0, outBestCU->getWidth(0), outBestCU->getHeight(0));
+ }
+ m_origYuv[depth]->copyPartToPartYuv(m_bestRecoYuv[depth], 0, outBestCU->getWidth(0), outBestCU->getHeight(0), true, true);
+ }
+ }
}
}
@@ -728,6 +751,8 @@
/* Adding costs from best SUbCUs */
outTempCU->copyPartFrom(subBestPartCU, nextDepth_partIndex, nextDepth, true); // Keep best part data to current temporary data.
xCopyYuv2Tmp(subBestPartCU->getTotalNumPart() * nextDepth_partIndex, nextDepth);
+ if(m_cfg->param.rdLevel == 0)
+ m_bestPredYuv[nextDepth]->copyToPartYuv(m_tmpPredYuv[depth], subBestPartCU->getTotalNumPart() * nextDepth_partIndex);
}
else if (bInSlice)
{
@@ -749,8 +774,6 @@
outTempCU->m_totalCost = m_rdCost->calcRdSADCost(outTempCU->m_totalDistortion, outTempCU->m_totalBits);
}
- outTempCU->m_totalCost = m_rdCost->calcRdCost(outTempCU->m_totalDistortion, outTempCU->m_totalBits);
-
if ((g_maxCUWidth >> depth) == outTempCU->getSlice()->getPPS()->getMinCuDQPSize() && outTempCU->getSlice()->getPPS()->getUseDQP())
{
bool hasResidual = false;
@@ -799,6 +822,9 @@
tempYuv = m_tmpRecoYuv[depth];
m_tmpRecoYuv[depth] = m_bestRecoYuv[depth];
m_bestRecoYuv[depth] = tempYuv;
+ tempYuv = m_tmpPredYuv[depth];
+ m_tmpPredYuv[depth] = m_bestPredYuv[depth];
+ m_bestPredYuv[depth] = tempYuv;
}
}
else
@@ -807,6 +833,9 @@
tempYuv = m_tmpRecoYuv[depth];
m_tmpRecoYuv[depth] = m_bestRecoYuv[depth];
m_bestRecoYuv[depth] = tempYuv;
+ tempYuv = m_tmpPredYuv[depth];
+ m_tmpPredYuv[depth] = m_bestPredYuv[depth];
+ m_bestPredYuv[depth] = tempYuv;
}
}
@@ -814,8 +843,15 @@
/* Copy Best data to Picture for next partition prediction. */
outBestCU->copyToPic((UChar)depth);
- /* Copy Yuv data to picture Yuv */
- xCopyYuv2Pic(outBestCU->getPic(), outBestCU->getAddr(), outBestCU->getZorderIdxInCU(), depth, depth, outBestCU, lpelx, tpely);
+ if(m_cfg->param.rdLevel == 0 && depth == 0)
+ {
+ encodeResidue(outBestCU, outBestCU, 0, 0, 0);
+ }
+ else
+ {
+ /* Copy Yuv data to picture Yuv */
+ xCopyYuv2Pic(outBestCU->getPic(), outBestCU->getAddr(), outBestCU->getZorderIdxInCU(), depth, depth, outBestCU, lpelx, tpely);
+ }
if (bBoundary || (bSliceEnd && bInsidePicture)) return;
More information about the x265-devel
mailing list