[x265-commits] [x265] weightP: fix crash due to access of lowres array

Kavitha Sampath kavitha at multicorewareinc.com
Tue Jan 28 15:43:27 CET 2014


details:   http://hg.videolan.org/x265/rev/728f31cc6eee
branches:  
changeset: 5925:728f31cc6eee
user:      Kavitha Sampath <kavitha at multicorewareinc.com>
date:      Tue Jan 28 17:47:22 2014 +0530
description:
weightP: fix crash due to access of lowres array

fix crash due to access of lowres array of references with invalid mvs in
weightCost
Subject: [x265] rc: bug fix in crf mode ;correct qscale set for all the frames.

details:   http://hg.videolan.org/x265/rev/854ff1616d38
branches:  stable
changeset: 5926:854ff1616d38
user:      Aarthi Thirumalai (aarthi at multicorewareinc.com)
date:      Tue Jan 28 17:23:43 2014 +0530
description:
rc: bug fix in crf mode ;correct qscale set for all the frames.
Subject: [x265] compress: insert check for merge MV candidates.

details:   http://hg.videolan.org/x265/rev/7f4537c4db7a
branches:  stable
changeset: 5927:7f4537c4db7a
user:      Deepthi Nandakumar <deepthi at multicorewareinc.com>
date:      Tue Jan 28 16:19:34 2014 +0530
description:
compress: insert check for merge MV candidates.
Subject: [x265] Merge with stable

details:   http://hg.videolan.org/x265/rev/923edbb08a59
branches:  
changeset: 5928:923edbb08a59
user:      Steve Borho <steve at borho.org>
date:      Tue Jan 28 08:07:08 2014 -0600
description:
Merge with stable

diffstat:

 source/encoder/compress.cpp         |  132 +++++++++++++++++++----------------
 source/encoder/ratecontrol.cpp      |    6 +-
 source/encoder/weightPrediction.cpp |   29 ++-----
 source/encoder/weightPrediction.h   |    2 +
 4 files changed, 88 insertions(+), 81 deletions(-)

diffs (292 lines):

