[FFmpeg-devel] [PATCH v3] libswscale: Extend the unaccelerated path of the unscaled yuv2rgb special converter with support for rgb444 output format
Janusz Krzysztofik
jkrzyszt
Thu Mar 4 12:46:03 CET 2010
In order to play video on a 12-bit display, like OMAP1 frambuffer with 12-bit
LCD controller that my Amstrad Delta videophone is equipped with, one or more
libswscale converters with rgb444 output pixel format support are required.
This patch adds such support to the unaccelerated path of the unscaled yuv2rgb
special converter.
Created and tested against ffmpeg svn revision 22185, on top of
[PATCH v2] Add initial support for 12-bit color mode.
Tested on Amstrad Delta with 24bpp IJPG and MP43 sourcers using patched
mplayer video output drivers.
Signed-off-by: Janusz Krzysztofik <jkrzyszt at tis.icnet.pl>
---
Changes since v2:
- drop redundant lines from dither table, rename it.
Changes since v1:
- do not add info on global rgb12 output format support yet,
- add support for dithering.
Michael,
Thanks again for your support.
Thanks,
Janusz
diff -upr trunk/doc/swscale.txt trunk.rgb12/doc/swscale.txt
--- trunk/doc/swscale.txt 2010-02-24 15:55:28.000000000 +0100
+++ trunk.rgb12/doc/swscale.txt 2010-02-25 04:31:55.000000000 +0100
@@ -30,7 +30,7 @@ slices, that is, consecutive non-overlap
special converter
These generally are unscaled converters of common
- formats, like YUV 4:2:0/4:2:2 -> RGB15/16/24/32. Though it could also
+ formats, like YUV 4:2:0/4:2:2 -> RGB12/15/16/24/32. Though it could also
in principle contain scalers optimized for specific common cases.
Main path
diff -upr trunk.orig/libswscale/swscale.c trunk/libswscale/swscale.c
--- trunk.orig/libswscale/swscale.c 2010-02-26 02:40:46.000000000 +0100
+++ trunk/libswscale/swscale.c 2010-03-03 01:45:00.000000000 +0100
@@ -27,7 +27,7 @@
{BGR,RGB}{1,4,8,15,16} support dithering
unscaled special converters (YV12=I420=IYUV, Y800=Y8)
- YV12 -> {BGR,RGB}{1,4,8,15,16,24,32}
+ YV12 -> {BGR,RGB}{1,4,8,12,15,16,24,32}
x -> x
YUV9 -> YV12
YUV9/YV12 -> Y800
@@ -198,6 +198,13 @@ DECLARE_ALIGNED(8, static const uint8_t,
{ 0, 4, 0, 4, 0, 4, 0, 4, },
};
+DECLARE_ALIGNED(8, const uint8_t, dither_4x4_16)[4][8]={
+{ 8, 4, 11, 7, 8, 4, 11, 7, },
+{ 2, 14, 1, 13, 2, 14, 1, 13, },
+{ 10, 6, 9, 5, 10, 6, 9, 5, },
+{ 0, 12, 3, 15, 0, 12, 3, 15, },
+};
+
DECLARE_ALIGNED(8, const uint8_t, dither_8x8_32)[8][8]={
{ 17, 9, 23, 15, 16, 8, 22, 14, },
{ 5, 29, 3, 27, 4, 28, 2, 26, },
diff -upr trunk.orig/libswscale/swscale_internal.h trunk/libswscale/swscale_internal.h
--- trunk.orig/libswscale/swscale_internal.h 2010-02-26 02:40:46.000000000 +0100
+++ trunk/libswscale/swscale_internal.h 2010-03-03 01:45:54.000000000 +0100
@@ -393,6 +393,7 @@ const char *sws_format_name(enum PixelFo
|| (x)==PIX_FMT_RGB24 \
|| (x)==PIX_FMT_RGB565 \
|| (x)==PIX_FMT_RGB555 \
+ || (x)==PIX_FMT_RGB444 \
|| (x)==PIX_FMT_RGB8 \
|| (x)==PIX_FMT_RGB4 \
|| (x)==PIX_FMT_RGB4_BYTE \
@@ -405,6 +406,7 @@ const char *sws_format_name(enum PixelFo
|| (x)==PIX_FMT_BGR24 \
|| (x)==PIX_FMT_BGR565 \
|| (x)==PIX_FMT_BGR555 \
+ || (x)==PIX_FMT_BGR444 \
|| (x)==PIX_FMT_BGR8 \
|| (x)==PIX_FMT_BGR4 \
|| (x)==PIX_FMT_BGR4_BYTE \
diff -upr trunk.orig/libswscale/yuv2rgb.c trunk/libswscale/yuv2rgb.c
--- trunk.orig/libswscale/yuv2rgb.c 2010-02-26 02:40:46.000000000 +0100
+++ trunk/libswscale/yuv2rgb.c 2010-03-03 02:29:10.000000000 +0100
@@ -34,6 +34,7 @@
#include "swscale_internal.h"
#include "libavutil/x86_cpu.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];
@@ -351,6 +352,32 @@ 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];
const uint8_t *d64 = dither_8x8_73[y&7];
@@ -552,6 +579,8 @@ SwsFunc ff_yuv2rgb_get_func_ptr(SwsConte
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:
@@ -598,6 +627,7 @@ av_cold int ff_yuv2rgb_c_init_tables(Sws
|| c->dstFormat==PIX_FMT_BGR24
|| c->dstFormat==PIX_FMT_RGB565
|| c->dstFormat==PIX_FMT_RGB555
+ || c->dstFormat==PIX_FMT_RGB444
|| c->dstFormat==PIX_FMT_RGB8
|| c->dstFormat==PIX_FMT_RGB4
|| c->dstFormat==PIX_FMT_RGB4_BYTE
@@ -694,6 +724,25 @@ av_cold int ff_yuv2rgb_c_init_tables(Sws
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;
+ }
+ 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;
More information about the ffmpeg-devel
mailing list