<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>