diff -r 3568c1b19947 -r 923edbb08a59 source/encoder/compress.cpp
--- a/source/encoder/compress.cpp	Tue Jan 28 01:49:03 2014 -0600
+++ b/source/encoder/compress.cpp	Tue Jan 28 08:07:08 2014 -0600
@@ -236,76 +236,90 @@ void TEncCu::xComputeCostMerge2Nx2N(TCom
     outBestCU->setMergeFlagSubParts(true, 0, 0, depth);
 
     int part = g_convertToBit[outTempCU->getWidth(0)];
-    int bestMergeCand = 0;
+    int bestMergeCand = -1;
     uint32_t bitsCand = 0;
+
     for (int mergeCand = 0; mergeCand < numValidMergeCand; ++mergeCand)
     {
-        // set MC parameters, interprets depth relative to LCU level
-        outTempCU->setMergeIndexSubParts(mergeCand, 0, 0, depth);
-        outTempCU->setInterDirSubParts(interDirNeighbours[mergeCand], 0, 0, depth);
-        outTempCU->getCUMvField(REF_PIC_LIST_0)->setAllMvField(mvFieldNeighbours[0 + 2 * mergeCand], SIZE_2Nx2N, 0, 0); // interprets depth relative to rpcTempCU level
-        outTempCU->getCUMvField(REF_PIC_LIST_1)->setAllMvField(mvFieldNeighbours[1 + 2 * mergeCand], SIZE_2Nx2N, 0, 0); // interprets depth relative to rpcTempCU level
+        /* TODO: check only necessary when -F>1, and ref pixels available is in units of LCU rows */
+        if ( mvFieldNeighbours[0 + 2 * mergeCand].mv.y < (m_cfg->param.searchRange+1) * 4
+          && mvFieldNeighbours[1 + 2 * mergeCand].mv.y < (m_cfg->param.searchRange+1) * 4)
+        {
+            // set MC parameters, interprets depth relative to LCU level
+            outTempCU->setMergeIndexSubParts(mergeCand, 0, 0, depth);
+            outTempCU->setInterDirSubParts(interDirNeighbours[mergeCand], 0, 0, depth);
+            outTempCU->getCUMvField(REF_PIC_LIST_0)->setAllMvField(mvFieldNeighbours[0 + 2 * mergeCand], SIZE_2Nx2N, 0, 0); // interprets depth relative to rpcTempCU level
+            outTempCU->getCUMvField(REF_PIC_LIST_1)->setAllMvField(mvFieldNeighbours[1 + 2 * mergeCand], SIZE_2Nx2N, 0, 0); // interprets depth relative to rpcTempCU level
 
-        // do MC only for Luma part
-        m_search->motionCompensation(outTempCU, m_tmpPredYuv[depth], REF_PIC_LIST_X, -1, true, false);
-        bitsCand = mergeCand + 1;
-        if (mergeCand == (int)m_cfg->param.maxNumMergeCand - 1)
-        {
-            bitsCand--;
-        }
-        outTempCU->m_totalBits = bitsCand;
-        outTempCU->m_totalDistortion = primitives.sa8d[part](m_origYuv[depth]->getLumaAddr(), m_origYuv[depth]->getStride(),
-                                                             m_tmpPredYuv[depth]->getLumaAddr(), m_tmpPredYuv[depth]->getStride());
-        outTempCU->m_totalCost = m_rdCost->calcRdSADCost(outTempCU->m_totalDistortion, outTempCU->m_totalBits);
+            // do MC only for Luma part
+            m_search->motionCompensation(outTempCU, m_tmpPredYuv[depth], REF_PIC_LIST_X, -1, true, false);
+            bitsCand = mergeCand + 1;
+            if (mergeCand == (int)m_cfg->param.maxNumMergeCand - 1)
+            {
+                bitsCand--;
+            }
+            outTempCU->m_totalBits = bitsCand;
+            outTempCU->m_totalDistortion = primitives.sa8d[part](m_origYuv[depth]->getLumaAddr(), m_origYuv[depth]->getStride(),
+                                                                 m_tmpPredYuv[depth]->getLumaAddr(), m_tmpPredYuv[depth]->getStride());
+            outTempCU->m_totalCost = m_rdCost->calcRdSADCost(outTempCU->m_totalDistortion, outTempCU->m_totalBits);
 
-        if (outTempCU->m_totalCost < outBestCU->m_totalCost)
-        {
-            bestMergeCand = mergeCand;
-            TComDataCU* tmp = outTempCU;
-            outTempCU = outBestCU;
-            outBestCU = tmp;
-            // Change Prediction data
-            TComYuv* yuv = bestPredYuv;
-            bestPredYuv = m_tmpPredYuv[depth];
-            m_tmpPredYuv[depth] = yuv;
+            if (outTempCU->m_totalCost < outBestCU->m_totalCost)
+            {
+                bestMergeCand = mergeCand;
+                TComDataCU* tmp = outTempCU;
+                outTempCU = outBestCU;
+                outBestCU = tmp;
+                // Change Prediction data
+                TComYuv* yuv = bestPredYuv;
+                bestPredYuv = m_tmpPredYuv[depth];
+                m_tmpPredYuv[depth] = yuv;
+            }
         }
     }
+    
+    if (bestMergeCand < 0)
+    {
+        outBestCU->setMergeFlagSubParts(false, 0, 0, depth);
+        outBestCU->initEstData(depth, outBestCU->getQP(0));
+    }
+    else
+    {
+        outTempCU->setMergeIndexSubParts(bestMergeCand, 0, 0, depth);
+        outTempCU->setInterDirSubParts(interDirNeighbours[bestMergeCand], 0, 0, depth);
+        outTempCU->getCUMvField(REF_PIC_LIST_0)->setAllMvField(mvFieldNeighbours[0 + 2 * bestMergeCand], SIZE_2Nx2N, 0, 0);
+        outTempCU->getCUMvField(REF_PIC_LIST_1)->setAllMvField(mvFieldNeighbours[1 + 2 * bestMergeCand], SIZE_2Nx2N, 0, 0);
+        outTempCU->m_totalBits = outBestCU->m_totalBits;
+        outTempCU->m_totalDistortion = outBestCU->m_totalDistortion;
+        outTempCU->m_totalCost = m_rdCost->calcRdSADCost(outTempCU->m_totalDistortion, outTempCU->m_totalBits);
+        if (m_cfg->param.rdLevel > 2)
+        {
+            //calculate the motion compensation for chroma for the best mode selected
+            int numPart = outBestCU->getNumPartInter();
+            for (int partIdx = 0; partIdx < numPart; partIdx++)
+            {
+                m_search->motionCompensation(outBestCU, bestPredYuv, REF_PIC_LIST_X, partIdx, false, true);
+            }
 
-    outTempCU->setMergeIndexSubParts(bestMergeCand, 0, 0, depth);
-    outTempCU->setInterDirSubParts(interDirNeighbours[bestMergeCand], 0, 0, depth);
-    outTempCU->getCUMvField(REF_PIC_LIST_0)->setAllMvField(mvFieldNeighbours[0 + 2 * bestMergeCand], SIZE_2Nx2N, 0, 0);
-    outTempCU->getCUMvField(REF_PIC_LIST_1)->setAllMvField(mvFieldNeighbours[1 + 2 * bestMergeCand], SIZE_2Nx2N, 0, 0);
-    outTempCU->m_totalBits = outBestCU->m_totalBits;
-    outTempCU->m_totalDistortion = outBestCU->m_totalDistortion;
-    outTempCU->m_totalCost = m_rdCost->calcRdSADCost(outTempCU->m_totalDistortion, outTempCU->m_totalBits);
-    if (m_cfg->param.rdLevel > 2)
-    {
-        //calculate the motion compensation for chroma for the best mode selected
-        int numPart = outBestCU->getNumPartInter();
-        for (int partIdx = 0; partIdx < numPart; partIdx++)
-        {
-            m_search->motionCompensation(outBestCU, bestPredYuv, REF_PIC_LIST_X, partIdx, false, true);
-        }
+            //No-residue mode
+            m_search->encodeResAndCalcRdInterCU(outBestCU, m_origYuv[depth], bestPredYuv, m_tmpResiYuv[depth], m_bestResiYuv[depth], m_tmpRecoYuv[depth], true);
 
-        //No-residue mode
-        m_search->encodeResAndCalcRdInterCU(outBestCU, m_origYuv[depth], bestPredYuv, m_tmpResiYuv[depth], m_bestResiYuv[depth], m_tmpRecoYuv[depth], true);
-
-        TComYuv* yuv = yuvReconBest;
-        yuvReconBest = m_tmpRecoYuv[depth];
-        m_tmpRecoYuv[depth] = yuv;
-
-        //Encode with residue
-        m_search->encodeResAndCalcRdInterCU(outTempCU, m_origYuv[depth], bestPredYuv, m_tmpResiYuv[depth], m_bestResiYuv[depth], m_tmpRecoYuv[depth], false);
-
-        if (outTempCU->m_totalCost < outBestCU->m_totalCost)    //Choose best from no-residue mode and residue mode
-        {
-            TComDataCU* tmp = outTempCU;
-            outTempCU = outBestCU;
-            outBestCU = tmp;
-
-            yuv = yuvReconBest;
+            TComYuv* yuv = yuvReconBest;
             yuvReconBest = m_tmpRecoYuv[depth];
             m_tmpRecoYuv[depth] = yuv;
+
+            //Encode with residue
+            m_search->encodeResAndCalcRdInterCU(outTempCU, m_origYuv[depth], bestPredYuv, m_tmpResiYuv[depth], m_bestResiYuv[depth], m_tmpRecoYuv[depth], false);
+
+            if (outTempCU->m_totalCost < outBestCU->m_totalCost)    //Choose best from no-residue mode and residue mode
+            {
+                TComDataCU* tmp = outTempCU;
+                outTempCU = outBestCU;
+                outBestCU = tmp;
+
+                yuv = yuvReconBest;
+                yuvReconBest = m_tmpRecoYuv[depth];
+                m_tmpRecoYuv[depth] = yuv;
+            }
         }
     }
     x265_emms();
diff -r 3568c1b19947 -r 923edbb08a59 source/encoder/ratecontrol.cpp
--- a/source/encoder/ratecontrol.cpp	Tue Jan 28 01:49:03 2014 -0600
+++ b/source/encoder/ratecontrol.cpp	Tue Jan 28 08:07:08 2014 -0600
@@ -517,10 +517,10 @@ double RateControl::rateEstimateQscale(R
 
             q = Clip3(lqmin, lqmax, q);
         }
-
-        else if (cfg->param.rc.rateControlMode == X265_RC_CRF && qCompress != 1)
+        else 
         {
-            q = qp2qScale(ABR_INIT_QP) / fabs(cfg->param.rc.ipFactor);
+            if (qCompress != 1 && framesDone == 0)
+                q = qp2qScale(ABR_INIT_QP) / fabs(cfg->param.rc.ipFactor);
         }
 
         double lmin1 = lmin[sliceType];
diff -r 3568c1b19947 -r 923edbb08a59 source/encoder/weightPrediction.cpp
--- a/source/encoder/weightPrediction.cpp	Tue Jan 28 01:49:03 2014 -0600
+++ b/source/encoder/weightPrediction.cpp	Tue Jan 28 08:07:08 2014 -0600
@@ -29,10 +29,6 @@
 
 using namespace x265;
 
-/** clip a, such that minVal <= a <= maxVal */
-//template<typename T>
-//inline T Clip3(T minVal, T maxVal, T a) { return std::min<T>(std::max<T>(minVal, a), maxVal); } ///< general min/max clip
-
 void WeightPrediction::mcChroma()
 {
     intptr_t strd = m_refStride;
@@ -92,7 +88,6 @@ uint32_t WeightPrediction::weightCost(pi
 {
     int stride = m_refStride;
     pixel *temp = (pixel*)X265_MALLOC(pixel, m_frmWidth * m_frmHeight);
-    bool nonBorderCU;
 
     if (w)
     {
@@ -108,30 +103,26 @@ uint32_t WeightPrediction::weightCost(pi
         stride = m_dstStride;
     }
 
-    int32_t cost = 0;
+    uint32_t cost = 0;
     int pixoff = 0;
     int mb = 0;
-    int count = 0;
     for (int y = 0; y < m_frmHeight; y += 8, pixoff = y * m_refStride)
     {
         for (int x = 0; x < m_frmWidth; x += 8, mb++, pixoff += 8)
         {
-            nonBorderCU = (x > 0) && (x < m_frmWidth - 8 - 1) && (y > 0) && (y < m_frmHeight - 8 - 1);
+            bool nonBorderCU = (x > 0) && (x < m_frmWidth - 8 - 1) && (y > 0) && (y < m_frmHeight - 8 - 1);
             if (nonBorderCU)
             {
-                if (m_mvs)
+                if (m_mcFlag)
                 {
                     if (m_mvCost[mb] < m_intraCost[mb])
                     {
-                        int satd = primitives.satd[LUMA_8x8](ref + (stride * y) + x, stride, cur + pixoff, m_refStride);
-                        cost += satd;
-                        count++;
+                        cost += primitives.satd[LUMA_8x8](ref + (stride * y) + x, stride, cur + pixoff, m_refStride);
                     }
                 }
                 else
                 {
-                    int satd = primitives.satd[LUMA_8x8](ref + (stride * y) + x, stride, cur + pixoff, m_refStride);
-                    cost += satd;
+                    cost += primitives.satd[LUMA_8x8](ref + (stride * y) + x, stride, cur + pixoff, m_refStride);
                 }
             }
         }
@@ -188,7 +179,7 @@ bool WeightPrediction::checkDenom(int de
     {
         for (int refIdxTemp = 0; (refIdxTemp < m_slice->getNumRefIdx(list)) && (numWeighted < 8); refIdxTemp++)
         {
-            bool mcFlag = false;
+            m_mcFlag = false;
             check = 0;
             fw = m_wp[list][refIdxTemp];
             ref  = &m_slice->getRefPic(list, refIdxTemp)->m_lowres;
@@ -200,7 +191,7 @@ bool WeightPrediction::checkDenom(int de
                 if (m_mvs[0].x != 0x7FFF)
                 {
                     m_mvCost = fenc->lowresMvCosts[0][difPoc - 1];
-                    mcFlag = true;
+                    m_mcFlag = true;
                 }
             }
             const float epsilon = 1.f / 128.f;
@@ -247,7 +238,7 @@ bool WeightPrediction::checkDenom(int de
                 case 0:
                     m_mcbuf = ref->fpelPlane;
                     m_inbuf = fenc->lowresPlane[0];
-                    if(mcFlag)
+                    if (m_mcFlag)
                     {
                         pixel *tempm_buf;
                         pixel m_buf8[8 * 8];
@@ -279,7 +270,7 @@ bool WeightPrediction::checkDenom(int de
                     m_mcbuf = m_slice->getRefPic(list, refIdxTemp)->getPicYuvOrg()->getCbAddr();
                     m_inbuf = m_slice->getPic()->getPicYuvOrg()->getCbAddr();
                     m_blockSize = 8;
-                    if(mcFlag) mcChroma();
+                    if (m_mcFlag) mcChroma();
                     break;
 
                 case 2:
@@ -287,7 +278,7 @@ bool WeightPrediction::checkDenom(int de
                     m_mcbuf = m_slice->getRefPic(list, refIdxTemp)->getPicYuvOrg()->getCrAddr();
                     m_inbuf = m_slice->getPic()->getPicYuvOrg()->getCrAddr();
                     m_blockSize = 8;
-                    if(mcFlag) mcChroma();
+                    if (m_mcFlag) mcChroma();
                     break;
                 }
 
diff -r 3568c1b19947 -r 923edbb08a59 source/encoder/weightPrediction.h
--- a/source/encoder/weightPrediction.h	Tue Jan 28 01:49:03 2014 -0600
+++ b/source/encoder/weightPrediction.h	Tue Jan 28 08:07:08 2014 -0600
@@ -43,6 +43,7 @@ private:
     int32_t *m_intraCost;
     MV *m_mvs;
     int m_bframes;
+    bool m_mcFlag;
 
 public:
 
@@ -58,6 +59,7 @@ public:
         m_refStride = m_slice->getPic()->m_lowres.lumaStride;
         m_intraCost = m_slice->getPic()->m_lowres.intraCost;
         m_bframes = param.bframes;
+        m_mcFlag = false;
 
         m_mcbuf = NULL;
         m_inbuf = NULL;


More information about the x265-commits mailing list