[x265-commits] [x265] refine picture boundary check

Satoshi Nakagawa nakagawa424 at oki.com
Wed May 7 04:44:29 CEST 2014


details:   http://hg.videolan.org/x265/rev/8c07f39ef5c5
branches:  
changeset: 6822:8c07f39ef5c5
user:      Satoshi Nakagawa <nakagawa424 at oki.com>
date:      Sat May 03 23:26:23 2014 +0900
description:
refine picture boundary check

- cleanup slice end check
- fix split bits for TOPSKIP
Subject: [x265] fix: residualQTIntrachroma() for 4:2:2

details:   http://hg.videolan.org/x265/rev/0e22bd1dfe6c
branches:  
changeset: 6823:0e22bd1dfe6c
user:      Satoshi Nakagawa <nakagawa424 at oki.com>
date:      Mon May 05 23:46:05 2014 +0900
description:
fix: residualQTIntrachroma() for 4:2:2
Subject: [x265] presets.rst edited online with Bitbucket - Correct spelling

details:   http://hg.videolan.org/x265/rev/607384b3312e
branches:  stable
changeset: 6824:607384b3312e
user:      Tom Vaughan <tom.vaughan at multicorewareinc.com>
date:      Wed May 07 02:19:54 2014 +0000
description:
presets.rst edited online with Bitbucket - Correct spelling
Subject: [x265] Merge with stable

details:   http://hg.videolan.org/x265/rev/8963bc3aa2e1
branches:  
changeset: 6825:8963bc3aa2e1
user:      Steve Borho <steve at borho.org>
date:      Tue May 06 21:43:35 2014 -0500
description:
Merge with stable

diffstat:

 doc/reST/presets.rst                   |    2 +-
 source/Lib/TLibCommon/TComYuv.cpp      |   14 +-
 source/Lib/TLibCommon/TComYuv.h        |    2 +-
 source/Lib/TLibEncoder/TEncCu.cpp      |  274 +++++++++++++-------------------
 source/Lib/TLibEncoder/TEncCu.h        |   11 +-
 source/Lib/TLibEncoder/TEncEntropy.cpp |   12 +-
 source/Lib/TLibEncoder/TEncSearch.cpp  |  222 ++++++++++++++------------
 source/encoder/compress.cpp            |  145 ++++++++---------
 8 files changed, 321 insertions(+), 361 deletions(-)

diffs (truncated from 1386 to 300 lines):

diff -r 608267a4f634 -r 8963bc3aa2e1 doc/reST/presets.rst
--- a/doc/reST/presets.rst	Tue May 06 20:46:31 2014 -0500
+++ b/doc/reST/presets.rst	Tue May 06 21:43:35 2014 -0500
@@ -6,7 +6,7 @@ x265 has a number of predefined :option:
 trade-offs between encode speed (encoded frames per second) and
 compression efficiency (quality per bit in the bitstream).  The default
 preset is medium, it does a reasonably good job of finding the best
-possible quality without spending enourmous CPU cycles looking for the
+possible quality without spending enormous CPU cycles looking for the
 absolute most efficient way to achieve that quality.  As you go higher
 than medium, the encoder takes shortcuts to improve performance at the
 expense of quality and compression efficiency.  As you go lower than
diff -r 608267a4f634 -r 8963bc3aa2e1 source/Lib/TLibCommon/TComYuv.cpp
--- a/source/Lib/TLibCommon/TComYuv.cpp	Tue May 06 20:46:31 2014 -0500
+++ b/source/Lib/TLibCommon/TComYuv.cpp	Tue May 06 21:43:35 2014 -0500
@@ -100,22 +100,16 @@ void TComYuv::clear()
     ::memset(m_bufV, 0, (m_cwidth * m_cheight) * sizeof(pixel));
 }
 
