[x265-commits] [x265] predict: prepare motionCompensation sets base class fields

Deepthi Nandakumar deepthi at multicorewareinc.com
Thu Jul 31 22:03:53 CEST 2014


details:   http://hg.videolan.org/x265/rev/8f30d3659f82
branches:  
changeset: 7661:8f30d3659f82
user:      Deepthi Nandakumar <deepthi at multicorewareinc.com>
date:      Thu Jul 31 06:44:12 2014 +0530
description:
predict: prepare motionCompensation sets base class fields
Subject: [x265] predict: save clipped MVs

details:   http://hg.videolan.org/x265/rev/323e8e87f903
branches:  
changeset: 7662:323e8e87f903
user:      Deepthi Nandakumar <deepthi at multicorewareinc.com>
date:      Thu Jul 31 15:57:26 2014 +0530
description:
predict: save clipped MVs
Subject: [x265] predict: nits, cleanup, add TODO comments

details:   http://hg.videolan.org/x265/rev/88a18a365d56
branches:  
changeset: 7663:88a18a365d56
user:      Deepthi Nandakumar <deepthi at multicorewareinc.com>
date:      Thu Jul 31 16:49:02 2014 +0530
description:
predict: nits, cleanup, add TODO comments
Subject: [x265] rc: update vbv for all b frames

details:   http://hg.videolan.org/x265/rev/e85b0aaa64e4
branches:  
changeset: 7664:e85b0aaa64e4
user:      Santhoshini Sekar <santhoshini at multicorewareinc.com>
date:      Thu Jul 31 11:08:02 2014 +0530
description:
rc: update vbv for all b frames

HEVC is complex (and slow) enough that we can afford to update/plan the VBV
buffer states for all frames, not just I and P. The leads to smoother rate
control, particularly when there are large stretches of B frames, and less
(over) compensation is necessary for P frames.

diffstat:

 source/Lib/TLibEncoder/TEncSearch.cpp |   18 ++--
 source/common/lowres.cpp              |    1 +
 source/common/lowres.h                |    4 +
 source/encoder/analysis.cpp           |   14 +-
 source/encoder/predict.cpp            |  122 +++++++++++++++++----------------
 source/encoder/predict.h              |   36 +++++----
 source/encoder/ratecontrol.cpp        |   34 +++------
 source/encoder/slicetype.cpp          |   29 ++++++-
 8 files changed, 141 insertions(+), 117 deletions(-)

diffs (truncated from 636 to 300 lines):

