[x265] [PATCH RFC] psy-rdoq: implementation of psy-rdoq

sumalatha at multicorewareinc.com sumalatha at multicorewareinc.com
Fri Jul 25 12:55:00 CEST 2014


# HG changeset patch
# User Sumalatha Polureddy<sumalatha at multicorewareinc.com>
# Date 1406282327 -19800
# Node ID 6b32dc49600b0799d4cfb1382e44107b5ae06ac1
# Parent  8aa4132d30977e841e6c7b7f817a571b492ef105
psy-rdoq: implementation of psy-rdoq

diff -r 8aa4132d3097 -r 6b32dc49600b source/Lib/TLibCommon/TComTrQuant.cpp
--- a/source/Lib/TLibCommon/TComTrQuant.cpp	Fri Jul 25 01:29:21 2014 -0500
+++ b/source/Lib/TLibCommon/TComTrQuant.cpp	Fri Jul 25 15:28:47 2014 +0530
@@ -64,6 +64,8 @@
     return y + ((x - y) & ((x - y) >> (sizeof(int) * CHAR_BIT - 1))); // min(x, y)
 }
 
+#define SIGN(x,y) ((x^(y >> 31))-(y >> 31))
+
 // ====================================================================================================================
 // TComTrQuant class member functions
 // ====================================================================================================================
