<div dir="ltr"><br><div class="gmail_extra"><br><br><div class="gmail_quote">On Fri, Jan 3, 2014 at 7:05 AM,  <span dir="ltr"><<a href="mailto:ashok@multicorewareinc.com" target="_blank">ashok@multicorewareinc.com</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"># HG changeset patch<br>
# User <a href="mailto:ashok@multicorewareinc.com">ashok@multicorewareinc.com</a><br>
# Date 1388754301 -19800<br>
#      Fri Jan 03 18:35:01 2014 +0530<br>
# Node ID e4ab306e0347e5a65c52be2d0845a6cf592c5713<br>
# Parent  eb68ca275978396b583891717f476d9eb35ab112<br>
Modify TComPrediction structure to support multiple color space formats<br>
<br>
diff -r eb68ca275978 -r e4ab306e0347 source/Lib/TLibCommon/TComPrediction.cpp<br>
--- a/source/Lib/TLibCommon/TComPrediction.cpp  Fri Jan 03 18:33:49 2014 +0530<br>
+++ b/source/Lib/TLibCommon/TComPrediction.cpp  Fri Jan 03 18:35:01 2014 +0530<br>
@@ -89,6 +89,9 @@<br>
<br>
 void TComPrediction::initTempBuff(int csp)<br>
 {<br>
+    m_hChromaShift = CHROMA_H_SHIFT(csp);<br>
+    m_vChromaShift = CHROMA_V_SHIFT(csp);<br>
+<br>
     if (m_predBuf == NULL)<br>
     {<br>
         m_predBufHeight  = ((MAX_CU_SIZE + 2) << 4);<br>
@@ -124,6 +127,31 @@<br>
 // Public member functions<br>
 // ====================================================================================================================<br>
<br>
+bool TComPrediction::filteringIntraReferenceSamples(uint32_t dirMode, uint32_t width, uint32_t height, int chFmt)<br>
+{<br>
+    bool bFilter;<br>
+    if(chFmt != CHROMA_444)<br></blockquote><div><br></div><div>white-space</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
+    {<br>
+        bFilter = false;<br>
+    }<br>
+    else<br>
+    {<br>
+        assert(width >= 4 && height >= 4 && width < 128 && height < 128);<br>
+<br>
+        if (dirMode == DC_IDX)<br>
+        {<br>
+            bFilter=false; //no smoothing for DC or LM chroma<br></blockquote><div><br></div><div>white-space</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">

+        }<br>
+        else<br>
+        {<br>
+            int diff = std::min<int>(abs((int) dirMode - HOR_IDX), abs((int)dirMode - VER_IDX));<br></blockquote><div><br></div><div>X265_MIN</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">

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