[x265-commits] [x265] predict: introduce PredictionUnit structure to maintain c...

Steve Borho steve at borho.org
Wed Feb 25 04:48:18 CET 2015


details:   http://hg.videolan.org/x265/rev/c9233cf40d60
branches:  
changeset: 9416:c9233cf40d60
user:      Steve Borho <steve at borho.org>
date:      Tue Feb 24 11:42:50 2015 -0600
description:
predict: introduce PredictionUnit structure to maintain current PU geometry

The whole idea of prepMotionCompensation was to cache some data that could be
shared between motionCompensation() calls but since the motion vectors and refs
were included in that data, it had to be re-done each time any way.  In the
mean-time, much code was taking advantage of the PU data members but in a
fragile way, data hazards were too common.

The PredictionUnit struct is intended to be stack allocated and the PU geometry
is valid so long as the structure is within scope, making the data safe.
Subject: [x265] search: pass PredictionUnit to mergeEstimation - removes redundant data

details:   http://hg.videolan.org/x265/rev/c03938eed71c
branches:  
changeset: 9417:c03938eed71c
user:      Steve Borho <steve at borho.org>
date:      Tue Feb 24 12:53:13 2015 -0600
description:
search: pass PredictionUnit to mergeEstimation - removes redundant data
Subject: [x265] search: improve comments and check strings in mergeEstimation()

details:   http://hg.videolan.org/x265/rev/14ee5be0465d
branches:  
changeset: 9418:14ee5be0465d
user:      Steve Borho <steve at borho.org>
date:      Tue Feb 24 12:57:26 2015 -0600
description:
search: improve comments and check strings in mergeEstimation()
Subject: [x265] search: prune temp members from MergeData, there was no caching

details:   http://hg.videolan.org/x265/rev/1700def8650e
branches:  
changeset: 9419:1700def8650e
user:      Steve Borho <steve at borho.org>
date:      Tue Feb 24 13:06:39 2015 -0600
description:
search: prune temp members from MergeData, there was no caching

Each PU had to generate its own list of merge candidates, so they might as well
be declared on the stack
Subject: [x265] search: misc variable renames and comment improvements

details:   http://hg.videolan.org/x265/rev/87173d41df87
branches:  
changeset: 9420:87173d41df87
user:      Steve Borho <steve at borho.org>
date:      Tue Feb 24 13:27:15 2015 -0600
description:
search: misc variable renames and comment improvements

diffstat:

 source/common/cudata.cpp    |   82 +++++++-------
 source/common/cudata.h      |    2 +-
 source/common/predict.cpp   |  225 ++++++++++++++++++++------------------
 source/common/predict.h     |   58 ++++-----
 source/encoder/analysis.cpp |  163 ++++++++++++---------------
 source/encoder/search.cpp   |  255 +++++++++++++++++++++----------------------
 source/encoder/search.h     |   23 +--
 7 files changed, 390 insertions(+), 418 deletions(-)

diffs (truncated from 1596 to 300 lines):

diff -r ce90d8c78ac9 -r 87173d41df87 source/common/cudata.cpp
--- a/source/common/cudata.cpp	Tue Feb 24 20:44:20 2015 -0600
+++ b/source/common/cudata.cpp	Tue Feb 24 13:27:15 2015 -0600
@@ -1375,8 +1375,8 @@ bool CUData::hasEqualMotion(uint32_t abs
     return true;
 }
 
