[MPlayer-dev-eng] [RFC][PATCH] Add support for 12-bit color mode.

Janusz Krzysztofik jkrzyszt at tis.icnet.pl
Mon Jan 18 17:09:34 CET 2010


Hi,

While trying to use mplayer on my ARM OMAP based Amstrad Delta (E3) 
videophone, I found this software not compatible with the 12-bit LCD display 
my device is equipped with. Fbdev and fbdev2 video output drivers did not work 
at all, while others like directfb, for example, gave incorrect colors.

The patch tries to extend mplayer with RGB12 aka RGB444 pixel format handling. 
It works for me with fbdev and fbdev2, selecting required color conversion 
filters automatically. It also works with directfb when provided with "-vf 
format=bgr12" option. I was not able to get correct results using sdl, 
neither with qtopia (wrong collors) nor fbcon (not working at all) drivers.

All new color conversion functions are supposed to work correctly except for 
dithering that I was not able to develop correct table values for by myself.
 
Some changes to video output drivers and other modules that I was not able to 
test are probably wrong or even not applicable.

Created against mplayer-1.0rc2.
Tested on omapfb framebuffer device with Amstrad Delta 12-bit LCD display.

Signed-off-by: Janusz Krzysztofik <jkrzyszt at tis.icnet.pl>

---

diff -uprd MPlayer-1.0rc2/codec-cfg.c.orig MPlayer-1.0rc2/codec-cfg.c
--- MPlayer-1.0rc2/codec-cfg.c.orig	2007-10-07 21:49:33.000000000 +0200
+++ MPlayer-1.0rc2/codec-cfg.c	2010-01-09 16:54:23.000000000 +0100
@@ -161,12 +161,14 @@ static int add_to_format(char *s, char *
 
 	        {"RGB4",  IMGFMT_RGB|4},
 	        {"RGB8",  IMGFMT_RGB|8},
+		{"RGB12", IMGFMT_RGB|12}, 
 		{"RGB15", IMGFMT_RGB|15}, 
 		{"RGB16", IMGFMT_RGB|16},
 		{"RGB24", IMGFMT_RGB|24},
 		{"RGB32", IMGFMT_RGB|32},
 		{"BGR4",  IMGFMT_BGR|4},
 		{"BGR8",  IMGFMT_BGR|8},
+		{"BGR12", IMGFMT_BGR|12},
 		{"BGR15", IMGFMT_BGR|15},
 		{"BGR16", IMGFMT_BGR|16},
 		{"BGR24", IMGFMT_BGR|24},
diff -uprd MPlayer-1.0rc2/etc/codecs.conf.orig MPlayer-1.0rc2/etc/codecs.conf
--- MPlayer-1.0rc2/etc/codecs.conf.orig	2007-10-07 21:49:33.000000000 +0200
+++ MPlayer-1.0rc2/etc/codecs.conf	2010-01-09 17:18:07.000000000 +0100
@@ -668,7 +668,7 @@ videocodec xvid
   out YUY2
   out UYVY
   out YVYU
-  out BGR32,BGR24,BGR16,BGR15
+  out BGR32,BGR24,BGR16,BGR15,BGR12
   dll "libxvidcore.a"
 
 ; is divx4vfw stable enough, working everywhere and faster than divxds?
@@ -2178,6 +2178,22 @@ videocodec rawbgr15
   format 0x4247520F
   out BGR15
 
+videocodec rawbgr12flip
+  info "RAW BGR12"
+  status working
+  driver raw
+  format 0x0
+  out BGR12 flip
+
+videocodec rawbgr12
+  info "RAW BGR12"
+  status working
+  driver raw
+  format 0x0
+  format 0x20776172
+  format 0x4247520C
+  out BGR12
+
 videocodec rawbgr8flip
   info "RAW BGR8"
   status working
@@ -2316,7 +2332,7 @@ videocodec null
   out YUY2
   out UYVY
   out YVU9
-  out BGR32,BGR24,BGR16,BGR15
+  out BGR32,BGR24,BGR16,BGR15,BGR12
 
 ;=============================================================================
 ;                   AUDIO CODECS
diff -uprd MPlayer-1.0rc2/fmt-conversion.h.orig MPlayer-1.0rc2/fmt-conversion.h
--- MPlayer-1.0rc2/fmt-conversion.h.orig	2007-10-07 21:49:33.000000000 +0200
+++ MPlayer-1.0rc2/fmt-conversion.h	2010-01-09 17:03:43.000000000 +0100
@@ -19,6 +19,8 @@ enum PixelFormat imgfmt2pixfmt(int fmt)
             return PIX_FMT_BGR565;
         case IMGFMT_BGR15:
             return PIX_FMT_BGR555;
+        case IMGFMT_BGR12:
+            return PIX_FMT_BGR444;
         case IMGFMT_BGR8:
             return PIX_FMT_BGR8;
         case IMGFMT_BGR4:
@@ -38,6 +40,8 @@ enum PixelFormat imgfmt2pixfmt(int fmt)
             return PIX_FMT_RGB565;
         case IMGFMT_RGB15:
             return PIX_FMT_RGB555;
+        case IMGFMT_RGB12:
+            return PIX_FMT_RGB444;
         case IMGFMT_RGB8:
             return PIX_FMT_RGB8;
         case IMGFMT_RGB4:
diff -uprd MPlayer-1.0rc2/gui/wm/ws.c.orig MPlayer-1.0rc2/gui/wm/ws.c
--- MPlayer-1.0rc2/gui/wm/ws.c.orig	2007-10-07 21:49:27.000000000 +0200
+++ MPlayer-1.0rc2/gui/wm/ws.c	2010-01-14 23:00:54.000000000 +0100
@@ -109,6 +109,12 @@ inline int wsSearch( Window win );
                                 pixel<<=5;\
 	                        pixel|=(r>>3)
 
+#define PACK_RGB12(r,g,b,pixel) pixel=(b>>4);\
+                                pixel<<=4;\
+                                pixel|=(g>>4);\
+                                pixel<<=4;\
+	                        pixel|=(r>>4)
+
 typedef void(*wsTConvFunc)( const unsigned char * in_pixels, unsigned char * out_pixels, unsigned num_pixels );
 wsTConvFunc wsConvFunc = NULL;
 										
@@ -320,6 +326,14 @@ wsXDNDInitialize();
      mp_dbg( MSGT_GPLAYER,MSGL_DBG2,"rgb32 to bgr15\n" );
      wsConvFunc=rgb32tobgr15;
      break;
+   case wsRGB12:
+     mp_dbg( MSGT_GPLAYER,MSGL_DBG2,"rgb32 to rgb12\n" );
+     wsConvFunc=rgb32to12;
+     break;
+   case wsBGR12:
+     mp_dbg( MSGT_GPLAYER,MSGL_DBG2,"rgb32 to bgr12\n" );
+     wsConvFunc=rgb32tobgr12;
+     break;
   }
  XSetErrorHandler( wsErrorHandler );
 }
@@ -990,6 +1004,8 @@ void wsSetBackgroundRGB( wsTWindow * win
    case wsBGR16: PACK_RGB16( r,g,b,color ); break;
    case wsRGB15: PACK_RGB15( b,g,r,color ); break;
    case wsBGR15: PACK_RGB15( r,g,b,color ); break;
+   case wsRGB12: PACK_RGB12( b,g,r,color ); break;
+   case wsBGR12: PACK_RGB12( r,g,b,color ); break;
   }
  XSetWindowBackground( wsDisplay,win->WindowID,color );
 }
@@ -1007,6 +1023,8 @@ void wsSetForegroundRGB( wsTWindow * win
    case wsBGR16: PACK_RGB16( r,g,b,color ); break;
    case wsRGB15: PACK_RGB15( b,g,r,color ); break;
    case wsBGR15: PACK_RGB15( r,g,b,color ); break;
+   case wsRGB12: PACK_RGB12( b,g,r,color ); break;
+   case wsBGR12: PACK_RGB12( r,g,b,color ); break;
   }
  XSetForeground( wsDisplay,win->wGC,color );
 }
@@ -1189,6 +1207,8 @@ int wsGetOutMask( void )
  if ( ( wsDepthOnScreen == 16 )&&( wsRedMask ==   0x1f )&&( wsGreenMask == 0x7e0 )&&( wsBlueMask == 0xf800 ) ) return wsBGR16;
  if ( ( wsDepthOnScreen == 15 )&&( wsRedMask == 0x7c00 )&&( wsGreenMask == 0x3e0 )&&( wsBlueMask ==   0x1f ) ) return wsRGB15;
  if ( ( wsDepthOnScreen == 15 )&&( wsRedMask ==   0x1f )&&( wsGreenMask == 0x3e0 )&&( wsBlueMask == 0x7c00 ) ) return wsBGR15;
+ if ( ( wsDepthOnScreen == 12 )&&( wsRedMask == 0x0f00 )&&( wsGreenMask == 0x0f0 )&&( wsBlueMask ==   0x0f ) ) return wsRGB12;
+ if ( ( wsDepthOnScreen == 12 )&&( wsRedMask ==   0x0f )&&( wsGreenMask == 0x0f0 )&&( wsBlueMask == 0x0f00 ) ) return wsBGR12;
  return 0;
 }
 
