X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=libswscale%2Fyuv2rgb.c;h=77d3d399daaffef00418e654b0b31f659d96803e;hb=c24b404ba6a115259c75ec9896528e415155abd1;hp=3c7bb3fd9f02583cde359e22450298fe3fa9a377;hpb=30b6147521a3b2a9df4a4094ccee65a5fd8bc18f;p=ffmpeg diff --git a/libswscale/yuv2rgb.c b/libswscale/yuv2rgb.c index 3c7bb3fd9f0..77d3d399daa 100644 --- a/libswscale/yuv2rgb.c +++ b/libswscale/yuv2rgb.c @@ -33,7 +33,9 @@ #include "swscale.h" #include "swscale_internal.h" #include "libavutil/x86_cpu.h" +#include "libavutil/bswap.h" +extern const uint8_t dither_4x4_16[4][8]; extern const uint8_t dither_8x8_32[8][8]; extern const uint8_t dither_8x8_73[8][8]; extern const uint8_t dither_8x8_220[8][8]; @@ -49,6 +51,13 @@ const int32_t ff_yuv2rgb_coeffs[8][4] = { {117579, 136230, 16907, 35559} /* SMPTE 240M (1987) */ }; +const int *sws_getCoefficients(int colorspace) +{ + if (colorspace > 7 || colorspace < 0) + colorspace = SWS_CS_DEFAULT; + return ff_yuv2rgb_coeffs[colorspace]; +} + #define LOADCHROMA(i) \ U = pu[i]; \ V = pv[i]; \ @@ -343,6 +352,32 @@ YUV2RGBFUNC(yuv2rgb_c_8, uint8_t, 0) CLOSEYUV2RGBFUNC(8) #endif +// r, g, b, dst_1, dst_2 +YUV2RGBFUNC(yuv2rgb_c_12_ordered_dither, uint16_t, 0) + const uint8_t *d16 = dither_4x4_16[y&3]; +#define PUTRGB12(dst,src,i,o) \ + Y = src[2*i]; \ + dst[2*i] = r[Y+d16[0+o]] + g[Y+d16[0+o]] + b[Y+d16[0+o]]; \ + Y = src[2*i+1]; \ + dst[2*i+1] = r[Y+d16[1+o]] + g[Y+d16[1+o]] + b[Y+d16[1+o]]; + + LOADCHROMA(0); + PUTRGB12(dst_1,py_1,0,0); + PUTRGB12(dst_2,py_2,0,0+8); + + LOADCHROMA(1); + PUTRGB12(dst_2,py_2,1,2+8); + PUTRGB12(dst_1,py_1,1,2); + + LOADCHROMA(2); + PUTRGB12(dst_1,py_1,2,4); + PUTRGB12(dst_2,py_2,2,4+8); + + LOADCHROMA(3); + PUTRGB12(dst_2,py_2,3,6+8); + PUTRGB12(dst_1,py_1,3,6); +CLOSEYUV2RGBFUNC(8) + // r, g, b, dst_1, dst_2 YUV2RGBFUNC(yuv2rgb_c_8_ordered_dither, uint8_t, 0) const uint8_t *d32 = dither_8x8_32[y&7]; @@ -508,7 +543,7 @@ CLOSEYUV2RGBFUNC(1) SwsFunc ff_yuv2rgb_get_func_ptr(SwsContext *c) { SwsFunc t = NULL; -#if (HAVE_MMX2 || HAVE_MMX) && CONFIG_GPL +#if HAVE_MMX t = ff_yuv2rgb_init_mmx(c); #endif #if HAVE_VIS @@ -545,6 +580,8 @@ SwsFunc ff_yuv2rgb_get_func_ptr(SwsContext *c) case PIX_FMT_BGR565: case PIX_FMT_RGB555: case PIX_FMT_BGR555: return yuv2rgb_c_16; + case PIX_FMT_RGB444: + case PIX_FMT_BGR444: return yuv2rgb_c_12_ordered_dither; case PIX_FMT_RGB8: case PIX_FMT_BGR8: return yuv2rgb_c_8_ordered_dither; case PIX_FMT_RGB4: @@ -558,10 +595,11 @@ SwsFunc ff_yuv2rgb_get_func_ptr(SwsContext *c) return NULL; } -static void fill_table(uint8_t* table[256], const int elemsize, const int inc, uint8_t *y_table) +static void fill_table(uint8_t* table[256], const int elemsize, const int inc, void *y_tab) { int i; int64_t cb = 0; + uint8_t *y_table = y_tab; y_table -= elemsize * (inc >> 9); @@ -583,18 +621,36 @@ static void fill_gv_table(int table[256], const int elemsize, const int inc) } } +static uint16_t roundToInt16(int64_t f) +{ + int r= (f + (1<<15))>>16; + if (r<-0x7FFF) return 0x8000; + else if (r> 0x7FFF) return 0x7FFF; + else return r; +} + av_cold int ff_yuv2rgb_c_init_tables(SwsContext *c, const int inv_table[4], int fullRange, int brightness, int contrast, int saturation) { const int isRgb = c->dstFormat==PIX_FMT_RGB32 || c->dstFormat==PIX_FMT_RGB32_1 || c->dstFormat==PIX_FMT_BGR24 - || c->dstFormat==PIX_FMT_RGB565 - || c->dstFormat==PIX_FMT_RGB555 + || c->dstFormat==PIX_FMT_RGB565BE + || c->dstFormat==PIX_FMT_RGB565LE + || c->dstFormat==PIX_FMT_RGB555BE + || c->dstFormat==PIX_FMT_RGB555LE + || c->dstFormat==PIX_FMT_RGB444BE + || c->dstFormat==PIX_FMT_RGB444LE || c->dstFormat==PIX_FMT_RGB8 || c->dstFormat==PIX_FMT_RGB4 || c->dstFormat==PIX_FMT_RGB4_BYTE || c->dstFormat==PIX_FMT_MONOBLACK; + const int isNotNe = c->dstFormat==PIX_FMT_NE(RGB565LE,RGB565BE) + || c->dstFormat==PIX_FMT_NE(RGB555LE,RGB555BE) + || c->dstFormat==PIX_FMT_NE(RGB444LE,RGB444BE) + || c->dstFormat==PIX_FMT_NE(BGR565LE,BGR565BE) + || c->dstFormat==PIX_FMT_NE(BGR555LE,BGR555BE) + || c->dstFormat==PIX_FMT_NE(BGR444LE,BGR444BE); const int bpp = c->dstFormatBpp; uint8_t *y_table; uint16_t *y_table16; @@ -628,6 +684,22 @@ av_cold int ff_yuv2rgb_c_init_tables(SwsContext *c, const int inv_table[4], int cgv = (cgv*contrast * saturation) >> 32; oy -= 256*brightness; + c->uOffset= 0x0400040004000400LL; + c->vOffset= 0x0400040004000400LL; + c->yCoeff= roundToInt16(cy *8192) * 0x0001000100010001ULL; + c->vrCoeff= roundToInt16(crv*8192) * 0x0001000100010001ULL; + c->ubCoeff= roundToInt16(cbu*8192) * 0x0001000100010001ULL; + c->vgCoeff= roundToInt16(cgv*8192) * 0x0001000100010001ULL; + c->ugCoeff= roundToInt16(cgu*8192) * 0x0001000100010001ULL; + c->yOffset= roundToInt16(oy * 8) * 0x0001000100010001ULL; + + c->yuv2rgb_y_coeff = (int16_t)roundToInt16(cy <<13); + c->yuv2rgb_y_offset = (int16_t)roundToInt16(oy << 9); + c->yuv2rgb_v2r_coeff= (int16_t)roundToInt16(crv<<13); + c->yuv2rgb_v2g_coeff= (int16_t)roundToInt16(cgv<<13); + c->yuv2rgb_u2g_coeff= (int16_t)roundToInt16(cgu<<13); + c->yuv2rgb_u2b_coeff= (int16_t)roundToInt16(cbu<<13); + //scale coefficients by cy crv = ((crv << 16) + 0x8000) / cy; cbu = ((cbu << 16) + 0x8000) / cy; @@ -687,6 +759,28 @@ av_cold int ff_yuv2rgb_c_init_tables(SwsContext *c, const int inv_table[4], int fill_table(c->table_bU, 1, cbu, y_table + yoffs + 2048); fill_gv_table(c->table_gV, 1, cgv); break; + case 12: + rbase = isRgb ? 8 : 0; + gbase = 4; + bbase = isRgb ? 0 : 8; + c->yuvTable = av_malloc(1024*3*2); + y_table16 = c->yuvTable; + yb = -(384<<16) - oy; + for (i = 0; i < 1024; i++) { + uint8_t yval = av_clip_uint8((yb + 0x8000) >> 16); + y_table16[i ] = (yval >> 4) << rbase; + y_table16[i+1024] = (yval >> 4) << gbase; + y_table16[i+2048] = (yval >> 4) << bbase; + yb += cy; + } + if (isNotNe) + for (i = 0; i < 1024*3; i++) + y_table16[i] = av_bswap16(y_table16[i]); + fill_table(c->table_rV, 2, crv, y_table16 + yoffs); + fill_table(c->table_gU, 2, cgu, y_table16 + yoffs + 1024); + fill_table(c->table_bU, 2, cbu, y_table16 + yoffs + 2048); + fill_gv_table(c->table_gV, 2, cgv); + break; case 15: case 16: rbase = isRgb ? bpp - 5 : 0; @@ -702,6 +796,9 @@ av_cold int ff_yuv2rgb_c_init_tables(SwsContext *c, const int inv_table[4], int y_table16[i+2048] = (yval >> 3) << bbase; yb += cy; } + if(isNotNe) + for (i = 0; i < 1024*3; i++) + y_table16[i] = av_bswap16(y_table16[i]); fill_table(c->table_rV, 2, crv, y_table16 + yoffs); fill_table(c->table_gU, 2, cgu, y_table16 + yoffs + 1024); fill_table(c->table_bU, 2, cbu, y_table16 + yoffs + 2048);