-/* Construct list of merging candidates */
-uint32_t CUData::getInterMergeCandidates(uint32_t absPartIdx, uint32_t puIdx, MVField(*mvFieldNeighbours)[2], uint8_t* interDirNeighbours) const
+/* Construct list of merging candidates, returns count */
+uint32_t CUData::getInterMergeCandidates(uint32_t absPartIdx, uint32_t puIdx, MVField(*candMvField)[2], uint8_t* candDir) const
 {
     uint32_t absPartAddr = m_absIdxInCTU + absPartIdx;
     const bool isInterB = m_slice->isInterB();
@@ -1385,10 +1385,10 @@ uint32_t CUData::getInterMergeCandidates
 
     for (uint32_t i = 0; i < maxNumMergeCand; ++i)
     {
-        mvFieldNeighbours[i][0].mv = 0;
-        mvFieldNeighbours[i][1].mv = 0;
-        mvFieldNeighbours[i][0].refIdx = REF_NOT_VALID;
-        mvFieldNeighbours[i][1].refIdx = REF_NOT_VALID;
+        candMvField[i][0].mv = 0;
+        candMvField[i][1].mv = 0;
+        candMvField[i][0].refIdx = REF_NOT_VALID;
+        candMvField[i][1].refIdx = REF_NOT_VALID;
     }
 
     /* calculate the location of upper-left corner pixel and size of the current PU */
@@ -1420,11 +1420,11 @@ uint32_t CUData::getInterMergeCandidates
     if (isAvailableA1)
     {
         // get Inter Dir
-        interDirNeighbours[count] = cuLeft->m_interDir[leftPartIdx];
+        candDir[count] = cuLeft->m_interDir[leftPartIdx];
         // get Mv from Left
-        cuLeft->getMvField(cuLeft, leftPartIdx, 0, mvFieldNeighbours[count][0]);
+        cuLeft->getMvField(cuLeft, leftPartIdx, 0, candMvField[count][0]);
         if (isInterB)
-            cuLeft->getMvField(cuLeft, leftPartIdx, 1, mvFieldNeighbours[count][1]);
+            cuLeft->getMvField(cuLeft, leftPartIdx, 1, candMvField[count][1]);
 
         count++;
     
@@ -1444,11 +1444,11 @@ uint32_t CUData::getInterMergeCandidates
     if (isAvailableB1 && (!isAvailableA1 || !cuLeft->hasEqualMotion(leftPartIdx, *cuAbove, abovePartIdx)))
     {
         // get Inter Dir
-        interDirNeighbours[count] = cuAbove->m_interDir[abovePartIdx];
+        candDir[count] = cuAbove->m_interDir[abovePartIdx];
         // get Mv from Left
-        cuAbove->getMvField(cuAbove, abovePartIdx, 0, mvFieldNeighbours[count][0]);
+        cuAbove->getMvField(cuAbove, abovePartIdx, 0, candMvField[count][0]);
         if (isInterB)
-            cuAbove->getMvField(cuAbove, abovePartIdx, 1, mvFieldNeighbours[count][1]);
+            cuAbove->getMvField(cuAbove, abovePartIdx, 1, candMvField[count][1]);
 
         count++;
    
@@ -1465,11 +1465,11 @@ uint32_t CUData::getInterMergeCandidates
     if (isAvailableB0 && (!isAvailableB1 || !cuAbove->hasEqualMotion(abovePartIdx, *cuAboveRight, aboveRightPartIdx)))
     {
         // get Inter Dir
-        interDirNeighbours[count] = cuAboveRight->m_interDir[aboveRightPartIdx];
+        candDir[count] = cuAboveRight->m_interDir[aboveRightPartIdx];
         // get Mv from Left
-        cuAboveRight->getMvField(cuAboveRight, aboveRightPartIdx, 0, mvFieldNeighbours[count][0]);
+        cuAboveRight->getMvField(cuAboveRight, aboveRightPartIdx, 0, candMvField[count][0]);
         if (isInterB)
-            cuAboveRight->getMvField(cuAboveRight, aboveRightPartIdx, 1, mvFieldNeighbours[count][1]);
+            cuAboveRight->getMvField(cuAboveRight, aboveRightPartIdx, 1, candMvField[count][1]);
 
         count++;
 
@@ -1486,11 +1486,11 @@ uint32_t CUData::getInterMergeCandidates
     if (isAvailableA0 && (!isAvailableA1 || !cuLeft->hasEqualMotion(leftPartIdx, *cuLeftBottom, leftBottomPartIdx)))
     {
         // get Inter Dir
-        interDirNeighbours[count] = cuLeftBottom->m_interDir[leftBottomPartIdx];
+        candDir[count] = cuLeftBottom->m_interDir[leftBottomPartIdx];
         // get Mv from Left
-        cuLeftBottom->getMvField(cuLeftBottom, leftBottomPartIdx, 0, mvFieldNeighbours[count][0]);
+        cuLeftBottom->getMvField(cuLeftBottom, leftBottomPartIdx, 0, candMvField[count][0]);
         if (isInterB)
-            cuLeftBottom->getMvField(cuLeftBottom, leftBottomPartIdx, 1, mvFieldNeighbours[count][1]);
+            cuLeftBottom->getMvField(cuLeftBottom, leftBottomPartIdx, 1, candMvField[count][1]);
 
         count++;
 
@@ -1510,11 +1510,11 @@ uint32_t CUData::getInterMergeCandidates
             && (!isAvailableB1 || !cuAbove->hasEqualMotion(abovePartIdx, *cuAboveLeft, aboveLeftPartIdx)))
         {
             // get Inter Dir
-            interDirNeighbours[count] = cuAboveLeft->m_interDir[aboveLeftPartIdx];
+            candDir[count] = cuAboveLeft->m_interDir[aboveLeftPartIdx];
             // get Mv from Left
-            cuAboveLeft->getMvField(cuAboveLeft, aboveLeftPartIdx, 0, mvFieldNeighbours[count][0]);
+            cuAboveLeft->getMvField(cuAboveLeft, aboveLeftPartIdx, 0, candMvField[count][0]);
             if (isInterB)
-                cuAboveLeft->getMvField(cuAboveLeft, aboveLeftPartIdx, 1, mvFieldNeighbours[count][1]);
+                cuAboveLeft->getMvField(cuAboveLeft, aboveLeftPartIdx, 1, candMvField[count][1]);
 
             count++;
 
@@ -1563,8 +1563,8 @@ uint32_t CUData::getInterMergeCandidates
         if (bExistMV)
         {
             dir |= 1;
-            mvFieldNeighbours[count][0].mv = colmv;
-            mvFieldNeighbours[count][0].refIdx = refIdx;
+            candMvField[count][0].mv = colmv;
+            candMvField[count][0].refIdx = refIdx;
         }
 
         if (isInterB)
@@ -1576,14 +1576,14 @@ uint32_t CUData::getInterMergeCandidates
             if (bExistMV)
             {
                 dir |= 2;
-                mvFieldNeighbours[count][1].mv = colmv;
-                mvFieldNeighbours[count][1].refIdx = refIdx;
+                candMvField[count][1].mv = colmv;
+                candMvField[count][1].refIdx = refIdx;
             }
         }
 
         if (dir != 0)
         {
-            interDirNeighbours[count] = (uint8_t)dir;
+            candDir[count] = (uint8_t)dir;
 
             count++;
         
@@ -1605,20 +1605,20 @@ uint32_t CUData::getInterMergeCandidates
             priorityList0 >>= 2;
             priorityList1 >>= 2;
 
-            if ((interDirNeighbours[i] & 0x1) && (interDirNeighbours[j] & 0x2))
+            if ((candDir[i] & 0x1) && (candDir[j] & 0x2))
             {
                 // get Mv from cand[i] and cand[j]
-                int refIdxL0 = mvFieldNeighbours[i][0].refIdx;
-                int refIdxL1 = mvFieldNeighbours[j][1].refIdx;
+                int refIdxL0 = candMvField[i][0].refIdx;
+                int refIdxL1 = candMvField[j][1].refIdx;
                 int refPOCL0 = m_slice->m_refPOCList[0][refIdxL0];
                 int refPOCL1 = m_slice->m_refPOCList[1][refIdxL1];
-                if (!(refPOCL0 == refPOCL1 && mvFieldNeighbours[i][0].mv == mvFieldNeighbours[j][1].mv))
+                if (!(refPOCL0 == refPOCL1 && candMvField[i][0].mv == candMvField[j][1].mv))
                 {
-                    mvFieldNeighbours[count][0].mv = mvFieldNeighbours[i][0].mv;
-                    mvFieldNeighbours[count][0].refIdx = refIdxL0;
-                    mvFieldNeighbours[count][1].mv = mvFieldNeighbours[j][1].mv;
-                    mvFieldNeighbours[count][1].refIdx = refIdxL1;
-                    interDirNeighbours[count] = 3;
+                    candMvField[count][0].mv = candMvField[i][0].mv;
+                    candMvField[count][0].refIdx = refIdxL0;
+                    candMvField[count][1].mv = candMvField[j][1].mv;
+                    candMvField[count][1].refIdx = refIdxL1;
+                    candDir[count] = 3;
 
                     count++;
 
@@ -1633,15 +1633,15 @@ uint32_t CUData::getInterMergeCandidates
     int refcnt = 0;
     while (count < maxNumMergeCand)
     {
-        interDirNeighbours[count] = 1;
-        mvFieldNeighbours[count][0].mv = 0;
-        mvFieldNeighbours[count][0].refIdx = r;
+        candDir[count] = 1;
+        candMvField[count][0].mv = 0;
+        candMvField[count][0].refIdx = r;
 
         if (isInterB)
         {
-            interDirNeighbours[count] = 3;
-            mvFieldNeighbours[count][1].mv.word = 0;
-            mvFieldNeighbours[count][1].refIdx = r;
+            candDir[count] = 3;
+            candMvField[count][1].mv.word = 0;
+            candMvField[count][1].refIdx = r;
         }
 
         count++;
diff -r ce90d8c78ac9 -r 87173d41df87 source/common/cudata.h
--- a/source/common/cudata.h	Tue Feb 24 20:44:20 2015 -0600
+++ b/source/common/cudata.h	Tue Feb 24 13:27:15 2015 -0600
@@ -195,7 +195,7 @@ public:
     uint8_t  getCbf(uint32_t absPartIdx, TextType ttype, uint32_t tuDepth) const { return (m_cbf[ttype][absPartIdx] >> tuDepth) & 0x1; }
     uint8_t  getQtRootCbf(uint32_t absPartIdx) const                             { return m_cbf[0][absPartIdx] || m_cbf[1][absPartIdx] || m_cbf[2][absPartIdx]; }
     int8_t   getRefQP(uint32_t currAbsIdxInCTU) const;
-    uint32_t getInterMergeCandidates(uint32_t absPartIdx, uint32_t puIdx, MVField (*mvFieldNeighbours)[2], uint8_t* interDirNeighbours) const;
+    uint32_t getInterMergeCandidates(uint32_t absPartIdx, uint32_t puIdx, MVField (*candMvField)[2], uint8_t* candDir) const;
     void     clipMv(MV& outMV) const;
     int      fillMvpCand(uint32_t puIdx, uint32_t absPartIdx, int picList, int refIdx, MV* amvpCand, MV* mvc) const;
     void     getIntraTUQtDepthRange(uint32_t tuDepthRange[2], uint32_t absPartIdx) const;
diff -r ce90d8c78ac9 -r 87173d41df87 source/common/predict.cpp
--- a/source/common/predict.cpp	Tue Feb 24 20:44:20 2015 -0600
+++ b/source/common/predict.cpp	Tue Feb 24 13:27:15 2015 -0600
@@ -34,6 +34,18 @@ using namespace x265;
 #pragma warning(disable: 4127) // conditional expression is constant
 #endif
 
+PredictionUnit::PredictionUnit(const CUData& cu, const CUGeom& cuGeom, int puIdx)
+{
+    /* address of CTU */
+    ctuAddr = cu.m_cuAddr;
+
+    /* offset of CU */
+    cuAbsPartIdx = cuGeom.absPartIdx;
+
+    /* offset and dimensions of PU */
+    cu.getPartIndexAndSize(puIdx, puAbsPartIdx, width, height);
+}
+
 namespace
 {
 inline pixel weightBidir(int w0, int16_t P0, int w1, int16_t P1, int round, int shift, int offset)
@@ -112,37 +124,25 @@ void Predict::predIntraChromaAng(uint32_
     primitives.cu[sizeIdx].intra_pred[dirMode](dst, stride, srcBuf, dirMode, 0);
 }
 
-void Predict::initMotionCompensation(const CUData& cu, const CUGeom& cuGeom, int partIdx)
+
+void Predict::motionCompensation(const CUData& cu, const PredictionUnit& pu, Yuv& predYuv, bool bLuma, bool bChroma)
 {
-    m_predSlice = cu.m_slice;
-    cu.getPartIndexAndSize(partIdx, m_puAbsPartIdx, m_puWidth, m_puHeight);
-    m_ctuAddr = cu.m_cuAddr;
-    m_cuAbsPartIdx = cuGeom.absPartIdx;
-}
+    int refIdx0 = cu.m_refIdx[0][pu.puAbsPartIdx];
+    int refIdx1 = cu.m_refIdx[1][pu.puAbsPartIdx];
 
-void Predict::prepMotionCompensation(const CUData& cu, const CUGeom& cuGeom, int partIdx)
-{
-    initMotionCompensation(cu, cuGeom, partIdx);
-
-    m_refIdx0      = cu.m_refIdx[0][m_puAbsPartIdx];
-    m_clippedMv[0] = cu.m_mv[0][m_puAbsPartIdx];
-    m_refIdx1      = cu.m_refIdx[1][m_puAbsPartIdx];
-    m_clippedMv[1] = cu.m_mv[1][m_puAbsPartIdx];
-    cu.clipMv(m_clippedMv[0]);
-    cu.clipMv(m_clippedMv[1]);
-}
-
-void Predict::motionCompensation(Yuv& predYuv, bool bLuma, bool bChroma)
-{
-    if (m_predSlice->isInterP())
+    if (cu.m_slice->isInterP())
     {
         /* P Slice */
         WeightValues wv0[3];
-        X265_CHECK(m_refIdx0 >= 0, "invalid P refidx\n");
-        X265_CHECK(m_refIdx0 < m_predSlice->m_numRefIdx[0], "P refidx out of range\n");
-        const WeightParam *wp0 = m_predSlice->m_weightPredTable[0][m_refIdx0];
 
-        if (m_predSlice->m_pps->bUseWeightPred && wp0->bPresentFlag)
+        X265_CHECK(refIdx0 >= 0, "invalid P refidx\n");
+        X265_CHECK(refIdx0 < cu.m_slice->m_numRefIdx[0], "P refidx out of range\n");
+        const WeightParam *wp0 = cu.m_slice->m_weightPredTable[0][refIdx0];
+
+        MV mv0 = cu.m_mv[0][pu.puAbsPartIdx];
+        cu.clipMv(mv0);
+
+        if (cu.m_slice->m_pps->bUseWeightPred && wp0->bPresentFlag)
         {
             for (int plane = 0; plane < 3; plane++)
             {
@@ -155,18 +155,18 @@ void Predict::motionCompensation(Yuv& pr
             ShortYuv& shortYuv = m_predShortYuv[0];
 
             if (bLuma)
-                predInterLumaShort(shortYuv, *m_predSlice->m_refPicList[0][m_refIdx0]->m_reconPic, m_clippedMv[0]);
+                predInterLumaShort(pu, shortYuv, *cu.m_slice->m_refPicList[0][refIdx0]->m_reconPic, mv0);
             if (bChroma)
-                predInterChromaShort(shortYuv, *m_predSlice->m_refPicList[0][m_refIdx0]->m_reconPic, m_clippedMv[0]);
+                predInterChromaShort(pu, shortYuv, *cu.m_slice->m_refPicList[0][refIdx0]->m_reconPic, mv0);
 
-            addWeightUni(predYuv, shortYuv, wv0, bLuma, bChroma);
+            addWeightUni(pu, predYuv, shortYuv, wv0, bLuma, bChroma);
         }
         else
         {
             if (bLuma)
-                predInterLumaPixel(predYuv, *m_predSlice->m_refPicList[0][m_refIdx0]->m_reconPic, m_clippedMv[0]);
+                predInterLumaPixel(pu, predYuv, *cu.m_slice->m_refPicList[0][refIdx0]->m_reconPic, mv0);
             if (bChroma)
-                predInterChromaPixel(predYuv, *m_predSlice->m_refPicList[0][m_refIdx0]->m_reconPic, m_clippedMv[0]);
+                predInterChromaPixel(pu, predYuv, *cu.m_slice->m_refPicList[0][refIdx0]->m_reconPic, mv0);
         }
     }
     else
@@ -176,10 +176,10 @@ void Predict::motionCompensation(Yuv& pr
         WeightValues wv0[3], wv1[3];
         const WeightParam *pwp0, *pwp1;
 
-        if (m_predSlice->m_pps->bUseWeightedBiPred)
+        if (cu.m_slice->m_pps->bUseWeightedBiPred)


More information about the x265-commits mailing list