[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