From 662664551c808be3bb1f78183e909dd8c6319eaa Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Sun, 14 Apr 2013 13:17:04 +0200 Subject: [PATCH] sws/output: factor yuv2rgb_write_full() out Signed-off-by: Michael Niedermayer --- libswscale/output.c | 184 +++++++++++++++++++++++--------------------- 1 file changed, 98 insertions(+), 86 deletions(-) diff --git a/libswscale/output.c b/libswscale/output.c index d9745fbab8..aa455b1c33 100644 --- a/libswscale/output.c +++ b/libswscale/output.c @@ -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];