-void TComYuv::copyToPicYuv(TComPicYuv* destPicYuv, uint32_t cuAddr, uint32_t absZOrderIdx, uint32_t depth, uint32_t partIdx)
+void TComYuv::copyToPicYuv(TComPicYuv* destPicYuv, uint32_t cuAddr, uint32_t absZOrderIdx)
 {
-    int width = m_width >> depth;
-    int part = partitionFromSizes(width, m_height >> depth);
-    pixel* srcY = getLumaAddr(partIdx, width);
     pixel* dstY = destPicYuv->getLumaAddr(cuAddr, absZOrderIdx);
 
-    primitives.luma_copy_pp[part](dstY, destPicYuv->getStride(), srcY, getStride());
+    primitives.luma_copy_pp[m_part](dstY, destPicYuv->getStride(), m_bufY, getStride());
 
-    width = m_cwidth >> depth;
-    pixel* srcU = getCbAddr(partIdx, width);
-    pixel* srcV = getCrAddr(partIdx, width);
     pixel* dstU = destPicYuv->getCbAddr(cuAddr, absZOrderIdx);
     pixel* dstV = destPicYuv->getCrAddr(cuAddr, absZOrderIdx);
-    primitives.chroma[m_csp].copy_pp[part](dstU, destPicYuv->getCStride(), srcU, getCStride());
-    primitives.chroma[m_csp].copy_pp[part](dstV, destPicYuv->getCStride(), srcV, getCStride());
+    primitives.chroma[m_csp].copy_pp[m_part](dstU, destPicYuv->getCStride(), m_bufU, getCStride());
+    primitives.chroma[m_csp].copy_pp[m_part](dstV, destPicYuv->getCStride(), m_bufV, getCStride());
 }
 
 void TComYuv::copyFromPicYuv(TComPicYuv* srcPicYuv, uint32_t cuAddr, uint32_t absZOrderIdx)
diff -r 608267a4f634 -r 8963bc3aa2e1 source/Lib/TLibCommon/TComYuv.h
--- a/source/Lib/TLibCommon/TComYuv.h	Tue May 06 20:46:31 2014 -0500
+++ b/source/Lib/TLibCommon/TComYuv.h	Tue May 06 21:43:35 2014 -0500
@@ -136,7 +136,7 @@ public:
     // ------------------------------------------------------------------------------------------------------------------
 
     //  Copy YUV buffer to picture buffer
-    void    copyToPicYuv(TComPicYuv* destPicYuv, uint32_t cuAddr, uint32_t absZOrderIdx, uint32_t depth, uint32_t partIdx);
+    void    copyToPicYuv(TComPicYuv* destPicYuv, uint32_t cuAddr, uint32_t absZOrderIdx);
 
     //  Copy YUV buffer from picture buffer
     void    copyFromPicYuv(TComPicYuv* srcPicYuv, uint32_t cuAddr, uint32_t absZOrderIdx);
diff -r 608267a4f634 -r 8963bc3aa2e1 source/Lib/TLibEncoder/TEncCu.cpp
--- a/source/Lib/TLibEncoder/TEncCu.cpp	Tue May 06 20:46:31 2014 -0500
+++ b/source/Lib/TLibEncoder/TEncCu.cpp	Tue May 06 21:43:35 2014 -0500
@@ -381,7 +381,7 @@ void TEncCu::compressCU(TComDataCU* cu)
 
     if (m_bestCU[0]->getSlice()->getSliceType() == I_SLICE)
     {
-        xCompressIntraCU(m_bestCU[0], m_tempCU[0], 0);
+        xCompressIntraCU(m_bestCU[0], m_tempCU[0], 0, false);
 #if LOG_CU_STATISTICS
         int i = 0, part;
         do
@@ -414,10 +414,10 @@ void TEncCu::compressCU(TComDataCU* cu)
 
             /* At the start of analysis, the best CU is a null pointer
             On return, it points to the CU encode with best chosen mode*/
-            xCompressInterCU(outBestCU, m_tempCU[0], cu, 0, 0, 4);
+            xCompressInterCU(outBestCU, m_tempCU[0], cu, 0, false, 0, 4);
         }
         else
-            xCompressCU(m_bestCU[0], m_tempCU[0], 0);
+            xCompressCU(m_bestCU[0], m_tempCU[0], 0, false);
 #if LOG_CU_STATISTICS
         int i = 0, part;
         do
@@ -473,7 +473,7 @@ void TEncCu::encodeCU(TComDataCU* cu)
     }
 
     // Encode CU data
-    xEncodeCU(cu, 0, 0);
+    xEncodeCU(cu, 0, 0, false);
 }
 
 // ====================================================================================================================