@@ -72,7 +74,9 @@
 {
     // allocate temporary buffers
     // OPT_ME: I may reduce this to short and output matched, but I am not sure it is right.
-    m_tmpCoeff = X265_MALLOC(int32_t, MAX_CU_SIZE * MAX_CU_SIZE);
+    m_resiDctCoeff = X265_MALLOC(int32_t, MAX_TR_SIZE * MAX_TR_SIZE * 3);
+    m_fencDctCoeff = m_resiDctCoeff + (MAX_TR_SIZE * MAX_TR_SIZE);
+    m_fencShortBuf = (int16_t*)(m_resiDctCoeff + (MAX_TR_SIZE * MAX_TR_SIZE * 2));
 
     // allocate bit estimation class (for RDOQ)
     m_estBitsSbac = new EstBitsSbac;
@@ -82,9 +86,9 @@
 TComTrQuant::~TComTrQuant()
 {
     // delete temporary buffers
-    if (m_tmpCoeff)
+    if (m_resiDctCoeff)
     {
-        X265_FREE(m_tmpCoeff);
+        X265_FREE(m_resiDctCoeff);
     }
 
     // delete bit estimation class
@@ -307,6 +311,8 @@
 }
 
 uint32_t TComTrQuant::transformNxN(TComDataCU* cu,
+                                   pixel*      fenc,
+                                   uint32_t    fencStride,
                                    int16_t*    residual,
                                    uint32_t    stride,
                                    coeff_t*    coeff,
@@ -316,10 +322,10 @@
                                    bool        useTransformSkip,
                                    bool        curUseRDOQ)
 {
+    int trSize = 1 << log2TrSize;
     if (cu->getCUTransquantBypass(absPartIdx))
     {
         uint32_t numSig = 0;
-        int trSize = 1 << log2TrSize;
         for (int k = 0; k < trSize; k++)
         {
             for (int j = 0; j < trSize; j++)
@@ -339,26 +345,32 @@
         const uint32_t sizeIdx = log2TrSize - 2;
         int useDST = (sizeIdx == 0 && ttype == TEXT_LUMA && cu->getPredictionMode(absPartIdx) == MODE_INTRA);
         int index = DCT_4x4 + sizeIdx - useDST;
-        primitives.dct[index](residual, m_tmpCoeff, stride);
+        if (m_isRdoq && (ttype == TEXT_LUMA))
+        {
+            // converting pixel to int and putting in separate buffer to take dct
+            primitives.square_copy_ps[sizeIdx](m_fencShortBuf, MAX_TR_SIZE, fenc, fencStride);
+            primitives.dct[index](m_fencShortBuf, m_fencDctCoeff, stride);
+        }
+        primitives.dct[index](residual, m_resiDctCoeff, stride);
         if (m_nr->bNoiseReduction)
         {
             if (index > 0)
             {
-                denoiseDct(m_tmpCoeff, m_nr->residualSum[sizeIdx], m_nr->offset[sizeIdx], (16 << sizeIdx * 2));
+                denoiseDct(m_resiDctCoeff, m_nr->residualSum[sizeIdx], m_nr->offset[sizeIdx], (16 << sizeIdx * 2));
                 m_nr->count[sizeIdx]++;
             }
         }
     }
     else
     {
-        xTransformSkip(residual, stride, m_tmpCoeff, log2TrSize);
+        xTransformSkip(residual, stride, m_resiDctCoeff, log2TrSize);
     }
 
     if (m_useRDOQ && curUseRDOQ)
     {
-        return xRateDistOptQuant(cu, m_tmpCoeff, coeff, log2TrSize, ttype, absPartIdx);
+        return xRateDistOptQuant(cu, m_fencDctCoeff, m_resiDctCoeff, coeff, log2TrSize, ttype, absPartIdx);
     }
-    return xQuant(cu, m_tmpCoeff, coeff, log2TrSize, ttype, absPartIdx);
+    return xQuant(cu, m_resiDctCoeff, coeff, log2TrSize, ttype, absPartIdx);
 }
 
 void TComTrQuant::invtransformNxN(bool transQuantBypass, int16_t* residual, uint32_t stride, coeff_t* coeff, uint32_t log2TrSize, TextType ttype, bool bIntra, bool useTransformSkip, uint32_t numSig)
@@ -388,7 +400,7 @@
     {
         static const int invQuantScales[6] = { 40, 45, 51, 57, 64, 72 };
         int scale = invQuantScales[rem] << per;
-        primitives.dequant_normal(coeff, m_tmpCoeff, numCoeff, scale, shift);
+        primitives.dequant_normal(coeff, m_resiDctCoeff, numCoeff, scale, shift);
     }
     else
     {
@@ -396,7 +408,7 @@
         int scalingListType = (!bIntra ? 3 : 0) + ttype;
         X265_CHECK(scalingListType < 6, "scalingListType invalid %d\n", scalingListType);
         int32_t *dequantCoef = getDequantCoeff(scalingListType, rem, log2TrSize - 2);
-        primitives.dequant_scaling(coeff, dequantCoef, m_tmpCoeff, numCoeff, per, shift);
+        primitives.dequant_scaling(coeff, dequantCoef, m_resiDctCoeff, numCoeff, per, shift);
     }
 
     if (!useTransformSkip)
@@ -414,18 +426,18 @@
             const int shift_2nd = 12 - (X265_DEPTH - 8);
             const int add_2nd = 1 << (shift_2nd - 1);
 
-            int dc_val = (((m_tmpCoeff[0] * 64 + add_1st) >> shift_1st) * 64 + add_2nd) >> shift_2nd;
+            int dc_val = (((m_resiDctCoeff[0] * 64 + add_1st) >> shift_1st) * 64 + add_2nd) >> shift_2nd;
             primitives.blockfill_s[sizeIdx](residual, stride, dc_val);
 
             return;
         }
 
         // TODO: this may need larger data types for X265_DEPTH > 8
-        primitives.idct[IDCT_4x4 + sizeIdx - useDST](m_tmpCoeff, residual, stride);
+        primitives.idct[IDCT_4x4 + sizeIdx - useDST](m_resiDctCoeff, residual, stride);
     }
     else
     {
-        xITransformSkip(m_tmpCoeff, residual, stride, log2TrSize);
+        xITransformSkip(m_resiDctCoeff, residual, stride, log2TrSize);
     }
 }
 
@@ -505,7 +517,7 @@
  * Rate distortion optimized quantization for entropy
  * coding engines using probability models like CABAC
  */
