Refactored RGB to AVC444v2

This commit is contained in:
Armin Novak 2018-02-02 08:45:13 +01:00
parent eb8e9cb410
commit 53cdd95de0
1 changed files with 307 additions and 207 deletions

View File

@ -1360,6 +1360,134 @@ static INLINE pstatus_t general_RGBToAVC444YUV(
return !PRIMITIVES_SUCCESS;
}
static INLINE void general_RGBToAVC444YUVv2_ANY_DOUBLE_ROW(
const BYTE* srcEven, const BYTE* srcOdd, UINT32 srcFormat,
BYTE* yLumaDstEven, BYTE* yLumaDstOdd,
BYTE* uLumaDst, BYTE* vLumaDst,
BYTE* yEvenChromaDst1, BYTE* yEvenChromaDst2,
BYTE* yOddChromaDst1, BYTE* yOddChromaDst2,
BYTE* uChromaDst1, BYTE* uChromaDst2,
BYTE* vChromaDst1, BYTE* vChromaDst2,
UINT32 width)
{
UINT32 x;
const UINT32 bpp = GetBytesPerPixel(srcFormat);
for (x = 0; x < width; x += 2)
{
BYTE Ya, Ua, Va;
BYTE Yb, Ub, Vb;
BYTE Yc, Uc, Vc;
BYTE Yd, Ud, Vd;
{
BYTE b, g, r;
const UINT32 color = ReadColor(srcEven, srcFormat);
srcEven += bpp;
SplitColor(color, srcFormat, &r, &g, &b, NULL, NULL);
Ya = RGB2Y(r, g, b);
Ua = RGB2U(r, g, b);
Va = RGB2V(r, g, b);
}
if (x < width - 1)
{
BYTE b, g, r;
const UINT32 color = ReadColor(srcEven, srcFormat);
srcEven += bpp;
SplitColor(color, srcFormat, &r, &g, &b, NULL, NULL);
Yb = RGB2Y(r, g, b);
Ub = RGB2U(r, g, b);
Vb = RGB2V(r, g, b);
}
else
{
Yb = Ya;
Ub = Ua;
Vb = Va;
}
if (srcOdd)
{
BYTE b, g, r;
const UINT32 color = ReadColor(srcOdd, srcFormat);
srcOdd += bpp;
SplitColor(color, srcFormat, &r, &g, &b, NULL, NULL);
Yc = RGB2Y(r, g, b);
Uc = RGB2U(r, g, b);
Vc = RGB2V(r, g, b);
}
else
{
Yc = Ya;
Uc = Ua;
Vc = Va;
}
if (srcOdd && (x < width - 1))
{
BYTE b, g, r;
const UINT32 color = ReadColor(srcOdd, srcFormat);
srcOdd += bpp;
SplitColor(color, srcFormat, &r, &g, &b, NULL, NULL);
Yd = RGB2Y(r, g, b);
Ud = RGB2U(r, g, b);
Vd = RGB2V(r, g, b);
}
else
{
Yd = Ya;
Ud = Ua;
Vd = Va;
}
/* Y [b1] */
*yLumaDstEven++ = Ya;
if (x < width - 1)
*yLumaDstEven++ = Yb;
if (srcOdd)
*yLumaDstOdd++ = Yc;
if (srcOdd && (x < width - 1))
*yLumaDstOdd++ = Yd;
/* 2x 2y [b2,b3] */
*uLumaDst++ = (Ua + Ub + Uc + Ud) / 4;
*vLumaDst++ = (Va + Vb + Vc + Vd) / 4;
/* 2x+1, y [b4,b5] even */
if (x < width - 1)
{
*yEvenChromaDst1++ = Ub;
*yEvenChromaDst2++ = Vb;
}
if (srcOdd)
{
/* 2x+1, y [b4,b5] odd */
if (x < width - 1)
{
*yOddChromaDst1++ = Ud;
*yOddChromaDst2++ = Vd;
}
/* 4x 2y+1 [b6, b7] */
if (x % 4 == 0)
{
*uChromaDst1++ = Uc;
*uChromaDst2++ = Vc;
}
/* 4x+2 2y+1 [b8, b9] */
else
{
*vChromaDst1++ = Uc;
*vChromaDst2++ = Vc;
}
}
}
}
static INLINE pstatus_t general_RGBToAVC444YUVv2_ANY(
const BYTE* pSrc, UINT32 srcFormat, UINT32 srcStep,
BYTE* pDst1[3], const UINT32 dst1Step[3],
@ -1415,228 +1543,200 @@ static INLINE pstatus_t general_RGBToAVC444YUVv2_ANY(
* }
*
*/
UINT32 x, y;
UINT32 y;
for (y = 0; y < roi->height; y++)
if (roi->height < 1 || roi->width < 1)
return !PRIMITIVES_SUCCESS;
for (y = 0; y < roi->height; y += 2)
{
const BYTE* src = pSrc + y * srcStep;
BYTE* b1 = pDst1 ? (pDst1[0] + y * dst1Step[0]) : NULL;
BYTE* b4 = pDst2 ? (pDst2[0] + y * dst2Step[0]) : NULL;
BYTE* b5 = pDst2 ? (pDst2[0] + y * dst2Step[0] + dst2Step[0] / 2) : NULL;
for (x = 0; x < roi->width; x++)
{
const UINT32 colorA = ReadColor(src, srcFormat);
BYTE r, g, b;
SplitColor(colorA, srcFormat, &r, &g, &b, NULL, NULL);
src += 4;
if (b1)
{
const BYTE y = RGB2Y(r, g, b);
*b1++ = y;
}
if (b4 && b5 && ((x & 1) == 1))
{
const BYTE u = RGB2U(r, g, b);
const BYTE v = RGB2V(r, g, b);
*b4++ = u;
*b5++ = v;
}
}
}
if (pDst1)
{
for (y = 0; y < roi->height / 2; y++)
{
const BYTE* src = pSrc + (2 * y) * srcStep;
BYTE* b2 = pDst1[1] + y * dst1Step[1];
BYTE* b3 = pDst1[2] + y * dst1Step[2];
for (x = 0; x < roi->width / 2; x++)
{
const UINT32 colorA = ReadColor(src, srcFormat);
const UINT32 colorB = ReadColor(src + 4, srcFormat);
const UINT32 colorC = ReadColor(src + srcStep, srcFormat);
const UINT32 colorD = ReadColor(src + 4 + srcStep, srcFormat);
BYTE r, g, b;
SplitColor(colorA, srcFormat, &r, &g, &b, NULL, NULL);
src += 8;
{
BYTE rr, gg, bb;
UINT16 u = RGB2U(r, g, b);
UINT16 v = RGB2V(r, g, b);
SplitColor(colorB, srcFormat, &rr, &gg, &bb, NULL, NULL);
u += RGB2U(rr, gg, bb);
v += RGB2V(rr, gg, bb);
SplitColor(colorC, srcFormat, &rr, &gg, &bb, NULL, NULL);
u += RGB2U(rr, gg, bb);
v += RGB2V(rr, gg, bb);
SplitColor(colorD, srcFormat, &rr, &gg, &bb, NULL, NULL);
u += RGB2U(rr, gg, bb);
v += RGB2V(rr, gg, bb);
u /= 4;
v /= 4;
*b2++ = u;
*b3++ = v;
}
}
}
}
if (pDst2)
{
for (y = 0; y < roi->height / 2; y++)
{
const BYTE* src = pSrc + (2 * y + 1) * srcStep;
BYTE* b6 = pDst2[1] + y * dst2Step[1];
BYTE* b7 = pDst2[1] + y * dst2Step[1] + dst2Step[1] / 2;
BYTE* b8 = pDst2[2] + y * dst2Step[2];
BYTE* b9 = pDst2[2] + y * dst2Step[2] + dst2Step[2] / 2;
for (x = 0; x < roi->width / 2; x++)
{
const UINT32 color = ReadColor(src, srcFormat);
BYTE r, g, b, u, v;
SplitColor(color, srcFormat, &r, &g, &b, NULL, NULL);
src += 8;
u = RGB2U(r, g, b);
v = RGB2V(r, g, b);
if (x & 1)
{
*b8++ = u;
*b9++ = v;
}
else
{
*b6++ = u;
*b7++ = v;
}
}
}
const BYTE* srcEven = (pSrc + y * srcStep);
const BYTE* srcOdd = (y < roi->height - 1) ? (srcEven + srcStep) : NULL;
BYTE* dstLumaYEven = (pDst1[0] + y * dst1Step[0]);
BYTE* dstLumaYOdd = (dstLumaYEven + dst1Step[0]);
BYTE* dstLumaU = (pDst1[1] + (y / 2) * dst1Step[1]);
BYTE* dstLumaV = (pDst1[2] + (y / 2) * dst1Step[2]);
BYTE* dstEvenChromaY1 = (pDst2[0] + y * dst2Step[0]);
BYTE* dstEvenChromaY2 = dstEvenChromaY1 + roi->width / 2;
BYTE* dstOddChromaY1 = dstEvenChromaY1 + dst2Step[0];
BYTE* dstOddChromaY2 = dstEvenChromaY2 + dst2Step[0];
BYTE* dstChromaU1 = (pDst2[1] + (y / 2) * dst2Step[1]);
BYTE* dstChromaV1 = (pDst2[2] + (y / 2) * dst2Step[2]);
BYTE* dstChromaU2 = dstChromaU1 + roi->width / 4;
BYTE* dstChromaV2 = dstChromaV1 + roi->width / 4;
general_RGBToAVC444YUVv2_ANY_DOUBLE_ROW(srcEven, srcOdd, srcFormat, dstLumaYEven,
dstLumaYOdd, dstLumaU, dstLumaV,
dstEvenChromaY1, dstEvenChromaY2,
dstOddChromaY1, dstOddChromaY2,
dstChromaU1, dstChromaU2,
dstChromaV1, dstChromaV2,
roi->width);
}
return PRIMITIVES_SUCCESS;
}
static INLINE void general_RGBToAVC444YUVv2_BGRX_DOUBLE_ROW(
const BYTE* srcEven, const BYTE* srcOdd,
BYTE* yLumaDstEven, BYTE* yLumaDstOdd,
BYTE* uLumaDst, BYTE* vLumaDst,
BYTE* yEvenChromaDst1, BYTE* yEvenChromaDst2,
BYTE* yOddChromaDst1, BYTE* yOddChromaDst2,
BYTE* uChromaDst1, BYTE* uChromaDst2,
BYTE* vChromaDst1, BYTE* vChromaDst2,
UINT32 width)
{
UINT32 x;
for (x = 0; x < width; x += 2)
{
BYTE Ya, Ua, Va;
BYTE Yb, Ub, Vb;
BYTE Yc, Uc, Vc;
BYTE Yd, Ud, Vd;
{
const BYTE b = *srcEven++;
const BYTE g = *srcEven++;
const BYTE r = *srcEven++;
srcEven++;
Ya = RGB2Y(r, g, b);
Ua = RGB2U(r, g, b);
Va = RGB2V(r, g, b);
}
if (x < width - 1)
{
const BYTE b = *srcEven++;
const BYTE g = *srcEven++;
const BYTE r = *srcEven++;
srcEven++;
Yb = RGB2Y(r, g, b);
Ub = RGB2U(r, g, b);
Vb = RGB2V(r, g, b);
}
else
{
Yb = Ya;
Ub = Ua;
Vb = Va;
}
if (srcOdd)
{
const BYTE b = *srcOdd++;
const BYTE g = *srcOdd++;
const BYTE r = *srcOdd++;
srcOdd++;
Yc = RGB2Y(r, g, b);
Uc = RGB2U(r, g, b);
Vc = RGB2V(r, g, b);
}
else
{
Yc = Ya;
Uc = Ua;
Vc = Va;
}
if (srcOdd && (x < width - 1))
{
const BYTE b = *srcOdd++;
const BYTE g = *srcOdd++;
const BYTE r = *srcOdd++;
srcOdd++;
Yd = RGB2Y(r, g, b);
Ud = RGB2U(r, g, b);
Vd = RGB2V(r, g, b);
}
else
{
Yd = Ya;
Ud = Ua;
Vd = Va;
}
/* Y [b1] */
*yLumaDstEven++ = Ya;
if (x < width - 1)
*yLumaDstEven++ = Yb;
if (srcOdd)
*yLumaDstOdd++ = Yc;
if (srcOdd && (x < width - 1))
*yLumaDstOdd++ = Yd;
/* 2x 2y [b2,b3] */
*uLumaDst++ = (Ua + Ub + Uc + Ud) / 4;
*vLumaDst++ = (Va + Vb + Vc + Vd) / 4;
/* 2x+1, y [b4,b5] even */
if (x < width - 1)
{
*yEvenChromaDst1++ = Ub;
*yEvenChromaDst2++ = Vb;
}
if (srcOdd)
{
/* 2x+1, y [b4,b5] odd */
if (x < width - 1)
{
*yOddChromaDst1++ = Ud;
*yOddChromaDst2++ = Vd;
}
/* 4x 2y+1 [b6, b7] */
if (x % 4 == 0)
{
*uChromaDst1++ = Uc;
*uChromaDst2++ = Vc;
}
/* 4x+2 2y+1 [b8, b9] */
else
{
*vChromaDst1++ = Uc;
*vChromaDst2++ = Vc;
}
}
}
}
static INLINE pstatus_t general_RGBToAVC444YUVv2_BGRX(
const BYTE* pSrc, UINT32 srcStep,
BYTE* pDst1[3], const UINT32 dst1Step[3],
BYTE* pDst2[3], const UINT32 dst2Step[3],
const prim_size_t* roi)
{
UINT32 x, y;
UINT32 y;
for (y = 0; y < roi->height; y++)
if (roi->height < 1 || roi->width < 1)
return !PRIMITIVES_SUCCESS;
for (y = 0; y < roi->height; y += 2)
{
const BYTE* src = pSrc + y * srcStep;
BYTE* b1 = pDst1 ? (pDst1[0] + y * dst1Step[0]) : NULL;
BYTE* b4 = pDst2 ? (pDst2[0] + y * dst2Step[0]) : NULL;
BYTE* b5 = pDst2 ? (pDst2[0] + y * dst2Step[0] + dst2Step[0] / 2) : NULL;
for (x = 0; x < roi->width; x++)
{
const BYTE b = *src++;
const BYTE g = *src++;
const BYTE r = *src++;
src++;
if (b1)
{
const BYTE y = RGB2Y(r, g, b);
*b1++ = y;
}
if (b4 && b5 && ((x & 1) == 1))
{
const BYTE u = RGB2U(r, g, b);
const BYTE v = RGB2V(r, g, b);
*b4++ = u;
*b5++ = v;
}
}
}
if (pDst1)
{
for (y = 0; y < roi->height / 2; y++)
{
const BYTE* src = pSrc + (2 * y) * srcStep;
BYTE* b2 = pDst1[1] + y * dst1Step[1];
BYTE* b3 = pDst1[2] + y * dst1Step[2];
for (x = 0; x < roi->width / 2; x++)
{
const BYTE b = *src++;
const BYTE g = *src++;
const BYTE r = *src++;
const BYTE a = *src++;
const BYTE* srcB = src;
const BYTE* srcC = src - 4 + srcStep;
const BYTE* srcD = src + srcStep;
BYTE rr, gg, bb;
UINT16 u = RGB2U(r, g, b);
UINT16 v = RGB2V(r, g, b);
bb = *srcB++;
gg = *srcB++;
rr = *srcB++;
u += RGB2U(rr, gg, bb);
v += RGB2V(rr, gg, bb);
bb = *srcC++;
gg = *srcC++;
rr = *srcC++;
u += RGB2U(rr, gg, bb);
v += RGB2V(rr, gg, bb);
bb = *srcD++;
gg = *srcD++;
rr = *srcD++;
u += RGB2U(rr, gg, bb);
v += RGB2V(rr, gg, bb);
u /= 4;
v /= 4;
src += 4;
*b2++ = u;
*b3++ = v;
}
}
}
if (pDst2)
{
for (y = 0; y < roi->height / 2; y++)
{
const BYTE* src = pSrc + (2 * y + 1) * srcStep;
BYTE* b6 = pDst2[1] + y * dst2Step[1];
BYTE* b7 = pDst2[1] + y * dst2Step[1] + dst2Step[1] / 2;
BYTE* b8 = pDst2[2] + y * dst2Step[2];
BYTE* b9 = pDst2[2] + y * dst2Step[2] + dst2Step[2] / 2;
for (x = 0; x < roi->width / 2; x++)
{
BYTE u, v;
const BYTE b = *src++;
const BYTE g = *src++;
const BYTE r = *src++;
src++;
src += 4;
u = RGB2U(r, g, b);
v = RGB2V(r, g, b);
if (x & 1)
{
*b8++ = u;
*b9++ = v;
}
else
{
*b6++ = u;
*b7++ = v;
}
}
}
const BYTE* srcEven = (pSrc + y * srcStep);
const BYTE* srcOdd = (y < roi->height - 1) ? (srcEven + srcStep) : NULL;
BYTE* dstLumaYEven = (pDst1[0] + y * dst1Step[0]);
BYTE* dstLumaYOdd = (dstLumaYEven + dst1Step[0]);
BYTE* dstLumaU = (pDst1[1] + (y / 2) * dst1Step[1]);
BYTE* dstLumaV = (pDst1[2] + (y / 2) * dst1Step[2]);
BYTE* dstEvenChromaY1 = (pDst2[0] + y * dst2Step[0]);
BYTE* dstEvenChromaY2 = dstEvenChromaY1 + roi->width / 2;
BYTE* dstOddChromaY1 = dstEvenChromaY1 + dst2Step[0];
BYTE* dstOddChromaY2 = dstEvenChromaY2 + dst2Step[0];
BYTE* dstChromaU1 = (pDst2[1] + (y / 2) * dst2Step[1]);
BYTE* dstChromaV1 = (pDst2[2] + (y / 2) * dst2Step[2]);
BYTE* dstChromaU2 = dstChromaU1 + roi->width / 4;
BYTE* dstChromaV2 = dstChromaV1 + roi->width / 4;
general_RGBToAVC444YUVv2_BGRX_DOUBLE_ROW(srcEven, srcOdd, dstLumaYEven,
dstLumaYOdd, dstLumaU, dstLumaV,
dstEvenChromaY1, dstEvenChromaY2,
dstOddChromaY1, dstOddChromaY2,
dstChromaU1, dstChromaU2,
dstChromaV1, dstChromaV2,
roi->width);
}
return PRIMITIVES_SUCCESS;