@@ -552,7 +552,7 @@ void TEncCu::deriveTestModeAMP(TComDataC
  *- for loop of QP value to compress the current CU with all possible QP
 */
 
-void TEncCu::xCompressIntraCU(TComDataCU*& outBestCU, TComDataCU*& outTempCU, uint32_t depth)
+void TEncCu::xCompressIntraCU(TComDataCU*& outBestCU, TComDataCU*& outTempCU, uint32_t depth, bool bInsidePicture)
 {
     //PPAScopeEvent(TEncCu_xCompressIntraCU + depth);
 
@@ -569,29 +569,19 @@ void TEncCu::xCompressIntraCU(TComDataCU
         m_origYuv[0]->copyPartToYuv(m_origYuv[depth], outBestCU->getZorderIdxInCU());
     }
 
-    // variable for Early CU determination
-    bool bSubBranch = true;
+    TComSlice* slice = outTempCU->getSlice();
+    if (!bInsidePicture)
+    {
+        uint32_t lpelx = outBestCU->getCUPelX();
+        uint32_t tpely = outBestCU->getCUPelY();
+        uint32_t rpelx = lpelx + outBestCU->getCUSize(0);
+        uint32_t bpely = tpely + outBestCU->getCUSize(0);
+        bInsidePicture = (rpelx <= slice->getSPS()->getPicWidthInLumaSamples() &&
+                          bpely <= slice->getSPS()->getPicHeightInLumaSamples());
+    }
 
-    // variable for Cbf fast mode PU decision
-    bool bBoundary = false;
-
-    uint32_t lpelx = outBestCU->getCUPelX();
-    uint32_t rpelx = lpelx + outBestCU->getCUSize(0) - 1;
-    uint32_t tpelx = outBestCU->getCUPelY();
-    uint32_t bpely = tpelx + outBestCU->getCUSize(0) - 1;
-
-    // If slice start or slice end is within this cu...
-    TComSlice * slice = outTempCU->getPic()->getSlice();
-    bool bSliceEnd = (slice->getSliceCurEndCUAddr() > outTempCU->getSCUAddr() && slice->getSliceCurEndCUAddr() < outTempCU->getSCUAddr() + outTempCU->getTotalNumPart());
-    bool bInsidePicture = (rpelx < outBestCU->getSlice()->getSPS()->getPicWidthInLumaSamples()) && (bpely < outBestCU->getSlice()->getSPS()->getPicHeightInLumaSamples());
-
-    //Data for splitting
-    uint8_t nextDepth = depth + 1;
-    uint32_t partUnitIdx = 0;
-    TComDataCU* subBestPartCU[4], *subTempPartCU[4];
-
-    //We need to split; so dont try these modes
-    if (!bSliceEnd && bInsidePicture)
+    // We need to split, so don't try these modes.
+    if (bInsidePicture)
     {
         outTempCU->initEstData(depth);
 
@@ -600,7 +590,7 @@ void TEncCu::xCompressIntraCU(TComDataCU
 
         if (depth == g_maxCUDepth - g_addCUDepth)
         {
-            if (outTempCU->getCUSize(0) > (1 << outTempCU->getSlice()->getSPS()->getQuadtreeTULog2MinSize()))
+            if (outTempCU->getCUSize(0) > (1 << slice->getSPS()->getQuadtreeTULog2MinSize()))
             {
                 xCheckRDCostIntra(outBestCU, outTempCU, SIZE_NxN);
             }
@@ -610,34 +600,26 @@ void TEncCu::xCompressIntraCU(TComDataCU
         m_entropyCoder->encodeSplitFlag(outBestCU, 0, depth);
         outBestCU->m_totalBits += m_entropyCoder->getNumberOfWrittenBits(); // split bits
         outBestCU->m_totalCost  = m_rdCost->calcRdCost(outBestCU->m_totalDistortion, outBestCU->m_totalBits);
-
-        // Early CU determination
-        if (outBestCU->isSkipped(0))
-            bSubBranch = false;
-        else
-            bSubBranch = true;
-    }
-    else if (!(bSliceEnd && bInsidePicture))
-    {
-        bBoundary = true;
     }
 
     outTempCU->initEstData(depth);
 
     // further split
-    if (bSubBranch && depth < g_maxCUDepth - g_addCUDepth)
+    if (depth < g_maxCUDepth - g_addCUDepth)
     {
+        uint8_t     nextDepth     = depth + 1;
+        TComDataCU* subBestPartCU = m_bestCU[nextDepth];
+        TComDataCU* subTempPartCU = m_tempCU[nextDepth];
+        uint32_t partUnitIdx = 0;
         for (; partUnitIdx < 4; partUnitIdx++)
         {
-            subBestPartCU[partUnitIdx] = m_bestCU[nextDepth];
-            subTempPartCU[partUnitIdx] = m_tempCU[nextDepth];
+            subBestPartCU->initSubCU(outTempCU, partUnitIdx, nextDepth); // clear sub partition datas or init.
 
-            subBestPartCU[partUnitIdx]->initSubCU(outTempCU, partUnitIdx, nextDepth);     // clear sub partition datas or init.
-            subTempPartCU[partUnitIdx]->initSubCU(outTempCU, partUnitIdx, nextDepth);     // clear sub partition datas or init.
-
-            bool bInSlice = subBestPartCU[partUnitIdx]->getSCUAddr() < slice->getSliceCurEndCUAddr();
-            if (bInSlice && (subBestPartCU[partUnitIdx]->getCUPelX() < slice->getSPS()->getPicWidthInLumaSamples()) && (subBestPartCU[partUnitIdx]->getCUPelY() < slice->getSPS()->getPicHeightInLumaSamples()))
+            if (bInsidePicture ||
+                ((subBestPartCU->getCUPelX() < slice->getSPS()->getPicWidthInLumaSamples()) &&
+                 (subBestPartCU->getCUPelY() < slice->getSPS()->getPicHeightInLumaSamples())))
             {
+                subTempPartCU->initSubCU(outTempCU, partUnitIdx, nextDepth); // clear sub partition datas or init.
                 if (0 == partUnitIdx) //initialize RD with previous depth buffer
                 {
                     m_rdSbacCoders[nextDepth][CI_CURR_BEST]->load(m_rdSbacCoders[depth][CI_CURR_BEST]);
@@ -647,33 +629,32 @@ void TEncCu::xCompressIntraCU(TComDataCU
                     m_rdSbacCoders[nextDepth][CI_CURR_BEST]->load(m_rdSbacCoders[nextDepth][CI_NEXT_BEST]);
                 }
 
-                xCompressIntraCU(subBestPartCU[partUnitIdx], subTempPartCU[partUnitIdx], nextDepth);
-                outTempCU->copyPartFrom(subBestPartCU[partUnitIdx], partUnitIdx, nextDepth); // Keep best part data to current temporary data.
-                xCopyYuv2Tmp(subBestPartCU[partUnitIdx]->getTotalNumPart() * partUnitIdx, nextDepth);
+                xCompressIntraCU(subBestPartCU, subTempPartCU, nextDepth, bInsidePicture);
+                outTempCU->copyPartFrom(subBestPartCU, partUnitIdx, nextDepth); // Keep best part data to current temporary data.
+                xCopyYuv2Tmp(subBestPartCU->getTotalNumPart() * partUnitIdx, nextDepth);
             }
-            else if (bInSlice)
+            else
             {
-                subBestPartCU[partUnitIdx]->copyToPic(nextDepth);
-                outTempCU->copyPartFrom(subBestPartCU[partUnitIdx], partUnitIdx, nextDepth);
+                subBestPartCU->copyToPic(nextDepth);
+                outTempCU->copyPartFrom(subBestPartCU, partUnitIdx, nextDepth);
             }
         }
 
-        if (!bBoundary)
+        if (bInsidePicture)
         {
             m_entropyCoder->resetBits();
             m_entropyCoder->encodeSplitFlag(outTempCU, 0, depth);
-
             outTempCU->m_totalBits += m_entropyCoder->getNumberOfWrittenBits(); // split bits
         }
         outTempCU->m_totalCost = m_rdCost->calcRdCost(outTempCU->m_totalDistortion, outTempCU->m_totalBits);
 
-        if ((g_maxCUSize >> depth) == outTempCU->getSlice()->getPPS()->getMinCuDQPSize() && outTempCU->getSlice()->getPPS()->getUseDQP())
+        if ((g_maxCUSize >> depth) == slice->getPPS()->getMinCuDQPSize() && slice->getPPS()->getUseDQP())
         {
             bool hasResidual = false;
-            for (uint32_t uiBlkIdx = 0; uiBlkIdx < outTempCU->getTotalNumPart(); uiBlkIdx++)
+            for (uint32_t blkIdx = 0; blkIdx < outTempCU->getTotalNumPart(); blkIdx++)
             {
-                if (outTempCU->getCbf(uiBlkIdx, TEXT_LUMA) || outTempCU->getCbf(uiBlkIdx, TEXT_CHROMA_U) |
-                    outTempCU->getCbf(uiBlkIdx, TEXT_CHROMA_V))
+                if (outTempCU->getCbf(blkIdx, TEXT_LUMA) || outTempCU->getCbf(blkIdx, TEXT_CHROMA_U) ||
+                    outTempCU->getCbf(blkIdx, TEXT_CHROMA_V))
                 {
                     hasResidual = true;
                     break;
@@ -694,15 +675,14 @@ void TEncCu::xCompressIntraCU(TComDataCU
         }
 
         m_rdSbacCoders[nextDepth][CI_NEXT_BEST]->store(m_rdSbacCoders[depth][CI_TEMP_BEST]);
-        xCheckBestMode(outBestCU, outTempCU, depth); // RD compare current prediction with split prediction.
+        xCheckBestMode(outBestCU, outTempCU, depth); // RD compare current CU against split
     }
-
     outBestCU->copyToPic(depth); // Copy Best data to Picture for next partition prediction.
 
+    if (!bInsidePicture) return;
+
     // Copy Yuv data to picture Yuv
-    xCopyYuv2Pic(outBestCU->getPic(), outBestCU->getAddr(), outBestCU->getZorderIdxInCU(), depth, depth, outBestCU, lpelx, tpelx);
-
-    if (bBoundary || (bSliceEnd && bInsidePicture)) return;
+    xCopyYuv2Pic(pic, outBestCU->getAddr(), outBestCU->getZorderIdxInCU(), depth);
 
     // Assert if Best prediction mode is NONE
     // Selected mode's RD-cost must be not MAX_INT64.
@@ -711,19 +691,20 @@ void TEncCu::xCompressIntraCU(TComDataCU
     assert(outBestCU->m_totalCost != MAX_INT64);
 }
 
-void TEncCu::xCompressCU(TComDataCU*& outBestCU, TComDataCU*& outTempCU, uint32_t depth, PartSize parentSize)
+void TEncCu::xCompressCU(TComDataCU*& outBestCU, TComDataCU*& outTempCU, uint32_t depth, bool bInsidePicture, PartSize parentSize)
 {
     //PPAScopeEvent(TEncCu_xCompressCU + depth);
 
     TComPic* pic = outBestCU->getPic();
 
-    // get Original YUV data from picture
     if (depth == 0)
     {
+        // get original YUV data from picture
         m_origYuv[depth]->copyFromPicYuv(pic->getPicYuvOrg(), outBestCU->getAddr(), outBestCU->getZorderIdxInCU());
     }
     else
     {
+        // copy partition YUV from depth 0 CTU cache
         m_origYuv[0]->copyPartToYuv(m_origYuv[depth], outBestCU->getZorderIdxInCU());
     }
 
@@ -734,26 +715,24 @@ void TEncCu::xCompressCU(TComDataCU*& ou
     bool doNotBlockPu = true;
     bool earlyDetectionSkipMode = false;
 
-    bool bBoundary = false;
-    uint32_t lpelx = outBestCU->getCUPelX();
-    uint32_t rpelx = lpelx + outBestCU->getCUSize(0) - 1;
-    uint32_t tpely = outBestCU->getCUPelY();
-    uint32_t bpely = tpely + outBestCU->getCUSize(0) - 1;
-
-    // If slice start or slice end is within this cu...
-    TComSlice* slice = outTempCU->getPic()->getSlice();
-    bool bSliceEnd = (slice->getSliceCurEndCUAddr() > outTempCU->getSCUAddr() &&
-                      slice->getSliceCurEndCUAddr() < outTempCU->getSCUAddr() + outTempCU->getTotalNumPart());
-    bool bInsidePicture = (rpelx < outBestCU->getSlice()->getSPS()->getPicWidthInLumaSamples()) &&
-        (bpely < outBestCU->getSlice()->getSPS()->getPicHeightInLumaSamples());
+    TComSlice* slice = outTempCU->getSlice();
+    if (!bInsidePicture)
+    {


More information about the x265-commits mailing list