mirror of
https://git.ffmpeg.org/ffmpeg.git
synced 2024-12-27 09:52:17 +00:00
sws/output: factor yuv2rgb_write_full() out
Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
This commit is contained in:
parent
f359be96ca
commit
662664551c
@ -1217,6 +1217,98 @@ YUV2RGBWRAPPER(yuv2rgb,, 8, AV_PIX_FMT_RGB8, 0)
|
||||
YUV2RGBWRAPPER(yuv2rgb,, 4, AV_PIX_FMT_RGB4, 0)
|
||||
YUV2RGBWRAPPER(yuv2rgb,, 4b, AV_PIX_FMT_RGB4_BYTE, 0)
|
||||
|
||||
static av_always_inline void yuv2rgb_write_full(SwsContext *c,
|
||||
uint8_t *dest, int i, int Y, int A, int U, int V,
|
||||
int y, enum AVPixelFormat target, int hasAlpha, int err[4])
|
||||
{
|
||||
int R, G, B;
|
||||
int isrgb8 = target == AV_PIX_FMT_BGR8 || target == AV_PIX_FMT_RGB8;
|
||||
|
||||
Y -= c->yuv2rgb_y_offset;
|
||||
Y *= c->yuv2rgb_y_coeff;
|
||||
Y += 1 << 21;
|
||||
R = Y + V*c->yuv2rgb_v2r_coeff;
|
||||
G = Y + V*c->yuv2rgb_v2g_coeff + U*c->yuv2rgb_u2g_coeff;
|
||||
B = Y + U*c->yuv2rgb_u2b_coeff;
|
||||
if ((R | G | B) & 0xC0000000) {
|
||||
R = av_clip_uintp2(R, 30);
|
||||
G = av_clip_uintp2(G, 30);
|
||||
B = av_clip_uintp2(B, 30);
|
||||
}
|
||||
|
||||
switch(target) {
|
||||
case AV_PIX_FMT_ARGB:
|
||||
dest[0] = hasAlpha ? A : 255;
|
||||
dest[1] = R >> 22;
|
||||
dest[2] = G >> 22;
|
||||
dest[3] = B >> 22;
|
||||
break;
|
||||
case AV_PIX_FMT_RGB24:
|
||||
dest[0] = R >> 22;
|
||||
dest[1] = G >> 22;
|
||||
dest[2] = B >> 22;
|
||||
break;
|
||||
case AV_PIX_FMT_RGBA:
|
||||
dest[0] = R >> 22;
|
||||
dest[1] = G >> 22;
|
||||
dest[2] = B >> 22;
|
||||
dest[3] = hasAlpha ? A : 255;
|
||||
break;
|
||||
case AV_PIX_FMT_ABGR:
|
||||
dest[0] = hasAlpha ? A : 255;
|
||||
dest[1] = B >> 22;
|
||||
dest[2] = G >> 22;
|
||||
dest[3] = R >> 22;
|
||||
break;
|
||||
case AV_PIX_FMT_BGR24:
|
||||
dest[0] = B >> 22;
|
||||
dest[1] = G >> 22;
|
||||
dest[2] = R >> 22;
|
||||
break;
|
||||
case AV_PIX_FMT_BGRA:
|
||||
dest[0] = B >> 22;
|
||||
dest[1] = G >> 22;
|
||||
dest[2] = R >> 22;
|
||||
dest[3] = hasAlpha ? A : 255;
|
||||
break;
|
||||
case AV_PIX_FMT_BGR4_BYTE:
|
||||
case AV_PIX_FMT_RGB4_BYTE:
|
||||
case AV_PIX_FMT_BGR8:
|
||||
case AV_PIX_FMT_RGB8:
|
||||
{
|
||||
int r,g,b;
|
||||
R >>= 22;
|
||||
G >>= 22;
|
||||
B >>= 22;
|
||||
R += (7*err[0] + 1*c->dither_error[0][i] + 5*c->dither_error[0][i+1] + 3*c->dither_error[0][i+2])>>4;
|
||||
G += (7*err[1] + 1*c->dither_error[1][i] + 5*c->dither_error[1][i+1] + 3*c->dither_error[1][i+2])>>4;
|
||||
B += (7*err[2] + 1*c->dither_error[2][i] + 5*c->dither_error[2][i+1] + 3*c->dither_error[2][i+2])>>4;
|
||||
c->dither_error[0][i] = err[0];
|
||||
c->dither_error[1][i] = err[1];
|
||||
c->dither_error[2][i] = err[2];
|
||||
r = R >> (isrgb8 ? 5 : 7);
|
||||
g = G >> (isrgb8 ? 5 : 6);
|
||||
b = B >> (isrgb8 ? 6 : 7);
|
||||
r = av_clip(r, 0, isrgb8 ? 7 : 1);
|
||||
g = av_clip(g, 0, isrgb8 ? 7 : 3);
|
||||
b = av_clip(b, 0, isrgb8 ? 3 : 1);
|
||||
err[0] = R - r*(isrgb8 ? 36 : 255);
|
||||
err[1] = G - g*(isrgb8 ? 36 : 85);
|
||||
err[2] = B - b*(isrgb8 ? 85 : 255);
|
||||
if(target == AV_PIX_FMT_BGR4_BYTE) {
|
||||
dest[0] = r + 2*g + 8*b;
|
||||
} else if(target == AV_PIX_FMT_RGB4_BYTE) {
|
||||
dest[0] = b + 2*g + 8*r;
|
||||
} else if(target == AV_PIX_FMT_BGR8) {
|
||||
dest[0] = r + 8*g + 64*b;
|
||||
} else if(target == AV_PIX_FMT_RGB8) {
|
||||
dest[0] = b + 4*g + 32*r;
|
||||
} else
|
||||
av_assert2(0);
|
||||
break;}
|
||||
}
|
||||
}
|
||||
|
||||
static av_always_inline void
|
||||
yuv2rgb_full_X_c_template(SwsContext *c, const int16_t *lumFilter,
|
||||
const int16_t **lumSrc, int lumFilterSize,
|
||||
@ -1228,14 +1320,17 @@ yuv2rgb_full_X_c_template(SwsContext *c, const int16_t *lumFilter,
|
||||
int i;
|
||||
int step = (target == AV_PIX_FMT_RGB24 || target == AV_PIX_FMT_BGR24) ? 3 : 4;
|
||||
int err[4] = {0};
|
||||
int isrgb8 = target == AV_PIX_FMT_BGR8 || target == AV_PIX_FMT_RGB8;
|
||||
|
||||
if( target == AV_PIX_FMT_BGR4_BYTE || target == AV_PIX_FMT_RGB4_BYTE
|
||||
|| target == AV_PIX_FMT_BGR8 || target == AV_PIX_FMT_RGB8)
|
||||
step = 1;
|
||||
|
||||
for (i = 0; i < dstW; i++) {
|
||||
int j;
|
||||
int Y = 1<<9;
|
||||
int U = (1<<9)-(128 << 19);
|
||||
int V = (1<<9)-(128 << 19);
|
||||
int R, G, B, A;
|
||||
int A;
|
||||
|
||||
for (j = 0; j < lumFilterSize; j++) {
|
||||
Y += lumSrc[j][i] * lumFilter[j];
|
||||
@ -1256,90 +1351,7 @@ yuv2rgb_full_X_c_template(SwsContext *c, const int16_t *lumFilter,
|
||||
if (A & 0x100)
|
||||
A = av_clip_uint8(A);
|
||||
}
|
||||
Y -= c->yuv2rgb_y_offset;
|
||||
Y *= c->yuv2rgb_y_coeff;
|
||||
Y += 1 << 21;
|
||||
R = Y + V*c->yuv2rgb_v2r_coeff;
|
||||
G = Y + V*c->yuv2rgb_v2g_coeff + U*c->yuv2rgb_u2g_coeff;
|
||||
B = Y + U*c->yuv2rgb_u2b_coeff;
|
||||
if ((R | G | B) & 0xC0000000) {
|
||||
R = av_clip_uintp2(R, 30);
|
||||
G = av_clip_uintp2(G, 30);
|
||||
B = av_clip_uintp2(B, 30);
|
||||
}
|
||||
|
||||
switch(target) {
|
||||
case AV_PIX_FMT_ARGB:
|
||||
dest[0] = hasAlpha ? A : 255;
|
||||
dest[1] = R >> 22;
|
||||
dest[2] = G >> 22;
|
||||
dest[3] = B >> 22;
|
||||
break;
|
||||
case AV_PIX_FMT_RGB24:
|
||||
dest[0] = R >> 22;
|
||||
dest[1] = G >> 22;
|
||||
dest[2] = B >> 22;
|
||||
break;
|
||||
case AV_PIX_FMT_RGBA:
|
||||
dest[0] = R >> 22;
|
||||
dest[1] = G >> 22;
|
||||
dest[2] = B >> 22;
|
||||
dest[3] = hasAlpha ? A : 255;
|
||||
break;
|
||||
case AV_PIX_FMT_ABGR:
|
||||
dest[0] = hasAlpha ? A : 255;
|
||||
dest[1] = B >> 22;
|
||||
dest[2] = G >> 22;
|
||||
dest[3] = R >> 22;
|
||||
break;
|
||||
case AV_PIX_FMT_BGR24:
|
||||
dest[0] = B >> 22;
|
||||
dest[1] = G >> 22;
|
||||
dest[2] = R >> 22;
|
||||
break;
|
||||
case AV_PIX_FMT_BGRA:
|
||||
dest[0] = B >> 22;
|
||||
dest[1] = G >> 22;
|
||||
dest[2] = R >> 22;
|
||||
dest[3] = hasAlpha ? A : 255;
|
||||
break;
|
||||
case AV_PIX_FMT_BGR4_BYTE:
|
||||
case AV_PIX_FMT_RGB4_BYTE:
|
||||
case AV_PIX_FMT_BGR8:
|
||||
case AV_PIX_FMT_RGB8:
|
||||
{
|
||||
int r,g,b;
|
||||
R >>= 22;
|
||||
G >>= 22;
|
||||
B >>= 22;
|
||||
R += (7*err[0] + 1*c->dither_error[0][i] + 5*c->dither_error[0][i+1] + 3*c->dither_error[0][i+2])>>4;
|
||||
G += (7*err[1] + 1*c->dither_error[1][i] + 5*c->dither_error[1][i+1] + 3*c->dither_error[1][i+2])>>4;
|
||||
B += (7*err[2] + 1*c->dither_error[2][i] + 5*c->dither_error[2][i+1] + 3*c->dither_error[2][i+2])>>4;
|
||||
c->dither_error[0][i] = err[0];
|
||||
c->dither_error[1][i] = err[1];
|
||||
c->dither_error[2][i] = err[2];
|
||||
r = R >> (isrgb8 ? 5 : 7);
|
||||
g = G >> (isrgb8 ? 5 : 6);
|
||||
b = B >> (isrgb8 ? 6 : 7);
|
||||
r = av_clip(r, 0, isrgb8 ? 7 : 1);
|
||||
g = av_clip(g, 0, isrgb8 ? 7 : 3);
|
||||
b = av_clip(b, 0, isrgb8 ? 3 : 1);
|
||||
err[0] = R - r*(isrgb8 ? 36 : 255);
|
||||
err[1] = G - g*(isrgb8 ? 36 : 85);
|
||||
err[2] = B - b*(isrgb8 ? 85 : 255);
|
||||
if(target == AV_PIX_FMT_BGR4_BYTE) {
|
||||
dest[0] = r + 2*g + 8*b;
|
||||
} else if(target == AV_PIX_FMT_RGB4_BYTE) {
|
||||
dest[0] = b + 2*g + 8*r;
|
||||
} else if(target == AV_PIX_FMT_BGR8) {
|
||||
dest[0] = r + 8*g + 64*b;
|
||||
} else if(target == AV_PIX_FMT_RGB8) {
|
||||
dest[0] = b + 4*g + 32*r;
|
||||
} else
|
||||
av_assert2(0);
|
||||
step = 1;
|
||||
break;}
|
||||
}
|
||||
yuv2rgb_write_full(c, dest, i, Y, A, U, V, y, target, hasAlpha, err);
|
||||
dest += step;
|
||||
}
|
||||
c->dither_error[0][i] = err[0];
|
||||
|
Loading…
Reference in New Issue
Block a user