changeset 33365:706871635af7

Make mp_get_chroma_shift simpler/more generic and add an argument to get the per-component bit depth. Use this to checking more properly for supported formats in gl and gl2 vos (only 8 and 16 bit are supported, 9 and 10 are not).
author reimar
date Tue, 10 May 2011 17:51:39 +0000
parents e1ee4895e500
children 9b1c1b141f04
files libmpcodecs/img_format.c libmpcodecs/img_format.h libmpcodecs/mp_image.c libvo/gl_common.c libvo/vo_gl.c libvo/vo_gl2.c
diffstat 6 files changed, 72 insertions(+), 52 deletions(-) [+]
line wrap: on
line diff
--- a/libmpcodecs/img_format.c	Tue May 10 08:42:52 2011 +0000
+++ b/libmpcodecs/img_format.c	Tue May 10 17:51:39 2011 +0000
@@ -19,6 +19,7 @@
 #include "config.h"
 #include "img_format.h"
 #include "stdio.h"
+#include "libavutil/bswap.h"
 
 const char *vo_format_name(int format)
 {
@@ -113,20 +114,57 @@
     return unknown_format;
 }
 
-int mp_get_chroma_shift(int format, int *x_shift, int *y_shift)
+int mp_get_chroma_shift(int format, int *x_shift, int *y_shift, int *component_bits)
 {
     int xs = 0, ys = 0;
     int bpp;
-    int bpp_factor = 1;
     int err = 0;
-    switch (format) {
-    case IMGFMT_420P16_LE:
-    case IMGFMT_420P16_BE:
-    case IMGFMT_420P10_LE:
-    case IMGFMT_420P10_BE:
-    case IMGFMT_420P9_LE:
-    case IMGFMT_420P9_BE:
-        bpp_factor = 2;
+    int bits = 8;
+    if ((format & 0xff0000f0) == 0x34000050)
+        format = av_bswap32(format);
+    if ((format & 0xf00000ff) == 0x50000034) {
+        switch (format >> 24) {
+        case 0x50:
+            break;
+        case 0x51:
+            bits = 16;
+            break;
+        case 0x52:
+            bits = 10;
+            break;
+        case 0x53:
+            bits = 9;
+            break;
+        default:
+            err = 1;
+            break;
+        }
+        switch (format & 0x00ffffff) {
+        case 0x00343434: // 444
+            xs = 0;
+            ys = 0;
+            break;
+        case 0x00323234: // 422
+            xs = 1;
+            ys = 0;
+            break;
+        case 0x00303234: // 420
+            xs = 1;
+            ys = 1;
+            break;
+        case 0x00313134: // 411
+            xs = 2;
+            ys = 0;
+            break;
+        case 0x00303434: // 440
+            xs = 0;
+            ys = 1;
+            break;
+        default:
+            err = 1;
+            break;
+        }
+    } else switch (format) {
     case IMGFMT_420A:
     case IMGFMT_I420:
     case IMGFMT_IYUV:
@@ -139,30 +177,6 @@
         xs = 2;
         ys = 2;
         break;
-    case IMGFMT_444P16_LE:
-    case IMGFMT_444P16_BE:
-        bpp_factor = 2;
-    case IMGFMT_444P:
-        xs = 0;
-        ys = 0;
-        break;
-    case IMGFMT_422P16_LE:
-    case IMGFMT_422P16_BE:
-    case IMGFMT_422P10_LE:
-    case IMGFMT_422P10_BE:
-        bpp_factor = 2;
-    case IMGFMT_422P:
-        xs = 1;
-        ys = 0;
-        break;
-    case IMGFMT_411P:
-        xs = 2;
-        ys = 0;
-        break;
-    case IMGFMT_440P:
-        xs = 0;
-        ys = 1;
-        break;
     case IMGFMT_Y8:
     case IMGFMT_Y800:
         xs = 31;
@@ -174,9 +188,10 @@
     }
     if (x_shift) *x_shift = xs;
     if (y_shift) *y_shift = ys;
+    if (component_bits) *component_bits = bits;
     bpp = 8 + ((16 >> xs) >> ys);
     if (format == IMGFMT_420A)
         bpp += 8;
-    bpp *= bpp_factor;
+    bpp *= (bits + 7) >> 3;
     return err ? 0 : bpp;
 }
--- a/libmpcodecs/img_format.h	Tue May 10 08:42:52 2011 +0000
+++ b/libmpcodecs/img_format.h	Tue May 10 17:51:39 2011 +0000
@@ -220,8 +220,9 @@
 /**
  * Calculates the scale shifts for the chroma planes for planar YUV
  *
+ * \param component_bits bits per component
  * \return bits-per-pixel for format if successful (i.e. format is 3 or 4-planes planar YUV), 0 otherwise
  */
-int mp_get_chroma_shift(int format, int *x_shift, int *y_shift);
+int mp_get_chroma_shift(int format, int *x_shift, int *y_shift, int *component_bits);
 
 #endif /* MPLAYER_IMG_FORMAT_H */
--- a/libmpcodecs/mp_image.c	Tue May 10 08:42:52 2011 +0000
+++ b/libmpcodecs/mp_image.c	Tue May 10 17:51:39 2011 +0000
@@ -123,9 +123,9 @@
     }
     mpi->flags|=MP_IMGFLAG_YUV;
     mpi->num_planes=3;
