performance optimization, the code is finally correct
git-svn-id: file:///srv/svn/repos/haiku/trunk/current@6592 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -176,41 +176,51 @@ void gfx_conv_yuv411p_rgb32_c(AVFrame *in, AVFrame *out, int width, int height)
|
|||||||
|
|
||||||
void gfx_conv_yuv420p_rgb32_c(AVFrame *in, AVFrame *out, int width, int height)
|
void gfx_conv_yuv420p_rgb32_c(AVFrame *in, AVFrame *out, int width, int height)
|
||||||
{
|
{
|
||||||
|
uint32 poutInc = 2 * out->linesize[0];
|
||||||
|
uint32 *poutEven = (uint32 *)out->data[0];
|
||||||
|
uint32 *poutOdd = (uint32 *)(out->linesize[0] + (uint8 *)poutEven);
|
||||||
|
|
||||||
|
uint32 pi1Inc = in->linesize[0];
|
||||||
|
uint32 pi1Inc2 = 2 * pi1Inc;
|
||||||
|
uint32 pi2Inc = in->linesize[1];
|
||||||
|
uint32 pi3Inc = in->linesize[2];
|
||||||
|
|
||||||
|
uint8 *pi1Base = (uint8 *)in->data[0];
|
||||||
|
uint8 *pi2Base = (uint8 *)in->data[1];
|
||||||
|
uint8 *pi3Base = (uint8 *)in->data[2];
|
||||||
|
|
||||||
for (int i = 0; i < height; i++) {
|
uint32 runs = height / 2;
|
||||||
|
for (uint32 i = 0; i < runs; i++) {
|
||||||
|
|
||||||
uint32 *pout = (uint32 *)(i * out->linesize[0] + (uint8 *)out->data[0]);
|
uint8 *pi1Even = i * pi1Inc2 + pi1Base;
|
||||||
uint8 *pi1 = i * in->linesize[0] + (uint8 *)in->data[0];
|
uint8 *pi1Odd = pi1Inc + pi1Even;
|
||||||
uint8 *pi2 = (i/2) * in->linesize[1] + (uint8 *)in->data[1];
|
uint8 *pi2 = i * pi2Inc + pi2Base;
|
||||||
uint8 *pi3 = (i/2) * in->linesize[2] + (uint8 *)in->data[2];
|
uint8 *pi3 = i *pi3Inc + pi3Base;
|
||||||
|
|
||||||
for (int j = 0; j < width; j+= 2) {
|
for (uint32 j = 0; j < (uint32)width; j+= 2) {
|
||||||
|
|
||||||
int32 Cb, Cr, Y0, Y1, Cr_R, Cr_G, Cb_G, Cb_B, R, G, B;
|
int32 Cr_R, Cr_G, Cb_G, Cb_B;
|
||||||
|
register int32 Y0, Y1, R, G, B;
|
||||||
uint32 Y = *(uint16 *)pi1;
|
|
||||||
pi1 += 2;
|
B = - 128 + *(pi2++);
|
||||||
|
R = - 128 + *(pi3++);
|
||||||
|
Cr_R = R * 52298;
|
||||||
|
Cr_G = R * -26640;
|
||||||
|
Cb_G = B * -12845;
|
||||||
|
Cb_B = B * 66493;
|
||||||
|
|
||||||
|
G = *(uint16 *)pi1Even;
|
||||||
|
pi1Even += 2;
|
||||||
|
Y0 = ((G & 0x000000ff) - 16) * 38142;
|
||||||
|
Y1 = (((G & 0x0000ff00) >> 8) - 16) * 38142;
|
||||||
|
|
||||||
Y1 = (((Y & 0x0000ff00) >> 8) - 16) * 38142;
|
|
||||||
Y0 = ((Y & 0x000000ff) - 16) * 38142;
|
|
||||||
|
|
||||||
Cb = - 128 + *pi2;
|
|
||||||
Cr = - 128 + *pi3;
|
|
||||||
pi2 ++;
|
|
||||||
pi3 ++;
|
|
||||||
|
|
||||||
Cr_R = Cr * 52298;
|
|
||||||
Cr_G = Cr * -26640;
|
|
||||||
Cb_G = Cb * -12845;
|
|
||||||
Cb_B = Cb * 66493;
|
|
||||||
|
|
||||||
R = (Y0 + Cr_R) >> 15;
|
R = (Y0 + Cr_R) >> 15;
|
||||||
if (R < 0) R = 0; else if (R > 255) R = 255;
|
if (R < 0) R = 0; else if (R > 255) R = 255;
|
||||||
G = (Y0 + Cr_G + Cb_G) >> 15;
|
G = (Y0 + Cr_G + Cb_G) >> 15;
|
||||||
if (G < 0) G = 0; else if (G > 255) G = 255;
|
if (G < 0) G = 0; else if (G > 255) G = 255;
|
||||||
B = (Y0 + Cb_B) >> 15;
|
B = (Y0 + Cb_B) >> 15;
|
||||||
if (B < 0) B = 0; else if (B > 255) B = 255;
|
if (B < 0) B = 0; else if (B > 255) B = 255;
|
||||||
pout[j] = (R << 16) | (G << 8) | B;
|
poutEven[j] = (R << 16) | (G << 8) | B;
|
||||||
|
|
||||||
R = (Y1 + Cr_R) >> 15;
|
R = (Y1 + Cr_R) >> 15;
|
||||||
if (R < 0) R = 0; else if (R > 255) R = 255;
|
if (R < 0) R = 0; else if (R > 255) R = 255;
|
||||||
@@ -218,9 +228,34 @@ void gfx_conv_yuv420p_rgb32_c(AVFrame *in, AVFrame *out, int width, int height)
|
|||||||
if (G < 0) G = 0; else if (G > 255) G = 255;
|
if (G < 0) G = 0; else if (G > 255) G = 255;
|
||||||
B = (Y1 + Cb_B) >> 15;
|
B = (Y1 + Cb_B) >> 15;
|
||||||
if (B < 0) B = 0; else if (B > 255) B = 255;
|
if (B < 0) B = 0; else if (B > 255) B = 255;
|
||||||
pout[j + 1] = (R << 16) | (G << 8) | B;
|
poutEven[j + 1] = (R << 16) | (G << 8) | B;
|
||||||
|
|
||||||
|
G = *(uint16 *)pi1Odd;
|
||||||
|
pi1Odd += 2;
|
||||||
|
Y0 = ((G & 0x000000ff) - 16) * 38142;
|
||||||
|
Y1 = (((G & 0x0000ff00) >> 8) - 16) * 38142;
|
||||||
|
|
||||||
|
R = (Y0 + Cr_R) >> 15;
|
||||||
|
if (R < 0) R = 0; else if (R > 255) R = 255;
|
||||||
|
G = (Y0 + Cr_G + Cb_G) >> 15;
|
||||||
|
if (G < 0) G = 0; else if (G > 255) G = 255;
|
||||||
|
B = (Y0 + Cb_B) >> 15;
|
||||||
|
if (B < 0) B = 0; else if (B > 255) B = 255;
|
||||||
|
poutOdd[j] = (R << 16) | (G << 8) | B;
|
||||||
|
|
||||||
|
R = (Y1 + Cr_R) >> 15;
|
||||||
|
if (R < 0) R = 0; else if (R > 255) R = 255;
|
||||||
|
G = (Y1 + Cr_G + Cb_G) >> 15;
|
||||||
|
if (G < 0) G = 0; else if (G > 255) G = 255;
|
||||||
|
B = (Y1 + Cb_B) >> 15;
|
||||||
|
if (B < 0) B = 0; else if (B > 255) B = 255;
|
||||||
|
poutOdd[j + 1] = (R << 16) | (G << 8) | B;
|
||||||
}
|
}
|
||||||
|
poutEven = (uint32 *)(poutInc + (uint8 *)poutEven);
|
||||||
|
poutOdd = (uint32 *)(poutInc + (uint8 *)poutOdd);
|
||||||
|
}
|
||||||
|
if (height & 1) {
|
||||||
|
// XXX special case for last line if height not multiple of 2 goes here
|
||||||
|
memset((height - 1) * out->linesize[0] + (uint8 *)out->data[0], 0, width * 4);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user