Subject: [E3-hacking] [PATCH v3] mplayer: add support for 12-bit color mode on framebuffer devices

From: Janusz Krzysztofik <[email-masked]>
Date: Fri, 16 Apr 2010 22:12:04 +0200

The patch extends mplayer with RGB12 aka RGB444 output pixel format handling,
limited to framebuffer devices. Both fbdev and fbdev2 as well as directdb 
video output drivers are supoorted. The fbdev/fbdev2 drivers work best, 
automatically selecting required color conversion filters. The directfb driver 
works correctly for me if I call mplayer with "-vf format=bgr12" option 
specified.

Created and tested against mplayer svn revision 31038.
Tested on omapfb framebuffer device with Amstrad Delta 12-bit LCD display.

Signed-off-by: Janusz Krzysztofik <[email-masked]>
---

Hi,

Still not being able to find enough spare time to test 12-bit related changes 
to sdl and x11 vo drivers, I decided to submit the patch without them for now.

I assumed that my few suggestions that hadn't been answered were acceptable.

I'm going to refresh, test and submit all dropped bits (ie. remaining vo 
drivers as well as codecs related) sooner or later.

Thanks,
Janusz

v2 changes:
- drop ffmpeg related bits, they don't belog here, parts of them have already 
  been included in the ffmpeg svn,
- drop codecs related changes till ffmpeg support is complete.
v3 changes:
- drop untested sdl and x11 vo drivers changes,
- replace tabs with spaces, except where pure tabs were consequently used in 
  the original code,
- break overly long lines,
- a few other cosmetic cleanups.

 fmt-conversion.c            |    4 ++++
 libmenu/menu.c              |    3 +++
 libmpcodecs/img_format.c    |    2 ++
 libmpcodecs/img_format.h    |   10 ++++++++++
 libmpcodecs/vf_1bpp.c       |    6 ++++++
 libmpcodecs/vf_expand.c     |    4 ++++
 libmpcodecs/vf_rgbtest.c    |    8 ++++++++
 libmpcodecs/vf_scale.c      |    2 ++
 libmpcodecs/vf_screenshot.c |    1 +
 libmpcodecs/vf_tile.c       |    8 +++++---
 libvo/osd.c                 |   33 +++++++++++++++++++++++++++++++++
 libvo/osd.h                 |    2 ++
 libvo/vo_directfb2.c        |   19 +++++++++++++++++++
 libvo/vo_fbdev.c            |   13 ++++++++++++-
 libvo/vo_fbdev2.c           |    8 ++++++++
 m_option.c                  |    2 ++
 16 files changed, 121 insertions(+), 4 deletions(-)

diff -uprN trunk.orig/fmt-conversion.c trunk/fmt-conversion.c
--- trunk.orig/fmt-conversion.c	2010-02-26 02:41:08.000000000 +0100
+++ trunk/fmt-conversion.c	2010-04-16 01:54:38.000000000 +0200
@@ -32,6 +32,8 @@ static const struct {
     {IMGFMT_BGR16LE, PIX_FMT_RGB565LE},
     {IMGFMT_BGR15BE, PIX_FMT_RGB555BE},
     {IMGFMT_BGR15LE, PIX_FMT_RGB555LE},
+    {IMGFMT_BGR12BE, PIX_FMT_RGB444BE},
+    {IMGFMT_BGR12LE, PIX_FMT_RGB444LE},
     {IMGFMT_BGR8,  PIX_FMT_RGB8},
     {IMGFMT_BGR4,  PIX_FMT_RGB4},
     {IMGFMT_BGR1,  PIX_FMT_MONOBLACK},
@@ -47,6 +49,8 @@ static const struct {
     {IMGFMT_RGB16LE, PIX_FMT_BGR565LE},
     {IMGFMT_RGB15BE, PIX_FMT_BGR555BE},
     {IMGFMT_RGB15LE, PIX_FMT_BGR555LE},
+    {IMGFMT_RGB12BE, PIX_FMT_BGR444BE},
+    {IMGFMT_RGB12LE, PIX_FMT_BGR444LE},
     {IMGFMT_RGB8,  PIX_FMT_BGR8},
     {IMGFMT_RGB4,  PIX_FMT_BGR4},
     {IMGFMT_BGR8,  PIX_FMT_PAL8},
diff -uprN trunk.orig/libmenu/menu.c trunk/libmenu/menu.c
--- trunk.orig/libmenu/menu.c	2010-02-26 02:40:48.000000000 +0100
+++ trunk/libmenu/menu.c	2010-04-16 01:54:38.000000000 +0200
@@ -376,6 +376,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 -uprN trunk.orig/libmpcodecs/img_format.c trunk/libmpcodecs/img_format.c
--- trunk.orig/libmpcodecs/img_format.c	2010-02-26 02:39:48.000000000 +0100
+++ trunk/libmpcodecs/img_format.c	2010-04-16 01:54:38.000000000 +0200
@@ -29,6 +29,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";
@@ -39,6 +40,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 -uprN trunk.orig/libmpcodecs/img_format.h trunk/libmpcodecs/img_format.h
--- trunk.orig/libmpcodecs/img_format.h	2010-02-26 02:39:48.000000000 +0100
+++ trunk/libmpcodecs/img_format.h	2010-04-16 01:54:38.000000000 +0200
@@ -29,6 +29,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)
@@ -42,6 +43,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)
@@ -53,10 +55,14 @@
 #define IMGFMT_ARGB IMGFMT_BGR32
 #define IMGFMT_RGBA (IMGFMT_BGR32|64)
 #define IMGFMT_RGB48NE IMGFMT_RGB48BE
