Browse code

libswscale: Extend the unaccelerated path of the unscaled yuv2rgb special converter with support for rgb444 output format. Patch by Janusz Krzysztofik jkrzyszt chez tis icnet pl

Originally committed as revision 30841 to svn://svn.mplayerhq.hu/mplayer/trunk/libswscale

Janusz Krzysztofik authored on 2010/03/05 17:32:54
Showing 3 changed files
... ...
@@ -27,7 +27,7 @@
27 27
   {BGR,RGB}{1,4,8,15,16} support dithering
28 28
 
29 29
   unscaled special converters (YV12=I420=IYUV, Y800=Y8)
30
-  YV12 -> {BGR,RGB}{1,4,8,15,16,24,32}
30
+  YV12 -> {BGR,RGB}{1,4,8,12,15,16,24,32}
31 31
   x -> x
32 32
   YUV9 -> YV12
33 33
   YUV9/YV12 -> Y800
... ...
@@ -198,6 +198,13 @@ DECLARE_ALIGNED(8, static const uint8_t, dither_2x2_8)[2][8]={
198 198
 {  0,   4,   0,   4,   0,   4,   0,   4, },
199 199
 };
200 200
 
201
+DECLARE_ALIGNED(8, const uint8_t, dither_4x4_16)[4][8]={
202
+{  8,   4,  11,   7,   8,   4,  11,   7, },
203
+{  2,  14,   1,  13,   2,  14,   1,  13, },
204
+{ 10,   6,   9,   5,  10,   6,   9,   5, },
205
+{  0,  12,   3,  15,   0,  12,   3,  15, },
206
+};
207
+
201 208
 DECLARE_ALIGNED(8, const uint8_t, dither_8x8_32)[8][8]={
202 209
 { 17,   9,  23,  15,  16,   8,  22,  14, },
203 210
 {  5,  29,   3,  27,   4,  28,   2,  26, },
... ...
@@ -395,6 +395,7 @@ const char *sws_format_name(enum PixelFormat format);
395 395
         || (x)==PIX_FMT_RGB565LE    \
396 396
         || (x)==PIX_FMT_RGB555BE    \
397 397
         || (x)==PIX_FMT_RGB555LE    \
398
+        || (x)==PIX_FMT_RGB444      \
398 399
         || (x)==PIX_FMT_RGB8        \
399 400
         || (x)==PIX_FMT_RGB4        \
400 401
         || (x)==PIX_FMT_RGB4_BYTE   \
... ...
@@ -409,6 +410,7 @@ const char *sws_format_name(enum PixelFormat format);
409 409
         || (x)==PIX_FMT_BGR565LE    \
410 410
         || (x)==PIX_FMT_BGR555BE    \
411 411
         || (x)==PIX_FMT_BGR555LE    \
412
+        || (x)==PIX_FMT_BGR444      \
412 413
         || (x)==PIX_FMT_BGR8        \
413 414
         || (x)==PIX_FMT_BGR4        \
414 415
         || (x)==PIX_FMT_BGR4_BYTE   \
... ...
@@ -35,6 +35,7 @@
35 35
 #include "libavutil/x86_cpu.h"
36 36
 #include "libavutil/bswap.h"
37 37
 
38
+extern const uint8_t dither_4x4_16[4][8];
38 39
 extern const uint8_t dither_8x8_32[8][8];
39 40
 extern const uint8_t dither_8x8_73[8][8];
40 41
 extern const uint8_t dither_8x8_220[8][8];
... ...
@@ -352,6 +353,32 @@ CLOSEYUV2RGBFUNC(8)
352 352
 #endif
353 353
 
354 354
 // r, g, b, dst_1, dst_2
355
+YUV2RGBFUNC(yuv2rgb_c_12_ordered_dither, uint16_t, 0)
356
+    const uint8_t *d16 = dither_4x4_16[y&3];
357
+#define PUTRGB12(dst,src,i,o)                                   \
358
+    Y = src[2*i];                                               \
359
+    dst[2*i]   = r[Y+d16[0+o]] + g[Y+d16[0+o]] + b[Y+d16[0+o]]; \
360
+    Y = src[2*i+1];                                             \
361
+    dst[2*i+1] = r[Y+d16[1+o]] + g[Y+d16[1+o]] + b[Y+d16[1+o]];
362
+
363
+    LOADCHROMA(0);
364
+    PUTRGB12(dst_1,py_1,0,0);
365
+    PUTRGB12(dst_2,py_2,0,0+8);
366
+
367
+    LOADCHROMA(1);
368
+    PUTRGB12(dst_2,py_2,1,2+8);
369
+    PUTRGB12(dst_1,py_1,1,2);
370
+
371
+    LOADCHROMA(2);
372
+    PUTRGB12(dst_1,py_1,2,4);
373
+    PUTRGB12(dst_2,py_2,2,4+8);
374
+
375
+    LOADCHROMA(3);
376
+    PUTRGB12(dst_2,py_2,3,6+8);
377
+    PUTRGB12(dst_1,py_1,3,6);
378
+CLOSEYUV2RGBFUNC(8)
379
+
380
+// r, g, b, dst_1, dst_2
355 381
 YUV2RGBFUNC(yuv2rgb_c_8_ordered_dither, uint8_t, 0)
356 382
     const uint8_t *d32 = dither_8x8_32[y&7];
357 383
     const uint8_t *d64 = dither_8x8_73[y&7];
... ...
@@ -553,6 +580,8 @@ SwsFunc ff_yuv2rgb_get_func_ptr(SwsContext *c)
553 553
     case PIX_FMT_BGR565:
554 554
     case PIX_FMT_RGB555:
555 555
     case PIX_FMT_BGR555:     return yuv2rgb_c_16;
556
+    case PIX_FMT_RGB444:
557
+    case PIX_FMT_BGR444:     return yuv2rgb_c_12_ordered_dither;
556 558
     case PIX_FMT_RGB8:
557 559
     case PIX_FMT_BGR8:       return yuv2rgb_c_8_ordered_dither;
558 560
     case PIX_FMT_RGB4:
... ...
@@ -601,6 +630,7 @@ av_cold int ff_yuv2rgb_c_init_tables(SwsContext *c, const int inv_table[4], int
601 601
                         || c->dstFormat==PIX_FMT_RGB565LE
602 602
                         || c->dstFormat==PIX_FMT_RGB555BE
603 603
                         || c->dstFormat==PIX_FMT_RGB555LE
604
+                        || c->dstFormat==PIX_FMT_RGB444
604 605
                         || c->dstFormat==PIX_FMT_RGB8
605 606
                         || c->dstFormat==PIX_FMT_RGB4
606 607
                         || c->dstFormat==PIX_FMT_RGB4_BYTE
... ...
@@ -701,6 +731,25 @@ av_cold int ff_yuv2rgb_c_init_tables(SwsContext *c, const int inv_table[4], int
701 701
         fill_table(c->table_bU, 1, cbu, y_table + yoffs + 2048);
702 702
         fill_gv_table(c->table_gV, 1, cgv);
703 703
         break;
704
+    case 12:
705
+        rbase = isRgb ? 8 : 0;
706
+        gbase = 4;
707
+        bbase = isRgb ? 0 : 8;
708
+        c->yuvTable = av_malloc(1024*3*2);
709
+        y_table16 = c->yuvTable;
710
+        yb = -(384<<16) - oy;
711
+        for (i = 0; i < 1024; i++) {
712
+            uint8_t yval = av_clip_uint8((yb + 0x8000) >> 16);
713
+            y_table16[i     ] = (yval >> 4)          << rbase;
714
+            y_table16[i+1024] = (yval >> 4) << gbase;
715
+            y_table16[i+2048] = (yval >> 4)          << bbase;
716
+            yb += cy;
717
+        }
718
+        fill_table(c->table_rV, 2, crv, y_table16 + yoffs);
719
+        fill_table(c->table_gU, 2, cgu, y_table16 + yoffs + 1024);
720
+        fill_table(c->table_bU, 2, cbu, y_table16 + yoffs + 2048);
721
+        fill_gv_table(c->table_gV, 2, cgv);
722
+        break;
704 723
     case 15:
705 724
     case 16:
706 725
         rbase = isRgb ? bpp - 5 : 0;