[x265] [PATCH 1 of 3] rd level: add functions to do residual encoding at depth 0 for best modes
deepthidevaki at multicorewareinc.com
deepthidevaki at multicorewareinc.com
Fri Dec 13 12:26:50 CET 2013
# HG changeset patch
# User Deepthi Devaki <deepthidevaki at multicorewareinc.com>
# Date 1386931800 -19800
# Node ID b39b6c3301686a28843bbf29fbd1a03c3dd2a320
# Parent 926f7034b2f06c2584cee92170940d381eb29327
rd level: add functions to do residual encoding at depth 0 for best modes.
This function will be used for rd level 0.
diff -r 926f7034b2f0 -r b39b6c330168 source/Lib/TLibCommon/TComDataCU.cpp
--- a/source/Lib/TLibCommon/TComDataCU.cpp Fri Dec 13 01:03:47 2013 +0530
+++ b/source/Lib/TLibCommon/TComDataCU.cpp Fri Dec 13 16:20:00 2013 +0530
@@ -464,6 +464,49 @@
m_cuColocated[1] = cu->getCUColocated(REF_PIC_LIST_1);
}
+void TComDataCU::copyToSubCU(TComDataCU* cu, uint32_t partUnitIdx, uint32_t depth)
+{
+ assert(partUnitIdx < 4);
+
+ uint32_t partOffset = (cu->getTotalNumPart() >> 2) * partUnitIdx;
+
+ m_pic = cu->getPic();
+ m_slice = m_pic->getSlice();
+ m_cuAddr = cu->getAddr();
+ m_absIdxInLCU = cu->getZorderIdxInCU() + partOffset;
+
+ m_cuPelX = cu->getCUPelX() + (g_maxCUWidth >> depth) * (partUnitIdx & 1);
+ m_cuPelY = cu->getCUPelY() + (g_maxCUHeight >> depth) * (partUnitIdx >> 1);
+
+ m_totalCost = MAX_INT64;
+ m_totalDistortion = 0;
+ m_totalBits = 0;
+ m_numPartitions = cu->getTotalNumPart() >> 2;
+
+ TComDataCU* rpcCU = m_pic->getCU(m_cuAddr);
+ int iSizeInUchar = sizeof(UChar) * m_numPartitions;
+ int sizeInChar = sizeof(char) * m_numPartitions;
+
+ memcpy(m_skipFlag, rpcCU->getSkipFlag() + m_absIdxInLCU, sizeof(*m_skipFlag) * m_numPartitions);
+ memcpy(m_qp, rpcCU->getQP() + m_absIdxInLCU, sizeInChar);
+
+ memcpy(m_partSizes, rpcCU->getPartitionSize() + m_absIdxInLCU, sizeof(*m_partSizes) * m_numPartitions);
+ memcpy(m_predModes, rpcCU->getPredictionMode() + m_absIdxInLCU, sizeof(*m_predModes) * m_numPartitions);
+
+ memcpy(m_lumaIntraDir, rpcCU->getLumaIntraDir() + m_absIdxInLCU, iSizeInUchar);
+ memcpy(m_depth, rpcCU->getDepth() + m_absIdxInLCU, iSizeInUchar);
+ memcpy(m_width, rpcCU->getWidth() + m_absIdxInLCU, iSizeInUchar);
+ memcpy(m_height, rpcCU->getHeight() + m_absIdxInLCU, iSizeInUchar);
+
+ uint32_t tmp = (g_maxCUWidth * g_maxCUHeight) >> (depth << 1);
+ uint32_t tmp2 = m_absIdxInLCU * m_pic->getMinCUWidth() * m_pic->getMinCUHeight();
+ memset(m_trCoeffY, 0, sizeof(TCoeff) * tmp);
+
+ tmp = ((g_maxCUWidth >> m_hChromaShift) * (g_maxCUHeight >> m_hChromaShift)) >> (depth << 1);
+ tmp2 = m_absIdxInLCU * (m_pic->getMinCUWidth() >> m_hChromaShift) * (m_pic->getMinCUHeight() >> m_vChromaShift);
+ memset(m_trCoeffCb, 0, sizeof(TCoeff) * tmp);
+ memset(m_trCoeffCr, 0, sizeof(TCoeff) * tmp);
+}
// --------------------------------------------------------------------------------------------------------------------
// Copy
// --------------------------------------------------------------------------------------------------------------------
@@ -603,6 +646,33 @@
memcpy(rpcCU->getPCMSampleCr() + tmp2, m_iPCMSampleCr, sizeof(Pel) * tmp);
}
+void TComDataCU::copyCodedToPic(UChar depth)
+{
+ TComDataCU* rpcCU = m_pic->getCU(m_cuAddr);
+
+ int iSizeInUchar = sizeof(UChar) * m_numPartitions;
+
+ memcpy(rpcCU->getSkipFlag() + m_absIdxInLCU, m_skipFlag, sizeof(*m_skipFlag) * m_numPartitions);
+ memcpy(rpcCU->getTransformIdx() + m_absIdxInLCU, m_trIdx, iSizeInUchar);
+ memcpy(rpcCU->getTransformSkip(TEXT_LUMA) + m_absIdxInLCU, m_transformSkip[0], iSizeInUchar);
+ memcpy(rpcCU->getTransformSkip(TEXT_CHROMA_U) + m_absIdxInLCU, m_transformSkip[1], iSizeInUchar);
+ memcpy(rpcCU->getTransformSkip(TEXT_CHROMA_V) + m_absIdxInLCU, m_transformSkip[2], iSizeInUchar);
+ memcpy(rpcCU->getChromaIntraDir() + m_absIdxInLCU, m_chromaIntraDir, iSizeInUchar);
+
+ memcpy(rpcCU->getCbf(TEXT_LUMA) + m_absIdxInLCU, m_cbf[0], iSizeInUchar);
+ memcpy(rpcCU->getCbf(TEXT_CHROMA_U) + m_absIdxInLCU, m_cbf[1], iSizeInUchar);
+ memcpy(rpcCU->getCbf(TEXT_CHROMA_V) + m_absIdxInLCU, m_cbf[2], iSizeInUchar);
+
+ uint32_t tmp = (g_maxCUWidth * g_maxCUHeight) >> (depth << 1);
+ uint32_t tmp2 = m_absIdxInLCU * m_pic->getMinCUWidth() * m_pic->getMinCUHeight();
+ memcpy(rpcCU->getCoeffY() + tmp2, m_trCoeffY, sizeof(TCoeff) * tmp);
+
+ tmp = ((g_maxCUWidth >> m_hChromaShift) * (g_maxCUHeight >> m_hChromaShift)) >> (depth << 1);
+ tmp2 = m_absIdxInLCU * (m_pic->getMinCUWidth() >> m_hChromaShift) * (m_pic->getMinCUHeight() >> m_vChromaShift);
+ memcpy(rpcCU->getCoeffCb() + tmp2, m_trCoeffCb, sizeof(TCoeff) * tmp);
+ memcpy(rpcCU->getCoeffCr() + tmp2, m_trCoeffCr, sizeof(TCoeff) * tmp);
+}
+
void TComDataCU::copyToPic(UChar depth, uint32_t partIdx, uint32_t partDepth)
{
TComDataCU* cu = m_pic->getCU(m_cuAddr);
diff -r 926f7034b2f0 -r b39b6c330168 source/Lib/TLibCommon/TComDataCU.h
--- a/source/Lib/TLibCommon/TComDataCU.h Fri Dec 13 01:03:47 2013 +0530
+++ b/source/Lib/TLibCommon/TComDataCU.h Fri Dec 13 16:20:00 2013 +0530
@@ -195,10 +195,12 @@
void initEstData(uint32_t depth, int qp);
void initSubCU(TComDataCU* cu, uint32_t partUnitIdx, uint32_t depth, int qp);
+ void copyToSubCU(TComDataCU* lcu, uint32_t partUnitIdx, uint32_t depth);
void copyPartFrom(TComDataCU* cu, uint32_t partUnitIdx, uint32_t depth, bool isRDObasedAnalysis = true);
void copyToPic(UChar depth);
void copyToPic(UChar depth, uint32_t partIdx, uint32_t partDepth);
+ void copyCodedToPic(UChar depth);
// -------------------------------------------------------------------------------------------------------------------
// member functions for CU description
diff -r 926f7034b2f0 -r b39b6c330168 source/Lib/TLibEncoder/TEncCu.h
--- a/source/Lib/TLibEncoder/TEncCu.h Fri Dec 13 01:03:47 2013 +0530
+++ b/source/Lib/TLibEncoder/TEncCu.h Fri Dec 13 16:20:00 2013 +0530
@@ -132,10 +132,8 @@
public:
-#if LOG_CU_STATISTICS
StatisticLog m_sliceTypeLog[3];
StatisticLog* m_log;
-#endif
TEncCu();
void init(Encoder* top);
@@ -175,6 +173,7 @@
void xComputeCostInter(TComDataCU* outTempCU, TComYuv* outPredYUV, PartSize partSize, bool bUseMRG = false);
void xComputeCostMerge2Nx2N(TComDataCU*& outBestCU, TComDataCU*& outTempCU, TComYuv*& bestPredYuv, TComYuv*& tmpPredYuv);
void xEncodeIntraInInter(TComDataCU* cu, TComYuv* fencYuv, TComYuv* predYuv, TShortYUV* outResiYuv, TComYuv* outReconYuv);
+ void encodeResidue(TComDataCU* lcu, TComDataCU* cu, uint32_t absPartIdx, UChar depth, uint32_t partIndex);
void xCheckRDCostIntra(TComDataCU*& outBestCU, TComDataCU*& outTempCU, PartSize partSize);
void xCheckRDCostIntraInInter(TComDataCU*& outBestCU, TComDataCU*& outTempCU, PartSize partSize);
void xCheckDQP(TComDataCU* cu);
diff -r 926f7034b2f0 -r b39b6c330168 source/Lib/TLibEncoder/TEncSearch.h
--- a/source/Lib/TLibEncoder/TEncSearch.h Fri Dec 13 01:03:47 2013 +0530
+++ b/source/Lib/TLibEncoder/TEncSearch.h Fri Dec 13 16:20:00 2013 +0530
@@ -171,6 +171,13 @@
void xSetIntraResultQT(TComDataCU* cu, uint32_t trDepth, uint32_t absPartIdx, bool bLumaOnly, TComYuv* reconYuv);
void generateCoeffRecon(TComDataCU* cu, TComYuv* fencYuv, TComYuv* predYuv, TShortYUV* resiYuv, TComYuv* reconYuv, bool skipRes);
+
+ void xEstimateResidualQT(TComDataCU* cu, uint32_t absPartIdx, uint32_t absTUPartIdx, TShortYUV* resiYuv, uint32_t depth,
+ uint64_t &rdCost, uint32_t &outBits, uint32_t &outDist, uint32_t *puiZeroDist, bool curUseRDOQ = true);
+ void xSetResidualQTData(TComDataCU* cu, uint32_t absPartIdx, uint32_t absTUPartIdx, TShortYUV* resiYuv, uint32_t depth, bool bSpatial);
+
+ void residualTransformQuantInter(TComDataCU* cu, uint32_t absPartIdx, uint32_t absTUPartIdx, TShortYUV* resiYuv, uint32_t depth, bool curUseRDOQ = true);
+
// -------------------------------------------------------------------------------------------------------------------
// compute symbol bits
// -------------------------------------------------------------------------------------------------------------------
@@ -245,11 +252,7 @@
// -------------------------------------------------------------------------------------------------------------------
void xEncodeResidualQT(TComDataCU* cu, uint32_t absPartIdx, uint32_t depth, bool bSubdivAndCbf, TextType ttype);
- void xEstimateResidualQT(TComDataCU* cu, uint32_t absPartIdx, uint32_t absTUPartIdx, TShortYUV* resiYuv, uint32_t depth,
- uint64_t &rdCost, uint32_t &outBits, uint32_t &outDist, uint32_t *puiZeroDist, bool curUseRDOQ = true);
- void xSetResidualQTData(TComDataCU* cu, uint32_t absPartIdx, uint32_t absTUPartIdx, TShortYUV* resiYuv, uint32_t depth, bool bSpatial);
- void residualTransformQuantInter(TComDataCU* cu, uint32_t absPartIdx, uint32_t absTUPartIdx, TShortYUV* resiYuv, uint32_t depth, bool curUseRDOQ = true);
-
+
void setWpScalingDistParam(TComDataCU* cu, int refIdx, int picList);
};
}
diff -r 926f7034b2f0 -r b39b6c330168 source/encoder/compress.cpp
--- a/source/encoder/compress.cpp Fri Dec 13 01:03:47 2013 +0530
+++ b/source/encoder/compress.cpp Fri Dec 13 16:20:00 2013 +0530
@@ -825,3 +825,136 @@
assert(outBestCU->getPredictionMode(0) != MODE_NONE);
assert(outBestCU->m_totalCost != MAX_DOUBLE);
}
+
+void TEncCu::encodeResidue(TComDataCU* lcu, TComDataCU* cu, uint32_t absPartIdx, UChar depth, uint32_t partIndex)
+{
+ UChar nextDepth = (UChar)(depth + 1);
+ TComDataCU* subTempPartCU = m_tempCU[nextDepth];
+ TComPic* pic = cu->getPic();
+ TComSlice* slice = cu->getPic()->getSlice();
+
+ if (depth != 0)
+ {
+ if (0 == partIndex) //initialize RD with previous depth buffer
+ {
+ m_rdSbacCoders[depth][CI_CURR_BEST]->load(m_rdSbacCoders[depth - 1][CI_CURR_BEST]);
+ }
+ else
+ {
+ m_rdSbacCoders[depth][CI_CURR_BEST]->load(m_rdSbacCoders[depth][CI_NEXT_BEST]);
+ }
+ }
+
+ if (((depth < lcu->getDepth(absPartIdx)) && (depth < (g_maxCUDepth - g_addCUDepth))))
+ {
+ uint32_t qNumParts = (pic->getNumPartInCU() >> (depth << 1)) >> 2;
+ for (uint32_t partUnitIdx = 0; partUnitIdx < 4; partUnitIdx++, absPartIdx += qNumParts)
+ {
+ uint32_t lpelx = lcu->getCUPelX() + g_rasterToPelX[g_zscanToRaster[absPartIdx]];
+ uint32_t tpely = lcu->getCUPelY() + g_rasterToPelY[g_zscanToRaster[absPartIdx]];
+ bool bInSlice = lcu->getSCUAddr() + absPartIdx < slice->getSliceCurEndCUAddr();
+ if (bInSlice && (lpelx < slice->getSPS()->getPicWidthInLumaSamples()) && (tpely < slice->getSPS()->getPicHeightInLumaSamples()))
+ {
+ subTempPartCU->copyToSubCU(cu, partUnitIdx, depth + 1);
+ encodeResidue(lcu, subTempPartCU, absPartIdx, depth + 1, partUnitIdx);
+ }
+ }
+
+ return;
+ }
+ if (lcu->getPredictionMode(absPartIdx) == MODE_INTER)
+ {
+ if (!lcu->getSkipFlag(absPartIdx))
+ {
+ //Calculate Residue
+ Pel* src2 = m_bestPredYuv[0]->getLumaAddr(absPartIdx);
+ Pel* src1 = m_origYuv[0]->getLumaAddr(absPartIdx);
+ int16_t* dst = m_tmpResiYuv[depth]->getLumaAddr(0);
+ uint32_t src2stride = m_bestPredYuv[0]->getStride();
+ uint32_t src1stride = m_origYuv[0]->getStride();
+ uint32_t dststride = m_tmpResiYuv[depth]->m_width;
+ int part = partitionFromSizes(cu->getWidth(0), cu->getWidth(0));
+ primitives.luma_sub_ps[part](dst, dststride, src1, src2, src1stride, src2stride);
+
+ src2 = m_bestPredYuv[0]->getCbAddr(absPartIdx);
+ src1 = m_origYuv[0]->getCbAddr(absPartIdx);
+ dst = m_tmpResiYuv[depth]->getCbAddr(0);
+ src2stride = m_bestPredYuv[0]->getCStride();
+ src1stride = m_origYuv[0]->getCStride();
+ dststride = m_tmpResiYuv[depth]->m_cwidth;
+ primitives.chroma[m_cfg->param.internalCsp].sub_ps[part](dst, dststride, src1, src2, src1stride, src2stride);
+
+ src2 = m_bestPredYuv[0]->getCrAddr(absPartIdx);
+ src1 = m_origYuv[0]->getCrAddr(absPartIdx);
+ dst = m_tmpResiYuv[depth]->getCrAddr(0);
+ dststride = m_tmpResiYuv[depth]->m_cwidth;
+ primitives.chroma[m_cfg->param.internalCsp].sub_ps[part](dst, dststride, src1, src2, src1stride, src2stride);
+
+ //Residual encoding
+ m_search->residualTransformQuantInter(cu, 0, 0, m_tmpResiYuv[depth], cu->getDepth(0), true);
+ m_search->xSetResidualQTData(cu, 0, 0, NULL, cu->getDepth(0), false);
+
+ if (lcu->getMergeFlag(absPartIdx) && cu->getPartitionSize(0) == SIZE_2Nx2N && !cu->getQtRootCbf(0))
+ {
+ cu->setSkipFlagSubParts(true, 0, depth);
+ cu->copyCodedToPic(depth);
+ }
+ else
+ {
+ cu->copyCodedToPic(depth);
+ m_search->xSetResidualQTData(cu, 0, 0, m_tmpResiYuv[depth], cu->getDepth(0), true);
+
+ //Generate Recon
+ Pel* pred = m_bestPredYuv[0]->getLumaAddr(absPartIdx);
+ int16_t* res = m_tmpResiYuv[depth]->getLumaAddr(0);
+ Pel* reco = m_bestRecoYuv[0]->getLumaAddr(absPartIdx);
+ dststride = m_bestRecoYuv[0]->getStride();
+ src1stride = m_bestPredYuv[0]->getStride();
+ src2stride = m_tmpResiYuv[depth]->m_width;
+ primitives.luma_add_ps[part](reco, dststride, pred, res, src1stride, src2stride);
+
+ pred = m_bestPredYuv[0]->getCbAddr(absPartIdx);
+ res = m_tmpResiYuv[depth]->getCbAddr(0);
+ reco = m_bestRecoYuv[0]->getCbAddr(absPartIdx);
+ dststride = m_bestRecoYuv[0]->getCStride();
+ src1stride = m_bestPredYuv[0]->getCStride();
+ src2stride = m_tmpResiYuv[depth]->m_cwidth;
+ primitives.chroma[m_cfg->param.internalCsp].add_ps[part](reco, dststride, pred, res, src1stride, src2stride);
+
+ pred = m_bestPredYuv[0]->getCrAddr(absPartIdx);
+ res = m_tmpResiYuv[depth]->getCrAddr(0);
+ reco = m_bestRecoYuv[0]->getCrAddr(absPartIdx);
+ primitives.chroma[m_cfg->param.internalCsp].add_ps[part](reco, dststride, pred, res, src1stride, src2stride);
+ m_bestRecoYuv[0]->copyToPicYuv(lcu->getPic()->getPicYuvRec(), lcu->getAddr(), 0);
+ return;
+ }
+ }
+
+ //Generate Recon
+ int part = partitionFromSizes(cu->getWidth(0), cu->getWidth(0));
+ Pel* src = m_bestPredYuv[0]->getLumaAddr(absPartIdx);
+ Pel* dst = m_bestRecoYuv[0]->getLumaAddr(absPartIdx);
+ uint32_t srcstride = m_bestPredYuv[0]->getStride();
+ uint32_t dststride = m_bestRecoYuv[0]->getStride();
+ primitives.luma_copy_pp[part](dst, dststride, src, srcstride);
+
+ src = m_bestPredYuv[0]->getCbAddr(absPartIdx);
+ dst = m_bestRecoYuv[0]->getCbAddr(absPartIdx);
+ srcstride = m_bestPredYuv[0]->getCStride();
+ dststride = m_bestRecoYuv[0]->getCStride();
+ primitives.chroma[m_cfg->param.internalCsp].copy_pp[part](dst, dststride, src, srcstride);
+
+ src = m_bestPredYuv[0]->getCrAddr(absPartIdx);
+ dst = m_bestRecoYuv[0]->getCrAddr(absPartIdx);
+ primitives.chroma[m_cfg->param.internalCsp].copy_pp[part](dst, dststride, src, srcstride);
+ m_bestRecoYuv[0]->copyToPicYuv(lcu->getPic()->getPicYuvRec(), lcu->getAddr(), 0);
+ }
+ else
+ {
+ m_origYuv[0]->copyPartToYuv(m_origYuv[depth], absPartIdx);
+ m_search->generateCoeffRecon(cu, m_origYuv[depth], m_modePredYuv[5][depth], m_tmpResiYuv[depth], m_tmpRecoYuv[depth], false);
+ m_tmpRecoYuv[depth]->copyToPicYuv(cu->getPic()->getPicYuvRec(), lcu->getAddr(), absPartIdx);
+ m_tmpRecoYuv[depth]->copyToPartYuv(m_bestRecoYuv[0], absPartIdx);
+ cu->copyCodedToPic(depth);
+ }
+}
More information about the x265-devel
mailing list