-    if (mp_get_chroma_shift(out_fmt, NULL, NULL)) {
+    if (mp_get_chroma_shift(out_fmt, NULL, NULL, NULL)) {
         mpi->flags|=MP_IMGFLAG_PLANAR;
-        mpi->bpp = mp_get_chroma_shift(out_fmt, &mpi->chroma_x_shift, &mpi->chroma_y_shift);
+        mpi->bpp = mp_get_chroma_shift(out_fmt, &mpi->chroma_x_shift, &mpi->chroma_y_shift, NULL);
         mpi->chroma_width  = mpi->width  >> mpi->chroma_x_shift;
         mpi->chroma_height = mpi->height >> mpi->chroma_y_shift;
     }
--- a/libvo/gl_common.c	Tue May 10 08:42:52 2011 +0000
+++ b/libvo/gl_common.c	Tue May 10 17:51:39 2011 +0000
@@ -253,7 +253,7 @@
   if (!gl_format) gl_format = &dummy2;
   if (!gl_type) gl_type = &dummy2;
 
-  if (mp_get_chroma_shift(fmt, NULL, NULL)) {
+  if (mp_get_chroma_shift(fmt, NULL, NULL, NULL)) {
     // reduce the possible cases a bit
     if (IMGFMT_IS_YUVP16_LE(fmt))
       fmt = IMGFMT_420P16_LE;
--- a/libvo/vo_gl.c	Tue May 10 08:42:52 2011 +0000
+++ b/libvo/vo_gl.c	Tue May 10 17:51:39 2011 +0000
@@ -241,7 +241,7 @@
   gl_conversion_params_t params = {gl_target, yuvconvtype,
       {colorspace, levelconv, bri, cont, hue, sat, rgamma, ggamma, bgamma},
       texture_width, texture_height, 0, 0, filter_strength};
-  mp_get_chroma_shift(image_format, &xs, &ys);
+  mp_get_chroma_shift(image_format, &xs, &ys, NULL);
   params.chrom_texw = params.texw >> xs;
   params.chrom_texh = params.texh >> ys;
   glSetupYUVConversion(&params);
@@ -551,7 +551,7 @@
     int i;
     int xs, ys;
     scale_type = get_scale_type(1);
-    mp_get_chroma_shift(image_format, &xs, &ys);
+    mp_get_chroma_shift(image_format, &xs, &ys, NULL);
     mpglGenTextures(21, default_texs);
     default_texs[21] = 0;
     for (i = 0; i < 7; i++) {
@@ -653,7 +653,7 @@
   image_height = height;
   image_width = width;
   image_format = format;
-  is_yuv = mp_get_chroma_shift(image_format, &xs, &ys) > 0;
+  is_yuv = mp_get_chroma_shift(image_format, &xs, &ys, NULL) > 0;
   is_yuv |= (xs << 8) | (ys << 16);
   glFindFormat(format, NULL, &gl_texfmt, &gl_format, &gl_type);
 
@@ -868,7 +868,7 @@
               x, y, w, h, slice_height);
   if (is_yuv) {
     int xs, ys;
-    mp_get_chroma_shift(image_format, &xs, &ys);
+    mp_get_chroma_shift(image_format, &xs, &ys, NULL);
     mpglActiveTexture(GL_TEXTURE1);
     glUploadTex(gl_target, gl_format, gl_type, src[1], stride[1],
                 x >> xs, y >> ys, w >> xs, h >> ys, slice_height);
@@ -935,7 +935,7 @@
   if (is_yuv) {
     // planar YUV
     int xs, ys;
-    mp_get_chroma_shift(image_format, &xs, &ys);
+    mp_get_chroma_shift(image_format, &xs, &ys, NULL);
     mpi->flags |= MP_IMGFLAG_COMMON_STRIDE | MP_IMGFLAG_COMMON_PLANE;
     mpi->stride[0] = mpi->width;
     mpi->planes[1] = mpi->planes[0] + mpi->stride[0] * mpi->height;
@@ -993,7 +993,7 @@
   if (force_pbo && !(mpi->flags & MP_IMGFLAG_DIRECT) && !gl_bufferptr && get_image(&mpi2) == VO_TRUE) {
     int bpp = is_yuv ? 8 : mpi->bpp;
     int xs, ys;
-    mp_get_chroma_shift(image_format, &xs, &ys);
+    mp_get_chroma_shift(image_format, &xs, &ys, NULL);
     memcpy_pic(mpi2.planes[0], mpi->planes[0], mpi->w * bpp / 8, mpi->h, mpi2.stride[0], mpi->stride[0]);
     if (is_yuv) {
       memcpy_pic(mpi2.planes[1], mpi->planes[1], mpi->w >> xs, mpi->h >> ys, mpi2.stride[1], mpi->stride[1]);
@@ -1035,7 +1035,7 @@
               mpi->x, mpi->y, w, h, slice);
   if (is_yuv) {
     int xs, ys;
-    mp_get_chroma_shift(image_format, &xs, &ys);
+    mp_get_chroma_shift(image_format, &xs, &ys, NULL);
     if ((mpi->flags & MP_IMGFLAG_DIRECT) && !(mpi->flags & MP_IMGFLAG_COMMON_PLANE)) {
       mpglBindBuffer(GL_PIXEL_UNPACK_BUFFER, gl_buffer_uv[0]);
       mpglUnmapBuffer(GL_PIXEL_UNPACK_BUFFER);
@@ -1072,6 +1072,7 @@
 static int
 query_format(uint32_t format)
 {
+    int depth;
     int caps = VFCAP_CSP_SUPPORTED | VFCAP_CSP_SUPPORTED_BY_HW |
                VFCAP_FLIP |
                VFCAP_HWSCALE_UP | VFCAP_HWSCALE_DOWN | VFCAP_ACCEPT_STRIDE;
@@ -1079,7 +1080,8 @@
       caps |= VFCAP_OSD | VFCAP_EOSD | (scaled_osd ? 0 : VFCAP_EOSD_UNSCALED);
     if (format == IMGFMT_RGB24 || format == IMGFMT_RGBA)
         return caps;
-    if (use_yuv && mp_get_chroma_shift(format, NULL, NULL) &&
+    if (use_yuv && mp_get_chroma_shift(format, NULL, NULL, &depth) &&
+        (depth == 8 || depth == 16) &&
         (IMGFMT_IS_YUVP16_NE(format) || !IMGFMT_IS_YUVP16(format)))
         return caps;
     // HACK, otherwise we get only b&w with some filters (e.g. -vf eq)
--- a/libvo/vo_gl2.c	Tue May 10 08:42:52 2011 +0000
+++ b/libvo/vo_gl2.c	Tue May 10 17:51:39 2011 +0000
@@ -275,7 +275,7 @@
       glTexEnvf (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
       if (is_yuv) {
         int xs, ys;
-        mp_get_chroma_shift(image_format, &xs, &ys);
+        mp_get_chroma_shift(image_format, &xs, &ys, NULL);
         mpglActiveTexture(GL_TEXTURE1);
         glCreateClearTex(GL_TEXTURE_2D, gl_internal_format, gl_bitmap_format,  gl_bitmap_type, GL_LINEAR,
                          texture_width >> xs, texture_height >> ys, 128);
@@ -581,7 +581,7 @@
         mpglBindProgram(GL_FRAGMENT_PROGRAM, fragprog);
         break;
     }
-    mp_get_chroma_shift(image_format, &xs, &ys);
+    mp_get_chroma_shift(image_format, &xs, &ys, NULL);
     params.chrom_texw = params.texw >> xs;
     params.chrom_texh = params.texh >> ys;
     glSetupYUVConversion(&params);
@@ -617,7 +617,7 @@
   image_height = height;
   image_width = width;
   image_format = format;
-  is_yuv = mp_get_chroma_shift(image_format, &xs, &ys) > 0;
+  is_yuv = mp_get_chroma_shift(image_format, &xs, &ys, NULL) > 0;
   is_yuv |= (xs << 8) | (ys << 16);
 
   int_pause = 0;
@@ -744,7 +744,7 @@
   struct TexSquare *texline = &texgrid[y / texture_height * texnumx];
   int subtex_y = y % texture_width;
   int xs, ys;
-  mp_get_chroma_shift(image_format, &xs, &ys);
+  mp_get_chroma_shift(image_format, &xs, &ys, NULL);
   while (rem_h > 0) {
     int rem_w = w;
     struct TexSquare *tsq = &texline[x / texture_width];
@@ -805,7 +805,9 @@
 static int
 query_format(uint32_t format)
 {
-  if (use_yuv && mp_get_chroma_shift(format, NULL, NULL) &&
+  int depth;
+  if (use_yuv && mp_get_chroma_shift(format, NULL, NULL, &depth) &&
+      (depth == 8 || depth == 16) &&
       (IMGFMT_IS_YUVP16_NE(format) || !IMGFMT_IS_YUVP16(format)))
     return VFCAP_CSP_SUPPORTED | VFCAP_CSP_SUPPORTED_BY_HW | VFCAP_OSD |
            VFCAP_HWSCALE_UP | VFCAP_HWSCALE_DOWN | VFCAP_ACCEPT_STRIDE;