+#define IMGFMT_RGB12BE IMGFMT_RGB12
+#define IMGFMT_RGB12LE (IMGFMT_RGB12|64)
 #define IMGFMT_RGB15BE IMGFMT_RGB15
 #define IMGFMT_RGB15LE (IMGFMT_RGB15|64)
 #define IMGFMT_RGB16BE IMGFMT_RGB16
 #define IMGFMT_RGB16LE (IMGFMT_RGB16|64)
+#define IMGFMT_BGR12BE IMGFMT_BGR12
+#define IMGFMT_BGR12LE (IMGFMT_BGR12|64)
 #define IMGFMT_BGR15BE IMGFMT_BGR15
 #define IMGFMT_BGR15LE (IMGFMT_BGR15|64)
 #define IMGFMT_BGR16BE IMGFMT_BGR16
@@ -67,10 +73,14 @@
 #define IMGFMT_ARGB (IMGFMT_RGB32|64)
 #define IMGFMT_RGBA IMGFMT_RGB32
 #define IMGFMT_RGB48NE IMGFMT_RGB48LE
+#define IMGFMT_RGB12BE (IMGFMT_RGB12|64)
+#define IMGFMT_RGB12LE IMGFMT_RGB12
 #define IMGFMT_RGB15BE (IMGFMT_RGB15|64)
 #define IMGFMT_RGB15LE IMGFMT_RGB15
 #define IMGFMT_RGB16BE (IMGFMT_RGB16|64)
 #define IMGFMT_RGB16LE IMGFMT_RGB16
+#define IMGFMT_BGR12BE (IMGFMT_BGR12|64)
+#define IMGFMT_BGR12LE IMGFMT_BGR12
 #define IMGFMT_BGR15BE (IMGFMT_BGR15|64)
 #define IMGFMT_BGR15LE IMGFMT_BGR15
 #define IMGFMT_BGR16BE (IMGFMT_BGR16|64)
