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

Janusz Krzysztofik jkrzyszt at tis.icnet.pl
Sun Feb 28 17:56:30 CET 2010


While trying to play video on my ARM OMAP1 based Amstrad Delta (E3) videophone 
with mplayer, I found it not compatible with the 12-bit LCD display my device 
is equipped with. To solve the problem, I patched several mplayer video output 
drivers to support my device. For them to be usefull, I also had to patch 
libswscale to be able to convert video to my device compatible RGB444 format.

This patch adds rudimentary support for RGB12 aka RGB444 pixel format handling 
to ffmpeg libraries, including the definitions of new pixel format ids, the 
pixel format desciption and the info and extensions to core helper functions 
provided by libavcodec/imgconvert.c. Other patches, based on this one, 
providing converters and possibly other features, will follow.

Created and tested against ffmpeg svn revision 22110 dated 2010-02-28.

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

---

diff -upr ffmpeg-9999.orig/libavcodec/imgconvert.c ffmpeg-9999/libavcodec/imgconvert.c
--- ffmpeg-9999.orig/libavcodec/imgconvert.c	2010-02-28 16:35:53.000000000 +0100
+++ ffmpeg-9999/libavcodec/imgconvert.c	2010-02-28 16:37:01.000000000 +0100
@@ -240,6 +240,18 @@ static const PixFmtInfo pix_fmt_info[PIX
         .pixel_type = FF_PIXEL_PACKED,
         .depth = 5,
     },
