[x265] [PATCH] Modify TComPrediction structure to support multiple color space formats

ashok at multicorewareinc.com ashok at multicorewareinc.com
Fri Jan 3 14:05:14 CET 2014


# HG changeset patch
# User ashok at multicorewareinc.com
# Date 1388754301 -19800
#      Fri Jan 03 18:35:01 2014 +0530
# Node ID e4ab306e0347e5a65c52be2d0845a6cf592c5713
# Parent  eb68ca275978396b583891717f476d9eb35ab112
Modify TComPrediction structure to support multiple color space formats

diff -r eb68ca275978 -r e4ab306e0347 source/Lib/TLibCommon/TComPrediction.cpp
--- a/source/Lib/TLibCommon/TComPrediction.cpp	Fri Jan 03 18:33:49 2014 +0530
+++ b/source/Lib/TLibCommon/TComPrediction.cpp	Fri Jan 03 18:35:01 2014 +0530
@@ -89,6 +89,9 @@
 
 void TComPrediction::initTempBuff(int csp)
 {
+    m_hChromaShift = CHROMA_H_SHIFT(csp);
+    m_vChromaShift = CHROMA_V_SHIFT(csp);
+
     if (m_predBuf == NULL)
     {
         m_predBufHeight  = ((MAX_CU_SIZE + 2) << 4);
@@ -124,6 +127,31 @@
 // Public member functions
 // ====================================================================================================================
 
+bool TComPrediction::filteringIntraReferenceSamples(uint32_t dirMode, uint32_t width, uint32_t height, int chFmt)
+{
+    bool bFilter;
+    if(chFmt != CHROMA_444)
+    {
+        bFilter = false;
+    }
+    else
+    {
+        assert(width >= 4 && height >= 4 && width < 128 && height < 128);
+
+        if (dirMode == DC_IDX)
+        {
+            bFilter=false; //no smoothing for DC or LM chroma
+        }
+        else
+        {
+            int diff = std::min<int>(abs((int) dirMode - HOR_IDX), abs((int)dirMode - VER_IDX));
+            uint32_t sizeIndex = g_convertToBit[width];
+            bFilter = diff > intraFilterThreshold[sizeIndex];
+        }
+    }
+    return bFilter;
+}
+
 void TComPrediction::predIntraLumaAng(uint32_t dirMode, Pel* dst, intptr_t stride, int size)
 {
     assert(g_convertToBit[size] >= 0);   //   4x  4
@@ -168,19 +196,77 @@
 }
 
 // Angular chroma
-void TComPrediction::predIntraChromaAng(Pel* src, uint32_t dirMode, Pel* dst, intptr_t stride, int width)
+void TComPrediction::predIntraChromaAng(Pel* src, uint32_t dirMode, Pel* dst, intptr_t stride, int width, int height, int chFmt)
 {
     int log2BlkSize = g_convertToBit[width];
 
     // Create the prediction
     Pel refAbv[3 * MAX_CU_SIZE];
     Pel refLft[3 * MAX_CU_SIZE];
-    int limit = (dirMode <= 25 && dirMode >= 11) ? (width + 1 + 1) : (2 * width + 1);
 
-    memcpy(refAbv + width - 1, src, (limit) * sizeof(Pel));
-    for (int k = 0; k < limit; k++)
+    const bool bUseFilteredPredictions = TComPrediction::filteringIntraReferenceSamples(dirMode, width, height, chFmt);
+
+    if (bUseFilteredPredictions)
     {
-        refLft[k + width - 1] = src[k * ADI_BUF_STRIDE];
+        uint32_t cuWidth2  = width << 1;
+        uint32_t cuHeight2 = height << 1;
+        // generate filtered intra prediction samples
+        // left and left above border + above and above right border + top left corner = length of 3. filter buffer
+        int bufSize = cuHeight2 + cuWidth2 + 1;
+        uint32_t wh = ADI_BUF_STRIDE * height;         // number of elements in one buffer
+
+        Pel* filteredBuf1 = src + wh;             // 1. filter buffer
+        Pel* filteredBuf2 = filteredBuf1 + wh;    // 2. filter buffer
+        Pel* filterBuf    = filteredBuf2 + wh;    // buffer for 2. filtering (sequential)
+        Pel* filterBufN   = filterBuf + bufSize;  // buffer for 1. filtering (sequential)
+
+        int l = 0;
+        // left border from bottom to top
+        for (int i = 0; i < cuHeight2; i++)
+        {
+            filterBuf[l++] = src[ADI_BUF_STRIDE * (cuHeight2 - i)];
+        }
+
+        // top left corner
+        filterBuf[l++] = src[0];
+
+        // above border from left to right
+        memcpy(&filterBuf[l], &src[1], cuWidth2 * sizeof(*filterBuf));
+
+        // 1. filtering with [1 2 1]
+        filterBufN[0] = filterBuf[0];
+        filterBufN[bufSize - 1] = filterBuf[bufSize - 1];
+        for (int i = 1; i < bufSize - 1; i++)
+        {
+            filterBufN[i] = (filterBuf[i - 1] + 2 * filterBuf[i] + filterBuf[i + 1] + 2) >> 2;
+        }
+
+       // fill 1. filter buffer with filtered values
+        l = 0;
+        for (int i = 0; i < cuHeight2; i++)
+        {
+            filteredBuf1[ADI_BUF_STRIDE * (cuHeight2 - i)] = filterBufN[l++];
+        }
+
+        filteredBuf1[0] = filterBufN[l++];
+        memcpy(&filteredBuf1[1], &filterBufN[l], cuWidth2 * sizeof(*filteredBuf1));
+
+        int limit = (2 * width + 1);
+        src += wh;
+        memcpy(refAbv + width - 1, src, (limit) * sizeof(Pel));
+        for (int k = 0; k < limit; k++)
+        {
+            refLft[k + width - 1] = src[k * ADI_BUF_STRIDE];
+        }
+    }
+    else
+    {
+        int limit = (dirMode <= 25 && dirMode >= 11) ? (width + 1 + 1) : (2 * width + 1);
+        memcpy(refAbv + width - 1, src, (limit) * sizeof(Pel));
+        for (int k = 0; k < limit; k++)
+        {
+            refLft[k + width - 1] = src[k * ADI_BUF_STRIDE];
+        }
     }
 
     // get starting pixel in block
@@ -510,7 +596,10 @@
     int refStride = refPic->getCStride();
     int dstStride = dstPic->getCStride();
 
-    int refOffset = (mv->x >> 3) + (mv->y >> 3) * refStride;
+    int shiftHor = (2 + cu->getHorzChromaShift());
+    int shiftVer = (2 + cu->getVertChromaShift());
+
+    int refOffset = (mv->x >> shiftHor) + (mv->y >> shiftVer) * refStride;
 
     Pel* refCb = refPic->getCbAddr(cu->getAddr(), cu->getZorderIdxInCU() + partAddr) + refOffset;
     Pel* refCr = refPic->getCrAddr(cu->getAddr(), cu->getZorderIdxInCU() + partAddr) + refOffset;
@@ -518,10 +607,11 @@
     Pel* dstCb = dstPic->getCbAddr(partAddr);
     Pel* dstCr = dstPic->getCrAddr(partAddr);
 
-    int xFrac = mv->x & 0x7;
-    int yFrac = mv->y & 0x7;
+    int xFrac = mv->x & ((1 << shiftHor)-1);
+    int yFrac = mv->y & ((1 << shiftVer)-1);
+
     int partEnum = partitionFromSizes(width, height);
-    int csp = X265_CSP_I420; // TODO: member var?
+    int csp = cu->getChromaFormat();
 
     if ((yFrac | xFrac) == 0)
     {
@@ -530,29 +620,27 @@
     }
     else if (yFrac == 0)
     {
-        primitives.chroma[csp].filter_hpp[partEnum](refCb, refStride, dstCb, dstStride, xFrac);
-        primitives.chroma[csp].filter_hpp[partEnum](refCr, refStride, dstCr, dstStride, xFrac);
+        primitives.chroma[csp].filter_hpp[partEnum](refCb, refStride, dstCb, dstStride, xFrac << (1 - cu->getHorzChromaShift()));
+        primitives.chroma[csp].filter_hpp[partEnum](refCr, refStride, dstCr, dstStride, xFrac << (1 - cu->getHorzChromaShift()));
     }
     else if (xFrac == 0)
     {
-        primitives.chroma[csp].filter_vpp[partEnum](refCb, refStride, dstCb, dstStride, yFrac);
-        primitives.chroma[csp].filter_vpp[partEnum](refCr, refStride, dstCr, dstStride, yFrac);
+        primitives.chroma[csp].filter_vpp[partEnum](refCb, refStride, dstCb, dstStride, yFrac << (1 - cu->getVertChromaShift()));
+        primitives.chroma[csp].filter_vpp[partEnum](refCr, refStride, dstCr, dstStride, yFrac << (1 - cu->getVertChromaShift()));
     }
     else
     {
-        int hShift = CHROMA_H_SHIFT(csp);
-        int vShift = CHROMA_V_SHIFT(csp);
-        uint32_t cxWidth = width >> hShift;
-        uint32_t cxHeight = height >> vShift;
+        uint32_t cxWidth  = width  >> m_hChromaShift;
+        uint32_t cxHeight = height >> m_vChromaShift;
         int extStride = cxWidth;
         int filterSize = NTAPS_CHROMA;
         int halfFilterSize = (filterSize >> 1);
 
-        primitives.chroma[csp].filter_hps[partEnum](refCb, refStride, m_immedVals, extStride,  xFrac, 1);
-        primitives.chroma_vsp(m_immedVals + (halfFilterSize - 1) * extStride, extStride, dstCb, dstStride, cxWidth, cxHeight, yFrac);
+        primitives.chroma[csp].filter_hps[partEnum](refCb, refStride, m_immedVals, extStride,  xFrac << (1 - cu->getHorzChromaShift()), 1);
+        primitives.chroma_vsp(m_immedVals + (halfFilterSize - 1) * extStride, extStride, dstCb, dstStride, cxWidth, cxHeight, yFrac << (1 - cu->getVertChromaShift()));
 
-        primitives.chroma[csp].filter_hps[partEnum](refCr, refStride, m_immedVals, extStride, xFrac, 1);
-        primitives.chroma_vsp(m_immedVals + (halfFilterSize - 1) * extStride, extStride, dstCr, dstStride, cxWidth, cxHeight, yFrac);
+        primitives.chroma[csp].filter_hps[partEnum](refCr, refStride, m_immedVals, extStride, xFrac << (1 - cu->getHorzChromaShift()), 1);
+        primitives.chroma_vsp(m_immedVals + (halfFilterSize - 1) * extStride, extStride, dstCr, dstStride, cxWidth, cxHeight, yFrac << (1 - cu->getVertChromaShift()));
     }
 }
 
@@ -562,7 +650,10 @@
     int refStride = refPic->getCStride();
     int dstStride = dstPic->m_cwidth;
 
-    int refOffset = (mv->x >> 3) + (mv->y >> 3) * refStride;
+    int shiftHor = (2 + cu->getHorzChromaShift());
+    int shiftVer = (2 + cu->getVertChromaShift());
+
+    int refOffset = (mv->x >> shiftHor) + (mv->y >> shiftVer) * refStride;
 
     Pel* refCb = refPic->getCbAddr(cu->getAddr(), cu->getZorderIdxInCU() + partAddr) + refOffset;
     Pel* refCr = refPic->getCrAddr(cu->getAddr(), cu->getZorderIdxInCU() + partAddr) + refOffset;
@@ -570,42 +661,41 @@
     int16_t* dstCb = dstPic->getCbAddr(partAddr);
     int16_t* dstCr = dstPic->getCrAddr(partAddr);
 
-    int xFrac = mv->x & 0x7;
-    int yFrac = mv->y & 0x7;
+    int xFrac = mv->x & ((1 << shiftHor)-1);
+    int yFrac = mv->y & ((1 << shiftVer)-1);
 
     int partEnum = partitionFromSizes(width, height);
-    int csp = X265_CSP_I420;
+    int csp = cu->getChromaFormat();
 
-    uint32_t cxWidth = width >> 1;
-    uint32_t cxHeight = height >> 1;
+    uint32_t cxWidth = width   >> m_hChromaShift;
+    uint32_t cxHeight = height >> m_vChromaShift;
 
-    assert(dstStride == MAX_CU_SIZE / 2);
     assert(((cxWidth | cxHeight) % 2) == 0);
 
     if ((yFrac | xFrac) == 0)
     {
-        primitives.chroma_p2s(refCb, refStride, dstCb, cxWidth, cxHeight);
-        primitives.chroma_p2s(refCr, refStride, dstCr, cxWidth, cxHeight);
+        primitives.chroma_p2s[csp](refCb, refStride, dstCb, cxWidth, cxHeight);
+        primitives.chroma_p2s[csp](refCr, refStride, dstCr, cxWidth, cxHeight);
     }
     else if (yFrac == 0)
     {
-        primitives.chroma[csp].filter_hps[partEnum](refCb, refStride, dstCb, dstStride, xFrac, 0);
-        primitives.chroma[csp].filter_hps[partEnum](refCr, refStride, dstCr, dstStride, xFrac, 0);
+        primitives.chroma[csp].filter_hps[partEnum](refCb, refStride, dstCb, dstStride, xFrac << (1 - cu->getHorzChromaShift()), 0);
+        primitives.chroma[csp].filter_hps[partEnum](refCr, refStride, dstCr, dstStride, xFrac << (1 - cu->getHorzChromaShift()), 0);
     }
     else if (xFrac == 0)
     {
-        primitives.ipfilter_ps[FILTER_V_P_S_4](refCb, refStride, dstCb, dstStride, cxWidth, cxHeight, g_chromaFilter[yFrac]);
-        primitives.ipfilter_ps[FILTER_V_P_S_4](refCr, refStride, dstCr, dstStride, cxWidth, cxHeight, g_chromaFilter[yFrac]);
+        primitives.ipfilter_ps[FILTER_V_P_S_4](refCb, refStride, dstCb, dstStride, cxWidth, cxHeight, g_chromaFilter[yFrac << (1 - cu->getVertChromaShift())]);
+        primitives.ipfilter_ps[FILTER_V_P_S_4](refCr, refStride, dstCr, dstStride, cxWidth, cxHeight, g_chromaFilter[yFrac << (1 - cu->getVertChromaShift())]);
     }
     else
     {
         int extStride = cxWidth;
         int filterSize = NTAPS_CHROMA;
         int halfFilterSize = (filterSize >> 1);
-        primitives.chroma[csp].filter_hps[partEnum](refCb, refStride, m_immedVals, extStride, xFrac, 1);
-        primitives.ipfilter_ss[FILTER_V_S_S_4](m_immedVals + (halfFilterSize - 1) * extStride, extStride, dstCb, dstStride, cxWidth, cxHeight, yFrac);
-        primitives.chroma[csp].filter_hps[partEnum](refCr, refStride, m_immedVals, extStride, xFrac, 1);
-        primitives.ipfilter_ss[FILTER_V_S_S_4](m_immedVals + (halfFilterSize - 1) * extStride, extStride, dstCr, dstStride, cxWidth, cxHeight, yFrac);
+        primitives.chroma[csp].filter_hps[partEnum](refCb, refStride, m_immedVals, extStride, xFrac << (1 - cu->getHorzChromaShift()), 1);
+        primitives.ipfilter_ss[FILTER_V_S_S_4](m_immedVals + (halfFilterSize - 1) * extStride, extStride, dstCb, dstStride, cxWidth, cxHeight, yFrac << (1 - cu->getVertChromaShift()));
+        primitives.chroma[csp].filter_hps[partEnum](refCr, refStride, m_immedVals, extStride, xFrac << (1 - cu->getHorzChromaShift()), 1);
+        primitives.ipfilter_ss[FILTER_V_S_S_4](m_immedVals + (halfFilterSize - 1) * extStride, extStride, dstCr, dstStride, cxWidth, cxHeight, yFrac << (1 - cu->getVertChromaShift()));
     }
 }
 
diff -r eb68ca275978 -r e4ab306e0347 source/Lib/TLibCommon/TComPrediction.h
--- a/source/Lib/TLibCommon/TComPrediction.h	Fri Jan 03 18:33:49 2014 +0530
+++ b/source/Lib/TLibCommon/TComPrediction.h	Fri Jan 03 18:35:01 2014 +0530
@@ -77,6 +77,9 @@
     Pel*      m_lumaRecBuffer; ///< array for down-sampled reconstructed luma sample
     int       m_lumaRecStride; ///< stride of m_lumaRecBuffer
 
+    int m_hChromaShift;
+    int m_vChromaShift;
+
     // motion compensation functions
     void xPredInterUni(TComDataCU* cu, uint32_t partAddr, int width, int height, int picList, TComYuv* outPredYuv, bool bLuma = true, bool bChroma = true);
     void xPredInterUni(TComDataCU* cu, uint32_t partAddr, int width, int height, int picList, TShortYUV* outPredYuv, bool bLuma = true, bool bChroma = true);
@@ -109,7 +112,8 @@
 
     // Angular Intra
     void predIntraLumaAng(uint32_t dirMode, Pel* pred, intptr_t stride, int width);
-    void predIntraChromaAng(Pel* src, uint32_t dirMode, Pel* pred, intptr_t stride, int width);
+    void predIntraChromaAng(Pel* src, uint32_t dirMode, Pel* pred, intptr_t stride, int width, int height, int chFmt);
+    bool filteringIntraReferenceSamples(uint32_t dirMode, uint32_t width, uint32_t height, int chFmt);
 
     Pel* getPredicBuf()             { return m_predBuf; }
 


More information about the x265-devel mailing list