diff -uprN trunk.orig/libmpcodecs/vf_1bpp.c trunk/libmpcodecs/vf_1bpp.c
--- trunk.orig/libmpcodecs/vf_1bpp.c	2010-02-26 02:39:43.000000000 +0100
+++ trunk/libmpcodecs/vf_1bpp.c	2010-04-16 01:54:38.000000000 +0200
@@ -45,6 +45,8 @@ static const unsigned int bgr_list[]={
     IMGFMT_444P,
 
     IMGFMT_YUY2,
+    IMGFMT_BGR12,
+    IMGFMT_RGB12,
     IMGFMT_BGR15,
     IMGFMT_RGB15,
     IMGFMT_BGR16,
@@ -150,6 +152,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 -uprN trunk.orig/libmpcodecs/vf_expand.c trunk/libmpcodecs/vf_expand.c
--- trunk.orig/libmpcodecs/vf_expand.c	2010-02-26 02:39:46.000000000 +0100
+++ trunk/libmpcodecs/vf_expand.c	2010-04-16 01:54:38.000000000 +0200
@@ -146,6 +146,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 -uprN trunk.orig/libmpcodecs/vf_rgbtest.c trunk/libmpcodecs/vf_rgbtest.c
--- trunk.orig/libmpcodecs/vf_rgbtest.c	2010-02-26 02:39:50.000000000 +0100
+++ trunk/libmpcodecs/vf_rgbtest.c	2010-04-16 01:54:38.000000000 +0200
@@ -37,11 +37,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:
@@ -54,6 +56,12 @@ 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 -uprN trunk.orig/libmpcodecs/vf_scale.c trunk/libmpcodecs/vf_scale.c
--- trunk.orig/libmpcodecs/vf_scale.c	2010-04-15 20:52:54.000000000 +0200
+++ trunk/libmpcodecs/vf_scale.c	2010-04-16 01:54:38.000000000 +0200
@@ -96,6 +96,8 @@ static const unsigned int outfmt_list[]=
     IMGFMT_RGB16,
     IMGFMT_BGR15,
     IMGFMT_RGB15,
+    IMGFMT_BGR12,
+    IMGFMT_RGB12,
     IMGFMT_Y800,
     IMGFMT_Y8,
     IMGFMT_BGR8,
diff -uprN trunk.orig/libmpcodecs/vf_screenshot.c trunk/libmpcodecs/vf_screenshot.c
--- trunk.orig/libmpcodecs/vf_screenshot.c	2010-02-26 02:39:43.000000000 +0100
+++ trunk/libmpcodecs/vf_screenshot.c	2010-04-16 01:54:38.000000000 +0200
@@ -258,6 +258,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 -uprN trunk.orig/libmpcodecs/vf_tile.c trunk/libmpcodecs/vf_tile.c
--- trunk.orig/libmpcodecs/vf_tile.c	2010-02-26 02:39:46.000000000 +0100
+++ trunk/libmpcodecs/vf_tile.c	2010-04-16 01:54:38.000000000 +0200
@@ -198,16 +198,18 @@ static void uninit(struct vf_instance *v
     free(vf->priv);
 }
 
-/* rgb/bgr 15->32 supported & some Yxxx */
+/* rgb/bgr 12...32 supported & some Yxxx */
 static int query_format(struct vf_instance *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:
diff -uprN trunk.orig/libvo/osd.c trunk/libvo/osd.c
--- trunk.orig/libvo/osd.c	2010-02-26 02:40:23.000000000 +0100
+++ trunk/libvo/osd.c	2010-04-16 01:54:38.000000000 +0200
@@ -329,6 +329,39 @@ 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 -uprN trunk.orig/libvo/osd.h trunk/libvo/osd.h
--- trunk.orig/libvo/osd.h	2010-02-26 02:40:23.000000000 +0100
+++ trunk/libvo/osd.h	2010-04-16 01:54:38.000000000 +0200
@@ -29,6 +29,8 @@ void vo_draw_alpha_yuy2(int w,  int h, u
 void vo_draw_alpha_uyvy(int w,  int h, unsigned char* src, unsigned char *srca, int srcstride, unsigned char* dstbase, int dststride);
 void vo_draw_alpha_rgb24(int w, int h, unsigned char* src, unsigned char *srca, int srcstride, unsigned char* dstbase, int dststride);
 void vo_draw_alpha_rgb32(int w, int h, unsigned char* src, unsigned char *srca, int srcstride, unsigned char* dstbase, int dststride);
+void vo_draw_alpha_rgb12(int w, int h, unsigned char* src, unsigned char *srca,
+                         int srcstride, unsigned char* dstbase, int dststride);
 void vo_draw_alpha_rgb15(int w, int h, unsigned char* src, unsigned char *srca, int srcstride, unsigned char* dstbase, int dststride);
 void vo_draw_alpha_rgb16(int w, int h, unsigned char* src, unsigned char *srca, int srcstride, unsigned char* dstbase, int dststride);
 
diff -uprN trunk.orig/libvo/vo_directfb2.c trunk/libvo/vo_directfb2.c
--- trunk.orig/libvo/vo_directfb2.c	2010-02-26 02:40:25.000000000 +0100
+++ trunk/libvo/vo_directfb2.c	2010-04-16 01:54:38.000000000 +0200
@@ -324,9 +324,13 @@ static DFBSurfacePixelFormat convformat(
 #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_ARGB4444; break;
+            case IMGFMT_BGR12: return  DSPF_ARGB4444; 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;
@@ -547,6 +551,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;
@@ -671,8 +677,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_ARGB4444: bpp=12; break;
 #else
         	    case DSPF_RGB15: bpp=15;break;
+                    case DSPF_RGB12: bpp=12; break;
 #endif
 		    case DSPF_RGB332 : bpp=8;break;
 		}
@@ -684,8 +692,10 @@ static int config(uint32_t s_width, uint
 	            case DSPF_RGB16:
 #if DIRECTFBVERSION > DFB_VERSION(0,9,15)
     		    case DSPF_ARGB1555:
+                    case DSPF_ARGB4444:
 #else
         	    case DSPF_RGB15:
+                    case DSPF_RGB12:
 #endif
 		    case DSPF_RGB332:
 				    mp_msg(MSGT_VO, MSGL_V,"DirectFB: Trying to recover via videomode change (VM).\n");
@@ -1493,6 +1503,15 @@ 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_ARGB4444:
+#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 -uprN trunk.orig/libvo/vo_fbdev.c trunk/libvo/vo_fbdev.c
--- trunk.orig/libvo/vo_fbdev.c	2010-03-18 21:43:44.000000000 +0100
+++ trunk/libvo/vo_fbdev.c	2010-04-16 01:54:38.000000000 +0200
@@ -521,6 +521,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;
     }
 }
 
@@ -700,7 +707,8 @@ static int fb_preinit(int reset)
     }
 
     if (vo_dbpp) {
-        if (vo_dbpp != 15 && vo_dbpp != 16 && vo_dbpp != 24 && vo_dbpp != 32) {
+        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;
         }
@@ -850,6 +858,9 @@ static int config(uint32_t width, uint32
     case 15:
         draw_alpha_p = vo_draw_alpha_rgb15;
         break;
+    case 12:
+        draw_alpha_p = vo_draw_alpha_rgb12;
+        break;
     default:
         return 1;
     }
diff -uprN trunk.orig/libvo/vo_fbdev2.c trunk/libvo/vo_fbdev2.c
--- trunk.orig/libvo/vo_fbdev2.c	2010-03-05 16:07:05.000000000 +0100
+++ trunk/libvo/vo_fbdev2.c	2010-04-16 01:54:38.000000000 +0200
@@ -77,6 +77,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;
 	}
 }
 