+    [PIX_FMT_RGB444BE] = {
+        .nb_channels = 3,
+        .color_type = FF_COLOR_RGB,
+        .pixel_type = FF_PIXEL_PACKED,
+        .depth = 4,
+    },
+    [PIX_FMT_RGB444LE] = {
+        .nb_channels = 3,
+        .color_type = FF_COLOR_RGB,
+        .pixel_type = FF_PIXEL_PACKED,
+        .depth = 4,
+    },
 
     /* gray / mono formats */
     [PIX_FMT_GRAY16BE] = {
@@ -316,6 +328,18 @@ static const PixFmtInfo pix_fmt_info[PIX
         .pixel_type = FF_PIXEL_PACKED,
         .depth = 5,
     },
+    [PIX_FMT_BGR444BE] = {
+        .nb_channels = 3,
+        .color_type = FF_COLOR_RGB,
+        .pixel_type = FF_PIXEL_PACKED,
+        .depth = 4,
+    },
+    [PIX_FMT_BGR444LE] = {
+        .nb_channels = 3,
+        .color_type = FF_COLOR_RGB,
+        .pixel_type = FF_PIXEL_PACKED,
+        .depth = 4,
+    },
     [PIX_FMT_RGB8] = {
         .nb_channels = 1,
         .color_type = FF_COLOR_RGB,
@@ -529,10 +553,14 @@ int ff_fill_linesize(AVPicture *picture,
         break;
     case PIX_FMT_GRAY16BE:
     case PIX_FMT_GRAY16LE:
+    case PIX_FMT_BGR444BE:
+    case PIX_FMT_BGR444LE:
     case PIX_FMT_BGR555BE:
     case PIX_FMT_BGR555LE:
     case PIX_FMT_BGR565BE:
     case PIX_FMT_BGR565LE:
+    case PIX_FMT_RGB444BE:
+    case PIX_FMT_RGB444LE:
     case PIX_FMT_RGB555BE:
     case PIX_FMT_RGB555LE:
     case PIX_FMT_RGB565BE:
@@ -626,10 +654,14 @@ int ff_fill_pointer(AVPicture *picture, 
     case PIX_FMT_RGB48LE:
     case PIX_FMT_GRAY16BE:
     case PIX_FMT_GRAY16LE:
+    case PIX_FMT_BGR444BE:
+    case PIX_FMT_BGR444LE:
     case PIX_FMT_BGR555BE:
     case PIX_FMT_BGR555LE:
     case PIX_FMT_BGR565BE:
     case PIX_FMT_BGR565LE:
+    case PIX_FMT_RGB444BE:
+    case PIX_FMT_RGB444LE:
     case PIX_FMT_RGB555BE:
     case PIX_FMT_RGB555LE:
     case PIX_FMT_RGB565BE:
@@ -699,10 +731,14 @@ int avpicture_layout(const AVPicture* sr
             pix_fmt == PIX_FMT_BGR565LE ||
             pix_fmt == PIX_FMT_BGR555BE ||
             pix_fmt == PIX_FMT_BGR555LE ||
+            pix_fmt == PIX_FMT_BGR444BE ||
+            pix_fmt == PIX_FMT_BGR444LE ||
             pix_fmt == PIX_FMT_RGB565BE ||
             pix_fmt == PIX_FMT_RGB565LE ||
             pix_fmt == PIX_FMT_RGB555BE ||
-            pix_fmt == PIX_FMT_RGB555LE)
+            pix_fmt == PIX_FMT_RGB555LE ||
+            pix_fmt == PIX_FMT_RGB444BE ||
+            pix_fmt == PIX_FMT_RGB444LE)
             w = width * 2;
         else if (pix_fmt == PIX_FMT_UYYVYY411)
             w = width + width/2;
@@ -778,7 +814,10 @@ int avcodec_get_pix_fmt_loss(enum PixelF
     pf = &pix_fmt_info[dst_pix_fmt];
     if (pf->depth < ps->depth ||
         ((dst_pix_fmt == PIX_FMT_RGB555BE || dst_pix_fmt == PIX_FMT_RGB555LE) &&
-         (src_pix_fmt == PIX_FMT_RGB565BE || src_pix_fmt == PIX_FMT_RGB565LE)))
+         (src_pix_fmt == PIX_FMT_RGB565BE || src_pix_fmt == PIX_FMT_RGB565LE)) ||
+        ((dst_pix_fmt == PIX_FMT_RGB444BE || dst_pix_fmt == PIX_FMT_RGB444LE) &&
+         (src_pix_fmt == PIX_FMT_RGB555BE || src_pix_fmt == PIX_FMT_RGB555LE ||
+          src_pix_fmt == PIX_FMT_RGB565BE || src_pix_fmt == PIX_FMT_RGB565LE)))
         loss |= FF_LOSS_DEPTH;
     if (dst_desc->log2_chroma_w > src_desc->log2_chroma_w ||
         dst_desc->log2_chroma_h > src_desc->log2_chroma_h)
@@ -836,10 +875,14 @@ static int avg_bits_per_pixel(enum Pixel
         case PIX_FMT_RGB565LE:
         case PIX_FMT_RGB555BE:
         case PIX_FMT_RGB555LE:
+        case PIX_FMT_RGB444BE:
+        case PIX_FMT_RGB444LE:
         case PIX_FMT_BGR565BE:
         case PIX_FMT_BGR565LE:
         case PIX_FMT_BGR555BE:
         case PIX_FMT_BGR555LE:
+        case PIX_FMT_BGR444BE:
+        case PIX_FMT_BGR444LE:
             bits = 16;
             break;
         case PIX_FMT_UYYVYY411:
@@ -956,10 +999,14 @@ int ff_get_plane_bytewidth(enum PixelFor
         case PIX_FMT_RGB565LE:
         case PIX_FMT_RGB555BE:
         case PIX_FMT_RGB555LE:
+        case PIX_FMT_RGB444BE:
+        case PIX_FMT_RGB444LE:
         case PIX_FMT_BGR565BE:
         case PIX_FMT_BGR565LE:
         case PIX_FMT_BGR555BE:
         case PIX_FMT_BGR555LE:
+        case PIX_FMT_BGR444BE:
+        case PIX_FMT_BGR444LE:
             bits = 16;
             break;
         case PIX_FMT_UYYVYY411:
Only in ffmpeg-9999/libavcodec: imgconvert.c.orig
diff -upr ffmpeg-9999.orig/libavutil/pixdesc.c ffmpeg-9999/libavutil/pixdesc.c
--- ffmpeg-9999.orig/libavutil/pixdesc.c	2010-02-28 16:35:53.000000000 +0100
+++ ffmpeg-9999/libavutil/pixdesc.c	2010-02-28 16:37:01.000000000 +0100
@@ -593,6 +593,29 @@ const AVPixFmtDescriptor av_pix_fmt_desc
             {0,1,1,0,4},        /* B */
         },
     },
+    [PIX_FMT_RGB444BE] = {
+        .name = "rgb444be",
+        .nb_components= 3,
+        .log2_chroma_w= 0,
+        .log2_chroma_h= 0,
+        .comp = {
+            {0,1,0,0,3},        /* R */
+            {0,1,1,4,3},        /* G */
+            {0,1,1,0,3},        /* B */
+        },
+        .flags = PIX_FMT_BE,
+    },
+    [PIX_FMT_RGB444LE] = {
+        .name = "rgb444le",
+        .nb_components= 3,
+        .log2_chroma_w= 0,
+        .log2_chroma_h= 0,
+        .comp = {
+            {0,1,2,0,3},        /* R */
+            {0,1,1,4,3},        /* G */
+            {0,1,1,0,3},        /* B */
+        },
+    },
     [PIX_FMT_BGR565BE] = {
         .name = "bgr565be",
         .nb_components= 3,
@@ -639,6 +662,29 @@ const AVPixFmtDescriptor av_pix_fmt_desc
             {0,1,1,0,4},        /* R */
         },
     },
+    [PIX_FMT_BGR444BE] = {
+        .name = "bgr444be",
+        .nb_components= 3,
+        .log2_chroma_w= 0,
+        .log2_chroma_h= 0,
+        .comp = {
+            {0,1,0,0,3},       /* B */
+            {0,1,1,4,3},       /* G */
+            {0,1,1,0,3},       /* R */
+        },
+        .flags = PIX_FMT_BE,
+     },
+    [PIX_FMT_BGR444LE] = {
+        .name = "bgr444le",
+        .nb_components= 3,
+        .log2_chroma_w= 0,
+        .log2_chroma_h= 0,
+        .comp = {
+            {0,1,2,0,3},        /* B */
+            {0,1,1,4,3},        /* G */
+            {0,1,1,0,3},        /* R */
+        },
+    },
     [PIX_FMT_VAAPI_MOCO] = {
         .name = "vaapi_moco",
         .log2_chroma_w = 1,
diff -upr ffmpeg-9999.orig/libavutil/pixfmt.h ffmpeg-9999/libavutil/pixfmt.h
--- ffmpeg-9999.orig/libavutil/pixfmt.h	2010-02-28 16:35:53.000000000 +0100
+++ ffmpeg-9999/libavutil/pixfmt.h	2010-02-28 16:37:01.000000000 +0100
@@ -127,6 +127,11 @@ enum PixelFormat {
     PIX_FMT_YUV444P16BE,  ///< planar YUV 4:4:4, 48bpp, (1 Cr & Cb sample per 1x1 Y samples), big-endian
     PIX_FMT_VDPAU_MPEG4,  ///< MPEG4 HW decoding with VDPAU, data[0] contains a vdpau_render_state struct which contains the bitstream of the 
slices as well as various fields extracted from headers
     PIX_FMT_DXVA2_VLD,    ///< HW decoding through DXVA2, Picture.data[3] contains a LPDIRECT3DSURFACE9 pointer
+
+    PIX_FMT_RGB444BE,  ///< packed RGB 4:4:4, 16bpp, (msb)4A 4R 4G 4B(lsb), big-endian, most significant bits to 0
+    PIX_FMT_RGB444LE,  ///< packed RGB 4:4:4, 16bpp, (msb)4A 4R 4G 4B(lsb), little-endian, most significant bits to 0
+    PIX_FMT_BGR444BE,  ///< packed BGR 4:4:4, 16bpp, (msb)4A 4B 4G 4R(lsb), big-endian, most significant bits to 1
+    PIX_FMT_BGR444LE,  ///< packed BGR 4:4:4, 16bpp, (msb)4A 4B 4G 4R(lsb), little-endian, most significant bits to 1
     PIX_FMT_NB,        ///< number of pixel formats, DO NOT USE THIS if you want to link with shared libav* because the number of formats might 
differ between versions
 };
 
@@ -145,8 +150,10 @@ enum PixelFormat {
 #define PIX_FMT_RGB48  PIX_FMT_NE(RGB48BE,  RGB48LE)
 #define PIX_FMT_RGB565 PIX_FMT_NE(RGB565BE, RGB565LE)
 #define PIX_FMT_RGB555 PIX_FMT_NE(RGB555BE, RGB555LE)
+#define PIX_FMT_RGB444 PIX_FMT_NE(RGB444BE, RGB444LE)
 #define PIX_FMT_BGR565 PIX_FMT_NE(BGR565BE, BGR565LE)
 #define PIX_FMT_BGR555 PIX_FMT_NE(BGR555BE, BGR555LE)
+#define PIX_FMT_BGR444 PIX_FMT_NE(BGR444BE, BGR444LE)
 
 #define PIX_FMT_YUV420P16 PIX_FMT_NE(YUV420P16BE, YUV420P16LE)
 #define PIX_FMT_YUV422P16 PIX_FMT_NE(YUV422P16BE, YUV422P16LE)



More information about the MPlayer-dev-eng mailing list