[x265] [PATCH] Modify TComPrediction structure to support multiple color space formats
Steve Borho
steve at borho.org
Wed Jan 8 00:42:58 CET 2014
On Fri, Jan 3, 2014 at 7:05 AM, <ashok at multicorewareinc.com> wrote:
> # 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)
>
white-space
> + {
> + 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
>
white-space
> + }
> + else
> + {
> + int diff = std::min<int>(abs((int) dirMode - HOR_IDX),
> abs((int)dirMode - VER_IDX));
>
X265_MIN
> + 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; }
>
> _______________________________________________
> x265-devel mailing list
> x265-devel at videolan.org
> https://mailman.videolan.org/listinfo/x265-devel
>
--
Steve Borho
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mailman.videolan.org/pipermail/x265-devel/attachments/20140107/bfff3f4b/attachment-0001.html>
More information about the x265-devel
mailing list