diff -uprd MPlayer-1.0rc2/libavcodec/flicvideo.c.orig MPlayer-1.0rc2/libavcodec/flicvideo.c
--- MPlayer-1.0rc2/libavcodec/flicvideo.c.orig	2007-10-07 21:49:36.000000000 +0200
+++ MPlayer-1.0rc2/libavcodec/flicvideo.c	2010-01-09 18:20:28.000000000 +0100
@@ -108,6 +108,7 @@ static int flic_decode_init(AVCodecConte
 
     switch (depth) {
         case 8  : avctx->pix_fmt = PIX_FMT_PAL8; break;
+        case 12 : avctx->pix_fmt = PIX_FMT_RGB444; break;
         case 15 : avctx->pix_fmt = PIX_FMT_RGB555; break;
         case 16 : avctx->pix_fmt = PIX_FMT_RGB565; break;
         case 24 : avctx->pix_fmt = PIX_FMT_BGR24; /* Supposedly BGR, but havent any files to test with */
@@ -707,6 +708,7 @@ static int flic_decode_frame(AVCodecCont
                                     buf, buf_size);
     }
     else if ((avctx->pix_fmt == PIX_FMT_RGB555) ||
+             (avctx->pix_fmt == PIX_FMT_RGB444) ||
              (avctx->pix_fmt == PIX_FMT_RGB565)) {
       return flic_decode_frame_15_16BPP(avctx, data, data_size,
                                         buf, buf_size);
diff -uprd MPlayer-1.0rc2/libavcodec/imgconvert.c.orig MPlayer-1.0rc2/libavcodec/imgconvert.c
--- MPlayer-1.0rc2/libavcodec/imgconvert.c.orig	2007-10-07 21:49:37.000000000 +0200
+++ MPlayer-1.0rc2/libavcodec/imgconvert.c	2010-01-14 23:06:36.000000000 +0100
@@ -214,6 +214,14 @@ static const PixFmtInfo pix_fmt_info[PIX
         .depth = 5,
         .x_chroma_shift = 0, .y_chroma_shift = 0,
     },
+    [PIX_FMT_RGB444] = {
+        .name = "rgb444",
+        .nb_channels = 3,
+        .color_type = FF_COLOR_RGB,
+        .pixel_type = FF_PIXEL_PACKED,
+        .depth = 4,
+        .x_chroma_shift = 0, .y_chroma_shift = 0,
+    },
 
     /* gray / mono formats */
     [PIX_FMT_GRAY16BE] = {
@@ -298,6 +306,14 @@ static const PixFmtInfo pix_fmt_info[PIX
         .depth = 5,
         .x_chroma_shift = 0, .y_chroma_shift = 0,
     },
+    [PIX_FMT_BGR444] = {
+        .name = "bgr444",
+        .nb_channels = 3,
+        .color_type = FF_COLOR_RGB,
+        .pixel_type = FF_PIXEL_PACKED,
+        .depth = 4,
+        .x_chroma_shift = 0, .y_chroma_shift = 0,
+    },
     [PIX_FMT_RGB8] = {
         .name = "rgb8",
         .nb_channels = 1,
@@ -507,8 +523,10 @@ int avpicture_fill(AVPicture *picture, u
         return size * 4;
     case PIX_FMT_GRAY16BE:
     case PIX_FMT_GRAY16LE:
+    case PIX_FMT_BGR444:
     case PIX_FMT_BGR555:
     case PIX_FMT_BGR565:
+    case PIX_FMT_RGB444:
     case PIX_FMT_RGB555:
     case PIX_FMT_RGB565:
     case PIX_FMT_YUYV422:
@@ -592,8 +610,10 @@ int avpicture_layout(const AVPicture* sr
     if (pf->pixel_type == FF_PIXEL_PACKED || pf->pixel_type == FF_PIXEL_PALETTE) {
         if (pix_fmt == PIX_FMT_YUYV422 ||
             pix_fmt == PIX_FMT_UYVY422 ||
+            pix_fmt == PIX_FMT_BGR444 ||
             pix_fmt == PIX_FMT_BGR565 ||
             pix_fmt == PIX_FMT_BGR555 ||
+            pix_fmt == PIX_FMT_RGB444 ||
             pix_fmt == PIX_FMT_RGB565 ||
             pix_fmt == PIX_FMT_RGB555)
             w = width * 2;
@@ -650,6 +670,8 @@ int avcodec_get_pix_fmt_loss(int dst_pix
     loss = 0;
     pf = &pix_fmt_info[dst_pix_fmt];
     if (pf->depth < ps->depth ||
+        (dst_pix_fmt == PIX_FMT_RGB444 && src_pix_fmt == PIX_FMT_RGB555) ||
+        (dst_pix_fmt == PIX_FMT_RGB444 && src_pix_fmt == PIX_FMT_RGB565) ||
         (dst_pix_fmt == PIX_FMT_RGB555 && src_pix_fmt == PIX_FMT_RGB565))
         loss |= FF_LOSS_DEPTH;
     if (pf->x_chroma_shift > ps->x_chroma_shift ||
@@ -705,8 +727,10 @@ static int avg_bits_per_pixel(int pix_fm
         case PIX_FMT_UYVY422:
         case PIX_FMT_RGB565:
         case PIX_FMT_RGB555:
+        case PIX_FMT_RGB444:
         case PIX_FMT_BGR565:
         case PIX_FMT_BGR555:
+        case PIX_FMT_BGR444:
             bits = 16;
             break;
         case PIX_FMT_UYYVYY411:
@@ -819,8 +843,10 @@ void av_picture_copy(AVPicture *dst, con
         case PIX_FMT_UYVY422:
         case PIX_FMT_RGB565:
         case PIX_FMT_RGB555:
+        case PIX_FMT_RGB444:
         case PIX_FMT_BGR565:
         case PIX_FMT_BGR555:
+        case PIX_FMT_BGR444:
             bits = 16;
             break;
         case PIX_FMT_UYYVYY411:
@@ -1612,6 +1638,28 @@ static inline unsigned int bitcopy_n(uns
     return (a & (0xff & ~mask)) | ((-((a >> n) & 1)) & mask);
 }
 
+/* rgb444 handling */
+
+#define RGB_NAME rgb444
+
+#define RGB_IN(r, g, b, s)\
+{\
+    unsigned int v = ((const uint16_t *)(s))[0];\
+    r = bitcopy_n(v >> (8 - 4), 4);\
+    g = bitcopy_n(v >> (4 - 4), 4);\
+    b = bitcopy_n(v << 4, 4);\
+}
+
+
+#define RGB_OUT(d, r, g, b)\
+{\
+    ((uint16_t *)(d))[0] = ((r >> 4) << 8) | ((g >> 4) << 4) | (b >> 4);\
+}
+
+#define BPP 2
+
+#include "imgconvert_template.h"
+
 /* rgb555 handling */
 
 #define RGB_NAME rgb555
@@ -1942,6 +1990,9 @@ static const ConvertEntry convert_table[
         [PIX_FMT_YUYV422] = {
             .convert = yuv420p_to_yuyv422,
         },
+        [PIX_FMT_RGB444] = {
+            .convert = yuv420p_to_rgb444
+        },
         [PIX_FMT_RGB555] = {
             .convert = yuv420p_to_rgb555
         },
@@ -1975,6 +2026,9 @@ static const ConvertEntry convert_table[
         },
     },
     [PIX_FMT_YUVJ420P] = {
+        [PIX_FMT_RGB444] = {
+            .convert = yuvj420p_to_rgb444
+        },
         [PIX_FMT_RGB555] = {
             .convert = yuvj420p_to_rgb555
         },
@@ -2022,6 +2076,9 @@ static const ConvertEntry convert_table[
         [PIX_FMT_RGB555] = {
             .convert = rgb24_to_rgb555
         },
+        [PIX_FMT_RGB444] = {
+            .convert = rgb24_to_rgb444
+        },
         [PIX_FMT_RGB32] = {
             .convert = rgb24_to_rgb32
         },
@@ -2057,6 +2114,9 @@ static const ConvertEntry convert_table[
         [PIX_FMT_RGB555] = {
             .convert = rgb32_to_rgb555
         },
+        [PIX_FMT_RGB444] = {
+            .convert = rgb32_to_rgb444
+        },
         [PIX_FMT_PAL8] = {
             .convert = rgb32_to_pal8
         },
@@ -2081,6 +2141,20 @@ static const ConvertEntry convert_table[
             .convert = bgr24_to_gray
         },
     },
+    [PIX_FMT_RGB444] = {
+        [PIX_FMT_RGB24] = {
+            .convert = rgb444_to_rgb24
+        },
+        [PIX_FMT_RGB32] = {
+            .convert = rgb444_to_rgb32
+        },
+        [PIX_FMT_YUV420P] = {
+            .convert = rgb444_to_yuv420p
+        },
+        [PIX_FMT_GRAY8] = {
+            .convert = rgb444_to_gray
+        },
+    },
     [PIX_FMT_RGB555] = {
         [PIX_FMT_RGB24] = {
             .convert = rgb555_to_rgb24
@@ -2126,6 +2200,9 @@ static const ConvertEntry convert_table[
         },
     },
     [PIX_FMT_GRAY8] = {
+        [PIX_FMT_RGB444] = {
+            .convert = gray_to_rgb444
+        },
         [PIX_FMT_RGB555] = {
             .convert = gray_to_rgb555
         },
@@ -2165,6 +2242,9 @@ static const ConvertEntry convert_table[
         },
     },
     [PIX_FMT_PAL8] = {
+        [PIX_FMT_RGB444] = {
+            .convert = pal8_to_rgb444
+        },
         [PIX_FMT_RGB555] = {
             .convert = pal8_to_rgb555
         },
diff -uprd MPlayer-1.0rc2/libavcodec/raw.c.orig MPlayer-1.0rc2/libavcodec/raw.c
--- MPlayer-1.0rc2/libavcodec/raw.c.orig	2007-10-07 21:49:37.000000000 +0200
+++ MPlayer-1.0rc2/libavcodec/raw.c	2010-01-09 18:09:12.000000000 +0100
@@ -43,6 +43,8 @@ const PixelFormatTag ff_raw_pixelFormatT
     { PIX_FMT_UYVY422, MKTAG('U', 'Y', 'V', 'Y') },
     { PIX_FMT_UYVY422, MKTAG('H', 'D', 'Y', 'C') },
     { PIX_FMT_GRAY8,   MKTAG('G', 'R', 'E', 'Y') },
+    { PIX_FMT_RGB444,  MKTAG('R', 'G', 'B', 12) },
+    { PIX_FMT_BGR444,  MKTAG('B', 'G', 'R', 12) },
     { PIX_FMT_RGB555,  MKTAG('R', 'G', 'B', 15) },
     { PIX_FMT_BGR555,  MKTAG('B', 'G', 'R', 15) },
     { PIX_FMT_RGB565,  MKTAG('R', 'G', 'B', 16) },
diff -uprd MPlayer-1.0rc2/libavcodec/rawdec.c.orig MPlayer-1.0rc2/libavcodec/rawdec.c
--- MPlayer-1.0rc2/libavcodec/rawdec.c.orig	2007-10-07 21:49:36.000000000 +0200
+++ MPlayer-1.0rc2/libavcodec/rawdec.c	2010-01-09 17:52:04.000000000 +0100
@@ -36,6 +36,7 @@ typedef struct RawVideoContext {
 static const PixelFormatTag pixelFormatBpsAVI[] = {
     { PIX_FMT_PAL8,    4 },
     { PIX_FMT_PAL8,    8 },
+    { PIX_FMT_RGB444, 12 },
     { PIX_FMT_RGB555, 15 },
     { PIX_FMT_RGB555, 16 },
     { PIX_FMT_BGR24,  24 },
diff -uprd MPlayer-1.0rc2/libavcodec/targa.c.orig MPlayer-1.0rc2/libavcodec/targa.c
--- MPlayer-1.0rc2/libavcodec/targa.c.orig	2007-10-07 21:49:37.000000000 +0200
+++ MPlayer-1.0rc2/libavcodec/targa.c	2010-01-09 18:16:17.000000000 +0100
@@ -121,6 +121,9 @@ static int decode_frame(AVCodecContext *
     case 8:
         avctx->pix_fmt = ((compr & (~TGA_RLE)) == TGA_BW) ? PIX_FMT_GRAY8 : PIX_FMT_PAL8;
         break;
+    case 12:
+        avctx->pix_fmt = PIX_FMT_RGB444;
+        break;
     case 15:
         avctx->pix_fmt = PIX_FMT_RGB555;
         break;
diff -uprd MPlayer-1.0rc2/libavformat/x11grab.c.orig MPlayer-1.0rc2/libavformat/x11grab.c
--- MPlayer-1.0rc2/libavformat/x11grab.c.orig	2007-10-07 21:49:38.000000000 +0200
+++ MPlayer-1.0rc2/libavformat/x11grab.c	2010-01-09 18:23:01.000000000 +0100
@@ -173,6 +173,11 @@ x11grab_read_header(AVFormatContext *s1,
                    image->blue_mask  == 0x001f ) {
             av_log(s1, AV_LOG_DEBUG, "16 bit RGB555\n");
             input_pixfmt = PIX_FMT_RGB555;
+        } else if (image->red_mask   == 0x0f00 &&
+                   image->green_mask == 0x00f0 &&
+                   image->blue_mask  == 0x000f ) {
+            av_log(s1, AV_LOG_DEBUG, "16 bit RGB444\n");
+            input_pixfmt = PIX_FMT_RGB444;
         } else {
             av_log(s1, AV_LOG_ERROR, "RGB ordering at image depth %i not supported ... aborting\n", image->bits_per_pixel);
             av_log(s1, AV_LOG_ERROR, "color masks: r 0x%.6lx g 0x%.6lx b 0x%.6lx\n", image->red_mask, image->green_mask, image->blue_mask);
diff -uprd MPlayer-1.0rc2/libavutil/avutil.h.orig MPlayer-1.0rc2/libavutil/avutil.h
--- MPlayer-1.0rc2/libavutil/avutil.h.orig	2007-10-07 21:49:34.000000000 +0200
+++ MPlayer-1.0rc2/libavutil/avutil.h	2010-01-09 20:59:40.000000000 +0100
@@ -75,6 +75,7 @@ enum PixelFormat {
     PIX_FMT_YUV411P,   ///< Planar YUV 4:1:1, 12bpp, (1 Cr & Cb sample per 4x1 Y samples)
     PIX_FMT_RGB565,    ///< Packed RGB 5:6:5, 16bpp, (msb)   5R 6G 5B(lsb), in cpu endianness
     PIX_FMT_RGB555,    ///< Packed RGB 5:5:5, 16bpp, (msb)1A 5R 5G 5B(lsb), in cpu endianness most significant bit to 0
+    PIX_FMT_RGB444,    ///< Packed RGB 4:4:4, 16bpp, (msb)4A 4R 4G 4B(lsb), in cpu endianness most significant bit to 0
     PIX_FMT_GRAY8,     ///<        Y        ,  8bpp
     PIX_FMT_MONOWHITE, ///<        Y        ,  1bpp, 0 is white, 1 is black
     PIX_FMT_MONOBLACK, ///<        Y        ,  1bpp, 0 is black, 1 is white
@@ -89,6 +90,7 @@ enum PixelFormat {
     PIX_FMT_BGR32,     ///< Packed RGB 8:8:8, 32bpp, (msb)8A 8B 8G 8R(lsb), in cpu endianness
     PIX_FMT_BGR565,    ///< Packed RGB 5:6:5, 16bpp, (msb)   5B 6G 5R(lsb), in cpu endianness
     PIX_FMT_BGR555,    ///< Packed RGB 5:5:5, 16bpp, (msb)1A 5B 5G 5R(lsb), in cpu endianness most significant bit to 1
+    PIX_FMT_BGR444,    ///< Packed RGB 4:4:4, 16bpp, (msb)4A 4B 4G 4R(lsb), in cpu endianness most significant bit to 1
     PIX_FMT_BGR8,      ///< Packed RGB 3:3:2,  8bpp, (msb)2B 3G 3R(lsb)
     PIX_FMT_BGR4,      ///< Packed RGB 1:2:1,  4bpp, (msb)1B 2G 1R(lsb)
     PIX_FMT_BGR4_BYTE, ///< Packed RGB 1:2:1,  8bpp, (msb)1B 2G 1R(lsb)
diff -uprd MPlayer-1.0rc2/libmenu/menu.c.orig MPlayer-1.0rc2/libmenu/menu.c
--- MPlayer-1.0rc2/libmenu/menu.c.orig	2007-10-07 21:49:32.000000000 +0200
+++ MPlayer-1.0rc2/libmenu/menu.c	2010-01-09 17:02:35.000000000 +0100
@@ -260,6 +260,9 @@ typedef void (*draw_alpha_f)(int w,int h
 
 inline static draw_alpha_f get_draw_alpha(uint32_t fmt) {
   switch(fmt) {
+  case IMGFMT_BGR12:
+  case IMGFMT_RGB12:
+    return vo_draw_alpha_rgb12;
   case IMGFMT_BGR15:
   case IMGFMT_RGB15:
     return vo_draw_alpha_rgb15;
diff -uprd MPlayer-1.0rc2/libmpcodecs/img_format.c.orig MPlayer-1.0rc2/libmpcodecs/img_format.c
--- MPlayer-1.0rc2/libmpcodecs/img_format.c.orig	2007-10-07 21:49:25.000000000 +0200
+++ MPlayer-1.0rc2/libmpcodecs/img_format.c	2010-01-09 02:12:36.000000000 +0100
@@ -11,6 +11,7 @@ const char *vo_format_name(int format)
 	case IMGFMT_RGB4: return("RGB 4-bit");
 	case IMGFMT_RG4B: return("RGB 4-bit per byte");
 	case IMGFMT_RGB8: return("RGB 8-bit");
+	case IMGFMT_RGB12: return("RGB 12-bit");
 	case IMGFMT_RGB15: return("RGB 15-bit");
 	case IMGFMT_RGB16: return("RGB 16-bit");
 	case IMGFMT_RGB24: return("RGB 24-bit");
@@ -19,6 +20,7 @@ const char *vo_format_name(int format)
 	case IMGFMT_BGR4: return("BGR 4-bit");
 	case IMGFMT_BG4B: return("BGR 4-bit per byte");
 	case IMGFMT_BGR8: return("BGR 8-bit");
+	case IMGFMT_BGR12: return("BGR 12-bit");
 	case IMGFMT_BGR15: return("BGR 15-bit");
 	case IMGFMT_BGR16: return("BGR 16-bit");
 	case IMGFMT_BGR24: return("BGR 24-bit");
diff -uprd MPlayer-1.0rc2/libmpcodecs/img_format.h.orig MPlayer-1.0rc2/libmpcodecs/img_format.h
--- MPlayer-1.0rc2/libmpcodecs/img_format.h.orig	2007-10-07 21:49:25.000000000 +0200
+++ MPlayer-1.0rc2/libmpcodecs/img_format.h	2010-01-09 02:13:22.000000000 +0100
@@ -10,6 +10,7 @@
 #define IMGFMT_RGB4  (IMGFMT_RGB|4)
 #define IMGFMT_RGB4_CHAR  (IMGFMT_RGB|4|128) // RGB4 with 1 pixel per byte
 #define IMGFMT_RGB8  (IMGFMT_RGB|8)
+#define IMGFMT_RGB12 (IMGFMT_RGB|12)
 #define IMGFMT_RGB15 (IMGFMT_RGB|15)
 #define IMGFMT_RGB16 (IMGFMT_RGB|16)
 #define IMGFMT_RGB24 (IMGFMT_RGB|24)
@@ -21,6 +22,7 @@
 #define IMGFMT_BGR4 (IMGFMT_BGR|4)
 #define IMGFMT_BGR4_CHAR (IMGFMT_BGR|4|128) // BGR4 with 1 pixel per byte
 #define IMGFMT_BGR8 (IMGFMT_BGR|8)
+#define IMGFMT_BGR12 (IMGFMT_BGR|12)
 #define IMGFMT_BGR15 (IMGFMT_BGR|15)
 #define IMGFMT_BGR16 (IMGFMT_BGR|16)
 #define IMGFMT_BGR24 (IMGFMT_BGR|24)
diff -uprd MPlayer-1.0rc2/libmpcodecs/vd_ffmpeg.c.orig MPlayer-1.0rc2/libmpcodecs/vd_ffmpeg.c
--- MPlayer-1.0rc2/libmpcodecs/vd_ffmpeg.c.orig	2007-10-07 21:49:25.000000000 +0200
+++ MPlayer-1.0rc2/libmpcodecs/vd_ffmpeg.c	2010-01-14 23:08:57.000000000 +0100
@@ -528,6 +528,7 @@ static int init_vo(sh_video_t *sh, enum 
 	case PIX_FMT_RGB24 :  ctx->best_csp=IMGFMT_RGB24;break; //qtrle
 	case PIX_FMT_RGB32:   ctx->best_csp=IMGFMT_BGR32;break; //huffyuv / mjpeg
 	case PIX_FMT_BGR24 :  ctx->best_csp=IMGFMT_BGR24;break; //8bps
+	case PIX_FMT_RGB444:  ctx->best_csp=IMGFMT_BGR12;break; //12bps
 	case PIX_FMT_RGB555:  ctx->best_csp=IMGFMT_BGR15;break; //rpza,cram
 	case PIX_FMT_RGB565:  ctx->best_csp=IMGFMT_BGR16;break; //4xm
 	case PIX_FMT_GRAY8:   ctx->best_csp=IMGFMT_Y800;break; // gray jpeg
diff -uprd MPlayer-1.0rc2/libmpcodecs/vd_raw.c.orig MPlayer-1.0rc2/libmpcodecs/vd_raw.c
--- MPlayer-1.0rc2/libmpcodecs/vd_raw.c.orig	2007-10-07 21:49:25.000000000 +0200
+++ MPlayer-1.0rc2/libmpcodecs/vd_raw.c	2010-01-09 02:40:21.000000000 +0100
@@ -35,6 +35,7 @@ static int init(sh_video_t *sh){
 	case 1:  sh->bih->biCompression=IMGFMT_BGR1; break;
 	case 4:  sh->bih->biCompression=IMGFMT_BGR4; break;
 	case 8:  sh->bih->biCompression=IMGFMT_BGR8; break;
+	case 12: sh->bih->biCompression=IMGFMT_BGR12; break;
 	case 15: sh->bih->biCompression=IMGFMT_BGR15; break;
 	// workaround bitcount==16 => bgr15 case for avi files:
 	case 16: sh->bih->biCompression=(sh->format)?IMGFMT_BGR16:IMGFMT_BGR15; break;
diff -uprd MPlayer-1.0rc2/libmpcodecs/vd_vfw.c.orig MPlayer-1.0rc2/libmpcodecs/vd_vfw.c
--- MPlayer-1.0rc2/libmpcodecs/vd_vfw.c.orig	2007-10-07 21:49:25.000000000 +0200
+++ MPlayer-1.0rc2/libmpcodecs/vd_vfw.c	2010-01-09 02:09:58.000000000 +0100
@@ -71,8 +71,10 @@ static void set_csp(BITMAPINFOHEADER *o_
 	case IMGFMT_BGR8:
 	    o_bih->biBitCount=8;
 	    break;
+	case IMGFMT_RGB12:
 	case IMGFMT_RGB15:
 	case IMGFMT_RGB16:
+	case IMGFMT_BGR12:
 	case IMGFMT_BGR15:
 	case IMGFMT_BGR16:
 	    o_bih->biBitCount=16;
diff -uprd MPlayer-1.0rc2/libmpcodecs/vd_xvid4.c.orig MPlayer-1.0rc2/libmpcodecs/vd_xvid4.c
--- MPlayer-1.0rc2/libmpcodecs/vd_xvid4.c.orig	2007-10-07 21:49:25.000000000 +0200
+++ MPlayer-1.0rc2/libmpcodecs/vd_xvid4.c	2010-01-09 02:37:01.000000000 +0100
@@ -129,6 +129,9 @@ static int init(sh_video_t *sh)
 		 * frame memcpy's overhead */
 		cs = (do_dr2)?XVID_CSP_INTERNAL:XVID_CSP_USER;
 		break;
+	case IMGFMT_BGR12: 
+		cs = XVID_CSP_RGB444;
+		break;
 	case IMGFMT_BGR15: 
 		cs = XVID_CSP_RGB555;
 		break;
diff -uprd MPlayer-1.0rc2/libmpcodecs/vf_1bpp.c.orig MPlayer-1.0rc2/libmpcodecs/vf_1bpp.c
--- MPlayer-1.0rc2/libmpcodecs/vf_1bpp.c.orig	2007-10-07 21:49:25.000000000 +0200
+++ MPlayer-1.0rc2/libmpcodecs/vf_1bpp.c	2010-01-09 02:09:45.000000000 +0100
@@ -27,6 +27,8 @@ static unsigned int bgr_list[]={
     IMGFMT_444P,
     
     IMGFMT_YUY2,
+    IMGFMT_BGR12,
+    IMGFMT_RGB12,
     IMGFMT_BGR15,
     IMGFMT_RGB15,
     IMGFMT_BGR16,
@@ -132,6 +134,10 @@ static int put_image(struct vf_instance_
     case IMGFMT_YUY2:
 	convert(mpi,dmpi,0x8000,0x80ff,2);
 	break;
+    case IMGFMT_BGR12:
+    case IMGFMT_RGB12:
+	convert(mpi,dmpi,0,0x0fff,2);
+	break;
     case IMGFMT_BGR15:
     case IMGFMT_RGB15:
 	convert(mpi,dmpi,0,0x7fff,2);
diff -uprd MPlayer-1.0rc2/libmpcodecs/vf_expand.c.orig MPlayer-1.0rc2/libmpcodecs/vf_expand.c
--- MPlayer-1.0rc2/libmpcodecs/vf_expand.c.orig	2007-10-07 21:49:25.000000000 +0200
+++ MPlayer-1.0rc2/libmpcodecs/vf_expand.c	2010-01-09 02:12:00.000000000 +0100
@@ -122,6 +122,10 @@ static void draw_func(int x0,int y0, int
 			vf->dmpi->stride[0]*y0+
 			(vf->dmpi->bpp>>3)*x0;
     switch(vf->dmpi->imgfmt){
+    case IMGFMT_BGR12:
+    case IMGFMT_RGB12:
+	vo_draw_alpha_rgb12(w,h,src,srca,stride,dst,vf->dmpi->stride[0]);
+	break;
     case IMGFMT_BGR15:
     case IMGFMT_RGB15:
 	vo_draw_alpha_rgb15(w,h,src,srca,stride,dst,vf->dmpi->stride[0]);
diff -uprd MPlayer-1.0rc2/libmpcodecs/vf_format.c.orig MPlayer-1.0rc2/libmpcodecs/vf_format.c
--- MPlayer-1.0rc2/libmpcodecs/vf_format.c.orig	2007-10-07 21:49:25.000000000 +0200
+++ MPlayer-1.0rc2/libmpcodecs/vf_format.c	2010-01-09 02:13:01.000000000 +0100
@@ -50,6 +50,7 @@ static int open(vf_instance_t *vf, char*
 	if(!strcasecmp(args,"bgr32")) vf->priv->fmt=IMGFMT_BGR32; else
 	if(!strcasecmp(args,"bgr16")) vf->priv->fmt=IMGFMT_BGR16; else
 	if(!strcasecmp(args,"bgr15")) vf->priv->fmt=IMGFMT_BGR15; else
+	if(!strcasecmp(args,"bgr12")) vf->priv->fmt=IMGFMT_BGR12; else
 	if(!strcasecmp(args,"bgr8")) vf->priv->fmt=IMGFMT_BGR8; else
 	if(!strcasecmp(args,"bgr4")) vf->priv->fmt=IMGFMT_BGR4; else
 	if(!strcasecmp(args,"bg4b")) vf->priv->fmt=IMGFMT_BG4B; else
@@ -58,6 +59,7 @@ static int open(vf_instance_t *vf, char*
 	if(!strcasecmp(args,"rgb32")) vf->priv->fmt=IMGFMT_RGB32; else
 	if(!strcasecmp(args,"rgb16")) vf->priv->fmt=IMGFMT_RGB16; else
 	if(!strcasecmp(args,"rgb15")) vf->priv->fmt=IMGFMT_RGB15; else
+	if(!strcasecmp(args,"rgb12")) vf->priv->fmt=IMGFMT_RGB12; else
 	if(!strcasecmp(args,"rgb8")) vf->priv->fmt=IMGFMT_RGB8; else
 	if(!strcasecmp(args,"rgb4")) vf->priv->fmt=IMGFMT_RGB4; else
 	if(!strcasecmp(args,"rg4b")) vf->priv->fmt=IMGFMT_RG4B; else
diff -uprd MPlayer-1.0rc2/libmpcodecs/vf_noformat.c.orig MPlayer-1.0rc2/libmpcodecs/vf_noformat.c
--- MPlayer-1.0rc2/libmpcodecs/vf_noformat.c.orig	2007-10-07 21:49:25.000000000 +0200
+++ MPlayer-1.0rc2/libmpcodecs/vf_noformat.c	2010-01-09 02:15:20.000000000 +0100
@@ -50,6 +50,7 @@ static int open(vf_instance_t *vf, char*
 	if(!strcasecmp(args,"bgr32")) vf->priv->fmt=IMGFMT_BGR32; else
 	if(!strcasecmp(args,"bgr16")) vf->priv->fmt=IMGFMT_BGR16; else
 	if(!strcasecmp(args,"bgr15")) vf->priv->fmt=IMGFMT_BGR15; else
+	if(!strcasecmp(args,"bgr12")) vf->priv->fmt=IMGFMT_BGR12; else
 	if(!strcasecmp(args,"bgr8")) vf->priv->fmt=IMGFMT_BGR8; else
 	if(!strcasecmp(args,"bgr4")) vf->priv->fmt=IMGFMT_BGR4; else
 	if(!strcasecmp(args,"bg4b")) vf->priv->fmt=IMGFMT_BG4B; else
@@ -58,6 +59,7 @@ static int open(vf_instance_t *vf, char*
 	if(!strcasecmp(args,"rgb32")) vf->priv->fmt=IMGFMT_RGB32; else
 	if(!strcasecmp(args,"rgb16")) vf->priv->fmt=IMGFMT_RGB16; else
 	if(!strcasecmp(args,"rgb15")) vf->priv->fmt=IMGFMT_RGB15; else
+	if(!strcasecmp(args,"rgb12")) vf->priv->fmt=IMGFMT_RGB12; else
 	if(!strcasecmp(args,"rgb8")) vf->priv->fmt=IMGFMT_RGB8; else
 	if(!strcasecmp(args,"rgb4")) vf->priv->fmt=IMGFMT_RGB4; else
 	if(!strcasecmp(args,"rg4b")) vf->priv->fmt=IMGFMT_RG4B; else
diff -uprd MPlayer-1.0rc2/libmpcodecs/vf_palette.c.orig MPlayer-1.0rc2/libmpcodecs/vf_palette.c
--- MPlayer-1.0rc2/libmpcodecs/vf_palette.c.orig	2007-10-07 21:49:25.000000000 +0200
+++ MPlayer-1.0rc2/libmpcodecs/vf_palette.c	2010-01-09 02:43:31.000000000 +0100
@@ -94,6 +94,12 @@ static int put_image(struct vf_instance_
     if(mpi->w==mpi->stride[0] && dmpi->w*(dmpi->bpp>>3)==dmpi->stride[0]){
 	// no stride conversion needed
 	switch(IMGFMT_RGB_DEPTH(dmpi->imgfmt)){
+	case 12:
+	    if (IMGFMT_IS_BGR(dmpi->imgfmt))
+		palette8tobgr12(mpi->planes[0],dmpi->planes[0],mpi->h*mpi->w,mpi->planes[1]);
+	    else
+		palette8torgb12(mpi->planes[0],dmpi->planes[0],mpi->h*mpi->w,mpi->planes[1]);
+	    break;
 	case 15:
 	    if (IMGFMT_IS_BGR(dmpi->imgfmt))
 		palette8tobgr15(mpi->planes[0],dmpi->planes[0],mpi->h*mpi->w,mpi->planes[1]);
@@ -125,6 +131,12 @@ static int put_image(struct vf_instance_
 	    unsigned char* src=mpi->planes[0]+y*mpi->stride[0];
 	    unsigned char* dst=dmpi->planes[0]+y*dmpi->stride[0];
 	    switch(IMGFMT_RGB_DEPTH(dmpi->imgfmt)){
+	    case 12:
+		if (IMGFMT_IS_BGR(dmpi->imgfmt))
+		    palette8tobgr12(src,dst,mpi->w,mpi->planes[1]);
+		else
+		    palette8torgb12(src,dst,mpi->w,mpi->planes[1]);
+		break;
 	    case 15:
 		if (IMGFMT_IS_BGR(dmpi->imgfmt))
 		    palette8tobgr15(src,dst,mpi->w,mpi->planes[1]);
@@ -179,10 +191,12 @@ static int open(vf_instance_t *vf, char*
     for(i=0;i<256;i++) gray_pal[i]=0x01010101*i;
     if (args)
     {
+	if (!strcasecmp(args,"rgb12")) vf->priv->fmt=IMGFMT_RGB12; else
 	if (!strcasecmp(args,"rgb15")) vf->priv->fmt=IMGFMT_RGB15; else
 	if (!strcasecmp(args,"rgb16")) vf->priv->fmt=IMGFMT_RGB16; else
 	if (!strcasecmp(args,"rgb24")) vf->priv->fmt=IMGFMT_RGB24; else
 	if (!strcasecmp(args,"rgb32")) vf->priv->fmt=IMGFMT_RGB32; else
+	if (!strcasecmp(args,"bgr12")) vf->priv->fmt=IMGFMT_BGR12; else
 	if (!strcasecmp(args,"bgr15")) vf->priv->fmt=IMGFMT_BGR15; else
 	if (!strcasecmp(args,"bgr16")) vf->priv->fmt=IMGFMT_BGR16; else
 	if (!strcasecmp(args,"bgr24")) vf->priv->fmt=IMGFMT_BGR24; else
diff -uprd MPlayer-1.0rc2/libmpcodecs/vf_rgbtest.c.orig MPlayer-1.0rc2/libmpcodecs/vf_rgbtest.c
--- MPlayer-1.0rc2/libmpcodecs/vf_rgbtest.c.orig	2007-10-07 21:49:25.000000000 +0200
+++ MPlayer-1.0rc2/libmpcodecs/vf_rgbtest.c	2010-01-09 02:17:49.000000000 +0100
@@ -18,11 +18,13 @@ struct vf_priv_s {
 
 static unsigned int getfmt(unsigned int outfmt){
     switch(outfmt){
+    case IMGFMT_RGB12:
     case IMGFMT_RGB15:
     case IMGFMT_RGB16:
     case IMGFMT_RGB24:
     case IMGFMT_RGBA:
     case IMGFMT_ARGB:
+    case IMGFMT_BGR12:
     case IMGFMT_BGR15:
     case IMGFMT_BGR16:
     case IMGFMT_BGR24:
@@ -35,6 +37,10 @@ static unsigned int getfmt(unsigned int 
 
 static void put_pixel(uint8_t *buf, int x, int y, int stride, int r, int g, int b, int fmt){
     switch(fmt){
+    case IMGFMT_BGR12: ((uint16_t*)(buf + y*stride))[x]= ((r>>4)<<8) | ((g>>4)<<4) | (b>>4);
+    break;
+    case IMGFMT_RGB12: ((uint16_t*)(buf + y*stride))[x]= ((b>>4)<<8) | ((g>>4)<<4) | (r>>4);
+    break;
     case IMGFMT_BGR15: ((uint16_t*)(buf + y*stride))[x]= ((r>>3)<<10) | ((g>>3)<<5) | (b>>3);
     break;
     case IMGFMT_RGB15: ((uint16_t*)(buf + y*stride))[x]= ((b>>3)<<10) | ((g>>3)<<5) | (r>>3);
diff -uprd MPlayer-1.0rc2/libmpcodecs/vf_scale.c.orig MPlayer-1.0rc2/libmpcodecs/vf_scale.c
--- MPlayer-1.0rc2/libmpcodecs/vf_scale.c.orig	2007-10-07 21:49:25.000000000 +0200
+++ MPlayer-1.0rc2/libmpcodecs/vf_scale.c	2010-01-09 02:38:57.000000000 +0100
@@ -72,6 +72,8 @@ static unsigned int outfmt_list[]={
     IMGFMT_RGB16,
     IMGFMT_BGR15,
     IMGFMT_RGB15,
+    IMGFMT_BGR12,
+    IMGFMT_RGB12,
     IMGFMT_Y800,
     IMGFMT_Y8,
     IMGFMT_BGR8,
@@ -451,7 +453,7 @@ static int control(struct vf_instance_s*
 
 //===========================================================================//
 
-//  supported Input formats: YV12, I420, IYUV, YUY2, UYVY, BGR32, BGR24, BGR16, BGR15, RGB32, RGB24, Y8, Y800
+//  supported Input formats: YV12, I420, IYUV, YUY2, UYVY, BGR32, BGR24, BGR16, BGR15, BGR12, RGB32, RGB24, Y8, Y800
 
 static int query_format(struct vf_instance_s* vf, unsigned int fmt){
     switch(fmt){
@@ -464,6 +466,7 @@ static int query_format(struct vf_instan
     case IMGFMT_BGR24:
     case IMGFMT_BGR16:
     case IMGFMT_BGR15:
+    case IMGFMT_BGR12:
     case IMGFMT_RGB32:
     case IMGFMT_RGB24:
     case IMGFMT_Y800: 
diff -uprd MPlayer-1.0rc2/libmpcodecs/vf_screenshot.c.orig MPlayer-1.0rc2/libmpcodecs/vf_screenshot.c
--- MPlayer-1.0rc2/libmpcodecs/vf_screenshot.c.orig	2007-10-07 21:49:25.000000000 +0200
+++ MPlayer-1.0rc2/libmpcodecs/vf_screenshot.c	2010-01-09 02:38:08.000000000 +0100
@@ -261,6 +261,7 @@ static int query_format(struct vf_instan
     case IMGFMT_BGR24:
     case IMGFMT_BGR16:
     case IMGFMT_BGR15:
+    case IMGFMT_BGR12:
     case IMGFMT_RGB32:
     case IMGFMT_RGB24:
     case IMGFMT_Y800: 
diff -uprd MPlayer-1.0rc2/libmpcodecs/vf_tile.c.orig MPlayer-1.0rc2/libmpcodecs/vf_tile.c
--- MPlayer-1.0rc2/libmpcodecs/vf_tile.c.orig	2007-10-07 21:49:25.000000000 +0200
+++ MPlayer-1.0rc2/libmpcodecs/vf_tile.c	2010-01-09 02:10:11.000000000 +0100
@@ -186,12 +186,14 @@ static void uninit(struct vf_instance_s*
 static int query_format(struct vf_instance_s* vf, unsigned int fmt)
 {
 	switch (fmt) {
-        /* rgb 15 -> 32 bit */
+        /* rgb 12 -> 32 bit */
+        case IMGFMT_RGB12:
         case IMGFMT_RGB15:
 	case IMGFMT_RGB16:
 	case IMGFMT_RGB24:
         case IMGFMT_RGB32:
-        /* bgr 15 -> 32 bit */
+        /* bgr 12 -> 32 bit */
+	case IMGFMT_BGR12:
 	case IMGFMT_BGR15:
 	case IMGFMT_BGR16:
 	case IMGFMT_BGR24:
Only in MPlayer-1.0rc2/libswscale: .yuv2rgb.c.swp
diff -uprd MPlayer-1.0rc2/libswscale/cs_test.c.orig MPlayer-1.0rc2/libswscale/cs_test.c
--- MPlayer-1.0rc2/libswscale/cs_test.c.orig	2007-10-07 21:49:31.000000000 +0200
+++ MPlayer-1.0rc2/libswscale/cs_test.c	2010-01-09 05:02:10.000000000 +0100
@@ -78,30 +78,47 @@ int main(int argc, char **argv)
             char *name;
             void (*func)(const uint8_t *src, uint8_t *dst, long src_size);
         } func_info[] = {
+            FUNC(2, 2, rgb12to15),
+            FUNC(2, 2, rgb12to16),
+            FUNC(2, 3, rgb12to24),
+            FUNC(2, 4, rgb12to32),
+            FUNC(2, 2, rgb15to12),
             FUNC(2, 2, rgb15to16),
             FUNC(2, 3, rgb15to24),
             FUNC(2, 4, rgb15to32),
             FUNC(2, 3, rgb16to24),
             FUNC(2, 4, rgb16to32),
+            FUNC(3, 2, rgb24to12),
             FUNC(3, 2, rgb24to15),
             FUNC(3, 2, rgb24to16),
             FUNC(3, 4, rgb24to32),
+            FUNC(4, 2, rgb32to12),
             FUNC(4, 2, rgb32to15),
             FUNC(4, 2, rgb32to16),
             FUNC(4, 3, rgb32to24),
             FUNC(2, 2, rgb16to15),
+            FUNC(2, 2, rgb16to12),
+            FUNC(2, 2, rgb12tobgr12),
+            FUNC(2, 2, rgb12tobgr15),
+            FUNC(2, 2, rgb12tobgr16),
+            FUNC(2, 3, rgb12tobgr24),
+            FUNC(2, 4, rgb12tobgr32),
+            FUNC(2, 2, rgb15tobgr12),
             FUNC(2, 2, rgb15tobgr15),
             FUNC(2, 2, rgb15tobgr16),
             FUNC(2, 3, rgb15tobgr24),
             FUNC(2, 4, rgb15tobgr32),
+            FUNC(2, 2, rgb16tobgr12),
             FUNC(2, 2, rgb16tobgr15),
             FUNC(2, 2, rgb16tobgr16),
             FUNC(2, 3, rgb16tobgr24),
             FUNC(2, 4, rgb16tobgr32),
+            FUNC(3, 2, rgb24tobgr12),
             FUNC(3, 2, rgb24tobgr15),
             FUNC(3, 2, rgb24tobgr16),
             FUNC(3, 3, rgb24tobgr24),
             FUNC(3, 4, rgb24tobgr32),
+            FUNC(4, 2, rgb32tobgr12),
             FUNC(4, 2, rgb32tobgr15),
             FUNC(4, 2, rgb32tobgr16),
             FUNC(4, 3, rgb32tobgr24),
diff -uprd MPlayer-1.0rc2/libswscale/internal_bfin.S.orig MPlayer-1.0rc2/libswscale/internal_bfin.S
--- MPlayer-1.0rc2/libswscale/internal_bfin.S.orig	2007-10-07 21:49:31.000000000 +0200
+++ MPlayer-1.0rc2/libswscale/internal_bfin.S	2010-01-09 20:17:47.000000000 +0100
@@ -346,6 +346,119 @@ DEFUN(yuv2rgb555_line,MEM,
         rts;
 DEFUN_END(yuv2rgb555_line)
 
+DEFUN(yuv2rgb444_line,MEM,
+   (uint8_t *Y, uint8_t *U, uint8_t *V, int *out, int dW, uint32_t *coeffs)):
+        link 0;
+        [--sp] = (r7:4);
+        p1 = [fp+ARG_OUT];
+        r3 = [fp+ARG_W];
+
+        i0 = r0;
+        i2 = r1;
+        i3 = r2;
+
+        r0 = [fp+ARG_COEFF];
+        i1 = r0;
+        b1 = i1;
+        l1 = COEFF_LEN;
+        m0 = COEFF_REL_CY_OFF;
+        p0 = r3;
+
+        r0   = [i0++];         // 2Y
+        r1.l = w[i2++];        // 2u
+        r1.h = w[i3++];        // 2v
+        p0 = p0>>2;
+
+        lsetup (.L0444, .L1444) lc0 = p0;
+
+        /*
+           uint32_t oy,oc,zero,cy,crv,rmask,cbu,bmask,cgu,cgv
+           r0 -- used to load 4ys
+           r1 -- used to load 2us,2vs
+           r4 -- y3,y2
+           r5 -- y1,y0
+           r6 -- u1,u0
+           r7 -- v1,v0
+        */
+                                                              r2=[i1++]; // oy
+.L0444:
+        /*
+        rrrrrrrr gggggggg bbbbbbbb
+         5432109876543210
+                     bbbb >>4
+                 gggggggg 
+             rrrrrrrr     <<4
+         xxxxrrrrggggbbbb
+        */
+
+        (r4,r5) = byteop16m (r1:0, r3:2)                   || r3=[i1++]; // oc
+        (r7,r6) = byteop16m (r1:0, r3:2) (r);
+        r5 = r5 << 2 (v);                                                // y1,y0
+        r4 = r4 << 2 (v);                                                // y3,y2
+        r6 = r6 << 2 (v)                                   || r0=[i1++]; // u1,u0, r0=zero
+        r7 = r7 << 2 (v)                                   || r1=[i1++]; // v1,v0  r1=cy
+        /* Y' = y*cy */
+        a1 = r1.h*r5.h, a0 = r1.l*r5.l                     || r1=[i1++]; // crv
+
+        /* R = Y+ crv*(Cr-128) */
+        r2.h = (a1 += r1.h*r7.l), r2.l = (a0 += r1.l*r7.l);
+                a1 -= r1.h*r7.l,          a0 -= r1.l*r7.l  || r5=[i1++]; // rmask
+        r2 = byteop3p(r3:2, r1:0)(LO)                      || r1=[i1++]; // cbu
+        r2 = r2 >> 4 (v);
+        r3 = r2 & r5;
+
+        /* B = Y+ cbu*(Cb-128) */
+        r2.h = (a1 += r1.h*r6.l), r2.l = (a0 += r1.l*r6.l);
+                a1 -= r1.h*r6.l,          a0 -= r1.l*r6.l  || r5=[i1++]; // bmask
+        r2 = byteop3p(r3:2, r1:0)(LO)                      || r1=[i1++]; // cgu
+        r2 = r2 << 4 (v);
+        r2 = r2 & r5;
+        r3 = r3 | r2;
+
+        /* G = Y+ cgu*(Cb-128)+cgv*(Cr-128) */
+                a1 += r1.h*r6.l,          a0 += r1.l*r6.l  || r1=[i1++]; // cgv
+        r2.h = (a1 += r1.h*r7.l), r2.l = (a0 += r1.l*r7.l);
+        r2 = byteop3p(r3:2, r1:0)(LO)                      || r5=[i1++m0]; // gmask
+        r2 = r2 & r5;
+        r3 = r3 | r2;
+        [p1++]=r3                                          || r1=[i1++]; // cy
+
+        /* Y' = y*cy */
+
+        a1 = r1.h*r4.h, a0 = r1.l*r4.l                     || r1=[i1++]; // crv
+
+        /* R = Y+ crv*(Cr-128) */
+        r2.h = (a1 += r1.h*r7.h), r2.l = (a0 += r1.l*r7.h);
+                a1 -= r1.h*r7.h,          a0 -= r1.l*r7.h  || r5=[i1++]; // rmask
+        r2 = byteop3p(r3:2, r1:0)(LO)                      || r1=[i1++]; // cbu
+        r2 = r2 >> 4 (v);
+        r3 = r2 & r5;
+
+        /* B = Y+ cbu*(Cb-128) */
+        r2.h = (a1 += r1.h*r6.h), r2.l = (a0 += r1.l*r6.h);
+                a1 -= r1.h*r6.h,          a0 -= r1.l*r6.h  || r5=[i1++]; // bmask
+        r2 = byteop3p(r3:2, r1:0)(LO)                      || r1=[i1++]; // cgu
+        r2 = r2 << 4 (v);
+        r2 = r2 & r5;
+        r3 = r3 | r2;
+
+        /* G = Y+ cgu*(Cb-128)+cgv*(Cr-128) */
+                a1 += r1.h*r6.h,          a0 += r1.l*r6.h  || r1=[i1++]; // cgv
+        r2.h = (a1 += r1.h*r7.h), r2.l = (a0 += r1.l*r7.h) || r5=[i1++]; // gmask
+        r2 = byteop3p(r3:2, r1:0)(LO)                      || r0=[i0++];     // 4Y
+        r2 = r2 & r5;
+        r3 = r3 | r2;
+        [p1++]=r3                                          || r1.h=w[i3++]; // 2v
+
+.L1444:                                                       r2=[i1++]; // oy
+
+        l1 = 0;
+
+        (r7:4) = [sp++];
+        unlink;
+        rts;
+DEFUN_END(yuv2rgb444_line)
+
 DEFUN(yuv2rgb24_line,MEM,
    (uint8_t *Y, uint8_t *U, uint8_t *V, int *out, int dW, uint32_t *coeffs)):
         link 0;
diff -uprd MPlayer-1.0rc2/libswscale/rgb2rgb.c.orig MPlayer-1.0rc2/libswscale/rgb2rgb.c
--- MPlayer-1.0rc2/libswscale/rgb2rgb.c.orig	2007-10-07 21:49:31.000000000 +0200
+++ MPlayer-1.0rc2/libswscale/rgb2rgb.c	2010-01-09 19:06:23.000000000 +0100
@@ -38,12 +38,20 @@
 void (*rgb24to32)(const uint8_t *src,uint8_t *dst,long src_size);
 void (*rgb24to16)(const uint8_t *src,uint8_t *dst,long src_size);
 void (*rgb24to15)(const uint8_t *src,uint8_t *dst,long src_size);
+void (*rgb24to12)(const uint8_t *src,uint8_t *dst,long src_size);
 void (*rgb32to24)(const uint8_t *src,uint8_t *dst,long src_size);
 void (*rgb32to16)(const uint8_t *src,uint8_t *dst,long src_size);
 void (*rgb32to15)(const uint8_t *src,uint8_t *dst,long src_size);
+void (*rgb32to12)(const uint8_t *src,uint8_t *dst,long src_size);
+void (*rgb12to15)(const uint8_t *src,uint8_t *dst,long src_size);
+void (*rgb12to16)(const uint8_t *src,uint8_t *dst,long src_size);
+void (*rgb12to24)(const uint8_t *src,uint8_t *dst,long src_size);
+void (*rgb12to32)(const uint8_t *src,uint8_t *dst,long src_size);
+void (*rgb15to12)(const uint8_t *src,uint8_t *dst,long src_size);
 void (*rgb15to16)(const uint8_t *src,uint8_t *dst,long src_size);
 void (*rgb15to24)(const uint8_t *src,uint8_t *dst,long src_size);
 void (*rgb15to32)(const uint8_t *src,uint8_t *dst,long src_size);
+void (*rgb16to12)(const uint8_t *src,uint8_t *dst,long src_size);
 void (*rgb16to15)(const uint8_t *src,uint8_t *dst,long src_size);
 void (*rgb16to24)(const uint8_t *src,uint8_t *dst,long src_size);
 void (*rgb16to32)(const uint8_t *src,uint8_t *dst,long src_size);
@@ -51,10 +59,12 @@ void (*rgb16to32)(const uint8_t *src,uin
 void (*rgb24tobgr24)(const uint8_t *src, uint8_t *dst, long src_size);
 void (*rgb24tobgr16)(const uint8_t *src, uint8_t *dst, long src_size);
 void (*rgb24tobgr15)(const uint8_t *src, uint8_t *dst, long src_size);
+void (*rgb24tobgr12)(const uint8_t *src, uint8_t *dst, long src_size);
 void (*rgb32tobgr32)(const uint8_t *src, uint8_t *dst, long src_size);
 //void (*rgb32tobgr24)(const uint8_t *src, uint8_t *dst, long src_size);
 void (*rgb32tobgr16)(const uint8_t *src, uint8_t *dst, long src_size);
 void (*rgb32tobgr15)(const uint8_t *src, uint8_t *dst, long src_size);
+void (*rgb32tobgr12)(const uint8_t *src, uint8_t *dst, long src_size);
 
 void (*yv12toyuy2)(const uint8_t *ysrc, const uint8_t *usrc, const uint8_t *vsrc, uint8_t *dst,
                    long width, long height,
@@ -343,6 +353,22 @@ void palette8tobgr15(const uint8_t *src,
         ((uint16_t *)dst)[i] = bswap_16(((uint16_t *)palette)[ src[i] ]);
 }
 
+/**
+ * Palette is assumed to contain BGR12, see rgb32to12 to convert the palette.
+ */
+void palette8torgb12(const uint8_t *src, uint8_t *dst, long num_pixels, const uint8_t *palette)
+{
+    long i;
+    for (i=0; i<num_pixels; i++)
+        ((uint16_t *)dst)[i] = ((uint16_t *)palette)[ src[i] ];
+}
+void palette8tobgr12(const uint8_t *src, uint8_t *dst, long num_pixels, const uint8_t *palette)
+{
+    long i;
+    for (i=0; i<num_pixels; i++)
+        ((uint16_t *)dst)[i] = bswap_16(((uint16_t *)palette)[ src[i] ]);
+}
+
 void rgb32tobgr24(const uint8_t *src, uint8_t *dst, long src_size)
 {
     long i;
@@ -456,6 +482,23 @@ void rgb16tobgr15(const uint8_t *src, ui
     }
 }
 
+void rgb16tobgr12(const uint8_t *src, uint8_t *dst, long src_size)
+{
+    long i;
+    long num_pixels = src_size >> 1;
+
+    for (i=0; i<num_pixels; i++)
+    {
+        unsigned b,g,r;
+        register uint16_t rgb;
+        rgb = src[2*i];
+        r = (rgb&0x1F)>>1;
+        g = (rgb&0x7E0)>>7;
+        b = (rgb&0xF800)>>12;
+        dst[2*i] = (b&0x0F) | ((g&0x0F)<<4) | ((r&0x0F)<<8);
+    }
+}
+
 void rgb15tobgr32(const uint8_t *src, uint8_t *dst, long src_size)
 {
     const uint16_t *end;
@@ -530,6 +573,114 @@ void rgb15tobgr15(const uint8_t *src, ui
     }
 }
 
+void rgb15tobgr12(const uint8_t *src, uint8_t *dst, long src_size)
+{
+    long i;
+    long num_pixels = src_size >> 1;
+
+    for (i=0; i<num_pixels; i++)
+    {
+        unsigned b,g,r;
+        register uint16_t rgb;
+        rgb = src[2*i];
+        r = (rgb&0x1F)>>1;
+        g = (rgb&0x3E0)>>6;
+        b = (rgb&0x7C00)>>11;
+        dst[2*i] = (b&0x0F) | ((g&0x0F)<<4) | ((r&0x0F)<<8);
+    }
+}
+
+void rgb12tobgr32(const uint8_t *src, uint8_t *dst, long src_size)
+{
+    const uint16_t *end;
+    uint8_t *d = (uint8_t *)dst;
+    const uint16_t *s = (const uint16_t *)src;
+    end = s + src_size/2;
+    while (s < end)
+    {
+        register uint16_t bgr;
+        bgr = *s++;
+        #ifdef WORDS_BIGENDIAN
+            *d++ = 0;
+            *d++ = (bgr&0x0F)<<4;
+            *d++ = bgr&0x0F0;
+            *d++ = (bgr&0x0F00)>>4;
+        #else
+            *d++ = (bgr&0x0F00)>>4;
+            *d++ = bgr&0x0F0;
+            *d++ = (bgr&0x0F)<<4;
+            *d++ = 0;
+        #endif
+    }
+}
+
+void rgb12tobgr24(const uint8_t *src, uint8_t *dst, long src_size)
+{
+    const uint16_t *end;
+    uint8_t *d = (uint8_t *)dst;
+    const uint16_t *s = (uint16_t *)src;
+    end = s + src_size/2;
+    while (s < end)
+    {
+        register uint16_t bgr;
+        bgr = *s++;
+        *d++ = (bgr&0x0F00)>>4;
+        *d++ = bgr&0x0F0;
+        *d++ = (bgr&0x0F)<<4;
+    }
+}
+
+void rgb12tobgr16(const uint8_t *src, uint8_t *dst, long src_size)
+{
+    long i;
+    long num_pixels = src_size >> 1;
+
+    for (i=0; i<num_pixels; i++)
+    {
+        unsigned b,g,r;
+        register uint16_t rgb;
+        rgb = src[2*i];
+        r = (rgb&0x0F)<<1;
+        g = (rgb&0x0F0)>>2;
+        b = (rgb&0x0F00)>>7;
+        dst[2*i] = (b&0x1F) | ((g&0x3F)<<5) | ((r&0x1F)<<11);
+    }
+}
+
+void rgb12tobgr15(const uint8_t *src, uint8_t *dst, long src_size)
+{
+    long i;
+    long num_pixels = src_size >> 1;
+
+    for (i=0; i<num_pixels; i++)
+    {
+        unsigned b,g,r;
+        register uint16_t rgb;
+        rgb = src[2*i];
+        r = (rgb&0x0F)<<1;
+        g = (rgb&0x0F0)>>3;
+        b = (rgb&0x0F00)>>7;
+        dst[2*i] = (b&0x1F) | ((g&0x1F)<<5) | ((r&0x1F)<<10);
+    }
+}
+
+void rgb12tobgr12(const uint8_t *src, uint8_t *dst, long src_size)
+{
+    long i;
+    long num_pixels = src_size >> 1;
+
+    for (i=0; i<num_pixels; i++)
+    {
+        unsigned b,g,r;
+        register uint16_t rgb;
+        rgb = src[2*i];
+        r = rgb&0x0F;
+        g = (rgb&0x0F0)>>4;
+        b = (rgb&0x0F00)>>8;
+        dst[2*i] = (b&0x0F) | ((g&0x0F)<<4) | ((r&0x0F)<<8);
+    }
+}
+
 void rgb8tobgr8(const uint8_t *src, uint8_t *dst, long src_size)
 {
     long i;
diff -uprd MPlayer-1.0rc2/libswscale/rgb2rgb.h.orig MPlayer-1.0rc2/libswscale/rgb2rgb.h
--- MPlayer-1.0rc2/libswscale/rgb2rgb.h.orig	2007-10-07 21:49:31.000000000 +0200
+++ MPlayer-1.0rc2/libswscale/rgb2rgb.h	2010-01-09 18:59:54.000000000 +0100
@@ -32,21 +32,31 @@
 extern void (*rgb24to32)   (const uint8_t *src, uint8_t *dst, long src_size);
 extern void (*rgb24to16)   (const uint8_t *src, uint8_t *dst, long src_size);
 extern void (*rgb24to15)   (const uint8_t *src, uint8_t *dst, long src_size);
+extern void (*rgb24to12)   (const uint8_t *src, uint8_t *dst, long src_size);
 extern void (*rgb32to24)   (const uint8_t *src, uint8_t *dst, long src_size);
 extern void (*rgb32to16)   (const uint8_t *src, uint8_t *dst, long src_size);
 extern void (*rgb32to15)   (const uint8_t *src, uint8_t *dst, long src_size);
+extern void (*rgb32to12)   (const uint8_t *src, uint8_t *dst, long src_size);
+extern void (*rgb12to15)   (const uint8_t *src, uint8_t *dst, long src_size);
+extern void (*rgb12to16)   (const uint8_t *src, uint8_t *dst, long src_size);
+extern void (*rgb12to24)   (const uint8_t *src, uint8_t *dst, long src_size);
+extern void (*rgb12to32)   (const uint8_t *src, uint8_t *dst, long src_size);
+extern void (*rgb15to12)   (const uint8_t *src, uint8_t *dst, long src_size);
 extern void (*rgb15to16)   (const uint8_t *src, uint8_t *dst, long src_size);
 extern void (*rgb15to24)   (const uint8_t *src, uint8_t *dst, long src_size);
 extern void (*rgb15to32)   (const uint8_t *src, uint8_t *dst, long src_size);
+extern void (*rgb16to12)   (const uint8_t *src, uint8_t *dst, long src_size);
 extern void (*rgb16to15)   (const uint8_t *src, uint8_t *dst, long src_size);
 extern void (*rgb16to24)   (const uint8_t *src, uint8_t *dst, long src_size);
 extern void (*rgb16to32)   (const uint8_t *src, uint8_t *dst, long src_size);
 extern void (*rgb24tobgr24)(const uint8_t *src, uint8_t *dst, long src_size);
 extern void (*rgb24tobgr16)(const uint8_t *src, uint8_t *dst, long src_size);
 extern void (*rgb24tobgr15)(const uint8_t *src, uint8_t *dst, long src_size);
+extern void (*rgb24tobgr12)(const uint8_t *src, uint8_t *dst, long src_size);
 extern void (*rgb32tobgr32)(const uint8_t *src, uint8_t *dst, long src_size);
 extern void (*rgb32tobgr16)(const uint8_t *src, uint8_t *dst, long src_size);
 extern void (*rgb32tobgr15)(const uint8_t *src, uint8_t *dst, long src_size);
+extern void (*rgb32tobgr12)(const uint8_t *src, uint8_t *dst, long src_size);
 
 extern void rgb24tobgr32(const uint8_t *src, uint8_t *dst, long src_size);
 extern void rgb32tobgr24(const uint8_t *src, uint8_t *dst, long src_size);
@@ -54,10 +64,17 @@ extern void rgb16tobgr32(const uint8_t *
 extern void rgb16tobgr24(const uint8_t *src, uint8_t *dst, long src_size);
 extern void rgb16tobgr16(const uint8_t *src, uint8_t *dst, long src_size);
 extern void rgb16tobgr15(const uint8_t *src, uint8_t *dst, long src_size);
+extern void rgb16tobgr12(const uint8_t *src, uint8_t *dst, long src_size);
 extern void rgb15tobgr32(const uint8_t *src, uint8_t *dst, long src_size);
 extern void rgb15tobgr24(const uint8_t *src, uint8_t *dst, long src_size);
 extern void rgb15tobgr16(const uint8_t *src, uint8_t *dst, long src_size);
 extern void rgb15tobgr15(const uint8_t *src, uint8_t *dst, long src_size);
+extern void rgb15tobgr12(const uint8_t *src, uint8_t *dst, long src_size);
+extern void rgb12tobgr32(const uint8_t *src, uint8_t *dst, long src_size);
+extern void rgb12tobgr24(const uint8_t *src, uint8_t *dst, long src_size);
+extern void rgb12tobgr16(const uint8_t *src, uint8_t *dst, long src_size);
+extern void rgb12tobgr15(const uint8_t *src, uint8_t *dst, long src_size);
+extern void rgb12tobgr12(const uint8_t *src, uint8_t *dst, long src_size);
 extern void rgb8tobgr8  (const uint8_t *src, uint8_t *dst, long src_size);
 
 
@@ -69,6 +86,8 @@ extern void palette8torgb16(const uint8_
 extern void palette8tobgr16(const uint8_t *src, uint8_t *dst, long num_pixels, const uint8_t *palette);
 extern void palette8torgb15(const uint8_t *src, uint8_t *dst, long num_pixels, const uint8_t *palette);
 extern void palette8tobgr15(const uint8_t *src, uint8_t *dst, long num_pixels, const uint8_t *palette);
+extern void palette8torgb12(const uint8_t *src, uint8_t *dst, long num_pixels, const uint8_t *palette);
+extern void palette8tobgr12(const uint8_t *src, uint8_t *dst, long num_pixels, const uint8_t *palette);
 
 /**
  *
diff -uprd MPlayer-1.0rc2/libswscale/rgb2rgb_template.c.orig MPlayer-1.0rc2/libswscale/rgb2rgb_template.c
--- MPlayer-1.0rc2/libswscale/rgb2rgb_template.c.orig	2007-10-07 21:49:31.000000000 +0200
+++ MPlayer-1.0rc2/libswscale/rgb2rgb_template.c	2010-01-14 23:23:16.000000000 +0100
@@ -234,6 +234,106 @@ static inline void RENAME(rgb32to24)(con
  MMX2, 3DNOW optimization by Nick Kurshev
  32bit c version, and and&add trick by Michael Niedermayer
 */
+static inline void RENAME(rgb12to15)(const uint8_t *src,uint8_t *dst,long src_size)
+{
+    register const uint8_t* s=src;
+    register uint8_t* d=dst;
+    register const uint8_t *end;
+    const uint8_t *mm_end;
+    end = s + src_size;
+#ifdef HAVE_MMX
+    __asm __volatile(PREFETCH"    %0"::"m"(*s));
+    __asm __volatile("movq        %0, %%mm4"::"m"(mask15s));
+    mm_end = end - 15;
+    while (s<mm_end)
+    {
+        __asm __volatile(
+        PREFETCH"  32%1         \n\t"
+        "movq        %1, %%mm0  \n\t"
+        "movq       8%1, %%mm2  \n\t"
+        "movq     %%mm0, %%mm1  \n\t"
+        "movq     %%mm2, %%mm3  \n\t"
+        "pand     %%mm4, %%mm0  \n\t"
+        "pand     %%mm4, %%mm2  \n\t"
+        "paddw    %%mm1, %%mm0  \n\t"
+        "paddw    %%mm3, %%mm2  \n\t"
+        MOVNTQ"   %%mm0,  %0    \n\t"
+        MOVNTQ"   %%mm2, 8%0"
+        :"=m"(*d)
+        :"m"(*s)
+        );
+        d+=16;
+        s+=16;
+    }
+    __asm __volatile(SFENCE:::"memory");
+    __asm __volatile(EMMS:::"memory");
+#endif
+    mm_end = end - 3;
+    while (s < mm_end)
+    {
+        register unsigned x= *((uint32_t *)s);
+        *((uint32_t *)d) = ((x<<1)&0x001E001E) | ((x<<2)&0x03C003C0) | \
+			   ((x<<3)&0x78007800);
+        d+=4;
+        s+=4;
+    }
+    if (s < end)
+    {
+        register unsigned short x= *((uint16_t *)s);
+        *((uint16_t *)d) = ((x<<1)&0x001E) | ((x<<2)&0x03C0) | ((x<<3)&0x7800);
+    }
+}
+
+static inline void RENAME(rgb12to16)(const uint8_t *src,uint8_t *dst,long src_size)
+{
+    register const uint8_t* s=src;
+    register uint8_t* d=dst;
+    register const uint8_t *end;
+    const uint8_t *mm_end;
+    end = s + src_size;
+#ifdef HAVE_MMX
+    __asm __volatile(PREFETCH"    %0"::"m"(*s));
+    __asm __volatile("movq        %0, %%mm4"::"m"(mask15s));
+    mm_end = end - 15;
+    while (s<mm_end)
+    {
+        __asm __volatile(
+        PREFETCH"  32%1         \n\t"
+        "movq        %1, %%mm0  \n\t"
+        "movq       8%1, %%mm2  \n\t"
+        "movq     %%mm0, %%mm1  \n\t"
+        "movq     %%mm2, %%mm3  \n\t"
+        "pand     %%mm4, %%mm0  \n\t"
+        "pand     %%mm4, %%mm2  \n\t"
+        "paddw    %%mm1, %%mm0  \n\t"
+        "paddw    %%mm3, %%mm2  \n\t"
+        MOVNTQ"   %%mm0,  %0    \n\t"
+        MOVNTQ"   %%mm2, 8%0"
+        :"=m"(*d)
+        :"m"(*s)
+        );
+        d+=16;
+        s+=16;
+    }
+    __asm __volatile(SFENCE:::"memory");
+    __asm __volatile(EMMS:::"memory");
+#endif
+    mm_end = end - 3;
+    while (s < mm_end)
+    {
+        register unsigned x= *((uint32_t *)s);
+        *((uint32_t *)d) = ((x<<1)&0x001E001E) | ((x<<3)&0x07800780) | \
+			   ((x<<4)&0xF000F000);
+        d+=4;
+        s+=4;
+    }
+    if (s < end)
+    {
+        register unsigned short x= *((uint16_t *)s);
+        *((uint16_t *)d) = ((x<<1)&0x001E) | ((x<<3)&0x0780) | ((x<<4)&0xF000);
+    }
+}
+
 static inline void RENAME(rgb15to16)(const uint8_t *src,uint8_t *dst,long src_size)
 {
     register const uint8_t* s=src;
@@ -339,6 +439,120 @@ static inline void RENAME(rgb16to15)(con
     }
 }
 
+static inline void RENAME(rgb15to12)(const uint8_t *src,uint8_t *dst,long src_size)
+{
+    register const uint8_t* s=src;
+    register uint8_t* d=dst;
+    register const uint8_t *end;
+    const uint8_t *mm_end;
+    end = s + src_size;
+#ifdef HAVE_MMX
+    __asm __volatile(PREFETCH"    %0"::"m"(*s));
+    __asm __volatile("movq        %0, %%mm7"::"m"(mask15rg));
+    __asm __volatile("movq        %0, %%mm6"::"m"(mask15b));
+    mm_end = end - 15;
+    while (s<mm_end)
+    {
+        __asm __volatile(
+        PREFETCH"  32%1         \n\t"
+        "movq        %1, %%mm0  \n\t"
+        "movq       8%1, %%mm2  \n\t"
+        "movq     %%mm0, %%mm1  \n\t"
+        "movq     %%mm2, %%mm3  \n\t"
+        "psrlq       $1, %%mm0  \n\t"
+        "psrlq       $1, %%mm2  \n\t"
+        "pand     %%mm7, %%mm0  \n\t"
+        "pand     %%mm7, %%mm2  \n\t"
+        "pand     %%mm6, %%mm1  \n\t"
+        "pand     %%mm6, %%mm3  \n\t"
+        "por      %%mm1, %%mm0  \n\t"
+        "por      %%mm3, %%mm2  \n\t"
+        MOVNTQ"   %%mm0,  %0    \n\t"
+        MOVNTQ"   %%mm2, 8%0"
+        :"=m"(*d)
+        :"m"(*s)
+        );
+        d+=16;
+        s+=16;
+    }
+    __asm __volatile(SFENCE:::"memory");
+    __asm __volatile(EMMS:::"memory");
+#endif
+    mm_end = end - 3;
+    while (s < mm_end)
+    {
+        register uint32_t x= *((uint32_t *)s);
+        *((uint32_t *)d) = ((x>>1)&0x000F000F) | ((x>>2)&0x00F000F0) | \
+			   ((x>>3)&0x0F000F00);
+        s+=4;
+        d+=4;
+    }
+    if (s < end)
+    {
+        register uint16_t x= *((uint16_t *)s);
+        *((uint16_t *)d) = ((x>>1)&0x000F) | ((x>>2)&0x00F0) | ((x>>3)&0x0F00);
+        s+=2;
+        d+=2;
+    }
+}
+
+static inline void RENAME(rgb16to12)(const uint8_t *src,uint8_t *dst,long src_size)
+{
+    register const uint8_t* s=src;
+    register uint8_t* d=dst;
+    register const uint8_t *end;
+    const uint8_t *mm_end;
+    end = s + src_size;
+#ifdef HAVE_MMX
+    __asm __volatile(PREFETCH"    %0"::"m"(*s));
+    __asm __volatile("movq        %0, %%mm7"::"m"(mask15rg));
+    __asm __volatile("movq        %0, %%mm6"::"m"(mask15b));
+    mm_end = end - 15;
+    while (s<mm_end)
+    {
+        __asm __volatile(
+        PREFETCH"  32%1         \n\t"
+        "movq        %1, %%mm0  \n\t"
+        "movq       8%1, %%mm2  \n\t"
+        "movq     %%mm0, %%mm1  \n\t"
+        "movq     %%mm2, %%mm3  \n\t"
+        "psrlq       $1, %%mm0  \n\t"
+        "psrlq       $1, %%mm2  \n\t"
+        "pand     %%mm7, %%mm0  \n\t"
+        "pand     %%mm7, %%mm2  \n\t"
+        "pand     %%mm6, %%mm1  \n\t"
+        "pand     %%mm6, %%mm3  \n\t"
+        "por      %%mm1, %%mm0  \n\t"
+        "por      %%mm3, %%mm2  \n\t"
+        MOVNTQ"   %%mm0,  %0    \n\t"
+        MOVNTQ"   %%mm2, 8%0"
+        :"=m"(*d)
+        :"m"(*s)
+        );
+        d+=16;
+        s+=16;
+    }
+    __asm __volatile(SFENCE:::"memory");
+    __asm __volatile(EMMS:::"memory");
+#endif
+    mm_end = end - 3;
+    while (s < mm_end)
+    {
+        register uint32_t x= *((uint32_t *)s);
+        *((uint32_t *)d) = ((x>>1)&0x000F000F) | ((x>>3)&0x00F000F0) | \
+			   ((x>>4)&0x0F000F00);
+        s+=4;
+        d+=4;
+    }
+    if (s < end)
+    {
+        register uint16_t x= *((uint16_t *)s);
+        *((uint16_t *)d) = ((x>>1)&0x000F) | ((x>>3)&0x00F0) | ((x>>4)&0x0F00);
+        s+=2;
+        d+=2;
+    }
+}
+
 static inline void RENAME(rgb32to16)(const uint8_t *src, uint8_t *dst, long src_size)
 {
     const uint8_t *s = src;
@@ -596,6 +810,104 @@ static inline void RENAME(rgb32to15)(con
     }
 }
 
+static inline void RENAME(rgb32to12)(const uint8_t *src, uint8_t *dst, long src_size)
+{
+    const uint8_t *s = src;
+    const uint8_t *end;
+#ifdef HAVE_MMX
+    const uint8_t *mm_end;
+#endif
+    uint16_t *d = (uint16_t *)dst;
+    end = s + src_size;
+#ifdef HAVE_MMX
+    mm_end = end - 15;
+#if 1 //is faster only if multiplies are reasonable fast (FIXME figure out on which CPUs this is faster, on Athlon it is slightly faster)
+    asm volatile(
+    "movq           %3, %%mm5   \n\t"
+    "movq           %4, %%mm6   \n\t"
+    "movq           %5, %%mm7   \n\t"
+    "jmp            2f          \n\t"
+    ASMALIGN(4)
+    "1:                         \n\t"
+    PREFETCH"   32(%1)          \n\t"
+    "movd         (%1), %%mm0   \n\t"
+    "movd        4(%1), %%mm3   \n\t"
+    "punpckldq   8(%1), %%mm0   \n\t"
+    "punpckldq  12(%1), %%mm3   \n\t"
+    "movq        %%mm0, %%mm1   \n\t"
+    "movq        %%mm3, %%mm4   \n\t"
+    "pand        %%mm6, %%mm0   \n\t"
+    "pand        %%mm6, %%mm3   \n\t"
+    "pmaddwd     %%mm7, %%mm0   \n\t"
+    "pmaddwd     %%mm7, %%mm3   \n\t"
+    "pand        %%mm5, %%mm1   \n\t"
+    "pand        %%mm5, %%mm4   \n\t"
+    "por         %%mm1, %%mm0   \n\t"
+    "por         %%mm4, %%mm3   \n\t"
+    "psrld          $6, %%mm0   \n\t"
+    "pslld         $10, %%mm3   \n\t"
+    "por         %%mm3, %%mm0   \n\t"
+    MOVNTQ"      %%mm0, (%0)    \n\t"
+    "add           $16,  %1     \n\t"
+    "add            $8,  %0     \n\t"
+    "2:                         \n\t"
+    "cmp            %2,  %1     \n\t"
+    " jb            1b          \n\t"
+    : "+r" (d), "+r"(s)
+    : "r" (mm_end), "m" (mask3215g), "m" (mask3216br), "m" (mul3215)
+    );
+#else
+    __asm __volatile(PREFETCH"    %0"::"m"(*src):"memory");
+    __asm __volatile(
+        "movq          %0, %%mm7    \n\t"
+        "movq          %1, %%mm6    \n\t"
+        ::"m"(red_15mask),"m"(green_15mask));
+    while (s < mm_end)
+    {
+        __asm __volatile(
+        PREFETCH"    32%1           \n\t"
+        "movd          %1, %%mm0    \n\t"
+        "movd         4%1, %%mm3    \n\t"
+        "punpckldq    8%1, %%mm0    \n\t"
+        "punpckldq   12%1, %%mm3    \n\t"
+        "movq       %%mm0, %%mm1    \n\t"
+        "movq       %%mm0, %%mm2    \n\t"
+        "movq       %%mm3, %%mm4    \n\t"
+        "movq       %%mm3, %%mm5    \n\t"
+        "psrlq         $3, %%mm0    \n\t"
+        "psrlq         $3, %%mm3    \n\t"
+        "pand          %2, %%mm0    \n\t"
+        "pand          %2, %%mm3    \n\t"
+        "psrlq         $6, %%mm1    \n\t"
+        "psrlq         $6, %%mm4    \n\t"
+        "pand       %%mm6, %%mm1    \n\t"
+        "pand       %%mm6, %%mm4    \n\t"
+        "psrlq         $9, %%mm2    \n\t"
+        "psrlq         $9, %%mm5    \n\t"
+        "pand       %%mm7, %%mm2    \n\t"
+        "pand       %%mm7, %%mm5    \n\t"
+        "por        %%mm1, %%mm0    \n\t"
+        "por        %%mm4, %%mm3    \n\t"
+        "por        %%mm2, %%mm0    \n\t"
+        "por        %%mm5, %%mm3    \n\t"
+        "psllq        $16, %%mm3    \n\t"
+        "por        %%mm3, %%mm0    \n\t"
+        MOVNTQ"     %%mm0, %0       \n\t"
+        :"=m"(*d):"m"(*s),"m"(blue_15mask):"memory");
+        d += 4;
+        s += 16;
+    }
+#endif
+    __asm __volatile(SFENCE:::"memory");
+    __asm __volatile(EMMS:::"memory");
+#endif
+    while (s < end)
+    {
+        register int rgb = *(uint32_t*)s; s += 4;
+        *d++ = ((rgb&0xF0)>>4) + ((rgb&0xF000)>>8) + ((rgb&0xF00000)>>12);
+    }
+}
+
 static inline void RENAME(rgb32tobgr15)(const uint8_t *src, uint8_t *dst, long src_size)
 {
     const uint8_t *s = src;
@@ -657,6 +969,67 @@ static inline void RENAME(rgb32tobgr15)(
     }
 }
 
+static inline void RENAME(rgb32tobgr12)(const uint8_t *src, uint8_t *dst, long src_size)
+{
+    const uint8_t *s = src;
+    const uint8_t *end;
+#ifdef HAVE_MMX
+    const uint8_t *mm_end;
+#endif
+    uint16_t *d = (uint16_t *)dst;
+    end = s + src_size;
+#ifdef HAVE_MMX
+    __asm __volatile(PREFETCH"    %0"::"m"(*src):"memory");
+    __asm __volatile(
+        "movq          %0, %%mm7    \n\t"
+        "movq          %1, %%mm6    \n\t"
+        ::"m"(red_15mask),"m"(green_15mask));
+    mm_end = end - 15;
+    while (s < mm_end)
+    {
+        __asm __volatile(
+        PREFETCH"    32%1           \n\t"
+        "movd          %1, %%mm0    \n\t"
+        "movd         4%1, %%mm3    \n\t"
+        "punpckldq    8%1, %%mm0    \n\t"
+        "punpckldq   12%1, %%mm3    \n\t"
+        "movq       %%mm0, %%mm1    \n\t"
+        "movq       %%mm0, %%mm2    \n\t"
+        "movq       %%mm3, %%mm4    \n\t"
+        "movq       %%mm3, %%mm5    \n\t"
+        "psllq         $7, %%mm0    \n\t"
+        "psllq         $7, %%mm3    \n\t"
+        "pand       %%mm7, %%mm0    \n\t"
+        "pand       %%mm7, %%mm3    \n\t"
+        "psrlq         $6, %%mm1    \n\t"
+        "psrlq         $6, %%mm4    \n\t"
+        "pand       %%mm6, %%mm1    \n\t"
+        "pand       %%mm6, %%mm4    \n\t"
+        "psrlq        $19, %%mm2    \n\t"
+        "psrlq        $19, %%mm5    \n\t"
+        "pand          %2, %%mm2    \n\t"
+        "pand          %2, %%mm5    \n\t"
+        "por        %%mm1, %%mm0    \n\t"
+        "por        %%mm4, %%mm3    \n\t"
+        "por        %%mm2, %%mm0    \n\t"
+        "por        %%mm5, %%mm3    \n\t"
+        "psllq        $16, %%mm3    \n\t"
+        "por        %%mm3, %%mm0    \n\t"
+        MOVNTQ"     %%mm0, %0       \n\t"
+        :"=m"(*d):"m"(*s),"m"(blue_15mask):"memory");
+        d += 4;
+        s += 16;
+    }
+    __asm __volatile(SFENCE:::"memory");
+    __asm __volatile(EMMS:::"memory");
+#endif
+    while (s < end)
+    {
+        register int rgb = *(uint32_t*)s; s += 4;
+        *d++ = ((rgb&0xF0)<<4) + ((rgb&0xF000)>>8) + ((rgb&0xF00000)>>20);
+    }
+}
+
 static inline void RENAME(rgb24to16)(const uint8_t *src, uint8_t *dst, long src_size)
 {
     const uint8_t *s = src;
@@ -846,6 +1219,69 @@ static inline void RENAME(rgb24to15)(con
     }
 }
 
+static inline void RENAME(rgb24to12)(const uint8_t *src, uint8_t *dst, long src_size)
+{
+    const uint8_t *s = src;
+    const uint8_t *end;
+#ifdef HAVE_MMX
+    const uint8_t *mm_end;
+#endif
+    uint16_t *d = (uint16_t *)dst;
+    end = s + src_size;
+#ifdef HAVE_MMX
+    __asm __volatile(PREFETCH"    %0"::"m"(*src):"memory");
+    __asm __volatile(
+        "movq          %0, %%mm7    \n\t"
+        "movq          %1, %%mm6    \n\t"
+        ::"m"(red_15mask),"m"(green_15mask));
+    mm_end = end - 11;
+    while (s < mm_end)
+    {
+        __asm __volatile(
+        PREFETCH"    32%1           \n\t"
+        "movd          %1, %%mm0    \n\t"
+        "movd         3%1, %%mm3    \n\t"
+        "punpckldq    6%1, %%mm0    \n\t"
+        "punpckldq    9%1, %%mm3    \n\t"
+        "movq       %%mm0, %%mm1    \n\t"
+        "movq       %%mm0, %%mm2    \n\t"
+        "movq       %%mm3, %%mm4    \n\t"
+        "movq       %%mm3, %%mm5    \n\t"
+        "psrlq         $3, %%mm0    \n\t"
+        "psrlq         $3, %%mm3    \n\t"
+        "pand          %2, %%mm0    \n\t"
+        "pand          %2, %%mm3    \n\t"
+        "psrlq         $6, %%mm1    \n\t"
+        "psrlq         $6, %%mm4    \n\t"
+        "pand       %%mm6, %%mm1    \n\t"
+        "pand       %%mm6, %%mm4    \n\t"
+        "psrlq         $9, %%mm2    \n\t"
+        "psrlq         $9, %%mm5    \n\t"
+        "pand       %%mm7, %%mm2    \n\t"
+        "pand       %%mm7, %%mm5    \n\t"
+        "por        %%mm1, %%mm0    \n\t"
+        "por        %%mm4, %%mm3    \n\t"
+        "por        %%mm2, %%mm0    \n\t"
+        "por        %%mm5, %%mm3    \n\t"
+        "psllq        $16, %%mm3    \n\t"
+        "por        %%mm3, %%mm0    \n\t"
+        MOVNTQ"     %%mm0, %0       \n\t"
+        :"=m"(*d):"m"(*s),"m"(blue_15mask):"memory");
+        d += 4;
+        s += 12;
+    }
+    __asm __volatile(SFENCE:::"memory");
+    __asm __volatile(EMMS:::"memory");
+#endif
+    while (s < end)
+    {
+        const int b = *s++;
+        const int g = *s++;
+        const int r = *s++;
+        *d++ = (b>>4) | (g&0xF0) | ((r&0xF0)<<4);
+    }
+}
+
 static inline void RENAME(rgb24tobgr15)(const uint8_t *src, uint8_t *dst, long src_size)
 {
     const uint8_t *s = src;
@@ -909,6 +1345,69 @@ static inline void RENAME(rgb24tobgr15)(
     }
 }
 
+static inline void RENAME(rgb24tobgr12)(const uint8_t *src, uint8_t *dst, long src_size)
+{
+    const uint8_t *s = src;
+    const uint8_t *end;
+#ifdef HAVE_MMX
+    const uint8_t *mm_end;
+#endif
+    uint16_t *d = (uint16_t *)dst;
+    end = s + src_size;
+#ifdef HAVE_MMX
+    __asm __volatile(PREFETCH"    %0"::"m"(*src):"memory");
+    __asm __volatile(
+        "movq         %0, %%mm7     \n\t"
+        "movq         %1, %%mm6     \n\t"
+        ::"m"(red_15mask),"m"(green_15mask));
+    mm_end = end - 15;
+    while (s < mm_end)
+    {
+        __asm __volatile(
+        PREFETCH"   32%1            \n\t"
+        "movd         %1, %%mm0     \n\t"
+        "movd        3%1, %%mm3     \n\t"
+        "punpckldq   6%1, %%mm0     \n\t"
+        "punpckldq   9%1, %%mm3     \n\t"
+        "movq      %%mm0, %%mm1     \n\t"
+        "movq      %%mm0, %%mm2     \n\t"
+        "movq      %%mm3, %%mm4     \n\t"
+        "movq      %%mm3, %%mm5     \n\t"
+        "psllq        $7, %%mm0     \n\t"
+        "psllq        $7, %%mm3     \n\t"
+        "pand      %%mm7, %%mm0     \n\t"
+        "pand      %%mm7, %%mm3     \n\t"
+        "psrlq        $6, %%mm1     \n\t"
+        "psrlq        $6, %%mm4     \n\t"
+        "pand      %%mm6, %%mm1     \n\t"
+        "pand      %%mm6, %%mm4     \n\t"
+        "psrlq       $19, %%mm2     \n\t"
+        "psrlq       $19, %%mm5     \n\t"
+        "pand         %2, %%mm2     \n\t"
+        "pand         %2, %%mm5     \n\t"
+        "por       %%mm1, %%mm0     \n\t"
+        "por       %%mm4, %%mm3     \n\t"
+        "por       %%mm2, %%mm0     \n\t"
+        "por       %%mm5, %%mm3     \n\t"
+        "psllq       $16, %%mm3     \n\t"
+        "por       %%mm3, %%mm0     \n\t"
+        MOVNTQ"    %%mm0, %0        \n\t"
+        :"=m"(*d):"m"(*s),"m"(blue_15mask):"memory");
+        d += 4;
+        s += 12;
+    }
+    __asm __volatile(SFENCE:::"memory");
+    __asm __volatile(EMMS:::"memory");
+#endif
+    while (s < end)
+    {
+        const int r = *s++;
+        const int g = *s++;
+        const int b = *s++;
+        *d++ = (b>>4) | (g&0xF0) | ((r&0xF0)<<4);
+    }
+}
+
 /*
   I use here less accurate approximation by simply
  left-shifting the input
@@ -1074,6 +1573,148 @@ static inline void RENAME(rgb15to24)(con
     }
 }
 
+static inline void RENAME(rgb12to24)(const uint8_t *src, uint8_t *dst, long src_size)
+{
+    const uint16_t *end;
+#ifdef HAVE_MMX
+    const uint16_t *mm_end;
+#endif
+    uint8_t *d = (uint8_t *)dst;
+    const uint16_t *s = (uint16_t *)src;
+    end = s + src_size/2;
+#ifdef HAVE_MMX
+    __asm __volatile(PREFETCH"    %0"::"m"(*s):"memory");
+    mm_end = end - 7;
+    while (s < mm_end)
+    {
+        __asm __volatile(
+        PREFETCH"    32%1           \n\t"
+        "movq          %1, %%mm0    \n\t"
+        "movq          %1, %%mm1    \n\t"
+        "movq          %1, %%mm2    \n\t"
+        "pand          %2, %%mm0    \n\t"
+        "pand          %3, %%mm1    \n\t"
+        "pand          %4, %%mm2    \n\t"
+        "psllq         $3, %%mm0    \n\t"
+        "psrlq         $2, %%mm1    \n\t"
+        "psrlq         $7, %%mm2    \n\t"
+        "movq       %%mm0, %%mm3    \n\t"
+        "movq       %%mm1, %%mm4    \n\t"
+        "movq       %%mm2, %%mm5    \n\t"
+        "punpcklwd     %5, %%mm0    \n\t"
+        "punpcklwd     %5, %%mm1    \n\t"
+        "punpcklwd     %5, %%mm2    \n\t"
+        "punpckhwd     %5, %%mm3    \n\t"
+        "punpckhwd     %5, %%mm4    \n\t"
+        "punpckhwd     %5, %%mm5    \n\t"
+        "psllq         $8, %%mm1    \n\t"
+        "psllq        $16, %%mm2    \n\t"
+        "por        %%mm1, %%mm0    \n\t"
+        "por        %%mm2, %%mm0    \n\t"
+        "psllq         $8, %%mm4    \n\t"
+        "psllq        $16, %%mm5    \n\t"
+        "por        %%mm4, %%mm3    \n\t"
+        "por        %%mm5, %%mm3    \n\t"
+
+        "movq       %%mm0, %%mm6    \n\t"
+        "movq       %%mm3, %%mm7    \n\t"
+
+        "movq         8%1, %%mm0    \n\t"
+        "movq         8%1, %%mm1    \n\t"
+        "movq         8%1, %%mm2    \n\t"
+        "pand          %2, %%mm0    \n\t"
+        "pand          %3, %%mm1    \n\t"
+        "pand          %4, %%mm2    \n\t"
+        "psllq         $3, %%mm0    \n\t"
+        "psrlq         $2, %%mm1    \n\t"
+        "psrlq         $7, %%mm2    \n\t"
+        "movq       %%mm0, %%mm3    \n\t"
+        "movq       %%mm1, %%mm4    \n\t"
+        "movq       %%mm2, %%mm5    \n\t"
+        "punpcklwd     %5, %%mm0    \n\t"
+        "punpcklwd     %5, %%mm1    \n\t"
+        "punpcklwd     %5, %%mm2    \n\t"
+        "punpckhwd     %5, %%mm3    \n\t"
+        "punpckhwd     %5, %%mm4    \n\t"
+        "punpckhwd     %5, %%mm5    \n\t"
+        "psllq         $8, %%mm1    \n\t"
+        "psllq        $16, %%mm2    \n\t"
+        "por        %%mm1, %%mm0    \n\t"
+        "por        %%mm2, %%mm0    \n\t"
+        "psllq         $8, %%mm4    \n\t"
+        "psllq        $16, %%mm5    \n\t"
+        "por        %%mm4, %%mm3    \n\t"
+        "por        %%mm5, %%mm3    \n\t"
+
+        :"=m"(*d)
+        :"m"(*s),"m"(mask15b),"m"(mask15g),"m"(mask15r), "m"(mmx_null)
+        :"memory");
+        /* Borrowed 32 to 24 */
+        __asm __volatile(
+        "movq       %%mm0, %%mm4    \n\t"
+        "movq       %%mm3, %%mm5    \n\t"
+        "movq       %%mm6, %%mm0    \n\t"
+        "movq       %%mm7, %%mm1    \n\t"
+
+        "movq       %%mm4, %%mm6    \n\t"
+        "movq       %%mm5, %%mm7    \n\t"
+        "movq       %%mm0, %%mm2    \n\t"
+        "movq       %%mm1, %%mm3    \n\t"
+
+        "psrlq         $8, %%mm2    \n\t"
+        "psrlq         $8, %%mm3    \n\t"
+        "psrlq         $8, %%mm6    \n\t"
+        "psrlq         $8, %%mm7    \n\t"
+        "pand          %2, %%mm0    \n\t"
+        "pand          %2, %%mm1    \n\t"
+        "pand          %2, %%mm4    \n\t"
+        "pand          %2, %%mm5    \n\t"
+        "pand          %3, %%mm2    \n\t"
+        "pand          %3, %%mm3    \n\t"
+        "pand          %3, %%mm6    \n\t"
+        "pand          %3, %%mm7    \n\t"
+        "por        %%mm2, %%mm0    \n\t"
+        "por        %%mm3, %%mm1    \n\t"
+        "por        %%mm6, %%mm4    \n\t"
+        "por        %%mm7, %%mm5    \n\t"
+
+        "movq       %%mm1, %%mm2    \n\t"
+        "movq       %%mm4, %%mm3    \n\t"
+        "psllq        $48, %%mm2    \n\t"
+        "psllq        $32, %%mm3    \n\t"
+        "pand          %4, %%mm2    \n\t"
+        "pand          %5, %%mm3    \n\t"
+        "por        %%mm2, %%mm0    \n\t"
+        "psrlq        $16, %%mm1    \n\t"
+        "psrlq        $32, %%mm4    \n\t"
+        "psllq        $16, %%mm5    \n\t"
+        "por        %%mm3, %%mm1    \n\t"
+        "pand          %6, %%mm5    \n\t"
+        "por        %%mm5, %%mm4    \n\t"
+
+        MOVNTQ"     %%mm0,   %0     \n\t"
+        MOVNTQ"     %%mm1,  8%0     \n\t"
+        MOVNTQ"     %%mm4, 16%0"
+
+        :"=m"(*d)
+        :"m"(*s),"m"(mask24l),"m"(mask24h),"m"(mask24hh),"m"(mask24hhh),"m"(mask24hhhh)
+        :"memory");
+        d += 24;
+        s += 8;
+    }
+    __asm __volatile(SFENCE:::"memory");
+    __asm __volatile(EMMS:::"memory");
+#endif
+    while (s < end)
+    {
+        register uint16_t bgr;
+        bgr = *s++;
+        *d++ = (bgr&0x0F)<<4;
+        *d++ = bgr&0x0F0;
+        *d++ = (bgr&0x0F00)>>4;
+    }
+}
+
 static inline void RENAME(rgb16to24)(const uint8_t *src, uint8_t *dst, long src_size)
 {
     const uint16_t *end;
@@ -1293,6 +1934,84 @@ static inline void RENAME(rgb15to32)(con
     }
 }
 
+static inline void RENAME(rgb12to32)(const uint8_t *src, uint8_t *dst, long src_size)
+{
+    const uint16_t *end;
+#ifdef HAVE_MMX
+    const uint16_t *mm_end;
+#endif
+    uint8_t *d = (uint8_t *)dst;
+    const uint16_t *s = (const uint16_t *)src;
+    end = s + src_size/2;
+#ifdef HAVE_MMX
+    __asm __volatile(PREFETCH"    %0"::"m"(*s):"memory");
+    __asm __volatile("pxor    %%mm7,%%mm7    \n\t":::"memory");
+    mm_end = end - 3;
+    while (s < mm_end)
+    {
+        __asm __volatile(
+        PREFETCH"    32%1           \n\t"
+        "movq          %1, %%mm0    \n\t"
+        "movq          %1, %%mm1    \n\t"
+        "movq          %1, %%mm2    \n\t"
+        "pand          %2, %%mm0    \n\t"
+        "pand          %3, %%mm1    \n\t"
+        "pand          %4, %%mm2    \n\t"
+        "psllq         $3, %%mm0    \n\t"
+        "psrlq         $2, %%mm1    \n\t"
+        "psrlq         $7, %%mm2    \n\t"
+        "movq       %%mm0, %%mm3    \n\t"
+        "movq       %%mm1, %%mm4    \n\t"
+        "movq       %%mm2, %%mm5    \n\t"
+        "punpcklwd  %%mm7, %%mm0    \n\t"
+        "punpcklwd  %%mm7, %%mm1    \n\t"
+        "punpcklwd  %%mm7, %%mm2    \n\t"
+        "punpckhwd  %%mm7, %%mm3    \n\t"
+        "punpckhwd  %%mm7, %%mm4    \n\t"
+        "punpckhwd  %%mm7, %%mm5    \n\t"
+        "psllq         $8, %%mm1    \n\t"
+        "psllq        $16, %%mm2    \n\t"
+        "por        %%mm1, %%mm0    \n\t"
+        "por        %%mm2, %%mm0    \n\t"
+        "psllq         $8, %%mm4    \n\t"
+        "psllq        $16, %%mm5    \n\t"
+        "por        %%mm4, %%mm3    \n\t"
+        "por        %%mm5, %%mm3    \n\t"
+        MOVNTQ"     %%mm0,  %0      \n\t"
+        MOVNTQ"     %%mm3, 8%0      \n\t"
+        :"=m"(*d)
+        :"m"(*s),"m"(mask15b),"m"(mask15g),"m"(mask15r)
+        :"memory");
+        d += 16;
+        s += 4;
+    }
+    __asm __volatile(SFENCE:::"memory");
+    __asm __volatile(EMMS:::"memory");
+#endif
+    while (s < end)
+    {
+#if 0 //slightly slower on athlon
+        int bgr= *s++;
+        *((uint32_t*)d)++ = ((bgr&0x1F)<<3) + ((bgr&0x3E0)<<6) + ((bgr&0x7C00)<<9);
+#else
+        register uint16_t bgr;
+        bgr = *s++;
+#ifdef WORDS_BIGENDIAN
+        *d++ = 0;
+        *d++ = (bgr&0x0F00)>>4;
+        *d++ = bgr&0x0F0;
+        *d++ = (bgr&0x0F)<<4;
+#else
+        *d++ = (bgr&0x0F)<<4;
+        *d++ = bgr&0x0F0;
+        *d++ = (bgr&0x0F00)>>4;
+        *d++ = 0;
+#endif
+
+#endif
+    }
+}
+
 static inline void RENAME(rgb16to32)(const uint8_t *src, uint8_t *dst, long src_size)
 {
     const uint16_t *end;
@@ -2710,24 +3429,34 @@ static inline void RENAME(yvu9_to_yuy2)(
 }
 
 static inline void RENAME(rgb2rgb_init)(void){
+    rgb12to15       = RENAME(rgb12to15);
+    rgb12to16       = RENAME(rgb12to16);
+    rgb12to24       = RENAME(rgb12to24);
+    rgb12to32       = RENAME(rgb12to32);
+    rgb15to12       = RENAME(rgb15to12);
     rgb15to16       = RENAME(rgb15to16);
     rgb15to24       = RENAME(rgb15to24);
     rgb15to32       = RENAME(rgb15to32);
     rgb16to24       = RENAME(rgb16to24);
     rgb16to32       = RENAME(rgb16to32);
     rgb16to15       = RENAME(rgb16to15);
+    rgb16to12       = RENAME(rgb16to12);
     rgb24to16       = RENAME(rgb24to16);
     rgb24to15       = RENAME(rgb24to15);
+    rgb24to12       = RENAME(rgb24to12);
     rgb24to32       = RENAME(rgb24to32);
     rgb32to16       = RENAME(rgb32to16);
     rgb32to15       = RENAME(rgb32to15);
+    rgb32to12       = RENAME(rgb32to12);
     rgb32to24       = RENAME(rgb32to24);
+    rgb24tobgr12    = RENAME(rgb24tobgr12);
     rgb24tobgr15    = RENAME(rgb24tobgr15);
     rgb24tobgr16    = RENAME(rgb24tobgr16);
     rgb24tobgr24    = RENAME(rgb24tobgr24);
     rgb32tobgr32    = RENAME(rgb32tobgr32);
     rgb32tobgr16    = RENAME(rgb32tobgr16);
     rgb32tobgr15    = RENAME(rgb32tobgr15);
+    rgb32tobgr12    = RENAME(rgb32tobgr12);
     yv12toyuy2      = RENAME(yv12toyuy2);
     yv12touyvy      = RENAME(yv12touyvy);
     yuv422ptoyuy2   = RENAME(yuv422ptoyuy2);
diff -uprd MPlayer-1.0rc2/libswscale/swscale.c.orig MPlayer-1.0rc2/libswscale/swscale.c
--- MPlayer-1.0rc2/libswscale/swscale.c.orig	2007-10-07 21:49:31.000000000 +0200
+++ MPlayer-1.0rc2/libswscale/swscale.c	2010-01-14 23:36:40.000000000 +0100
@@ -22,12 +22,12 @@
  */
 
 /*
-  supported Input formats: YV12, I420/IYUV, YUY2, UYVY, BGR32, BGR24, BGR16, BGR15, RGB32, RGB24, Y8/Y800, YVU9/IF09, PAL8
-  supported output formats: YV12, I420/IYUV, YUY2, UYVY, {BGR,RGB}{1,4,8,15,16,24,32}, Y8/Y800, YVU9/IF09
-  {BGR,RGB}{1,4,8,15,16} support dithering
+  supported Input formats: YV12, I420/IYUV, YUY2, UYVY, BGR32, BGR24, BGR16, BGR15, BGR12, RGB32, RGB24, Y8/Y800, YVU9/IF09, PAL8
+  supported output formats: YV12, I420/IYUV, YUY2, UYVY, {BGR,RGB}{1,4,8,12,15,16,24,32}, Y8/Y800, YVU9/IF09
+  {BGR,RGB}{1,4,8,12,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
@@ -109,10 +109,12 @@ untested special converters
         || (x)==PIX_FMT_BGR24       \
         || (x)==PIX_FMT_BGR565      \
         || (x)==PIX_FMT_BGR555      \
+        || (x)==PIX_FMT_BGR444      \
         || (x)==PIX_FMT_BGR32       \
         || (x)==PIX_FMT_RGB24       \
         || (x)==PIX_FMT_RGB565      \
         || (x)==PIX_FMT_RGB555      \
+        || (x)==PIX_FMT_RGB444      \
         || (x)==PIX_FMT_GRAY8       \
         || (x)==PIX_FMT_YUV410P     \
         || (x)==PIX_FMT_GRAY16BE    \
@@ -193,6 +195,9 @@ static volatile uint64_t attribute_used 
 static volatile uint64_t attribute_used __attribute__((aligned(8))) g5Dither;
 static volatile uint64_t attribute_used __attribute__((aligned(8))) g6Dither;
 static volatile uint64_t attribute_used __attribute__((aligned(8))) r5Dither;
+static volatile uint64_t attribute_used __attribute__((aligned(8))) b4Dither;
+static volatile uint64_t attribute_used __attribute__((aligned(8))) g4Dither;
+static volatile uint64_t attribute_used __attribute__((aligned(8))) r4Dither;
 
 static uint64_t __attribute__((aligned(8))) dither4[2]={
         0x0103010301030103LL,
@@ -202,12 +207,19 @@ static uint64_t __attribute__((aligned(8
         0x0602060206020602LL,
         0x0004000400040004LL,};
 
+static uint64_t __attribute__((aligned(8))) dither16[2]={
+        0x0602060206020602LL,
+        0x0004000400040004LL,};
+
 static uint64_t                __attribute__((aligned(8))) b16Mask=   0x001F001F001F001FLL;
 static uint64_t attribute_used __attribute__((aligned(8))) g16Mask=   0x07E007E007E007E0LL;
 static uint64_t attribute_used __attribute__((aligned(8))) r16Mask=   0xF800F800F800F800LL;
 static uint64_t                __attribute__((aligned(8))) b15Mask=   0x001F001F001F001FLL;
 static uint64_t attribute_used __attribute__((aligned(8))) g15Mask=   0x03E003E003E003E0LL;
 static uint64_t attribute_used __attribute__((aligned(8))) r15Mask=   0x7C007C007C007C00LL;
+static uint64_t                __attribute__((aligned(8))) b12Mask=   0x000F000F000F000FLL;
+static uint64_t attribute_used __attribute__((aligned(8))) g12Mask=   0x00F000F000F000F0LL;
+static uint64_t attribute_used __attribute__((aligned(8))) r12Mask=   0x0F000F000F000F00LL;
 
 static uint64_t attribute_used __attribute__((aligned(8))) M24A=      0x00FF0000FF0000FFLL;
 static uint64_t attribute_used __attribute__((aligned(8))) M24B=      0xFF0000FF0000FF00LL;
@@ -234,6 +246,7 @@ static SwsVector *sws_getConvVec(SwsVect
 
 extern const uint8_t dither_2x2_4[2][8];
 extern const uint8_t dither_2x2_8[2][8];
+extern const uint8_t dither_2x2_16[2][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];
@@ -303,6 +316,8 @@ char *sws_format_name(enum PixelFormat f
             return "rgb565";
         case PIX_FMT_RGB555:
             return "rgb555";
+        case PIX_FMT_RGB444:
+            return "rgb444";
         case PIX_FMT_GRAY16BE:
             return "gray16be";
         case PIX_FMT_GRAY16LE:
@@ -339,6 +354,8 @@ char *sws_format_name(enum PixelFormat f
             return "bgr565";
         case PIX_FMT_BGR555:
             return "bgr555";
+        case PIX_FMT_BGR444:
+            return "bgr444";
         case PIX_FMT_BGR8:
             return "bgr8";
         case PIX_FMT_BGR4:
@@ -605,6 +622,21 @@ static inline void yuv2nv12XinC(int16_t 
             }\
         }\
         break;\
+    case PIX_FMT_RGB444:\
+    case PIX_FMT_BGR444:\
+        {\
+            const int dr1= dither_2x2_16[y&1    ][0];\
+            const int dg1= dither_2x2_16[y&1    ][1];\
+            const int db1= dither_2x2_16[(y&1)^1][0];\
+            const int dr2= dither_2x2_16[y&1    ][1];\
+            const int dg2= dither_2x2_16[y&1    ][0];\
+            const int db2= dither_2x2_16[(y&1)^1][1];\
+            func(uint16_t)\
+                ((uint16_t*)dest)[i2+0]= r[Y1+dr1] + g[Y1+dg1] + b[Y1+db1];\
+                ((uint16_t*)dest)[i2+1]= r[Y2+dr2] + g[Y2+dg2] + b[Y2+db2];\
+            }\
+        }\
+        break;\
     case PIX_FMT_RGB8:\
     case PIX_FMT_BGR8:\
         {\
@@ -787,6 +819,21 @@ static inline void yuv2packedXinC(SwsCon
             }
         }
         break;
+    case PIX_FMT_RGB444:
+    case PIX_FMT_BGR444:
+        {
+            const int dr1= dither_2x2_16[y&1    ][0];
+            const int dg1= dither_2x2_16[y&1    ][1];
+            const int db1= dither_2x2_16[(y&1)^1][0];
+            const int dr2= dither_2x2_16[y&1    ][1];
+            const int dg2= dither_2x2_16[y&1    ][0];
+            const int db2= dither_2x2_16[(y&1)^1][1];
+            YSCALE_YUV_2_RGBX_C(uint16_t)
+                ((uint16_t*)dest)[i2+0]= r[Y1+dr1] + g[Y1+dg1] + b[Y1+db1];
+                ((uint16_t*)dest)[i2+1]= r[Y2+dr2] + g[Y2+dg2] + b[Y2+db2];
+            }
+        }
+        break;
     case PIX_FMT_RGB8:
     case PIX_FMT_BGR8:
         {
@@ -1629,48 +1676,66 @@ static int rgb2rgbWrapper(SwsContext *c,
     const int dstFormat= c->dstFormat;
     const int srcBpp= (fmt_depth(srcFormat) + 7) >> 3;
     const int dstBpp= (fmt_depth(dstFormat) + 7) >> 3;
-    const int srcId= fmt_depth(srcFormat) >> 2; /* 1:0, 4:1, 8:2, 15:3, 16:4, 24:6, 32:8 */
-    const int dstId= fmt_depth(dstFormat) >> 2;
+					    /* 1:0, 4:1, 8:3, 12:5, 15:6, 16:7, 24:B, 32:F */
+    const int srcId= ((((fmt_depth(srcFormat)&0x1C)>>1)|(fmt_depth(srcFormat)&0x01))-1)&0x0F;
+    const int dstId= ((((fmt_depth(dstFormat)&0x1C)>>1)|(fmt_depth(dstFormat)&0x01))-1)&0x0F;
     void (*conv)(const uint8_t *src, uint8_t *dst, long src_size)=NULL;
 
     /* BGR -> BGR */
     if (  (isBGR(srcFormat) && isBGR(dstFormat))
        || (isRGB(srcFormat) && isRGB(dstFormat))){
         switch(srcId | (dstId<<4)){
-        case 0x34: conv= rgb16to15; break;
-        case 0x36: conv= rgb24to15; break;
-        case 0x38: conv= rgb32to15; break;
-        case 0x43: conv= rgb15to16; break;
-        case 0x46: conv= rgb24to16; break;
-        case 0x48: conv= rgb32to16; break;
-        case 0x63: conv= rgb15to24; break;
-        case 0x64: conv= rgb16to24; break;
-        case 0x68: conv= rgb32to24; break;
-        case 0x83: conv= rgb15to32; break;
-        case 0x84: conv= rgb16to32; break;
-        case 0x86: conv= rgb24to32; break;
+        case 0x56: conv= rgb15to12; break;
+        case 0x57: conv= rgb16to12; break;
+        case 0x5B: conv= rgb24to12; break;
+        case 0x5F: conv= rgb32to12; break;
+        case 0x65: conv= rgb12to15; break;
+        case 0x67: conv= rgb16to15; break;
+        case 0x6B: conv= rgb24to15; break;
+        case 0x6F: conv= rgb32to15; break;
+        case 0x75: conv= rgb12to16; break;
+        case 0x76: conv= rgb15to16; break;
+        case 0x7B: conv= rgb24to16; break;
+        case 0x7F: conv= rgb32to16; break;
+        case 0xB5: conv= rgb12to24; break;
+        case 0xB6: conv= rgb15to24; break;
+        case 0xB7: conv= rgb16to24; break;
+        case 0xBF: conv= rgb32to24; break;
+        case 0xF5: conv= rgb12to32; break;
+        case 0xF6: conv= rgb15to32; break;
+        case 0xF7: conv= rgb16to32; break;
+        case 0xFB: conv= rgb24to32; break;
         default: av_log(c, AV_LOG_ERROR, "swScaler: internal error %s -> %s converter\n",
                         sws_format_name(srcFormat), sws_format_name(dstFormat)); break;
         }
     }else if (  (isBGR(srcFormat) && isRGB(dstFormat))
              || (isRGB(srcFormat) && isBGR(dstFormat))){
         switch(srcId | (dstId<<4)){
-        case 0x33: conv= rgb15tobgr15; break;
-        case 0x34: conv= rgb16tobgr15; break;
-        case 0x36: conv= rgb24tobgr15; break;
-        case 0x38: conv= rgb32tobgr15; break;
-        case 0x43: conv= rgb15tobgr16; break;
-        case 0x44: conv= rgb16tobgr16; break;
-        case 0x46: conv= rgb24tobgr16; break;
-        case 0x48: conv= rgb32tobgr16; break;
-        case 0x63: conv= rgb15tobgr24; break;
-        case 0x64: conv= rgb16tobgr24; break;
-        case 0x66: conv= rgb24tobgr24; break;
-        case 0x68: conv= rgb32tobgr24; break;
-        case 0x83: conv= rgb15tobgr32; break;
-        case 0x84: conv= rgb16tobgr32; break;
-        case 0x86: conv= rgb24tobgr32; break;
-        case 0x88: conv= rgb32tobgr32; break;
+        case 0x55: conv= rgb12tobgr12; break;
+        case 0x56: conv= rgb15tobgr12; break;
+        case 0x57: conv= rgb16tobgr12; break;
+        case 0x5B: conv= rgb24tobgr12; break;
+        case 0x5F: conv= rgb32tobgr12; break;
+        case 0x65: conv= rgb12tobgr15; break;
+        case 0x66: conv= rgb15tobgr15; break;
+        case 0x67: conv= rgb16tobgr15; break;
+        case 0x6B: conv= rgb24tobgr15; break;
+        case 0x6F: conv= rgb32tobgr15; break;
+        case 0x75: conv= rgb12tobgr16; break;
+        case 0x76: conv= rgb15tobgr16; break;
+        case 0x77: conv= rgb16tobgr16; break;
+        case 0x7B: conv= rgb24tobgr16; break;
+        case 0x7F: conv= rgb32tobgr16; break;
+        case 0xB5: conv= rgb12tobgr24; break;
+        case 0xB6: conv= rgb15tobgr24; break;
+        case 0xB7: conv= rgb16tobgr24; break;
+        case 0xBB: conv= rgb24tobgr24; break;
+        case 0xBF: conv= rgb32tobgr24; break;
+        case 0xF5: conv= rgb12tobgr32; break;
+        case 0xF6: conv= rgb15tobgr32; break;
+        case 0xF7: conv= rgb16tobgr32; break;
+        case 0xFB: conv= rgb24tobgr32; break;
+        case 0xFF: conv= rgb32tobgr32; break;
         default: av_log(c, AV_LOG_ERROR, "swScaler: internal error %s -> %s converter\n",
                         sws_format_name(srcFormat), sws_format_name(dstFormat)); break;
         }
@@ -2425,7 +2490,7 @@ SwsContext *sws_getContext(int srcW, int
         else
             av_log(c, AV_LOG_INFO, "SwScaler: ehh flags invalid?! ");
 
-        if (dstFormat==PIX_FMT_BGR555 || dstFormat==PIX_FMT_BGR565)
+        if (dstFormat==PIX_FMT_BGR444 || dstFormat==PIX_FMT_BGR555 || dstFormat==PIX_FMT_BGR565)
             av_log(c, AV_LOG_INFO, "from %s to%s %s ",
                    sws_format_name(srcFormat), dither, sws_format_name(dstFormat));
         else
@@ -2505,6 +2570,8 @@ SwsContext *sws_getContext(int srcW, int
             av_log(c, AV_LOG_VERBOSE, "SwScaler: using %s YV12->BGR16 Converter\n", (flags & SWS_CPU_CAPS_MMX) ? "MMX" : "C");
         else if (dstFormat==PIX_FMT_BGR555)
             av_log(c, AV_LOG_VERBOSE, "SwScaler: using %s YV12->BGR15 Converter\n", (flags & SWS_CPU_CAPS_MMX) ? "MMX" : "C");
+        else if (dstFormat==PIX_FMT_BGR444)
+            av_log(c, AV_LOG_VERBOSE, "SwScaler: using %s YV12->BGR12 Converter\n", (flags & SWS_CPU_CAPS_MMX) ? "MMX" : "C");
 
         av_log(c, AV_LOG_VERBOSE, "SwScaler: %dx%d -> %dx%d\n", srcW, srcH, dstW, dstH);
     }
diff -uprd MPlayer-1.0rc2/libswscale/swscale_internal.h.orig MPlayer-1.0rc2/libswscale/swscale_internal.h
--- MPlayer-1.0rc2/libswscale/swscale_internal.h.orig	2007-10-07 21:49:31.000000000 +0200
+++ MPlayer-1.0rc2/libswscale/swscale_internal.h	2010-01-09 18:59:04.000000000 +0100
@@ -213,6 +213,7 @@ char *sws_format_name(int format);
         || (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   \
@@ -223,6 +224,7 @@ char *sws_format_name(int format);
         || (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   \
@@ -248,6 +250,9 @@ static inline int fmt_depth(int fmt)
         case PIX_FMT_BGR555:
         case PIX_FMT_RGB555:
             return 15;
+        case PIX_FMT_BGR444:
+        case PIX_FMT_RGB444:
+            return 12;
         case PIX_FMT_BGR8:
         case PIX_FMT_RGB8:
             return 8;
diff -uprd MPlayer-1.0rc2/libswscale/swscale_template.c.orig MPlayer-1.0rc2/libswscale/swscale_template.c
--- MPlayer-1.0rc2/libswscale/swscale_template.c.orig	2007-10-07 21:49:31.000000000 +0200
+++ MPlayer-1.0rc2/libswscale/swscale_template.c	2010-01-14 22:30:53.000000000 +0100
@@ -744,6 +744,32 @@
     " jb             1b             \n\t"
 #define WRITEBGR15(dst, dstw, index)  REAL_WRITEBGR15(dst, dstw, index)
 
+#define REAL_WRITEBGR12(dst, dstw, index) \
+    "pand "MANGLE(bF0)", %%mm2  \n\t" /* B */\
+    "pand "MANGLE(bF0)", %%mm4  \n\t" /* G */\
+    "pand "MANGLE(bF0)", %%mm5  \n\t" /* R */\
+    "psrlq           $4, %%mm2  \n\t"\
+    "psrlq           $4, %%mm5  \n\t"\
+\
+    "movq         %%mm2, %%mm1  \n\t"\
+    "movq         %%mm4, %%mm3  \n\t"\
+\
+    "punpcklbw    %%mm7, %%mm3  \n\t"\
+    "punpcklbw    %%mm5, %%mm2  \n\t"\
+    "punpckhbw    %%mm7, %%mm4  \n\t"\
+    "punpckhbw    %%mm5, %%mm1  \n\t"\
+\
+    "por          %%mm3, %%mm2  \n\t"\
+    "por          %%mm4, %%mm1  \n\t"\
+\
+    MOVNTQ(%%mm2,  (dst, index, 2))\
+    MOVNTQ(%%mm1, 8(dst, index, 2))\
+\
+    "add             $8, "#index"   \n\t"\
+    "cmp        "#dstw", "#index"   \n\t"\
+    " jb             1b             \n\t"
+#define WRITEBGR12(dst, dstw, index)  REAL_WRITEBGR12(dst, dstw, index)
+
 #define WRITEBGR24OLD(dst, dstw, index) \
     /* mm2=B, %%mm4=G, %%mm5=R, %%mm7=0 */\
     "movq      %%mm2, %%mm1             \n\t" /* B */\
@@ -1062,6 +1088,19 @@ static inline void RENAME(yuv2packedX)(S
             : "%"REG_a, "%"REG_c, "%"REG_d, "%"REG_S
             );
             return;
+        case PIX_FMT_BGR444:
+            YSCALEYUV2PACKEDX_ACCURATE
+            YSCALEYUV2RGBX
+            /* mm2=B, %%mm4=G, %%mm5=R, %%mm7=0 */
+#ifdef DITHER1XBPP
+            "paddusb "MANGLE(b4Dither)", %%mm2\n\t"
+            "paddusb "MANGLE(g4Dither)", %%mm4\n\t"
+            "paddusb "MANGLE(r4Dither)", %%mm5\n\t"
+#endif
+
+            WRITEBGR12(%4, %5, %%REGa)
+            YSCALEYUV2PACKEDX_END
+            return;
         case PIX_FMT_BGR555:
             YSCALEYUV2PACKEDX_ACCURATE
             YSCALEYUV2RGBX
@@ -1122,6 +1161,19 @@ static inline void RENAME(yuv2packedX)(S
             : "%"REG_a, "%"REG_c, "%"REG_d, "%"REG_S
             );
             return;
+        case PIX_FMT_BGR444:
+            YSCALEYUV2PACKEDX
+            YSCALEYUV2RGBX
+            /* mm2=B, %%mm4=G, %%mm5=R, %%mm7=0 */
+#ifdef DITHER1XBPP
+            "paddusb "MANGLE(b4Dither)", %%mm2  \n\t"
+            "paddusb "MANGLE(g4Dither)", %%mm4  \n\t"
+            "paddusb "MANGLE(r4Dither)", %%mm5  \n\t"
+#endif
+
+            WRITEBGR12(%4, %5, %%REGa)
+            YSCALEYUV2PACKEDX_END
+            return;
         case PIX_FMT_BGR555:
             YSCALEYUV2PACKEDX
             YSCALEYUV2RGBX
@@ -1399,6 +1451,21 @@ FULL_YSCALEYUV2RGB
                         clip_table15r[(Y + yuvtab_3343[V]) >>13];
                 }
             }
+            else if (dstFormat==PIX_FMT_BGR444)
+            {
+                int i;
+                for (i=0;i<dstW;i++){
+                    // vertical linear interpolation && yuv2rgb in a single step:
+                    int Y=yuvtab_2568[((buf0[i]*yalpha1+buf1[i]*yalpha)>>19)];
+                    int U=((uvbuf0[i]*uvalpha1+uvbuf1[i]*uvalpha)>>19);
+                    int V=((uvbuf0[i+2048]*uvalpha1+uvbuf1[i+2048]*uvalpha)>>19);
+
+                    ((uint16_t*)dest)[i] =
+                        clip_table12b[(Y + yuvtab_40cf[U]) >>13] |
+                        clip_table12g[(Y + yuvtab_1a1e[V] + yuvtab_0c92[U]) >>13] |
+                        clip_table12r[(Y + yuvtab_3343[V]) >>13];
+                }
+            }
         }//FULL_UV_IPOL
     else
     {
@@ -1434,6 +1501,27 @@ FULL_YSCALEYUV2RGB
                 "a" (&c->redDither)
                 );
                 return;
+            case PIX_FMT_BGR444:
+                asm volatile(
+                "mov %%"REG_b", "ESP_OFFSET"(%5)        \n\t"
+                "mov        %4, %%"REG_b"               \n\t"
+                "push %%"REG_BP"                        \n\t"
+                YSCALEYUV2RGB(%%REGBP, %5)
+                /* mm2=B, %%mm4=G, %%mm5=R, %%mm7=0 */
+#ifdef DITHER1XBPP
+                "paddusb "MANGLE(b4Dither)", %%mm2      \n\t"
+                "paddusb "MANGLE(g4Dither)", %%mm4      \n\t"
+                "paddusb "MANGLE(r4Dither)", %%mm5      \n\t"
+#endif
+
+                WRITEBGR12(%%REGb, 8280(%5), %%REGBP)
+                "pop %%"REG_BP"                         \n\t"
+                "mov "ESP_OFFSET"(%5), %%"REG_b"        \n\t"
+
+                :: "c" (buf0), "d" (buf1), "S" (uvbuf0), "D" (uvbuf1), "m" (dest),
+                "a" (&c->redDither)
+                );
+                return;
             case PIX_FMT_BGR555:
                 asm volatile(
                 "mov %%"REG_b", "ESP_OFFSET"(%5)        \n\t"
@@ -1545,6 +1633,26 @@ static inline void RENAME(yuv2packed1)(S
             "a" (&c->redDither)
             );
             return;
+        case PIX_FMT_BGR444:
+            asm volatile(
+            "mov %%"REG_b", "ESP_OFFSET"(%5)        \n\t"
+            "mov        %4, %%"REG_b"               \n\t"
+            "push %%"REG_BP"                        \n\t"
+            YSCALEYUV2RGB1(%%REGBP, %5)
+            /* mm2=B, %%mm4=G, %%mm5=R, %%mm7=0 */
+#ifdef DITHER1XBPP
+            "paddusb "MANGLE(b4Dither)", %%mm2      \n\t"
+            "paddusb "MANGLE(g4Dither)", %%mm4      \n\t"
+            "paddusb "MANGLE(r4Dither)", %%mm5      \n\t"
+#endif
+            WRITEBGR12(%%REGb, 8280(%5), %%REGBP)
+            "pop %%"REG_BP"                         \n\t"
+            "mov "ESP_OFFSET"(%5), %%"REG_b"        \n\t"
+
+            :: "c" (buf0), "d" (buf1), "S" (uvbuf0), "D" (uvbuf1), "m" (dest),
+            "a" (&c->redDither)
+            );
+            return;
         case PIX_FMT_BGR555:
             asm volatile(
             "mov %%"REG_b", "ESP_OFFSET"(%5)        \n\t"
@@ -1634,6 +1742,26 @@ static inline void RENAME(yuv2packed1)(S
             "a" (&c->redDither)
             );
             return;
+        case PIX_FMT_BGR444:
+            asm volatile(
+            "mov %%"REG_b", "ESP_OFFSET"(%5)        \n\t"
+            "mov        %4, %%"REG_b"               \n\t"
+            "push %%"REG_BP"                        \n\t"
+            YSCALEYUV2RGB1b(%%REGBP, %5)
+            /* mm2=B, %%mm4=G, %%mm5=R, %%mm7=0 */
+#ifdef DITHER1XBPP
+            "paddusb "MANGLE(b4Dither)", %%mm2      \n\t"
+            "paddusb "MANGLE(g4Dither)", %%mm4      \n\t"
+            "paddusb "MANGLE(r4Dither)", %%mm5      \n\t"
+#endif
+            WRITEBGR12(%%REGb, 8280(%5), %%REGBP)
+            "pop %%"REG_BP"                         \n\t"
+            "mov "ESP_OFFSET"(%5), %%"REG_b"        \n\t"
+
+            :: "c" (buf0), "d" (buf1), "S" (uvbuf0), "D" (uvbuf1), "m" (dest),
+            "a" (&c->redDither)
+            );
+            return;
         case PIX_FMT_BGR555:
             asm volatile(
             "mov %%"REG_b", "ESP_OFFSET"(%5)        \n\t"
@@ -2145,6 +2273,43 @@ static inline void RENAME(bgr15ToUV)(uin
     }
 }
 
+static inline void RENAME(bgr12ToY)(uint8_t *dst, uint8_t *src, int width)
+{
+    int i;
+    for (i=0; i<width; i++)
+    {
+        int d= ((uint16_t*)src)[i];
+        int b= d&0x0F;
+        int g= (d>>4)&0x0F;
+        int r= (d>>8)&0x0F;
+
+        dst[i]= ((RY*r + GY*g + BY*b)>>(RGB2YUV_SHIFT-6)) + 16;
+    }
+}
+
+
+static inline void RENAME(bgr12ToUV)(uint8_t *dstU, uint8_t *dstV, uint8_t *src1, uint8_t *src2, int width)
+{
+    int i;
+    assert(src1==src2);
+    for (i=0; i<width; i++)
+    {
+        int d0= ((uint32_t*)src1)[i];
+
+        int dl= (d0&0x00F00F0F);
+        int dh= ((d0>>4)&0x00F0F00F);
+
+        int dh2= (dh>>12) + (dh<<20);
+        int d= dh2 + dl;
+
+        int b= d&0x7F;
+        int r= (d>>8)&0x7F;
+        int g= d>>20;
+        dstU[i]= ((RU*r + GU*g + BU*b)>>(RGB2YUV_SHIFT+1-6)) + 128;
+        dstV[i]= ((RV*r + GV*g + BV*b)>>(RGB2YUV_SHIFT+1-6)) + 128;
+    }
+}
+
 
 static inline void RENAME(rgb32ToY)(uint8_t *dst, uint8_t *src, int width)
 {
@@ -2272,6 +2437,39 @@ static inline void RENAME(rgb15ToUV)(uin
     }
 }
 
+static inline void RENAME(rgb12ToY)(uint8_t *dst, uint8_t *src, int width)
+{
+    int i;
+    for (i=0; i<width; i++)
+    {
+        int d= ((uint16_t*)src)[i];
+        int r= d&0x0F;
+        int g= (d>>4)&0x0F;
+        int b= (d>>8)&0x0F;
+
+        dst[i]= ((RY*r + GY*g + BY*b)>>(RGB2YUV_SHIFT-6)) + 16;
+    }
+}
+
+static inline void RENAME(rgb12ToUV)(uint8_t *dstU, uint8_t *dstV, uint8_t *src1, uint8_t *src2, int width)
+{
+    int i;
+    assert(src1 == src2);
+    for (i=0; i<width; i++)
+    {
+        int d0= ((uint32_t*)src1)[i];
+
+        int dl= (d0&0x00F00F0F);
+        int d= dl + (((d0>>16) + (d0<<16))&0x00F00F0F);
+
+        int r= d&0x3F;
+        int b= (d>>8)&0x3F;
+        int g= d>>20;
+        dstU[i]= ((RU*r + GU*g + BU*b)>>(RGB2YUV_SHIFT+1-6)) + 128;
+        dstV[i]= ((RV*r + GV*g + BV*b)>>(RGB2YUV_SHIFT+1-6)) + 128;
+    }
+}
+
 static inline void RENAME(palToY)(uint8_t *dst, uint8_t *src, int width, uint32_t *pal)
 {
     int i;
@@ -2516,6 +2714,11 @@ static inline void RENAME(hyscale)(uint1
         RENAME(bgr15ToY)(formatConvBuffer, src, srcW);
         src= formatConvBuffer;
     }
+    else if (srcFormat==PIX_FMT_BGR444)
+    {
+        RENAME(bgr12ToY)(formatConvBuffer, src, srcW);
+        src= formatConvBuffer;
+    }
     else if (srcFormat==PIX_FMT_BGR32)
     {
         RENAME(rgb32ToY)(formatConvBuffer, src, srcW);
@@ -2536,6 +2739,11 @@ static inline void RENAME(hyscale)(uint1
         RENAME(rgb15ToY)(formatConvBuffer, src, srcW);
         src= formatConvBuffer;
     }
+    else if (srcFormat==PIX_FMT_RGB444)
+    {
+        RENAME(rgb12ToY)(formatConvBuffer, src, srcW);
+        src= formatConvBuffer;
+    }
     else if (srcFormat==PIX_FMT_RGB8 || srcFormat==PIX_FMT_BGR8 || srcFormat==PIX_FMT_PAL8 || srcFormat==PIX_FMT_BGR4_BYTE  || 
srcFormat==PIX_FMT_RGB4_BYTE)
     {
         RENAME(palToY)(formatConvBuffer, src, srcW, pal);
@@ -2724,6 +2932,12 @@ inline static void RENAME(hcscale)(uint1
         src1= formatConvBuffer;
         src2= formatConvBuffer+2048;
     }
+    else if (srcFormat==PIX_FMT_BGR444)
+    {
+        RENAME(bgr12ToUV)(formatConvBuffer, formatConvBuffer+2048, src1, src2, srcW);
+        src1= formatConvBuffer;
+        src2= formatConvBuffer+2048;
+    }
     else if (srcFormat==PIX_FMT_BGR32)
     {
         RENAME(rgb32ToUV)(formatConvBuffer, formatConvBuffer+2048, src1, src2, srcW);
@@ -2748,6 +2962,12 @@ inline static void RENAME(hcscale)(uint1
         src1= formatConvBuffer;
         src2= formatConvBuffer+2048;
     }
+    else if (srcFormat==PIX_FMT_RGB444)
+    {
+        RENAME(rgb12ToUV)(formatConvBuffer, formatConvBuffer+2048, src1, src2, srcW);
+        src1= formatConvBuffer;
+        src2= formatConvBuffer+2048;
+    }
     else if (isGray(srcFormat))
     {
         return;
@@ -3128,6 +3348,9 @@ static int RENAME(swScale)(SwsContext *c
         g6Dither= dither4[dstY&1];
         g5Dither= dither8[dstY&1];
         r5Dither= dither8[(dstY+1)&1];
+        b4Dither= dither16[dstY&1];
+        g4Dither= dither16[dstY&1];
+        r4Dither= dither16[(dstY+1)&1];
 #endif
         if (dstY < dstH-2)
         {
diff -uprd MPlayer-1.0rc2/libswscale/yuv2rgb.c.orig MPlayer-1.0rc2/libswscale/yuv2rgb.c
--- MPlayer-1.0rc2/libswscale/yuv2rgb.c.orig	2007-10-07 21:49:31.000000000 +0200
+++ MPlayer-1.0rc2/libswscale/yuv2rgb.c	2010-01-14 23:46:03.000000000 +0100
@@ -59,6 +59,11 @@ const uint8_t  __attribute__((aligned(8)
 {  0,   4,   0,   4,   0,   4,   0,   4, },
 };
 
+const uint8_t  __attribute__((aligned(8))) dither_2x2_16[2][8]={
+{  6,   2,   6,   2,   6,   2,   6,   2, },
+{  0,   4,   0,   4,   0,   4,   0,   4, },
+};
+
 const uint8_t  __attribute__((aligned(8))) dither_8x8_32[8][8]={
 { 17,   9,  23,  15,  16,   8,  22,  14, },
 {  5,  29,   3,  27,   4,  28,   2,  26, },
@@ -160,6 +165,7 @@ const uint8_t  __attribute__((aligned(8)
 
 /* hope these constant values are cache line aligned */
 static uint64_t attribute_used __attribute__((aligned(8))) mmx_00ffw   = 0x00ff00ff00ff00ffULL;
+static uint64_t attribute_used __attribute__((aligned(8))) mmx_f0f0w   = 0xf0f0f0f0f0f0f0f0ULL;
 static uint64_t attribute_used __attribute__((aligned(8))) mmx_redmask = 0xf8f8f8f8f8f8f8f8ULL;
 static uint64_t attribute_used __attribute__((aligned(8))) mmx_grnmask = 0xfcfcfcfcfcfcfcfcULL;
 
@@ -173,6 +179,9 @@ static volatile uint64_t attribute_used 
 static volatile uint64_t attribute_used __attribute__((aligned(8))) g5Dither;
 static volatile uint64_t attribute_used __attribute__((aligned(8))) g6Dither;
 static volatile uint64_t attribute_used __attribute__((aligned(8))) r5Dither;
+static volatile uint64_t attribute_used __attribute__((aligned(8))) b4Dither;
+static volatile uint64_t attribute_used __attribute__((aligned(8))) g4Dither;
+static volatile uint64_t attribute_used __attribute__((aligned(8))) r4Dither;
 
 static uint64_t __attribute__((aligned(8))) dither4[2]={
     0x0103010301030103LL,
@@ -182,6 +191,10 @@ static uint64_t __attribute__((aligned(8
     0x0602060206020602LL,
     0x0004000400040004LL,};
 
+static uint64_t __attribute__((aligned(8))) dither16[2]={
+    0x0602060206020602LL,
+    0x0004000400040004LL,};
+
 #undef HAVE_MMX
 
 //MMX versions
@@ -623,6 +636,7 @@ SwsFunc yuv2rgb_get_func_ptr (SwsContext
         case PIX_FMT_BGR24:  return yuv420_rgb24_MMX2;
         case PIX_FMT_BGR565: return yuv420_rgb16_MMX2;
         case PIX_FMT_BGR555: return yuv420_rgb15_MMX2;
+        case PIX_FMT_BGR444: return yuv420_rgb12_MMX2;
         }
     }
     if (c->flags & SWS_CPU_CAPS_MMX){
@@ -631,6 +645,7 @@ SwsFunc yuv2rgb_get_func_ptr (SwsContext
         case PIX_FMT_BGR24:  return yuv420_rgb24_MMX;
         case PIX_FMT_BGR565: return yuv420_rgb16_MMX;
         case PIX_FMT_BGR555: return yuv420_rgb15_MMX;
+        case PIX_FMT_BGR444: return yuv420_rgb12_MMX;
         }
     }
 #endif
@@ -669,6 +684,8 @@ SwsFunc yuv2rgb_get_func_ptr (SwsContext
     case PIX_FMT_RGB32: return yuv2rgb_c_32;
     case PIX_FMT_RGB24: return yuv2rgb_c_24_rgb;
     case PIX_FMT_BGR24: return yuv2rgb_c_24_bgr;
+    case PIX_FMT_RGB444:
+    case PIX_FMT_BGR444:
     case PIX_FMT_RGB565:
     case PIX_FMT_BGR565:
     case PIX_FMT_RGB555:
@@ -771,6 +788,7 @@ int yuv2rgb_c_init_tables (SwsContext *c
             ((uint8_t * )table_b)[i] = table_Y[i+384];
         break;
 
+    case 12:
     case 15:
     case 16:
         table_start= table_16 = av_malloc ((197 + 2*682 + 256 + 132) * sizeof (uint16_t));
@@ -781,23 +799,23 @@ int yuv2rgb_c_init_tables (SwsContext *c
         table_g = table_16 + 197 + 2*682;
 
         for (i = -197; i < 256+197; i++) {
-            int j = table_Y[i+384] >> 3;
+            int j = table_Y[i+384] >> ((bpp==12) ? 4 : 3);
 
             if (isRgb)
-                j <<= ((bpp==16) ? 11 : 10);
+                j <<= ((bpp==16) ? 11 : ((bpp==15) ? 10 : 8));
 
             ((uint16_t *)table_r)[i] = j;
         }
         for (i = -132; i < 256+132; i++) {
-            int j = table_Y[i+384] >> ((bpp==16) ? 2 : 3);
+            int j = table_Y[i+384] >> ((bpp==16) ? 2 : ((bpp==15) ? 3 : 4));
 
-            ((uint16_t *)table_g)[i] = j << 5;
+            ((uint16_t *)table_g)[i] = j << ((bpp==12) ? 4 : 5);
         }
         for (i = -232; i < 256+232; i++) {
-            int j = table_Y[i+384] >> 3;
+            int j = table_Y[i+384] >> ((bpp==12) ? 4 : 3);
 
             if (!isRgb)
-                j <<= ((bpp==16) ? 11 : 10);
+                j <<= ((bpp==16) ? 11 : ((bpp==15) ? 10 : 8));
 
             ((uint16_t *)table_b)[i] = j;
         }
diff -uprd MPlayer-1.0rc2/libswscale/yuv2rgb_bfin.c.orig MPlayer-1.0rc2/libswscale/yuv2rgb_bfin.c
--- MPlayer-1.0rc2/libswscale/yuv2rgb_bfin.c.orig	2007-10-07 21:49:31.000000000 +0200
+++ MPlayer-1.0rc2/libswscale/yuv2rgb_bfin.c	2010-01-09 19:09:36.000000000 +0100
@@ -39,6 +39,9 @@
 
 #define L1CODE __attribute__ ((l1_text))
 
+extern void ff_bfin_yuv2rgb444_line (uint8_t *Y, uint8_t *U, uint8_t *V, uint8_t *out,
+                                     int w, uint32_t *coeffs) L1CODE;
+
 extern void ff_bfin_yuv2rgb555_line (uint8_t *Y, uint8_t *U, uint8_t *V, uint8_t *out,
                                      int w, uint32_t *coeffs) L1CODE;
 
@@ -127,6 +130,24 @@ static int core_yuv420_rgb (SwsContext *
 }
 
 
+static int bfin_yuv420_rgb444 (SwsContext *c,
+                               uint8_t **in, int *instrides,
+                               int srcSliceY, int srcSliceH,
+                               uint8_t **oplanes, int *outstrides)
+{
+    return core_yuv420_rgb (c,in,instrides,srcSliceY,srcSliceH,oplanes,outstrides,
+                            ff_bfin_yuv2rgb444_line, 1, 444);
+}
+
+static int bfin_yuv420_bgr444 (SwsContext *c,
+                               uint8_t **in, int *instrides,
+                               int srcSliceY, int srcSliceH,
+                               uint8_t **oplanes, int *outstrides)
+{
+    return core_yuv420_rgb (c,in,instrides,srcSliceY,srcSliceH,oplanes,outstrides,
+                            ff_bfin_yuv2rgb444_line, 0, 444);
+}
+
 static int bfin_yuv420_rgb555 (SwsContext *c,
                                uint8_t **in, int *instrides,
                                int srcSliceY, int srcSliceH,
@@ -187,6 +208,8 @@ SwsFunc ff_bfin_yuv2rgb_get_func_ptr (Sw
     SwsFunc f;
 
     switch(c->dstFormat) {
+    case PIX_FMT_RGB444: f = bfin_yuv420_rgb444; break;
+    case PIX_FMT_BGR444: f = bfin_yuv420_bgr444; break;
     case PIX_FMT_RGB555: f = bfin_yuv420_rgb555; break;
     case PIX_FMT_BGR555: f = bfin_yuv420_bgr555; break;
     case PIX_FMT_RGB565: f = bfin_yuv420_rgb565; break;
diff -uprd MPlayer-1.0rc2/libswscale/yuv2rgb_template.c.orig MPlayer-1.0rc2/libswscale/yuv2rgb_template.c
--- MPlayer-1.0rc2/libswscale/yuv2rgb_template.c.orig	2007-10-07 21:49:31.000000000 +0200
+++ MPlayer-1.0rc2/libswscale/yuv2rgb_template.c	2010-01-14 23:43:47.000000000 +0100
@@ -305,6 +305,92 @@ YUV2RGB
     return srcSliceH;
 }
 
+static inline int RENAME(yuv420_rgb12)(SwsContext *c, uint8_t* src[], int srcStride[], int srcSliceY,
+                                       int srcSliceH, uint8_t* dst[], int dstStride[]){
+    int y, h_size;
+
+    if(c->srcFormat == PIX_FMT_YUV422P){
+        srcStride[1] *= 2;
+        srcStride[2] *= 2;
+    }
+
+    h_size= (c->dstW+7)&~7;
+    if(h_size*2 > FFABS(dstStride[0])) h_size-=8;
+
+    __asm__ __volatile__ ("pxor %mm4, %mm4;" /* zero mm4 */ );
+    //printf("%X %X %X %X %X %X %X %X %X %X\n", (int)&c->redDither, (int)&b5Dither, (int)src[0], (int)src[1], (int)src[2], (int)dst[0],
+    //srcStride[0],srcStride[1],srcStride[2],dstStride[0]);
+    for (y= 0; y<srcSliceH; y++ ) {
+        uint8_t *image = dst[0] + (y+srcSliceY)*dstStride[0];
+        uint8_t *py = src[0] + y*srcStride[0];
+        uint8_t *pu = src[1] + (y>>1)*srcStride[1];
+        uint8_t *pv = src[2] + (y>>1)*srcStride[2];
+        long index= -h_size/2;
+
+        b4Dither= dither16[y&1];
+        g4Dither= dither16[y&1];
+        r4Dither= dither16[(y+1)&1];
+        /* this mmx assembly code deals with SINGLE scan line at a time, it convert 8
+           pixels in each iteration */
+        __asm__ __volatile__ (
+        /* load data for start of next scan line */
+        "movd    (%2, %0), %%mm0;" /* Load 4 Cb 00 00 00 00 u3 u2 u1 u0 */
+        "movd    (%3, %0), %%mm1;" /* Load 4 Cr 00 00 00 00 v3 v2 v1 v0 */
+        "movq (%5, %0, 2), %%mm6;" /* Load 8  Y Y7 Y6 Y5 Y4 Y3 Y2 Y1 Y0 */
+        //".balign 16     \n\t"
+        "1:             \n\t"
+YUV2RGB
+
+#ifdef DITHER1XBPP
+        "paddusb "MANGLE(b4Dither)", %%mm0  \n\t"
+        "paddusb "MANGLE(g4Dither)", %%mm2  \n\t"
+        "paddusb "MANGLE(r4Dither)", %%mm1  \n\t"
+#endif
+
+        /* mask unneeded bits off */
+        "pand "MANGLE(mmx_f0f0w)", %%mm0;" /* b7b6b5b4 0_0_0_0 b7b6b5b4 0_0_0_0 */
+        "pand "MANGLE(mmx_f0f0w)", %%mm2;" /* g7g6g5g4 0_0_0_0 g7g6g5g4 0_0_0_0 */
+        "pand "MANGLE(mmx_f0f0w)", %%mm1;" /* r7r6r5r4 0_0_0_0 r7r6r5r4 0_0_0_0 */
+
+        "psrlw   $4, %%mm0;" /* 0_0_0_0 b7b6b5b4 0_0_0_0 b7b6b5b4 */
+        "psrlw   $4, %%mm1;" /* 0_0_0_0 r7r6r5r4 0_0_0_0 r7r6r5r4 */
+        "pxor %%mm4, %%mm4;" /* zero mm4 */
+
+        "movq %%mm0, %%mm5;" /* Copy B7-B0 */
+        "movq %%mm2, %%mm7;" /* Copy G7-G0 */
+
+        /* convert rgb24 plane to rgb12 pack for pixel 0-3 */
+        "punpcklbw %%mm4, %%mm2;" /* 0_0_0_0 0_0_0_0 g7g6g5g4 0_0_0_0 */
+        "punpcklbw %%mm1, %%mm0;" /* 0_0_0_0 r7r6r5r4 0_0_0_0 b7b6b5b4 */
+
+        "por %%mm2, %%mm0;" /* 0_0_0_0 r7r6r5r4 g7g6g5g4 b7b6b5b4 */
+
+        "movq 8 (%5, %0, 2), %%mm6;" /* Load 8 Y Y7 Y6 Y5 Y4 Y3 Y2 Y1 Y0 */
+        MOVNTQ "      %%mm0, (%1);"  /* store pixel 0-3 */
+
+        /* convert rgb24 plane to rgb12 pack for pixel 0-3 */
+        "punpckhbw %%mm4, %%mm7;" /* 0_0_0_0 0_0_0_0 g7g6g5g4 0_0_0_0 */
+        "punpckhbw %%mm1, %%mm5;" /* 0_0_0_0 r7r6r5r4 0_0_0_0 b7b6b5b4 */
+
+        "movd 4 (%2, %0), %%mm0;" /* Load 4 Cb 00 00 00 00 u3 u2 u1 u0 */
+
+        "por       %%mm7, %%mm5;" /* 0_0_0_0 r7r6r5r4 g7g6g5g4 b7b6b5b4 */
+        "movd 4 (%3, %0), %%mm1;" /* Load 4 Cr 00 00 00 00 v3 v2 v1 v0 */
+
+        MOVNTQ " %%mm5, 8 (%1);" /* store pixel 4-7 */
+
+        "add $16, %1            \n\t"
+        "add $4, %0             \n\t"
+        " js 1b                 \n\t"
+        : "+r" (index), "+r" (image)
+        : "r" (pu - index), "r" (pv - index), "r"(&c->redDither), "r" (py - 2*index)
+        );
+    }
+
+    __asm__ __volatile__ (EMMS);
+    return srcSliceH;
+}
+
 static inline int RENAME(yuv420_rgb24)(SwsContext *c, uint8_t* src[], int srcStride[], int srcSliceY,
                                        int srcSliceH, uint8_t* dst[], int dstStride[]){
     int y, h_size;
diff -uprd MPlayer-1.0rc2/libvo/gl_common.c.orig MPlayer-1.0rc2/libvo/gl_common.c
--- MPlayer-1.0rc2/libvo/gl_common.c.orig	2007-10-07 21:49:28.000000000 +0200
+++ MPlayer-1.0rc2/libvo/gl_common.c	2010-01-09 17:42:01.000000000 +0100
@@ -200,6 +200,10 @@ int glFindFormat(uint32_t fmt, int *bpp,
       gl_type = GL_UNSIGNED_BYTE_2_3_3_REV;
       break;
 #endif
+    case IMGFMT_RGB12:
+      *gl_format = GL_RGBA;
+      *gl_type = GL_UNSIGNED_SHORT_4_4_4_4_REV;
+      break;
     case IMGFMT_RGB15:
       *gl_format = GL_RGBA;
       *gl_type = GL_UNSIGNED_SHORT_1_5_5_5_REV;
@@ -218,6 +222,10 @@ int glFindFormat(uint32_t fmt, int *bpp,
       gl_type = GL_UNSIGNED_BYTE_3_3_2;
       break;
 #endif
+    case IMGFMT_BGR12:
+      *gl_format = GL_BGRA;
+      *gl_type = GL_UNSIGNED_SHORT_4_4_4_4_REV;
+      break;
     case IMGFMT_BGR15:
       *gl_format = GL_BGRA;
       *gl_type = GL_UNSIGNED_SHORT_1_5_5_5_REV;
diff -uprd MPlayer-1.0rc2/libvo/osd.c.orig MPlayer-1.0rc2/libvo/osd.c
--- MPlayer-1.0rc2/libvo/osd.c.orig	2007-10-07 21:49:28.000000000 +0200
+++ MPlayer-1.0rc2/libvo/osd.c	2010-01-09 03:02:25.000000000 +0100
@@ -297,6 +297,38 @@ void vo_draw_alpha_init(void){
 	}
 }
 
+void vo_draw_alpha_rgb12(int w,int h, unsigned char* src, unsigned char *srca, int srcstride, unsigned char* dstbase,int dststride){
+    int y;
+    for(y=0;y<h;y++){
+        register unsigned short *dst = (unsigned short*) dstbase;
+        register int x;
+        for(x=0;x<w;x++){
+            if(srca[x]){
+#ifdef FAST_OSD
+#ifdef FAST_OSD_TABLE
+                dst[x]=fast_osd_12bpp_table[src[x]];
+#else
+		register unsigned int a=src[x]>>4;
+                dst[x]=(a<<8)|(a<<4)|a;
+#endif
+#else
+                unsigned char r=dst[x]&0x0F;
+                unsigned char g=(dst[x]>>4)&0x0F;
+                unsigned char b=(dst[x]>>8)&0x0F;
+                r=(((r*srca[x])>>4)+src[x])>>4;
+                g=(((g*srca[x])>>4)+src[x])>>4;
+                b=(((b*srca[x])>>4)+src[x])>>4;
+                dst[x]=(b<<8)|(g<<4)|r;
+#endif
+            }
+        }
+        src+=srcstride;
+        srca+=srcstride;
+        dstbase+=dststride;
+    }
+    return;
+}
+
 void vo_draw_alpha_rgb15(int w,int h, unsigned char* src, unsigned char *srca, int srcstride, unsigned char* dstbase,int dststride){
     int y;
     for(y=0;y<h;y++){
diff -uprd MPlayer-1.0rc2/libvo/osd.h.orig MPlayer-1.0rc2/libvo/osd.h
--- MPlayer-1.0rc2/libvo/osd.h.orig	2007-10-07 21:49:28.000000000 +0200
+++ MPlayer-1.0rc2/libvo/osd.h	2010-01-09 02:54:08.000000000 +0100
@@ -12,6 +12,7 @@ extern void vo_draw_alpha_yuy2(int w,int
 extern void vo_draw_alpha_uyvy(int w,int h, unsigned char* src, unsigned char *srca, int srcstride, unsigned char* dstbase,int dststride);
 extern void vo_draw_alpha_rgb24(int w,int h, unsigned char* src, unsigned char *srca, int srcstride, unsigned char* dstbase,int dststride);
 extern void vo_draw_alpha_rgb32(int w,int h, unsigned char* src, unsigned char *srca, int srcstride, unsigned char* dstbase,int dststride);
+extern void vo_draw_alpha_rgb12(int w,int h, unsigned char* src, unsigned char *srca, int srcstride, unsigned char* dstbase,int dststride);
 extern void vo_draw_alpha_rgb15(int w,int h, unsigned char* src, unsigned char *srca, int srcstride, unsigned char* dstbase,int dststride);
 extern void vo_draw_alpha_rgb16(int w,int h, unsigned char* src, unsigned char *srca, int srcstride, unsigned char* dstbase,int dststride);
 
diff -uprd MPlayer-1.0rc2/libvo/vesa_lvo.c.orig MPlayer-1.0rc2/libvo/vesa_lvo.c
--- MPlayer-1.0rc2/libvo/vesa_lvo.c.orig	2007-10-07 21:49:28.000000000 +0200
+++ MPlayer-1.0rc2/libvo/vesa_lvo.c	2010-01-09 02:53:50.000000000 +0100
@@ -97,6 +97,8 @@ int      vlvo_init(unsigned src_width,un
 	    image_bpp=16;
 	    mga_vid_config.frame_size = awidth*src_height*2;
 	    break;
+        case IMGFMT_RGB12:
+        case IMGFMT_BGR12:
         case IMGFMT_RGB15:
         case IMGFMT_BGR15:
         case IMGFMT_RGB16:
@@ -248,6 +250,10 @@ static void draw_alpha(int x0,int y0, in
 {
     uint32_t bespitch = /*(*/mga_vid_config.src_width;// + 15) & ~15;
     switch(mga_vid_config.format){
+    case IMGFMT_BGR12:
+    case IMGFMT_RGB12:
+	vo_draw_alpha_rgb12(w,h,src,srca,stride,lvo_mem+2*(y0*bespitch+x0),2*bespitch);
+	break;
     case IMGFMT_BGR15:
     case IMGFMT_RGB15:
 	vo_draw_alpha_rgb15(w,h,src,srca,stride,lvo_mem+2*(y0*bespitch+x0),2*bespitch);
diff -uprd MPlayer-1.0rc2/libvo/vo_aa.c.orig MPlayer-1.0rc2/libvo/vo_aa.c
--- MPlayer-1.0rc2/libvo/vo_aa.c.orig	2007-10-07 21:49:28.000000000 +0200
+++ MPlayer-1.0rc2/libvo/vo_aa.c	2010-01-09 03:10:55.000000000 +0100
@@ -317,6 +317,7 @@ query_format(uint32_t format) {
 	case IMGFMT_BGR32:
 	case IMGFMT_BGR24:
 	case IMGFMT_BGR16:
+	case IMGFMT_BGR12:
 	case IMGFMT_BGR15:
 	case IMGFMT_RGB32:
 	case IMGFMT_RGB24:
@@ -332,6 +333,7 @@ draw_frame(uint8_t *src[]) {
   int stride[3] = { 0 , 0 , 0 };
 
   switch(image_format) {
+  case IMGFMT_BGR12:
   case IMGFMT_BGR15:
   case IMGFMT_BGR16:
     stride[0] = src_width*2;
diff -uprd MPlayer-1.0rc2/libvo/vo_dga.c.orig MPlayer-1.0rc2/libvo/vo_dga.c
--- MPlayer-1.0rc2/libvo/vo_dga.c.orig	2007-10-07 21:49:28.000000000 +0200
+++ MPlayer-1.0rc2/libvo/vo_dga.c	2010-01-09 02:27:45.000000000 +0100
@@ -250,12 +250,16 @@ static void draw_alpha(int x0, int y0, i
             vo_draw_alpha_rgb24(w, h, src, srca, stride, d + 3 * offset,
                                 3 * buffer_stride);
             break;
+        case 16:
+            vo_draw_alpha_rgb16(w, h, src, srca, stride, d + 2 * offset,
+                                2 * buffer_stride);
+            break;
         case 15:
             vo_draw_alpha_rgb15(w, h, src, srca, stride, d + 2 * offset,
                                 2 * buffer_stride);
             break;
-        case 16:
-            vo_draw_alpha_rgb16(w, h, src, srca, stride, d + 2 * offset,
+        case 12:
+            vo_draw_alpha_rgb12(w, h, src, srca, stride, d + 2 * offset,
                                 2 * buffer_stride);
             break;
     }
diff -uprd MPlayer-1.0rc2/libvo/vo_directfb2.c.orig MPlayer-1.0rc2/libvo/vo_directfb2.c
--- MPlayer-1.0rc2/libvo/vo_directfb2.c.orig	2007-10-07 21:49:28.000000000 +0200
+++ MPlayer-1.0rc2/libvo/vo_directfb2.c	2010-01-14 23:50:38.000000000 +0100
@@ -322,9 +322,13 @@ DFBSurfacePixelFormat convformat(uint32_
 #if DIRECTFBVERSION > DFB_VERSION(0,9,15)
             case IMGFMT_RGB15: return  DSPF_ARGB1555; break;
             case IMGFMT_BGR15: return  DSPF_ARGB1555; break;
+            case IMGFMT_RGB12: return  DSPF_RGB444; break;
+            case IMGFMT_BGR12: return  DSPF_RGB444; break;
 #else
             case IMGFMT_RGB15: return  DSPF_RGB15; break;
             case IMGFMT_BGR15: return  DSPF_RGB15; break;
+            case IMGFMT_RGB12: return  DSPF_RGB12; break;
+            case IMGFMT_BGR12: return  DSPF_RGB12; break;
 #endif
             case IMGFMT_YUY2:  return  DSPF_YUY2; break;
             case IMGFMT_UYVY:  return  DSPF_UYVY; break;
@@ -544,6 +548,8 @@ static int config(uint32_t s_width, uint
     		    case IMGFMT_BGR16:
             	    case IMGFMT_RGB15:
 	    	    case IMGFMT_BGR15:
+            	    case IMGFMT_RGB12:
+	    	    case IMGFMT_BGR12:
 					params.bpp=16;
 					break;
 		    default:		params.bpp=0;
@@ -668,8 +674,10 @@ static int config(uint32_t s_width, uint
 	            case DSPF_RGB16: bpp=16;break;
 #if DIRECTFBVERSION > DFB_VERSION(0,9,15)
     		    case DSPF_ARGB1555: bpp=15;break;
+    		    case DSPF_RGB444: bpp=12;break;
 #else
         	    case DSPF_RGB15: bpp=15;break;
+        	    case DSPF_RGB12: bpp=12;break;
 #endif
 		    case DSPF_RGB332 : bpp=8;break;
 		}
@@ -681,8 +689,10 @@ static int config(uint32_t s_width, uint
 	            case DSPF_RGB16:
 #if DIRECTFBVERSION > DFB_VERSION(0,9,15)
     		    case DSPF_ARGB1555:
+    		    case DSPF_RGB444:
 #else
         	    case DSPF_RGB15:
+        	    case DSPF_RGB12:
 #endif
 		    case DSPF_RGB332:
 				    mp_msg(MSGT_VO, MSGL_INFO,"DirectFB: Trying to recover via videomode change (VM).\n");
@@ -1491,6 +1501,13 @@ static void draw_alpha(int x0, int y0, i
 #endif
                         vo_draw_alpha_rgb15(w,h,src,srca,stride,((uint8_t *) dst)+pitch*y0 + 2*x0,pitch);
                         break;
+#if DIRECTFBVERSION > DFB_VERSION(0,9,15)
+                case DSPF_RGB444:
+#else
+                case DSPF_RGB12:
+#endif
+                        vo_draw_alpha_rgb12(w,h,src,srca,stride,((uint8_t *) dst)+pitch*y0 + 2*x0,pitch);
+                        break;
 
 		case DSPF_YUY2:
     			vo_draw_alpha_yuy2(w,h,src,srca,stride,((uint8_t *) dst) + pitch*y0 + 2*x0,pitch);
diff -uprd MPlayer-1.0rc2/libvo/vo_directx.c.orig MPlayer-1.0rc2/libvo/vo_directx.c
--- MPlayer-1.0rc2/libvo/vo_directx.c.orig	2007-10-07 21:49:28.000000000 +0200
+++ MPlayer-1.0rc2/libvo/vo_directx.c	2010-01-09 02:32:31.000000000 +0100
@@ -123,6 +123,8 @@ static directx_fourcc_caps g_ddpf[] =
 	{"YUY2 ",IMGFMT_YUY2 ,0,{sizeof(DDPIXELFORMAT), DDPF_FOURCC,MAKEFOURCC('Y','U','Y','2'),0,0,0,0,0}},
 	{"UYVY ",IMGFMT_UYVY ,0,{sizeof(DDPIXELFORMAT), DDPF_FOURCC,MAKEFOURCC('U','Y','V','Y'),0,0,0,0,0}},
  	{"BGR8 ",IMGFMT_BGR8 ,0,{sizeof(DDPIXELFORMAT), DDPF_RGB, 0, 8,  0x00000000, 0x00000000, 0x00000000, 0}},   
+	{"RGB12",IMGFMT_RGB12,0,{sizeof(DDPIXELFORMAT), DDPF_RGB, 0, 16,  0x0000000F, 0x000000F0, 0x00000F00, 0}},   //RGB 4:4:4
+	{"BGR12",IMGFMT_BGR12,0,{sizeof(DDPIXELFORMAT), DDPF_RGB, 0, 16,  0x00000F00, 0x000000F0, 0x0000000F, 0}},   
 	{"RGB15",IMGFMT_RGB15,0,{sizeof(DDPIXELFORMAT), DDPF_RGB, 0, 16,  0x0000001F, 0x000003E0, 0x00007C00, 0}},   //RGB 5:5:5
 	{"BGR15",IMGFMT_BGR15,0,{sizeof(DDPIXELFORMAT), DDPF_RGB, 0, 16,  0x00007C00, 0x000003E0, 0x0000001F, 0}},   
 	{"RGB16",IMGFMT_RGB16,0,{sizeof(DDPIXELFORMAT), DDPF_RGB, 0, 16,  0x0000001F, 0x000007E0, 0x0000F800, 0}},   //RGB 5:6:5
@@ -160,6 +162,10 @@ static void draw_alpha(int x0, int y0, i
     case IMGFMT_UYVY :
         vo_draw_alpha_yuy2(w,h,src,srca,stride,((uint8_t *) image) + dstride*y0 + 2*x0 + 1,dstride);
     break;
+	case IMGFMT_RGB12:	
+    case IMGFMT_BGR12:
+		vo_draw_alpha_rgb12(w,h,src,srca,stride,((uint8_t *) image)+dstride*y0+2*x0,dstride);
+    break;
 	case IMGFMT_RGB15:	
     case IMGFMT_BGR15:
 		vo_draw_alpha_rgb15(w,h,src,srca,stride,((uint8_t *) image)+dstride*y0+2*x0,dstride);
diff -uprd MPlayer-1.0rc2/libvo/vo_fbdev.c.orig MPlayer-1.0rc2/libvo/vo_fbdev.c
--- MPlayer-1.0rc2/libvo/vo_fbdev.c.orig	2007-10-07 21:49:28.000000000 +0200
+++ MPlayer-1.0rc2/libvo/vo_fbdev.c	2010-01-09 23:26:55.000000000 +0100
@@ -503,6 +503,13 @@ static void set_bpp(struct fb_var_screen
 			p->green.offset = 5;
 			p->blue.length = 5;
 			break;
+		case 12:
+			p->red.offset = 8;
+			p->green.length = 4;
+			p->red.length = 4;
+			p->green.offset = 4;
+			p->blue.length = 4;
+			break;
 	}
 }
 
@@ -684,7 +691,7 @@ static int fb_preinit(int reset)
 	}
 
 	if (vo_dbpp) {
-		if (vo_dbpp != 15 && vo_dbpp != 16 && vo_dbpp != 24 &&
+		if (vo_dbpp != 12 && vo_dbpp != 15 && vo_dbpp != 16 && vo_dbpp != 24 &&
 				vo_dbpp != 32) {
 			mp_msg(MSGT_VO, MSGL_ERR, "can't switch to %d bpp\n", vo_dbpp);
 			goto err_out_fd;
@@ -885,6 +892,7 @@ static int config(uint32_t width, uint32
 		case 24: draw_alpha_p = vo_draw_alpha_rgb24; break;
 		case 16: draw_alpha_p = vo_draw_alpha_rgb16; break;
 		case 15: draw_alpha_p = vo_draw_alpha_rgb15; break;
+		case 12: draw_alpha_p = vo_draw_alpha_rgb12; break;
 		default: return 1;
 	}
 
diff -uprd MPlayer-1.0rc2/libvo/vo_fbdev2.c.orig MPlayer-1.0rc2/libvo/vo_fbdev2.c
--- MPlayer-1.0rc2/libvo/vo_fbdev2.c.orig	2007-10-07 21:49:28.000000000 +0200
+++ MPlayer-1.0rc2/libvo/vo_fbdev2.c	2010-01-09 23:09:43.000000000 +0100
@@ -62,6 +62,13 @@ static void set_bpp(struct fb_var_screen
 			p->green.offset = 5;
 			p->blue.length = 5;
 			break;
+		case 12:
+			p->red.offset = 8;
+			p->green.length = 4;
+			p->red.length = 4;
+			p->green.offset = 4;
+			p->blue.length = 4;
+			break;
 	}
 }
 
@@ -232,6 +239,7 @@ static int config(uint32_t width, uint32
 		case 24: draw_alpha_p = vo_draw_alpha_rgb24; break;
 		case 16: draw_alpha_p = vo_draw_alpha_rgb16; break;
 		case 15: draw_alpha_p = vo_draw_alpha_rgb15; break;
+		case 12: draw_alpha_p = vo_draw_alpha_rgb12; break;
 		default: return 1;
 	}
 
diff -uprd MPlayer-1.0rc2/libvo/vo_ggi.c.orig MPlayer-1.0rc2/libvo/vo_ggi.c
--- MPlayer-1.0rc2/libvo/vo_ggi.c.orig	2007-10-07 21:49:28.000000000 +0200
+++ MPlayer-1.0rc2/libvo/vo_ggi.c	2010-01-09 02:54:45.000000000 +0100
@@ -94,6 +94,10 @@ static void set_graphtype(uint32_t forma
     case IMGFMT_BGR8:
         mode->graphtype = GT_8BIT;
         break;
+    case IMGFMT_RGB12:
+    case IMGFMT_BGR12:
+        mode->graphtype = GT_12BIT;
+        break;
     case IMGFMT_RGB15:
     case IMGFMT_BGR15:
         mode->graphtype = GT_15BIT;
diff -uprd MPlayer-1.0rc2/libvo/vo_gl2.c.orig MPlayer-1.0rc2/libvo/vo_gl2.c
--- MPlayer-1.0rc2/libvo/vo_gl2.c.orig	2007-10-07 21:49:28.000000000 +0200
+++ MPlayer-1.0rc2/libvo/vo_gl2.c	2010-01-09 03:03:01.000000000 +0100
@@ -446,6 +446,10 @@ static void draw_alpha_15(int x0,int y0,
    vo_draw_alpha_rgb15(w,h,src,srca,stride,ImageData+2*(y0*image_width+x0),2*image_width);
 }
 
+static void draw_alpha_12(int x0,int y0, int w,int h, unsigned char* src, unsigned char *srca, int stride){
+   vo_draw_alpha_rgb12(w,h,src,srca,stride,ImageData+2*(y0*image_width+x0),2*image_width);
+}
+
 static void draw_alpha_null(int x0,int y0, int w,int h, unsigned char* src, unsigned char *srca, int stride){
 }
 
diff -uprd MPlayer-1.0rc2/libvo/vo_sdl.c.orig MPlayer-1.0rc2/libvo/vo_sdl.c
--- MPlayer-1.0rc2/libvo/vo_sdl.c.orig	2007-10-07 21:49:28.000000000 +0200
+++ MPlayer-1.0rc2/libvo/vo_sdl.c	2010-01-10 01:26:45.000000000 +0100
@@ -344,6 +344,10 @@ static void draw_alpha(int x0,int y0, in
         if(priv->dblit) {
             x0 *= priv->surface->format->BytesPerPixel;
 		switch(priv->format) {
+		case IMGFMT_RGB12:
+		case IMGFMT_BGR12:
+    			vo_draw_alpha_rgb12(w,h,src,srca,stride,((uint8_t *) 
priv->surface->pixels)+y0*priv->surface->pitch+x0,priv->surface->pitch);
+		break;
 		case IMGFMT_RGB15:
 		case IMGFMT_BGR15:
     			vo_draw_alpha_rgb15(w,h,src,srca,stride,((uint8_t *) 
priv->surface->pixels)+y0*priv->surface->pitch+x0,priv->surface->pitch);
@@ -365,6 +369,10 @@ static void draw_alpha(int x0,int y0, in
 		else {
             x0 *= priv->rgbsurface->format->BytesPerPixel;
 		switch(priv->format) {
+		case IMGFMT_RGB12:
+		case IMGFMT_BGR12:
+    			vo_draw_alpha_rgb12(w,h,src,srca,stride,((uint8_t *) 
priv->rgbsurface->pixels)+y0*priv->rgbsurface->pitch+x0,priv->rgbsurface->pitch);
+		break;
 		case IMGFMT_RGB15:
 		case IMGFMT_BGR15:
     			vo_draw_alpha_rgb15(w,h,src,srca,stride,((uint8_t *) 
priv->rgbsurface->pixels)+y0*priv->rgbsurface->pitch+x0,priv->rgbsurface->pitch);
@@ -792,12 +800,14 @@ config(uint32_t width, uint32_t height, 
 		case IMGFMT_YVYU:
             priv->mode = YUV;
             break;
+		case IMGFMT_BGR12:	
 		case IMGFMT_BGR15:	
 		case IMGFMT_BGR16:	
 		case IMGFMT_BGR24:	
 		case IMGFMT_BGR32:	
 			priv->mode = BGR;
 			break;
+        case IMGFMT_RGB12:	
         case IMGFMT_RGB15:	
         case IMGFMT_RGB16:	
         case IMGFMT_RGB24:	
@@ -967,7 +977,14 @@ static int setup_surfaces(void)
 		// 24 bit: r:ff0000 g:ff00 b:ff
 		// 16 bit: r:1111100000000000b g:0000011111100000b b:0000000000011111b
 		// 15 bit: r:111110000000000b g:000001111100000b b:000000000011111b
+		// 12 bit: r:111100000000b g:000011110000b b:000000001111b
 		// FIXME: colorkey detect based on bpp, FIXME static bpp value, FIXME alpha value correct?
+	    case IMGFMT_RGB12:
+            priv->rgbsurface = SDL_CreateRGBSurface (SDL_SRCCOLORKEY, surfwidth, surfheight, 12, 0x000F, 0x00F0, 0x0F00, 0);
+	    break;	
+	    case IMGFMT_BGR12:
+            priv->rgbsurface = SDL_CreateRGBSurface (SDL_SRCCOLORKEY, surfwidth, surfheight, 12, 0x0F00, 0x00F0, 0x000F, 0);
+	    break;	
 	    case IMGFMT_RGB15:
             priv->rgbsurface = SDL_CreateRGBSurface (SDL_SRCCOLORKEY, surfwidth, surfheight, 15, 31, 992, 31744, 0);
 	    break;	
@@ -1060,6 +1077,8 @@ static int draw_frame(uint8_t *src[])
 	    SDL_OVR_UNLOCK
             break;
 	
+	case IMGFMT_RGB12:
+	case IMGFMT_BGR12:	
 	case IMGFMT_RGB15:
 	case IMGFMT_BGR15:	
 	case IMGFMT_RGB16:
@@ -1397,6 +1416,8 @@ static void erase_rectangle(int x, int y
                 break;
         }
             
+        case IMGFMT_RGB12:
+        case IMGFMT_BGR12:
         case IMGFMT_RGB15:
         case IMGFMT_BGR15:
         case IMGFMT_RGB16:
@@ -1499,6 +1520,8 @@ static void flip_page (void)
 	struct sdl_priv_s *priv = &sdl_priv;
 
 	switch(priv->format) {
+	    case IMGFMT_RGB12:
+	    case IMGFMT_BGR12:	
 	    case IMGFMT_RGB15:
 	    case IMGFMT_BGR15:	
 	    case IMGFMT_RGB16:
@@ -1553,6 +1576,8 @@ query_format(uint32_t format)
     case IMGFMT_YVYU:
         return VFCAP_CSP_SUPPORTED | VFCAP_CSP_SUPPORTED_BY_HW | VFCAP_OSD |
             VFCAP_HWSCALE_UP | VFCAP_HWSCALE_DOWN;
+    case IMGFMT_RGB12:
+    case IMGFMT_BGR12:
     case IMGFMT_RGB15:
     case IMGFMT_BGR15:
     case IMGFMT_RGB16:
diff -uprd MPlayer-1.0rc2/libvo/vo_svga.c.orig MPlayer-1.0rc2/libvo/vo_svga.c
--- MPlayer-1.0rc2/libvo/vo_svga.c.orig	2007-10-07 21:49:28.000000000 +0200
+++ MPlayer-1.0rc2/libvo/vo_svga.c	2010-01-09 17:32:37.000000000 +0100
@@ -712,6 +712,9 @@ static void draw_alpha(int x0, int y0, i
     case 15:
       vo_draw_alpha_rgb15(w, h, src, srca, stride, base, mode_stride);
       break;
+    case 12:
+      vo_draw_alpha_rgb12(w, h, src, srca, stride, base, mode_stride);
+      break;
   }
 }
 
diff -uprd MPlayer-1.0rc2/libvo/vo_vesa.c.orig MPlayer-1.0rc2/libvo/vo_vesa.c
--- MPlayer-1.0rc2/libvo/vo_vesa.c.orig	2007-10-07 21:49:28.000000000 +0200
+++ MPlayer-1.0rc2/libvo/vo_vesa.c	2010-01-09 02:35:25.000000000 +0100
@@ -348,6 +348,19 @@ static void draw_alpha_15(int x0,int y0,
    vo_draw_alpha_rgb15(w,h,src,srca,stride,dga_buffer+2*(y0*dstride+x0),2*dstride);
 }
 
+static void draw_alpha_12(int x0,int y0, int w,int h, unsigned char* src, unsigned char *srca, int stride)
+{
+   int dstride=HAS_DGA()?video_mode_info.XResolution:dstW;
+#ifndef OSD_OUTSIDE_MOVIE
+   if(HAS_DGA())
+   {
+	x0 += x_offset;
+	y0 += y_offset;
+   }
+#endif
+   vo_draw_alpha_rgb12(w,h,src,srca,stride,dga_buffer+2*(y0*dstride+x0),2*dstride);
+}
+
 static void draw_alpha_null(int x0,int y0, int w,int h, unsigned char* src, unsigned char *srca, int stride)
 {
   UNUSED(x0);
@@ -685,6 +698,8 @@ config(uint32_t width, uint32_t height, 
 	{
 		case IMGFMT_BGR8:
 		case IMGFMT_RGB8:  bpp = 8; break;
+		case IMGFMT_BGR12:
+                case IMGFMT_RGB12: bpp = 12; break;
 		case IMGFMT_BGR15:
                 case IMGFMT_RGB15: bpp = 15; break;
 		case IMGFMT_BGR16:
@@ -700,6 +715,9 @@ config(uint32_t width, uint32_t height, 
 	if(vo_dbpp) bpp = vo_dbpp;
 	switch(bpp)
 	{
+	  case 12: draw_alpha_fnc = draw_alpha_12;
+		   dstFourcc = IMGFMT_BGR12;
+		   break;
 	  case 15: draw_alpha_fnc = draw_alpha_15;
 		   dstFourcc = IMGFMT_BGR15;
 		   break;
diff -uprd MPlayer-1.0rc2/libvo/vo_x11.c.orig MPlayer-1.0rc2/libvo/vo_x11.c
--- MPlayer-1.0rc2/libvo/vo_x11.c.orig	2007-10-07 21:49:28.000000000 +0200
+++ MPlayer-1.0rc2/libvo/vo_x11.c	2010-01-09 02:52:32.000000000 +0100
@@ -140,6 +140,14 @@ static void draw_alpha_15(int x0, int y0
                         2 * image_width);
 }
 
+static void draw_alpha_12(int x0, int y0, int w, int h, unsigned char *src,
+                          unsigned char *srca, int stride)
+{
+    vo_draw_alpha_rgb12(w, h, src, srca, stride,
+                        ImageData + 2 * (y0 * image_width + x0),
+                        2 * image_width);
+}
+
 static void draw_alpha_null(int x0, int y0, int w, int h,
                             unsigned char *src, unsigned char *srca,
                             int stride)
@@ -279,6 +287,8 @@ struct fmt2Xfmtentry_s {
   {IMGFMT_RGB8,  BO_NONNATIVE, 0x00000007, 0x00000038, 0x000000C0},
   {IMGFMT_BGR8,  BO_NATIVE,    0x000000E0, 0x0000001C, 0x00000003},
   {IMGFMT_BGR8,  BO_NONNATIVE, 0x000000E0, 0x0000001C, 0x00000003},
+  {IMGFMT_RGB12, BO_NATIVE,    0x0000000F, 0x000000F0, 0x00000F00},
+  {IMGFMT_BGR12, BO_NATIVE,    0x00000F00, 0x000000F0, 0x0000000F},
   {IMGFMT_RGB15, BO_NATIVE,    0x0000001F, 0x000003E0, 0x00007C00},
   {IMGFMT_BGR15, BO_NATIVE,    0x00007C00, 0x000003E0, 0x0000001F},
   {IMGFMT_RGB16, BO_NATIVE,    0x0000001F, 0x000007E0, 0x0000F800},
@@ -642,6 +652,8 @@ static int draw_frame(uint8_t * src[])
         stride[0] = srcW * 2;
     else if (in_format == IMGFMT_BGR8)
         stride[0] = srcW;
+    else if (in_format == IMGFMT_BGR12)
+        stride[0] = srcW * 2;
     else if (in_format == IMGFMT_BGR15)
         stride[0] = srcW * 2;
     else if (in_format == IMGFMT_BGR16)
@@ -704,6 +716,7 @@ static int query_format(uint32_t format)
     switch (format)
     {
 //   case IMGFMT_BGR8:  
+//   case IMGFMT_BGR12:
 //   case IMGFMT_BGR15:
 //   case IMGFMT_BGR16:
 //   case IMGFMT_BGR24:
diff -uprd MPlayer-1.0rc2/libvo/vosub_vidix.c.orig MPlayer-1.0rc2/libvo/vosub_vidix.c
--- MPlayer-1.0rc2/libvo/vosub_vidix.c.orig	2007-10-07 21:49:28.000000000 +0200
+++ MPlayer-1.0rc2/libvo/vosub_vidix.c	2010-01-09 02:55:26.000000000 +0100
@@ -321,6 +321,11 @@ static void draw_alpha(int x0,int y0, in
 	bespitch = (vidix_play.src.w*2 + apitch) & (~apitch);
 	vo_draw_alpha_rgb15(w,h,src,srca,stride,lvo_mem+y0*bespitch+2*x0,bespitch);
         break;
+    case IMGFMT_RGB12:
+    case IMGFMT_BGR12:
+	bespitch = (vidix_play.src.w*2 + apitch) & (~apitch);
+	vo_draw_alpha_rgb12(w,h,src,srca,stride,lvo_mem+y0*bespitch+2*x0,bespitch);
+        break;
     default:
 	return;
     }
diff -uprd MPlayer-1.0rc2/loader/dmo/DMO_VideoDecoder.c.orig MPlayer-1.0rc2/loader/dmo/DMO_VideoDecoder.c
--- MPlayer-1.0rc2/loader/dmo/DMO_VideoDecoder.c.orig	2007-10-07 21:49:32.000000000 +0200
+++ MPlayer-1.0rc2/loader/dmo/DMO_VideoDecoder.c	2010-01-09 18:23:56.000000000 +0100
@@ -73,6 +73,7 @@ static ct check[] = {
     { fccIYUV, 24, &MEDIASUBTYPE_IYUV,   CAP_IYUV, NULL     },
 
     {       8,  8, &MEDIASUBTYPE_RGB8,   CAP_NONE, "RGB8"   },
+    {      12, 16, &MEDIASUBTYPE_RGB444, CAP_NONE, "RGB444" },
     {      15, 16, &MEDIASUBTYPE_RGB555, CAP_NONE, "RGB555" },
     {      16, 16, &MEDIASUBTYPE_RGB565, CAP_NONE, "RGB565" },
     {      24, 24, &MEDIASUBTYPE_RGB24,  CAP_NONE, "RGB24"  },
@@ -376,6 +377,9 @@ int DMO_VideoDecoder_SetDestFmt(DMO_Vide
 
 	switch (bits)
         {
+	case 12:
+	    this->m_sDestType.subtype = MEDIASUBTYPE_RGB444;
+    	    break;
 	case 15:
 	    this->m_sDestType.subtype = MEDIASUBTYPE_RGB555;
     	    break;
diff -uprd MPlayer-1.0rc2/loader/dshow/DS_VideoDecoder.c.orig MPlayer-1.0rc2/loader/dshow/DS_VideoDecoder.c
--- MPlayer-1.0rc2/loader/dshow/DS_VideoDecoder.c.orig	2007-10-07 21:49:32.000000000 +0200
+++ MPlayer-1.0rc2/loader/dshow/DS_VideoDecoder.c	2010-01-14 23:53:35.000000000 +0100
@@ -423,6 +423,9 @@ int DS_VideoDecoder_SetDestFmt(DS_VideoD
 
 	switch (bits)
         {
+	case 12:
+	    this->m_sDestType.subtype = MEDIASUBTYPE_RGB444;
+    	    break;
 	case 15:
 	    this->m_sDestType.subtype = MEDIASUBTYPE_RGB555;
     	    break;
diff -uprd MPlayer-1.0rc2/loader/dshow/guids.c.orig MPlayer-1.0rc2/loader/dshow/guids.c
--- MPlayer-1.0rc2/loader/dshow/guids.c.orig	2007-10-07 21:49:32.000000000 +0200
+++ MPlayer-1.0rc2/loader/dshow/guids.c	2010-01-09 18:26:08.000000000 +0100
@@ -36,6 +36,8 @@ const GUID MEDIASUBTYPE_RGB565={0xe436eb
     {0x9f, 0x53, 0x00, 0x20, 0xaf, 0x0b, 0xa7, 0x70}};
 const GUID MEDIASUBTYPE_RGB555={0xe436eb7c, 0x524f, 0x11ce,
     {0x9f, 0x53, 0x00, 0x20, 0xaf, 0x0b, 0xa7, 0x70}};
+const GUID MEDIASUBTYPE_RGB444={0xe436eb7c, 0x524f, 0x11ce,
+    {0x9f, 0x53, 0x00, 0x20, 0xaf, 0x0b, 0xa7, 0x70}};
 const GUID MEDIASUBTYPE_RGB24={0xe436eb7d, 0x524f, 0x11ce,
     {0x9f, 0x53, 0x00, 0x20, 0xaf, 0x0b, 0xa7, 0x70}};
 const GUID MEDIASUBTYPE_RGB32={0xe436eb7e, 0x524f, 0x11ce,
diff -uprd MPlayer-1.0rc2/loader/dshow/guids.h.orig MPlayer-1.0rc2/loader/dshow/guids.h
--- MPlayer-1.0rc2/loader/dshow/guids.h.orig	2007-10-07 21:49:32.000000000 +0200
+++ MPlayer-1.0rc2/loader/dshow/guids.h	2010-01-09 18:24:38.000000000 +0100
@@ -63,6 +63,7 @@ extern const GUID MEDIASUBTYPE_RGB4;
 extern const GUID MEDIASUBTYPE_RGB8;
 extern const GUID MEDIASUBTYPE_RGB565;
 extern const GUID MEDIASUBTYPE_RGB555;
+extern const GUID MEDIASUBTYPE_RGB444;
 extern const GUID MEDIASUBTYPE_RGB24;
 extern const GUID MEDIASUBTYPE_RGB32;
 extern const GUID MEDIASUBTYPE_YUYV;
diff -uprd MPlayer-1.0rc2/m_option.c.orig MPlayer-1.0rc2/m_option.c
--- MPlayer-1.0rc2/m_option.c.orig	2007-10-07 21:49:33.000000000 +0200
+++ MPlayer-1.0rc2/m_option.c	2010-01-09 17:03:02.000000000 +0100
@@ -1033,6 +1033,7 @@ static struct {
   {"bgr32", IMGFMT_BGR32},
   {"bgr16", IMGFMT_BGR16},
   {"bgr15", IMGFMT_BGR15},
+  {"bgr12", IMGFMT_BGR12},
   {"bgr8", IMGFMT_BGR8},
   {"bgr4", IMGFMT_BGR4},
   {"bg4b", IMGFMT_BG4B},
@@ -1041,6 +1042,7 @@ static struct {
   {"rgb32", IMGFMT_RGB32},
   {"rgb16", IMGFMT_RGB16},
   {"rgb15", IMGFMT_RGB15},
+  {"rgb12", IMGFMT_RGB12},
   {"rgb8", IMGFMT_RGB8},
   {"rgb4", IMGFMT_RGB4},
   {"rg4b", IMGFMT_RG4B},
diff -uprd MPlayer-1.0rc2/stream/tv.c.orig MPlayer-1.0rc2/stream/tv.c
--- MPlayer-1.0rc2/stream/tv.c.orig	2007-10-07 21:49:26.000000000 +0200
+++ MPlayer-1.0rc2/stream/tv.c	2010-01-09 16:55:29.000000000 +0100
@@ -321,6 +321,7 @@ static int open_tv(tvi_handle_t *tvh)
       IMGFMT_RGB24,
       IMGFMT_RGB16,
       IMGFMT_RGB15
+      IMGFMT_RGB12
     };
 
     if (funcs->control(tvh->priv, TVI_CONTROL_IS_VIDEO, 0) != TVI_CONTROL_TRUE)
@@ -351,6 +352,7 @@ static int open_tv(tvi_handle_t *tvh)
 	case IMGFMT_BGR24:
 	case IMGFMT_BGR16:
 	case IMGFMT_BGR15:
+	case IMGFMT_BGR12:
 	    break;
 	default:
 	    mp_msg(MSGT_TV, MSGL_ERR, MSGTR_TV_UnknownImageFormat,tvh->tv_param->outfmt);
diff -uprd MPlayer-1.0rc2/stream/tvi_v4l.c.orig MPlayer-1.0rc2/stream/tvi_v4l.c
--- MPlayer-1.0rc2/stream/tvi_v4l.c.orig	2007-10-07 21:49:26.000000000 +0200
+++ MPlayer-1.0rc2/stream/tvi_v4l.c	2010-01-09 20:56:46.000000000 +0100
@@ -163,7 +163,7 @@ static const char *device_cap2name[] = {
 };
 
 static const char *device_palette2name[] = {
-    "-", "grey", "hi240", "rgb16", "rgb24", "rgb32", "rgb15", "yuv422",
+    "-", "grey", "hi240", "rgb16", "rgb24", "rgb32", "rgb12", "rgb15", "yuv422",
     "yuyv", "uyvy", "yuv420", "yuv411", "raw", "yuv422p", "yuv411p",
     "yuv420p", "yuv410p"
 };
@@ -209,6 +209,8 @@ static int palette2depth(int palette)
     switch(palette)
     {
         /* component */
+        case VIDEO_PALETTE_RGB444:
+            return(12);
         case VIDEO_PALETTE_RGB555:
             return(15);
         case VIDEO_PALETTE_RGB565:
@@ -238,6 +240,8 @@ static int format2palette(int format)
 {
     switch(format)
     {
+        case IMGFMT_BGR12:
+            return(VIDEO_PALETTE_RGB444);
         case IMGFMT_BGR15:
             return(VIDEO_PALETTE_RGB555);
         case IMGFMT_BGR16:
@@ -899,7 +903,7 @@ static int start(priv_t *priv)
     priv->picture.palette = format2palette(priv->format);
     priv->picture.depth = palette2depth(priv->picture.palette);
 
-    if (priv->format != IMGFMT_BGR15) {
+    if ((priv->format != IMGFMT_BGR12) && (priv->format != IMGFMT_BGR15)) {
         priv->bytesperline = priv->width * priv->picture.depth / 8;
     } else {
         priv->bytesperline = priv->width * 2;
diff -uprd MPlayer-1.0rc2/stream/tvi_v4l2.c.orig MPlayer-1.0rc2/stream/tvi_v4l2.c
--- MPlayer-1.0rc2/stream/tvi_v4l2.c.orig	2007-10-07 21:49:26.000000000 +0200
+++ MPlayer-1.0rc2/stream/tvi_v4l2.c	2010-01-09 20:55:54.000000000 +0100
@@ -169,6 +169,7 @@ static void *video_grabber(void *data);
     This may be an useful translation table for some others:
 
     IMGFMT_RGB8  == V4L2_PIX_FMT_RGB332
+    IMGFMT_BGR12 == V4L2_PIX_FMT_RGB444
     IMGFMT_BGR15 == V4L2_PIX_FMT_RGB555
     IMGFMT_BGR16 == V4L2_PIX_FMT_RGB565
     IMGFMT_RGB24 == V4L2_PIX_FMT_RGB24
@@ -189,6 +190,7 @@ static int fcc_mp2vl(int fcc)
 {
     switch (fcc) {
     case IMGFMT_RGB8:   return V4L2_PIX_FMT_RGB332;
+    case IMGFMT_BGR12:  return V4L2_PIX_FMT_RGB444;
     case IMGFMT_BGR15:  return V4L2_PIX_FMT_RGB555;
     case IMGFMT_BGR16:  return V4L2_PIX_FMT_RGB565;
     case IMGFMT_RGB24:  return V4L2_PIX_FMT_RGB24;
@@ -213,6 +215,7 @@ static int fcc_vl2mp(int fcc)
 {
     switch (fcc) {
     case V4L2_PIX_FMT_RGB332:   return IMGFMT_RGB8;
+    case V4L2_PIX_FMT_RGB444:   return IMGFMT_BGR12;
     case V4L2_PIX_FMT_RGB555:   return IMGFMT_BGR15;
     case V4L2_PIX_FMT_RGB565:   return IMGFMT_BGR16;
     case V4L2_PIX_FMT_RGB24:    return IMGFMT_RGB24;
@@ -240,6 +243,7 @@ static const char *pixfmt2name(int pixfm
 
     switch (pixfmt) {
     case V4L2_PIX_FMT_RGB332:       return "RGB332";
+    case V4L2_PIX_FMT_RGB444:       return "RGB444";
     case V4L2_PIX_FMT_RGB555:       return "RGB555";
     case V4L2_PIX_FMT_RGB565:       return "RGB565";
     case V4L2_PIX_FMT_RGB555X:      return "RGB555X";
@@ -280,6 +284,7 @@ static int pixfmt2depth(int pixfmt)
     switch (pixfmt) {
     case V4L2_PIX_FMT_RGB332:
         return 8;
+    case V4L2_PIX_FMT_RGB444:
     case V4L2_PIX_FMT_RGB555:
     case V4L2_PIX_FMT_RGB565:
     case V4L2_PIX_FMT_RGB555X:



More information about the MPlayer-dev-eng mailing list