-uint32_t TComTrQuant::xRateDistOptQuant(TComDataCU* cu, int32_t* srcCoeff, coeff_t* dstCoeff, uint32_t log2TrSize,
+uint32_t TComTrQuant::xRateDistOptQuant(TComDataCU* cu, int32_t* fencCoeff, int32_t* srcCoeff, coeff_t* dstCoeff, uint32_t log2TrSize,
                                         TextType ttype, uint32_t absPartIdx)
 {
     uint32_t trSize = 1 << log2TrSize;
@@ -573,6 +585,9 @@
         const int patternSigCtx = TComTrQuant::calcPatternSigCtx(sigCoeffGroupFlag64, cgPosX, cgPosY, codingParameters.log2TrSizeCG);
         for (int scanPosinCG = cgSize - 1; scanPosinCG >= 0; scanPosinCG--)
         {
+            bool dcCoeffFlag = false;
+            if ((cgScanPos == 0) && (scanPosinCG == 0))
+                dcCoeffFlag = true;
             scanPos = cgScanPos * cgSize + scanPosinCG;
             //===== quantization =====
             uint32_t blkPos = codingParameters.scan[scanPos];
@@ -614,7 +629,7 @@
                 {
                     level = xGetCodedLevel(costCoeff[scanPos], curCostSig, costSig[scanPos],
                                            levelDouble, maxAbsLevel, baseLevel, greaterOneBits, levelAbsBits, goRiceParam,
-                                           c1c2Idx, qbits, scaleFactor, 1);
+                                           c1c2Idx, qbits, scaleFactor, 1, srcCoeff[blkPos], fencCoeff[blkPos], ttype, dcCoeffFlag);
                     sigRateDelta[blkPos] = 0;
                 }
                 else
@@ -631,7 +646,7 @@
                         curCostSig = xGetRateSigCoef(1, ctxSig);
                         level = xGetCodedLevel(costCoeff[scanPos], curCostSig, costSig[scanPos],
                                                levelDouble, maxAbsLevel, baseLevel, greaterOneBits, levelAbsBits, goRiceParam,
-                                               c1c2Idx, qbits, scaleFactor, 0);
+                                               c1c2Idx, qbits, scaleFactor, 0, srcCoeff[blkPos], fencCoeff[blkPos], ttype, dcCoeffFlag);
                     }
                     else
                     {
@@ -1126,7 +1141,11 @@
                                             uint32_t     c1c2Idx,
                                             int          qbits,
                                             double       scaleFactor,
-                                            bool         last) const
+                                            bool         last,
+                                            int          signCoef,
+                                            int          origCoef,
+                                            TextType     ttype,
+                                            bool         dcCoeffFlag) const
 {
     uint32_t   bestAbsLevel = 0;
 
@@ -1155,7 +1174,16 @@
     for (int absLevel = maxAbsLevel; absLevel >= minAbsLevel; absLevel--)
     {
         X265_CHECK(fabs((double)err2 - double(levelDouble  - (absLevel << qbits)) * double(levelDouble  - (absLevel << qbits)) * scaleFactor) < 1e-5, "err2 check failure\n");
-        double curCost = err2 + xGetICRateCost(absLevel, diffLevel, greaterOneBits, levelAbsBits, absGoRice, c1c2Idx);
+        double curCost = 0;
+        if (m_isRdoq && (ttype == TEXT_LUMA) && (dcCoeffFlag == false))
+        {
+            int unquantAbsLevel = (maxAbsLevel << qbits);
+            int predictedCoef = origCoef - signCoef;
+            int psyValue = abs(unquantAbsLevel + SIGN(predictedCoef, signCoef)); // test with differnt cases to check whether SIGN is required
+            curCost = err2 + xGetICRateCost(absLevel, diffLevel, greaterOneBits, levelAbsBits, absGoRice, c1c2Idx) - (m_psyRdoqScale * psyValue * m_lambda);
+        }
+        else
+            curCost = err2 + xGetICRateCost(absLevel, diffLevel, greaterOneBits, levelAbsBits, absGoRice, c1c2Idx);
         curCost       += curCostSig;
 
         if (curCost < bestCodedCost)
diff -r 8aa4132d3097 -r 6b32dc49600b source/Lib/TLibCommon/TComTrQuant.h
--- a/source/Lib/TLibCommon/TComTrQuant.h	Fri Jul 25 01:29:21 2014 -0500
+++ b/source/Lib/TLibCommon/TComTrQuant.h	Fri Jul 25 15:28:47 2014 +0530
@@ -120,8 +120,20 @@
     // initialize class
     void init(bool useRDOQ);
 
+
+    void setPsyRdoqScale(double scale)
+    {
+        m_psyRdoqScale = scale;
+    }
+
+    bool setPsyRdoq(double scale)
+    {
+        m_isRdoq = scale != 0 ? true : false;
+    }
+
+
     // transform & inverse transform functions
-    uint32_t transformNxN(TComDataCU* cu, int16_t* residual, uint32_t stride, coeff_t* coeff, uint32_t log2TrSize,
+    uint32_t transformNxN(TComDataCU* cu, pixel* fenc, uint32_t fencStride, int16_t* residual, uint32_t stride, coeff_t* coeff, uint32_t log2TrSize,
                           TextType ttype, uint32_t absPartIdx, bool useTransformSkip = false, bool curUseRDOQ = true);
 
     void invtransformNxN(bool transQuantBypass, int16_t* residual, uint32_t stride, coeff_t* coeff, uint32_t log2TrSize, TextType ttype, bool bIntra, bool useTransformSkip, uint32_t numSig);
@@ -207,7 +219,13 @@
     bool     m_useRDOQ;
     bool     m_scalingListEnabledFlag;
 
-    int32_t* m_tmpCoeff;
+    double   m_psyRdoqScale;
+    bool     m_isRdoq;
+    coeff_t* m_resiDctCoeff; // tmp buffer which stores the dct of residual
+
+    coeff_t* m_fencDctCoeff;
+    int16_t* m_fencShortBuf;
+
     int32_t* m_quantCoef[ScalingList::NUM_SIZES][ScalingList::NUM_LISTS][ScalingList::NUM_REM];     ///< array of quantization matrix coefficient 4x4
     int32_t* m_dequantCoef[ScalingList::NUM_SIZES][ScalingList::NUM_LISTS][ScalingList::NUM_REM];   ///< array of dequantization matrix coefficient 4x4
 
@@ -221,11 +239,11 @@
     uint32_t xQuant(TComDataCU* cu, int32_t* src, coeff_t* dst, uint32_t log2TrSize, TextType ttype, uint32_t absPartIdx);
 
     // RDOQ functions
-    uint32_t xRateDistOptQuant(TComDataCU* cu, int32_t* srcCoeff, coeff_t* dstCoeff, uint32_t log2TrSize, TextType ttype, uint32_t absPartIdx);
+    uint32_t xRateDistOptQuant(TComDataCU* cu, int32_t* fencCoeff, int32_t* srcCoeff, coeff_t* dstCoeff, uint32_t log2TrSize, TextType ttype, uint32_t absPartIdx);
 
     inline uint32_t xGetCodedLevel(double& codedCost, const double curCostSig, double& codedCostSig, int levelDouble,
                                    uint32_t maxAbsLevel, uint32_t baseLevel, const int *greaterOneBits, const int *levelAbsBits, uint32_t absGoRice,
-                                   uint32_t c1c2Idx, int qbits, double scale, bool bLast) const;
+                                   uint32_t c1c2Idx, int qbits, double scale, bool bLast, int sign_coef, int orig_coef, TextType ttype, bool dcCoeffFlag) const;
 
     inline double xGetICRateCost(uint32_t absLevel, int32_t  diffLevel, const int *greaterOneBits, const int *levelAbsBits, uint32_t absGoRice, uint32_t c1c2Idx) const;
 
diff -r 8aa4132d3097 -r 6b32dc49600b source/Lib/TLibEncoder/TEncSearch.cpp
--- a/source/Lib/TLibEncoder/TEncSearch.cpp	Fri Jul 25 01:29:21 2014 -0500
+++ b/source/Lib/TLibEncoder/TEncSearch.cpp	Fri Jul 25 15:28:47 2014 +0530
@@ -436,7 +436,7 @@
         m_entropyCoder->estBit(m_trQuant.m_estBitsSbac, log2TrSize, TEXT_LUMA);
 
     //--- transform and quantization ---
-    uint32_t numSig = m_trQuant.transformNxN(cu, residual, stride, coeff, log2TrSize, TEXT_LUMA, absPartIdx, useTransformSkip);
+    uint32_t numSig = m_trQuant.transformNxN(cu, fenc, stride, residual, stride, coeff, log2TrSize, TEXT_LUMA, absPartIdx, useTransformSkip);
 
     //--- set coded block flag ---
     cbf = numSig ? 1 : 0;
@@ -505,7 +505,7 @@
         m_entropyCoder->estBit(m_trQuant.m_estBitsSbac, log2TrSizeC, TEXT_CHROMA);
 
     //--- transform and quantization ---
-    uint32_t numSig = m_trQuant.transformNxN(cu, residual, stride, coeff, log2TrSizeC, ttype, absPartIdx, useTransformSkipC);
+    uint32_t numSig = m_trQuant.transformNxN(cu, fenc, stride, residual, stride, coeff, log2TrSizeC, ttype, absPartIdx, useTransformSkipC);
 
     //--- set coded block flag ---
     cbf = numSig ? 1 : 0;
@@ -865,7 +865,7 @@
         primitives.calcresidual[sizeIdx](fenc, pred, residual, stride);
 
         //===== transform and quantization =====
-        uint32_t numSig = m_trQuant.transformNxN(cu, residual, stride, coeff, log2TrSize, TEXT_LUMA, absPartIdx, useTransformSkip);
+        uint32_t numSig = m_trQuant.transformNxN(cu, fenc, stride, residual, stride, coeff, log2TrSize, TEXT_LUMA, absPartIdx, useTransformSkip);
 
         //--- set coded block flag ---
         cu->setCbfSubParts((numSig ? 1 : 0) << trDepth, TEXT_LUMA, absPartIdx, fullDepth);
@@ -1338,7 +1338,7 @@
                 primitives.calcresidual[sizeIdxC](fenc, pred, residual, stride);
 
                 //--- transform and quantization ---
-                uint32_t numSig = m_trQuant.transformNxN(cu, residual, stride, coeff, log2TrSizeC, ttype, absPartIdxC, useTransformSkipC);
+                uint32_t numSig = m_trQuant.transformNxN(cu, fenc, stride, residual, stride, coeff, log2TrSizeC, ttype, absPartIdxC, useTransformSkipC);
 
                 //--- set coded block flag ---
                 cu->setCbfPartRange((((numSig > 0) ? 1 : 0) << trDepth), ttype, absPartIdxC, tuIterator.absPartIdxStep);
@@ -2480,7 +2480,7 @@
 
     if (cu->getPredictionMode(0) == MODE_INTER)
     {
-        residualTransformQuantInter(cu, 0, resiYuv, cu->getDepth(0), true);
+        residualTransformQuantInter(cu, 0, fencYuv, resiYuv, cu->getDepth(0), true);
         if (cu->getQtRootCbf(0))
             reconYuv->addClip(predYuv, resiYuv, cu->getLog2CUSize(0));
         else
@@ -2499,7 +2499,7 @@
     }
 }
 
-void TEncSearch::residualTransformQuantInter(TComDataCU* cu, uint32_t absPartIdx, ShortYuv* resiYuv, const uint32_t depth, bool curuseRDOQ)
+void TEncSearch::residualTransformQuantInter(TComDataCU* cu, uint32_t absPartIdx, TComYuv* fencYuv, ShortYuv* resiYuv, const uint32_t depth, bool curuseRDOQ)
 {
     X265_CHECK(cu->getDepth(0) == cu->getDepth(absPartIdx), "invalid depth\n");
     const uint32_t trMode = depth - cu->getDepth(0);
@@ -2550,7 +2550,7 @@
         const uint32_t strideResiY = resiYuv->m_width;
         const uint32_t strideResiC = resiYuv->m_cwidth;
 
-        uint32_t numSigY = m_trQuant.transformNxN(cu, curResiY, strideResiY, coeffCurY,
+        uint32_t numSigY = m_trQuant.transformNxN(cu, fencYuv->getLumaAddr(absPartIdx), fencYuv->getStride(), curResiY, strideResiY, coeffCurY,
                                                   log2TrSize, TEXT_LUMA, absPartIdx, false, curuseRDOQ);
 
         cu->setCbfSubParts(numSigY ? setCbf : 0, TEXT_LUMA, absPartIdx, depth);
@@ -2575,9 +2575,9 @@
                 cu->setTransformSkipPartRange(0, TEXT_CHROMA_U, absPartIdxC, tuIterator.absPartIdxStep);
                 cu->setTransformSkipPartRange(0, TEXT_CHROMA_V, absPartIdxC, tuIterator.absPartIdxStep);
 
-                uint32_t numSigU = m_trQuant.transformNxN(cu, curResiU, strideResiC, coeffCurU + subTUOffset,
+                uint32_t numSigU = m_trQuant.transformNxN(cu, fencYuv->getCbAddr(absPartIdxC), fencYuv->getCStride(), curResiU, strideResiC, coeffCurU + subTUOffset,
                                                           log2TrSizeC, TEXT_CHROMA_U, absPartIdxC, false, curuseRDOQ);
-                uint32_t numSigV = m_trQuant.transformNxN(cu, curResiV, strideResiC, coeffCurV + subTUOffset,
+                uint32_t numSigV = m_trQuant.transformNxN(cu, fencYuv->getCrAddr(absPartIdxC), fencYuv->getCStride(), curResiV, strideResiC, coeffCurV + subTUOffset,
                                                           log2TrSizeC, TEXT_CHROMA_V, absPartIdxC, false, curuseRDOQ);
 
                 cu->setCbfPartRange(numSigU ? setCbf : 0, TEXT_CHROMA_U, absPartIdxC, tuIterator.absPartIdxStep);
@@ -2609,7 +2609,7 @@
     {
         const uint32_t qPartNumSubdiv = cu->m_pic->getNumPartInCU() >> ((depth + 1) << 1);
         for (uint32_t i = 0; i < 4; ++i)
-            residualTransformQuantInter(cu, absPartIdx + i * qPartNumSubdiv, resiYuv, depth + 1, curuseRDOQ);
+            residualTransformQuantInter(cu, absPartIdx + i * qPartNumSubdiv, fencYuv, resiYuv, depth + 1, curuseRDOQ);
 
         uint32_t ycbf = 0;
         uint32_t ucbf = 0;
@@ -2715,7 +2715,7 @@
         if (m_bEnableRDOQ && curuseRDOQ)
             m_entropyCoder->estBit(m_trQuant.m_estBitsSbac, log2TrSize, TEXT_LUMA);
 
-        numSigY = m_trQuant.transformNxN(cu, resiYuv->getLumaAddr(absPartIdx), resiYuv->m_width, coeffCurY,
+        numSigY = m_trQuant.transformNxN(cu, fencYuv->getLumaAddr(absPartIdx), fencYuv->getStride(), resiYuv->getLumaAddr(absPartIdx), resiYuv->m_width, coeffCurY,
                                          log2TrSize, TEXT_LUMA, absPartIdx, false, curuseRDOQ);
 
         cu->setCbfSubParts(numSigY ? setCbf : 0, TEXT_LUMA, absPartIdx, depth);
@@ -2743,9 +2743,9 @@
                 if (m_bEnableRDOQ && curuseRDOQ)
                     m_entropyCoder->estBit(m_trQuant.m_estBitsSbac, log2TrSizeC, TEXT_CHROMA);
 
-                numSigU[tuIterator.section] = m_trQuant.transformNxN(cu, resiYuv->getCbAddr(absPartIdxC), resiYuv->m_cwidth, coeffCurU + subTUOffset,
+                numSigU[tuIterator.section] = m_trQuant.transformNxN(cu, fencYuv->getCbAddr(absPartIdxC), fencYuv->getCStride(), resiYuv->getCbAddr(absPartIdxC), resiYuv->m_cwidth, coeffCurU + subTUOffset,
                                                                      log2TrSizeC, TEXT_CHROMA_U, absPartIdxC, false, curuseRDOQ);
-                numSigV[tuIterator.section] = m_trQuant.transformNxN(cu, resiYuv->getCrAddr(absPartIdxC), resiYuv->m_cwidth, coeffCurV + subTUOffset,
+                numSigV[tuIterator.section] = m_trQuant.transformNxN(cu, fencYuv->getCrAddr(absPartIdxC), fencYuv->getCStride(), resiYuv->getCrAddr(absPartIdxC), resiYuv->m_cwidth, coeffCurV + subTUOffset,
                                                                      log2TrSizeC, TEXT_CHROMA_V, absPartIdxC, false, curuseRDOQ);
 
                 cu->setCbfPartRange(numSigU[tuIterator.section] ? setCbf : 0, TEXT_CHROMA_U, absPartIdxC, tuIterator.absPartIdxStep);
@@ -3074,7 +3074,7 @@
             if (m_bEnableRDOQ)
                 m_entropyCoder->estBit(m_trQuant.m_estBitsSbac, log2TrSize, TEXT_LUMA);
 
-            uint32_t numSigTSkipY = m_trQuant.transformNxN(cu, resiYuv->getLumaAddr(absPartIdx), resiYuv->m_width, tsCoeffY,
+            uint32_t numSigTSkipY = m_trQuant.transformNxN(cu, fencYuv->getLumaAddr(absPartIdx), fencYuv->getStride(), resiYuv->getLumaAddr(absPartIdx), resiYuv->m_width, tsCoeffY,
                                                            log2TrSize, TEXT_LUMA, absPartIdx, true, curuseRDOQ);
             cu->setCbfSubParts(numSigTSkipY ? setCbf : 0, TEXT_LUMA, absPartIdx, depth);
 
@@ -3155,9 +3155,9 @@
                 if (m_bEnableRDOQ)
                     m_entropyCoder->estBit(m_trQuant.m_estBitsSbac, log2TrSizeC, TEXT_CHROMA);
 
-                uint32_t numSigTSkipU = m_trQuant.transformNxN(cu, resiYuv->getCbAddr(absPartIdxC), resiYuv->m_cwidth, tsCoeffU,
+                uint32_t numSigTSkipU = m_trQuant.transformNxN(cu, fencYuv->getCbAddr(absPartIdxC), fencYuv->getCStride(), resiYuv->getCbAddr(absPartIdxC), resiYuv->m_cwidth, tsCoeffU,
                                                                log2TrSizeC, TEXT_CHROMA_U, absPartIdxC, true, curuseRDOQ);
-                uint32_t numSigTSkipV = m_trQuant.transformNxN(cu, resiYuv->getCrAddr(absPartIdxC), resiYuv->m_cwidth, tsCoeffV,
+                uint32_t numSigTSkipV = m_trQuant.transformNxN(cu, fencYuv->getCrAddr(absPartIdxC), fencYuv->getCStride(), resiYuv->getCrAddr(absPartIdxC), resiYuv->m_cwidth, tsCoeffV,
                                                                log2TrSizeC, TEXT_CHROMA_V, absPartIdxC, true, curuseRDOQ);
 
                 cu->setCbfPartRange(numSigTSkipU ? setCbf : 0, TEXT_CHROMA_U, absPartIdxC, tuIterator.absPartIdxStep);
diff -r 8aa4132d3097 -r 6b32dc49600b source/Lib/TLibEncoder/TEncSearch.h
--- a/source/Lib/TLibEncoder/TEncSearch.h	Fri Jul 25 01:29:21 2014 -0500
+++ b/source/Lib/TLibEncoder/TEncSearch.h	Fri Jul 25 15:28:47 2014 +0530
@@ -165,7 +165,7 @@
                              uint64_t &rdCost, uint32_t &outBits, uint32_t &outDist, uint32_t *puiZeroDist, bool curUseRDOQ = true);
     void xSetResidualQTData(TComDataCU* cu, uint32_t absPartIdx, ShortYuv* resiYuv, uint32_t depth, bool bSpatial);
 
-    void residualTransformQuantInter(TComDataCU* cu, uint32_t absPartIdx, ShortYuv* resiYuv, uint32_t depth, bool curUseRDOQ = true);
+    void residualTransformQuantInter(TComDataCU* cu, uint32_t absPartIdx, TComYuv* fencYuv, ShortYuv* resiYuv, uint32_t depth, bool curUseRDOQ = true);
 
     // -------------------------------------------------------------------------------------------------------------------
     // compute symbol bits
diff -r 8aa4132d3097 -r 6b32dc49600b source/common/param.cpp
--- a/source/common/param.cpp	Fri Jul 25 01:29:21 2014 -0500
+++ b/source/common/param.cpp	Fri Jul 25 15:28:47 2014 +0530
@@ -163,6 +163,7 @@
     param->crQpOffset = 0;
     param->rdPenalty = 0;
     param->psyRd = 0.0;
+    param->psyRdoq = 0.0;
     param->bIntraInBFrames = 1;
     param->bLossless = 0;
     param->bCULossless = 0;
@@ -361,11 +362,13 @@
         {
             param->rc.aqStrength = 0.0;
             param->psyRd = 0.0;
+            param->psyRdoq = 0.0;
         }
         else if (!strcmp(tune, "ssim"))
         {
             param->rc.aqMode = X265_AQ_AUTO_VARIANCE;
             param->psyRd = 0.0;
+            param->psyRdoq = 0.0;
         }
         else if (!strcmp(tune, "fastdecode") ||
                  !strcmp(tune, "fast-decode"))
diff -r 8aa4132d3097 -r 6b32dc49600b source/encoder/analysis.cpp
--- a/source/encoder/analysis.cpp	Fri Jul 25 01:29:21 2014 -0500
+++ b/source/encoder/analysis.cpp	Fri Jul 25 15:28:47 2014 +0530
@@ -49,6 +49,8 @@
 {
     m_param = top->m_param;
     m_trQuant.init(top->m_bEnableRDOQ);
+    m_trQuant.setPsyRdoqScale(m_param->psyRdoq);
+    m_trQuant.setPsyRdoq(m_param->psyRdoq);
 
     if (!top->m_scalingList.m_bEnabled)
     {
@@ -1894,7 +1896,7 @@
             primitives.chroma[m_param->internalCsp].sub_ps[part](dst, dststride, src1, src2, src1stride, src2stride);
 
             // Residual encoding
-            residualTransformQuantInter(cu, 0, m_tmpResiYuv[depth], cu->getDepth(0), true);
+            residualTransformQuantInter(cu, 0, m_origYuv[0], m_tmpResiYuv[depth], cu->getDepth(0), true);
             checkDQP(cu);
 
             if (lcu->getMergeFlag(absPartIdx) && cu->getPartitionSize(0) == SIZE_2Nx2N && !cu->getQtRootCbf(0))
diff -r 8aa4132d3097 -r 6b32dc49600b source/encoder/encoder.cpp
--- a/source/encoder/encoder.cpp	Fri Jul 25 01:29:21 2014 -0500
+++ b/source/encoder/encoder.cpp	Fri Jul 25 15:28:47 2014 +0530
@@ -1287,8 +1287,8 @@
         p->crQpOffset += 6;
     }
 
-    // disable RDOQ if psy-rd is enabled; until we make it psy-aware
-    m_bEnableRDOQ = p->psyRd == 0.0 && p->rdLevel >= 4;
+    // disable RDOQ if rdlevel < 4 or if psy-rd is enabled without psy-rdoq
+    m_bEnableRDOQ = p->rdLevel >= 4 ? (p->psyRdoq || !p->psyRd) : 0;
 
     if (p->bLossless)
     {
diff -r 8aa4132d3097 -r 6b32dc49600b source/x265.h
--- a/source/x265.h	Fri Jul 25 01:29:21 2014 -0500
+++ b/source/x265.h	Fri Jul 25 15:28:47 2014 +0530
@@ -617,6 +617,10 @@
      * energy of the source, at the cost of lost compression. Default 0.0 */
     double    psyRd;
 
+    /* Psycho-visual rate-distortion opt quantize strength. Only has an effect in presets
+     * which use RDOQ. Default 0.0 */
+    double    psyRdoq;
+
     /*== Coding tools ==*/
 
     /* Enable the implicit signaling of the sign bit of the last coefficient of


More information about the x265-devel mailing list