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

Janusz Krzysztofik jkrzyszt at tis.icnet.pl
Sat Apr 3 15:55:10 BST 2010


Saturday 03 April 2010 10:54:54 Diego Biurrun wrote:
> On Fri, Mar 19, 2010 at 01:52:42AM +0100, Janusz Krzysztofik wrote:
> > The patch extends 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 wasn't able to get correct
> > results using sdl, neither with qtopia (incorrect collors) nor fbcon (not
> > working at all) drivers. I haven't tested the x11 output driver
> > modifications.
>
> If you give detailed testing instructions, perhaps somebody else can.

Hi Diego,
First, you need a hardware that supports 12-bit graphics mode, I guess. I'm 
not aware of any such machines/graphics adapters except for Amstrad E3 
(Delta), but I may be wrong.

I use a highly customized, OpenEmbedded genrated system based on Angstrom 
distribution, with no stable configuration ready to provide yet. To prepare 
instructions on how SDL or X could be get working on it, I'd in fact spend my 
time on testing it myself.

E3-hacking guys,
I know they don't like cross-posting on the mplayer-dev-eng, but I'm CCing 
you (should probably do it already before) in hope someone who runs Debian 
with X on his E3 can do some testing, please. For best results, please use 
linux-2.6.34-rcX if you can, or try my 12-bit support fix, already mnetioned 
on the e3-hacking before[1]. Below you can find links to this mplayer patch 
submission message copy[2] and pending discussion[3] (you may have a look at 
date/thread indexes for completness since threads tend to get broken on month 
boundaries). I also resubmit the patch (unchanged) for your convenience.

> > --- trunk.orig/libvo/osd.c	2010-02-26 02:40:23.000000000 +0100
> > +++ trunk/libvo/osd.c	2010-03-19 01:01:29.000000000 +0100
> > @@ -329,6 +329,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){
> > +} 
> > +
> >  void vo_draw_alpha_rgb15(int w,int h, unsigned char* src, unsigned char
> > *srca, int srcstride, unsigned char* dstbase,int dststride){
>
> vo_draw_alpha_rgb12() looks very similar to vo_draw_alpha_rgb15() and
> vo_draw_alpha_rgb16().  Ideally this should be refactored in some way.

Sounds like better being addressed by a separate patch. Can I revisit it 
later, when finished with this one?

> > --- trunk.orig/libvo/vo_fbdev.c	2010-03-18 21:43:44.000000000 +0100
> > +++ trunk/libvo/vo_fbdev.c	2010-03-19 01:01:29.000000000 +0100
> > @@ -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;
>
> Please keep the = vertically aligned like the surrounding code does.

OK.

> > @@ -700,7 +707,7 @@ 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) {
>
> Please break overly long lines.

OK.

Thanks,
Janusz

[1] http://patchwork.kernel.org/patch/72933/
[2] http://lists.mplayerhq.hu/pipermail/mplayer-dev-eng/2010-March/064116.html
[3] http://lists.mplayerhq.hu/pipermail/mplayer-dev-eng/2010-April/064198.html

Signed-off-by: Janusz Krzysztofik <jkrzyszt at tis.icnet.pl>
---
diff -upr 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-03-19 01:01:29.000000000 +0100
@@ -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 -upr 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-03-19 01:01:29.000000000 +0100
@@ -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 -upr 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-03-19 01:01:29.000000000 +0100
@@ -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 -upr 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-03-19 01:01:29.000000000 +0100
@@ -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 -upr 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-03-19 01:01:29.000000000 +0100
@@ -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 -upr 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-03-19 01:01:29.000000000 +0100
@@ -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 -upr 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-03-19 01:01:29.000000000 +0100
@@ -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,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 -upr trunk.orig/libmpcodecs/vf_scale.c trunk/libmpcodecs/vf_scale.c
--- trunk.orig/libmpcodecs/vf_scale.c	2010-02-26 02:39:49.000000000 +0100
+++ trunk/libmpcodecs/vf_scale.c	2010-03-19 01:01:29.000000000 +0100
@@ -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 -upr 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-03-19 01:01:29.000000000 +0100
@@ -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 -upr 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-03-19 01:01:29.000000000 +0100
@@ -202,12 +202,14 @@ static void uninit(struct vf_instance *v
 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 -upr 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-03-19 01:01:29.000000000 +0100
@@ -329,6 +329,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 -upr 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-03-19 01:01:29.000000000 +0100
@@ -29,6 +29,7 @@ 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 -upr 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-03-19 01:01:29.000000000 +0100
@@ -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,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_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 -upr 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-03-19 01:01:29.000000000 +0100
@@ -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,7 @@ 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 +857,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 -upr 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-03-19 01:01:29.000000000 +0100
@@ -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 -upr trunk.orig/libvo/vo_sdl.c trunk/libvo/vo_sdl.c
--- trunk.orig/libvo/vo_sdl.c	2010-02-26 02:40:23.000000000 +0100
+++ trunk/libvo/vo_sdl.c	2010-03-19 01:01:29.000000000 +0100
@@ -299,6 +299,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);
@@ -320,6 +324,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);
@@ -741,12 +749,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:
@@ -909,7 +919,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;
@@ -1002,6 +1019,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:
@@ -1334,6 +1353,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:
@@ -1436,6 +1457,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:
@@ -1490,6 +1513,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 -upr trunk.orig/libvo/vo_x11.c trunk/libvo/vo_x11.c
--- trunk.orig/libvo/vo_x11.c	2010-02-26 02:40:25.000000000 +0100
+++ trunk/libvo/vo_x11.c	2010-03-19 01:01:29.000000000 +0100
@@ -146,6 +146,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)
@@ -285,6 +293,8 @@ const 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},
@@ -620,6 +630,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 -upr 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-03-19 01:01:29.000000000 +0100
@@ -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},



More information about the e3-hacking mailing list