diff -r 29ca05751777 -r e85b0aaa64e4 source/Lib/TLibEncoder/TEncSearch.cpp
--- a/source/Lib/TLibEncoder/TEncSearch.cpp	Thu Jul 31 02:06:50 2014 -0500
+++ b/source/Lib/TLibEncoder/TEncSearch.cpp	Thu Jul 31 11:08:02 2014 +0530
@@ -1857,6 +1857,7 @@ uint32_t TEncSearch::xMergeEstimation(TC
         cu->getCUMvField(REF_PIC_LIST_1)->m_mv[m.absPartIdx] = m.mvFieldNeighbours[mergeCand][1].mv;
         cu->getCUMvField(REF_PIC_LIST_1)->m_refIdx[m.absPartIdx] = (char)m.mvFieldNeighbours[mergeCand][1].refIdx;
 
+        prepMotionCompensation(cu, puIdx);
         motionCompensation(cu, &m_predTempYuv, REF_PIC_LIST_X, true, false);
         uint32_t costCand = m_me.bufSATD(m_predTempYuv.getLumaAddr(m.absPartIdx), m_predTempYuv.getStride());
         uint32_t bitsCand = getTUBits(mergeCand, m.maxNumMergeCand);
@@ -1905,11 +1906,6 @@ bool TEncSearch::predInterSearch(TComDat
         uint32_t partAddr;
         int      roiWidth, roiHeight;
         cu->getPartIndexAndSize(partIdx, partAddr, roiWidth, roiHeight);
-        
-        /* Prediction data for each partition */
-        m_partAddr = partAddr;
-        m_width = roiWidth;
-        m_height = roiHeight;        
 
         pixel* pu = fenc->getLumaAddr(cu->getAddr(), cu->getZorderIdxInCU() + partAddr);
         m_me.setSourcePU(pu - fenc->getLumaAddr(), roiWidth, roiHeight);
@@ -1940,6 +1936,7 @@ bool TEncSearch::predInterSearch(TComDat
                 cu->getCUMvField(REF_PIC_LIST_1)->setAllMvField(merge.mvField[1], partSize, partAddr, 0, partIdx);
                 totalmebits += merge.bits;
 
+                prepMotionCompensation(cu, partIdx);     
                 motionCompensation(cu, predYuv, REF_PIC_LIST_X, true, bChroma);
                 continue;
             }
@@ -1982,7 +1979,8 @@ bool TEncSearch::predInterSearch(TComDat
 
                     cu->clipMv(mvCand);
 
-                    predInterLumaBlk(cu->m_slice->m_refPicList[l][ref]->getPicYuvRec(), cu->getAddr(), cu->getZorderIdxInCU(), &mvCand, &m_predTempYuv);
+                    prepMotionCompensation(cu, partIdx);
+                    predInterLumaBlk(cu->m_slice->m_refPicList[l][ref]->getPicYuvRec(), &m_predTempYuv, &mvCand);
                     uint32_t cost = m_me.bufSAD(m_predTempYuv.getLumaAddr(partAddr), m_predTempYuv.getStride());
                     cost = (uint32_t)m_rdCost.calcRdSADCost(cost, MVP_IDX_BITS);
 
@@ -2028,8 +2026,10 @@ bool TEncSearch::predInterSearch(TComDat
             // Generate reference subpels
             TComPicYuv *refPic0 = cu->m_slice->m_refPicList[0][list[0].ref]->getPicYuvRec();
             TComPicYuv *refPic1 = cu->m_slice->m_refPicList[1][list[1].ref]->getPicYuvRec();
-            predInterLumaBlk(refPic0, cu->getAddr(), cu->getZorderIdxInCU(), &list[0].mv, &m_predYuv[0]);
-            predInterLumaBlk(refPic1, cu->getAddr(), cu->getZorderIdxInCU(), &list[1].mv, &m_predYuv[1]);
+            
+            prepMotionCompensation(cu, partIdx);
+            predInterLumaBlk(refPic0, &m_predYuv[0], &list[0].mv);
+            predInterLumaBlk(refPic1, &m_predYuv[1], &list[1].mv);
 
             pixel *pred0 = m_predYuv[0].getLumaAddr(partAddr);
             pixel *pred1 = m_predYuv[1].getLumaAddr(partAddr);
@@ -2155,7 +2155,7 @@ bool TEncSearch::predInterSearch(TComDat
 
             totalmebits += list[1].bits;
         }
-
+        prepMotionCompensation(cu, partIdx);
         motionCompensation(cu, predYuv, REF_PIC_LIST_X, true, bChroma);
     }
 
diff -r 29ca05751777 -r e85b0aaa64e4 source/common/lowres.cpp
--- a/source/common/lowres.cpp	Thu Jul 31 02:06:50 2014 -0500
+++ b/source/common/lowres.cpp	Thu Jul 31 11:08:02 2014 +0530
@@ -135,6 +135,7 @@ void Lowres::init(TComPicYuv *orig, int 
     sliceType = type;
     frameNum = poc;
     leadingBframes = 0;
+    indB = 0;
     satdCost = (int64_t)-1;
     memset(costEst, -1, sizeof(costEst));
     memset(weightedCostDelta, 0, sizeof(weightedCostDelta));
diff -r 29ca05751777 -r e85b0aaa64e4 source/common/lowres.h
--- a/source/common/lowres.h	Thu Jul 31 02:06:50 2014 -0500
+++ b/source/common/lowres.h	Thu Jul 31 11:08:02 2014 +0530
@@ -121,8 +121,11 @@ struct Lowres : public ReferencePlanes
     uint16_t(*lowresCosts[X265_BFRAME_MAX + 2][X265_BFRAME_MAX + 2]);
     int32_t*  lowresMvCosts[2][X265_BFRAME_MAX + 1];
     MV*       lowresMvs[2][X265_BFRAME_MAX + 1];
+
+    /* used for vbvLookahead */
     int       plannedType[X265_LOOKAHEAD_MAX + 1];
     int64_t   plannedSatd[X265_LOOKAHEAD_MAX + 1];
+    int       indB;
     int       bframes;
 
     /* rate control / adaptive quant data */
@@ -132,6 +135,7 @@ struct Lowres : public ReferencePlanes
     uint64_t  wp_ssd[3];       // This is different than SSDY, this is sum(pixel^2) - sum(pixel)^2 for entire frame
     uint64_t  wp_sum[3];
 
+    /* cutree intermediate data */
     uint16_t* propagateCost;
     double    weightedCostDelta[X265_BFRAME_MAX + 2];
 
diff -r 29ca05751777 -r e85b0aaa64e4 source/encoder/analysis.cpp
--- a/source/encoder/analysis.cpp	Thu Jul 31 02:06:50 2014 -0500
+++ b/source/encoder/analysis.cpp	Thu Jul 31 11:08:02 2014 +0530
@@ -660,7 +660,7 @@ void Analysis::compressInterCU_rd0_4(TCo
                     int numPart = outBestCU->getNumPartInter();
                     for (int partIdx = 0; partIdx < numPart; partIdx++)
                     {
-                        outBestCU->getPartIndexAndSize(partIdx, m_partAddr, m_width, m_height);
+                        prepMotionCompensation(outBestCU, partIdx);
                         motionCompensation(outBestCU, m_bestPredYuv[depth], REF_PIC_LIST_X, false, true);
                     }
 
@@ -733,7 +733,7 @@ void Analysis::compressInterCU_rd0_4(TCo
                         int numPart = outBestCU->getNumPartInter();
                         for (int partIdx = 0; partIdx < numPart; partIdx++)
                         {
-                            outBestCU->getPartIndexAndSize(partIdx, m_partAddr, m_width, m_height);
+                            prepMotionCompensation(outBestCU, partIdx);
                             motionCompensation(outBestCU, m_bestPredYuv[depth], REF_PIC_LIST_X, false, true);
                         }
 
@@ -758,7 +758,7 @@ void Analysis::compressInterCU_rd0_4(TCo
                         int numPart = outBestCU->getNumPartInter();
                         for (int partIdx = 0; partIdx < numPart; partIdx++)
                         {
-                            outBestCU->getPartIndexAndSize(partIdx, m_partAddr, m_width, m_height);
+                            prepMotionCompensation(outBestCU, partIdx);
                             motionCompensation(outBestCU, m_bestPredYuv[depth], REF_PIC_LIST_X, false, true);
                         }
 
@@ -775,7 +775,7 @@ void Analysis::compressInterCU_rd0_4(TCo
                         int numPart = outBestCU->getNumPartInter();
                         for (int partIdx = 0; partIdx < numPart; partIdx++)
                         {
-                            outBestCU->getPartIndexAndSize(partIdx, m_partAddr, m_width, m_height);
+                            prepMotionCompensation(outBestCU, partIdx);
                             motionCompensation(outBestCU, m_bestPredYuv[depth], REF_PIC_LIST_X, false, true);
                         }
                     }
@@ -1371,7 +1371,7 @@ void Analysis::checkMerge2Nx2N_rd0_4(TCo
 
             // do MC only for Luma part
             /* Set CU parameters for motion compensation */
-            outTempCU->getPartIndexAndSize(0, m_partAddr, m_width, m_height);
+            prepMotionCompensation(outTempCU, 0);
             motionCompensation(outTempCU, m_tmpPredYuv[depth], REF_PIC_LIST_X, true, false);
             uint32_t bitsCand = getTUBits(mergeCand, maxNumMergeCand);
             outTempCU->m_totalBits = bitsCand;
@@ -1410,7 +1410,7 @@ void Analysis::checkMerge2Nx2N_rd0_4(TCo
             int numPart = outBestCU->getNumPartInter();
             for (int partIdx = 0; partIdx < numPart; partIdx++)
             {
-                outBestCU->getPartIndexAndSize(partIdx, m_partAddr, m_width, m_height);
+                prepMotionCompensation(outBestCU, partIdx);
                 motionCompensation(outBestCU, bestPredYuv, REF_PIC_LIST_X, false, true);
             }
 
@@ -1484,7 +1484,7 @@ void Analysis::checkMerge2Nx2N_rd5_6(TCo
                     outTempCU->getCUMvField(REF_PIC_LIST_1)->setAllMvField(mvFieldNeighbours[mergeCand][1], SIZE_2Nx2N, 0, 0); // interprets depth relative to outTempCU level
 
                     // do MC
-                    outTempCU->getPartIndexAndSize(0, m_partAddr, m_width, m_height);
+                    prepMotionCompensation(outTempCU, 0);
                     motionCompensation(outTempCU, m_tmpPredYuv[depth], REF_PIC_LIST_X, true, true);
                     // estimate residual and encode everything
                     if (noResidual)
diff -r 29ca05751777 -r e85b0aaa64e4 source/encoder/predict.cpp
--- a/source/encoder/predict.cpp	Thu Jul 31 02:06:50 2014 -0500
+++ b/source/encoder/predict.cpp	Thu Jul 31 11:08:02 2014 +0530
@@ -191,117 +191,119 @@ void Predict::predIntraChromaAng(pixel* 
     primitives.intra_pred[sizeIdx][dirMode](dst, stride, refLft + tuSize - 1, refAbv + tuSize - 1, dirMode, 0);
 }
 
-bool Predict::checkIdenticalMotion(TComDataCU* cu)
+bool Predict::checkIdenticalMotion()
 {
-    X265_CHECK(cu->m_slice->isInterB(), "identical motion check in P frame\n");
-    if (!cu->m_slice->m_pps->bUseWeightedBiPred)
+    X265_CHECK(m_slice->isInterB(), "identical motion check in P frame\n");
+    if (!m_slice->m_pps->bUseWeightedBiPred)
     {
-        int refIdxL0 = cu->getCUMvField(0)->getRefIdx(m_partAddr);
-        int refIdxL1 = cu->getCUMvField(1)->getRefIdx(m_partAddr);
+        int refIdxL0 = m_mvField[0]->getRefIdx(m_partAddr);
+        int refIdxL1 = m_mvField[1]->getRefIdx(m_partAddr);
         if (refIdxL0 >= 0 && refIdxL1 >= 0)
         {
-            int refPOCL0 = cu->m_slice->m_refPOCList[0][refIdxL0];
-            int refPOCL1 = cu->m_slice->m_refPOCList[1][refIdxL1];
-            if (refPOCL0 == refPOCL1 && cu->getCUMvField(0)->getMv(m_partAddr) == cu->getCUMvField(1)->getMv(m_partAddr))
+            int refPOCL0 = m_slice->m_refPOCList[0][refIdxL0];
+            int refPOCL1 = m_slice->m_refPOCList[1][refIdxL1];
+            if (refPOCL0 == refPOCL1 && m_mvField[0]->getMv(m_partAddr) == m_mvField[1]->getMv(m_partAddr))
                 return true;
         }
     }
     return false;
 }
 
+void Predict::prepMotionCompensation(TComDataCU* cu, int partIdx)
+{
+    m_slice = cu->m_slice;
+    cu->getPartIndexAndSize(partIdx, m_partAddr, m_width, m_height);
+    m_cuAddr = cu->getAddr();
+    m_zOrderIdxinCU = cu->getZorderIdxInCU();
+
+    m_mvField[0] = cu->getCUMvField(REF_PIC_LIST_0);
+    m_mvField[1] = cu->getCUMvField(REF_PIC_LIST_1);
+
+    ClippedMv[0] = m_mvField[0]->getMv(m_partAddr);
+    ClippedMv[1] = m_mvField[1]->getMv(m_partAddr);
+    cu->clipMv(ClippedMv[0]);
+    cu->clipMv(ClippedMv[1]);
+}
+
 void Predict::motionCompensation(TComDataCU* cu, TComYuv* predYuv, int list, bool bLuma, bool bChroma)
 {
-    if (cu->m_slice->isInterP())
+    if (m_slice->isInterP())
         list = REF_PIC_LIST_0;
     if (list != REF_PIC_LIST_X)
     {
-        if (cu->m_slice->m_pps->bUseWeightPred)
+        if (m_slice->m_pps->bUseWeightPred)
         {
             ShortYuv* shortYuv = &m_predShortYuv[0];
-            int refId = cu->getCUMvField(list)->getRefIdx(m_partAddr);
+            int refId = m_mvField[list]->getRefIdx(m_partAddr);
             X265_CHECK(refId >= 0, "refidx is not positive\n");
 
-            MV mv = cu->getCUMvField(list)->getMv(m_partAddr);
-            cu->clipMv(mv);
             if (bLuma)
-                predInterLumaBlk(cu->m_slice->m_refPicList[list][refId]->getPicYuvRec(), cu->getAddr(), cu->getZorderIdxInCU(),
-                                  &mv, shortYuv);
+                predInterLumaBlk(m_slice->m_refPicList[list][refId]->getPicYuvRec(), shortYuv, &ClippedMv[list]);
             if (bChroma)
-                predInterChromaBlk(cu->m_slice->m_refPicList[list][refId]->getPicYuvRec(), cu->getAddr(), cu->getZorderIdxInCU(), 
-                                    &mv, shortYuv);
+                predInterChromaBlk(m_slice->m_refPicList[list][refId]->getPicYuvRec(), shortYuv, &ClippedMv[list]);
 
             xWeightedPredictionUni(cu, shortYuv, m_partAddr, m_width, m_height, list, predYuv, -1, bLuma, bChroma);
         }
         else
-            predInterUni(cu, list, predYuv, bLuma, bChroma);
+            predInterUni(list, predYuv, bLuma, bChroma);
     }
     else
     {
-        if (checkIdenticalMotion(cu))
-            predInterUni(cu, REF_PIC_LIST_0, predYuv, bLuma, bChroma);
+        if (checkIdenticalMotion())
+            predInterUni(REF_PIC_LIST_0, predYuv, bLuma, bChroma);
         else
             predInterBi(cu, predYuv, bLuma, bChroma);
     }
 }
 
-void Predict::predInterUni(TComDataCU* cu, int list, TComYuv* outPredYuv, bool bLuma, bool bChroma)
+void Predict::predInterUni(int list, TComYuv* outPredYuv, bool bLuma, bool bChroma)
 {
-    int refIdx = cu->getCUMvField(list)->getRefIdx(m_partAddr);
+    int refIdx = m_mvField[list]->getRefIdx(m_partAddr);
 
     X265_CHECK(refIdx >= 0, "refidx is not positive\n");
 
-    MV mv = cu->getCUMvField(list)->getMv(m_partAddr);
-    cu->clipMv(mv);
-
     if (bLuma)
-        predInterLumaBlk(cu->m_slice->m_refPicList[list][refIdx]->getPicYuvRec(), cu->getAddr(), cu->getZorderIdxInCU(), 
-                          &mv, outPredYuv);
+        predInterLumaBlk(m_slice->m_refPicList[list][refIdx]->getPicYuvRec(), outPredYuv, &ClippedMv[list]);
 
     if (bChroma)
-        predInterChromaBlk(cu->m_slice->m_refPicList[list][refIdx]->getPicYuvRec(), cu->getAddr(), cu->getZorderIdxInCU(), 
-                            &mv, outPredYuv);
+        predInterChromaBlk(m_slice->m_refPicList[list][refIdx]->getPicYuvRec(), outPredYuv, &ClippedMv[list]);
 }
 
-void Predict::predInterUni(TComDataCU* cu, int list, ShortYuv* outPredYuv, bool bLuma, bool bChroma)
+void Predict::predInterUni(int list, ShortYuv* outPredYuv, bool bLuma, bool bChroma)
 {
-    int refIdx = cu->getCUMvField(list)->getRefIdx(m_partAddr);
+    int refIdx = m_mvField[list]->getRefIdx(m_partAddr);
 
     X265_CHECK(refIdx >= 0, "refidx is not positive\n");
 
-    MV mv = cu->getCUMvField(list)->getMv(m_partAddr);
-    cu->clipMv(mv);
-
     if (bLuma)
-        predInterLumaBlk(cu->m_slice->m_refPicList[list][refIdx]->getPicYuvRec(), cu->getAddr(), cu->getZorderIdxInCU(), 
-                          &mv, outPredYuv);
+        predInterLumaBlk(m_slice->m_refPicList[list][refIdx]->getPicYuvRec(), outPredYuv, &ClippedMv[list]);
     if (bChroma)
-        predInterChromaBlk(cu->m_slice->m_refPicList[list][refIdx]->getPicYuvRec(), cu->getAddr(), cu->getZorderIdxInCU(), 
-                            &mv, outPredYuv);
+        predInterChromaBlk(m_slice->m_refPicList[list][refIdx]->getPicYuvRec(), outPredYuv, &ClippedMv[list]);
 }
 
 void Predict::predInterBi(TComDataCU* cu, TComYuv* outPredYuv, bool bLuma, bool bChroma)
 {


More information about the x265-commits mailing list