@@ -247,6 +254,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 -uprN trunk.orig/m_option.c trunk/m_option.c
--- trunk.orig/m_option.c	2010-03-05 16:07:13.000000000 +0100
+++ trunk/m_option.c	2010-04-16 01:54:38.000000000 +0200
@@ -1080,6 +1080,7 @@ static struct {
   {"bgr32", IMGFMT_BGR32},
   {"bgr16", IMGFMT_BGR16},
   {"bgr15", IMGFMT_BGR15},
+  {"bgr12", IMGFMT_BGR12},
   {"bgr8", IMGFMT_BGR8},
   {"bgr4", IMGFMT_BGR4},
   {"bg4b", IMGFMT_BG4B},
@@ -1091,6 +1092,7 @@ static struct {
   {"rgb32", IMGFMT_RGB32},
   {"rgb16", IMGFMT_RGB16},
   {"rgb15", IMGFMT_RGB15},
+  {"rgb12", IMGFMT_RGB12},
   {"rgb8", IMGFMT_RGB8},
   {"rgb4", IMGFMT_RGB4},
   {"rg4b", IMGFMT_RG4B},

---

From: Janusz Krzysztofik <[email-masked]>
Date: Tue, 4 May 2010 13:24:54 +0200

Hi,

I'm not sure if there is still something wrong with this patch. If so, could 
you, mplayer maintainers, please give your comments for me to have a chance to 
correct it?

Thanks,
Janusz

----------  Original message  ----------

Subject: [PATCH v3] mplayer: add support for 12-bit color mode on framebuffer devices
Date: 2010-04-16
From: Janusz Krzysztofik <[email-masked]>
To: [email-masked]

Hi,

Thanks,
Janusz

v2 changes:

 
 
     IMGFMT_YUY2,
+    IMGFMT_BGR12,
+    IMGFMT_RGB12,
     IMGFMT_BGR15,
     IMGFMT_RGB15,
     IMGFMT_BGR16,

 

 
 		case DSPF_YUY2:

     if (vo_dbpp) {

-------------------------------------------------------