[linux-dvb] USBVision - YUV Conversion (Using RGB instead of BGR)

Dwaine Garden dwainegarden at rogers.com
Mon Jan 14 00:35:45 CET 2008


Thierry,  I think we need you to sign off on the patch.

sign-off: Dwaine Garden


Thierry Merle <thierry.merle at free.fr> wrote: Dwaine Garden a écrit :
> Thierry,  the patch looks good.  I completed a lot of testing. 
>
> http://linuxtv.org/hg/~tmerle/v4l-dvb-pre/rev/62903ced0d52
>
> Dwaine
>
>
Thanks Dwaine for testing this patch.

The full history:
- when asking the driver RGB32, RGB24, RGB15, RGB16 formats, the picture
has wrong colors (people are purple, ...).
This comes from a YUV to RGB color conversion that was applied following
the V4L spec
http://www.linuxtv.org/downloads/video4linux/API/V4L2_API/spec/r2295.htm
but pixel color values were put in reverse order (I don't know why).
This patch fixes the byte order.

Thierry

--- a/linux/drivers/media/video/usbvision/usbvision-core.c Wed Jan 09 21:34:53 2008 +0100
+++ b/linux/drivers/media/video/usbvision/usbvision-core.c Thu Jan 10 22:20:34 2008 +0100
@@ -672,25 +672,29 @@ static enum ParseState usbvision_parse_l
 
    YUV_TO_RGB_BY_THE_BOOK(yuyv[0], yuyv[1], yuyv[3], rv, gv, bv);
    switch (frame->v4l2_format.format) {
-    case V4L2_PIX_FMT_RGB565:
-     *f++ = (0x1F & (bv >> 3)) | (0xE0 & (gv << 3));
-     *f++ = (0x07 & (gv >> 5)) | (0xF8 &  rv);
-     break;
-    case V4L2_PIX_FMT_RGB24:
-     *f++ = bv;
-     *f++ = gv;
-     *f++ = rv;
-     break;
-    case V4L2_PIX_FMT_RGB32:
-     *f++ = bv;
-     *f++ = gv;
-     *f++ = rv;
-     f++;
-     break;
-    case V4L2_PIX_FMT_RGB555:
-     *f++ = (0x1F & (bv >> 3)) | (0xE0 & (gv << 2));
-     *f++ = (0x03 & (gv >> 6)) | (0x7C & (rv >> 1));
-     break;
+   case V4L2_PIX_FMT_RGB565:
+    *f++ = (0x1F & rv) |
+     (0xE0 & (gv << 5));
+    *f++ = (0x07 & (gv >> 3)) |
+     (0xF8 &  bv);
+    break;
+   case V4L2_PIX_FMT_RGB24:
+    *f++ = rv;
+    *f++ = gv;
+    *f++ = bv;
+    break;
+   case V4L2_PIX_FMT_RGB32:
+    *f++ = rv;
+    *f++ = gv;
+    *f++ = bv;
+    f++;
+    break;
+   case V4L2_PIX_FMT_RGB555:
+    *f++ = (0x1F & rv) |
+     (0xE0 & (gv << 5));
+    *f++ = (0x03 & (gv >> 3)) |
+     (0x7C & (bv << 2));
+    break;
    }
   }
   clipmask_index += clipmask_add;
@@ -704,25 +708,29 @@ static enum ParseState usbvision_parse_l
 
    YUV_TO_RGB_BY_THE_BOOK(yuyv[2], yuyv[1], yuyv[3], rv, gv, bv);
    switch (frame->v4l2_format.format) {
-    case V4L2_PIX_FMT_RGB565:
-     *f++ = (0x1F & (bv >> 3)) | (0xE0 & (gv << 3));
-     *f++ = (0x07 & (gv >> 5)) | (0xF8 &  rv);
-     break;
-    case V4L2_PIX_FMT_RGB24:
-     *f++ = bv;
-     *f++ = gv;
-     *f++ = rv;
-     break;
-    case V4L2_PIX_FMT_RGB32:
-     *f++ = bv;
-     *f++ = gv;
-     *f++ = rv;
-     f++;
-     break;
-    case V4L2_PIX_FMT_RGB555:
-     *f++ = (0x1F & (bv >> 3)) | (0xE0 & (gv << 2));
-     *f++ = (0x03 & (gv >> 6)) | (0x7C & (rv >> 1));
-     break;
+   case V4L2_PIX_FMT_RGB565:
+    *f++ = (0x1F & rv) |
+     (0xE0 & (gv << 5));
+    *f++ = (0x07 & (gv >> 3)) |
+     (0xF8 &  bv);
+    break;
+   case V4L2_PIX_FMT_RGB24:
+    *f++ = rv;
+    *f++ = gv;
+    *f++ = bv;
+    break;
+   case V4L2_PIX_FMT_RGB32:
+    *f++ = rv;
+    *f++ = gv;
+    *f++ = bv;
+    f++;
+    break;
+   case V4L2_PIX_FMT_RGB555:
+    *f++ = (0x1F & rv) |
+     (0xE0 & (gv << 5));
+    *f++ = (0x03 & (gv >> 3)) |
+     (0x7C & (bv << 2));
+    break;
    }
   }
   clipmask_index += clipmask_add;
@@ -990,22 +998,26 @@ static enum ParseState usbvision_parse_c
      *f++ = Y[Idx];
      break;
     case V4L2_PIX_FMT_RGB555:
-     *f++ = (0x1F & (bv >> 3)) | (0xE0 & (gv << 2));
-     *f++ = (0x03 & (gv >> 6)) | (0x7C & (rv >> 1));
+     *f++ = (0x1F & rv) |
+      (0xE0 & (gv << 5));
+     *f++ = (0x03 & (gv >> 3)) |
+      (0x7C & (bv << 2));
      break;
     case V4L2_PIX_FMT_RGB565:
-     *f++ = (0x1F & (bv >> 3)) | (0xE0 & (gv << 3));
-     *f++ = (0x07 & (gv >> 5)) | (0xF8 &  rv);
+     *f++ = (0x1F & rv) |
+      (0xE0 & (gv << 5));
+     *f++ = (0x07 & (gv >> 3)) |
+      (0xF8 &  bv);
      break;
     case V4L2_PIX_FMT_RGB24:
+     *f++ = rv;
+     *f++ = gv;
      *f++ = bv;
-     *f++ = gv;
-     *f++ = rv;
      break;
     case V4L2_PIX_FMT_RGB32:
+     *f++ = rv;
+     *f++ = gv;
      *f++ = bv;
-     *f++ = gv;
-     *f++ = rv;
      f++;
      break;
    }
@@ -1119,28 +1131,33 @@ static enum ParseState usbvision_parse_l
     r_ = (y_ + ur) >> 16;
 
     switch (frame->v4l2_format.format) {
-     case V4L2_PIX_FMT_RGB565:
-      g = LIMIT_RGB(g_);
-      *f_even++ = (0x1F & (LIMIT_RGB(b_) >> 3)) | (0xE0 & (g << 3));
-      *f_even++ = (0x07 & (          g   >> 5)) | (0xF8 & LIMIT_RGB(r_));
-      break;
-     case V4L2_PIX_FMT_RGB24:
-      *f_even++ = LIMIT_RGB(b_);
-      *f_even++ = LIMIT_RGB(g_);
-      *f_even++ = LIMIT_RGB(r_);
-      break;
-     case V4L2_PIX_FMT_RGB32:
-      *f_even++ = LIMIT_RGB(b_);
-      *f_even++ = LIMIT_RGB(g_);
-      *f_even++ = LIMIT_RGB(r_);
-      f_even++;
-      break;
-     case V4L2_PIX_FMT_RGB555:
-      g = LIMIT_RGB(g_);
-      *f_even++ = (0x1F & (LIMIT_RGB(b_) >> 3)) | (0xE0 & (g << 2));
-      *f_even++ = (0x03 & (          g   >> 6)) |
-           (0x7C & (LIMIT_RGB(r_) >> 1));
-      break;
+    case V4L2_PIX_FMT_RGB565:
+     g = LIMIT_RGB(g_);
+     *f_even++ =
+      (0x1F & LIMIT_RGB(r_)) |
+      (0xE0 & (g << 5));
+     *f_even++ =
+      (0x07 & (g >> 3)) |
+      (0xF8 &  LIMIT_RGB(b_));
+     break;
+    case V4L2_PIX_FMT_RGB24:
+     *f_even++ = LIMIT_RGB(r_);
+     *f_even++ = LIMIT_RGB(g_);
+     *f_even++ = LIMIT_RGB(b_);
+     break;
+    case V4L2_PIX_FMT_RGB32:
+     *f_even++ = LIMIT_RGB(r_);
+     *f_even++ = LIMIT_RGB(g_);
+     *f_even++ = LIMIT_RGB(b_);
+     f_even++;
+     break;
+    case V4L2_PIX_FMT_RGB555:
+     g = LIMIT_RGB(g_);
+     *f_even++ = (0x1F & LIMIT_RGB(r_)) |
+      (0xE0 & (g << 5));
+     *f_even++ = (0x03 & (g >> 3)) |
+      (0x7C & (LIMIT_RGB(b_) << 2));
+     break;
     }
    }
    clipmask_even_index += clipmask_add;
@@ -1158,28 +1175,33 @@ static enum ParseState usbvision_parse_l
     r_ = (y_ + ur) >> 16;
 
     switch (frame->v4l2_format.format) {
-     case V4L2_PIX_FMT_RGB565:
-      g = LIMIT_RGB(g_);
-      *f_even++ = (0x1F & (LIMIT_RGB(b_) >> 3)) | (0xE0 & (g << 3));
-      *f_even++ = (0x07 & (          g   >> 5)) | (0xF8 & LIMIT_RGB(r_));
-      break;
-     case V4L2_PIX_FMT_RGB24:
-      *f_even++ = LIMIT_RGB(b_);
-      *f_even++ = LIMIT_RGB(g_);
-      *f_even++ = LIMIT_RGB(r_);
-      break;
-     case V4L2_PIX_FMT_RGB32:
-      *f_even++ = LIMIT_RGB(b_);
-      *f_even++ = LIMIT_RGB(g_);
-      *f_even++ = LIMIT_RGB(r_);
-      f_even++;
-      break;
-     case V4L2_PIX_FMT_RGB555:
-      g = LIMIT_RGB(g_);
-      *f_even++ = (0x1F & (LIMIT_RGB(b_) >> 3)) | (0xE0 & (g << 2));
-      *f_even++ = (0x03 & (          g   >> 6)) |
-           (0x7C & (LIMIT_RGB(r_) >> 1));
-      break;
+    case V4L2_PIX_FMT_RGB565:
+     g = LIMIT_RGB(g_);
+     *f_even++ =
+      (0x1F & LIMIT_RGB(r_)) |
+      (0xE0 & (g << 5));
+     *f_even++ =
+      (0x07 & (g >> 3)) |
+      (0xF8 &  LIMIT_RGB(b_));
+     break;
+    case V4L2_PIX_FMT_RGB24:
+     *f_even++ = LIMIT_RGB(r_);
+     *f_even++ = LIMIT_RGB(g_);
+     *f_even++ = LIMIT_RGB(b_);
+     break;
+    case V4L2_PIX_FMT_RGB32:
+     *f_even++ = LIMIT_RGB(r_);
+     *f_even++ = LIMIT_RGB(g_);
+     *f_even++ = LIMIT_RGB(b_);
+     f_even++;
+     break;
+    case V4L2_PIX_FMT_RGB555:
+     g = LIMIT_RGB(g_);
+     *f_even++ = (0x1F & LIMIT_RGB(r_)) |
+      (0xE0 & (g << 5));
+     *f_even++ = (0x03 & (g >> 3)) |
+      (0x7C & (LIMIT_RGB(b_) << 2));
+     break;
     }
    }
    clipmask_even_index += clipmask_add;
@@ -1199,28 +1221,33 @@ static enum ParseState usbvision_parse_l
     r_ = (y_ + ur) >> 16;
 
     switch (frame->v4l2_format.format) {
-     case V4L2_PIX_FMT_RGB565:
-      g = LIMIT_RGB(g_);
-      *f_odd++ = (0x1F & (LIMIT_RGB(b_) >> 3)) | (0xE0 & (g << 3));
-      *f_odd++ = (0x07 & (          g   >> 5)) | (0xF8 & LIMIT_RGB(r_));
-      break;
-     case V4L2_PIX_FMT_RGB24:
-      *f_odd++ = LIMIT_RGB(b_);
-      *f_odd++ = LIMIT_RGB(g_);
-      *f_odd++ = LIMIT_RGB(r_);
-      break;
-     case V4L2_PIX_FMT_RGB32:
-      *f_odd++ = LIMIT_RGB(b_);
-      *f_odd++ = LIMIT_RGB(g_);
-      *f_odd++ = LIMIT_RGB(r_);
-      f_odd++;
-      break;
-     case V4L2_PIX_FMT_RGB555:
-      g = LIMIT_RGB(g_);
-      *f_odd++ = (0x1F & (LIMIT_RGB(b_) >> 3)) | (0xE0 & (g << 2));
-      *f_odd++ = (0x03 & (          g   >> 6)) |
-          (0x7C & (LIMIT_RGB(r_) >> 1));
-      break;
+    case V4L2_PIX_FMT_RGB565:
+     g = LIMIT_RGB(g_);
+     *f_odd++ =
+      (0x1F & LIMIT_RGB(r_)) |
+      (0xE0 & (g << 5));
+     *f_odd++ =
+      (0x07 & (g >> 3)) |
+      (0xF8 &  LIMIT_RGB(b_));
+     break;
+    case V4L2_PIX_FMT_RGB24:
+     *f_odd++ = LIMIT_RGB(r_);
+     *f_odd++ = LIMIT_RGB(g_);
+     *f_odd++ = LIMIT_RGB(b_);
+     break;
+    case V4L2_PIX_FMT_RGB32:
+     *f_odd++ = LIMIT_RGB(r_);
+     *f_odd++ = LIMIT_RGB(g_);
+     *f_odd++ = LIMIT_RGB(b_);
+     f_odd++;
+     break;
+    case V4L2_PIX_FMT_RGB555:
+     g = LIMIT_RGB(g_);
+     *f_odd++ = (0x1F & LIMIT_RGB(r_)) |
+      (0xE0 & (g << 5));
+     *f_odd++ = (0x03 & (g >> 3)) |
+      (0x7C & (LIMIT_RGB(b_) << 2));
+     break;
     }
    }
    clipmask_odd_index += clipmask_add;
@@ -1238,28 +1265,33 @@ static enum ParseState usbvision_parse_l
     r_ = (y_ + ur) >> 16;
 
     switch (frame->v4l2_format.format) {
-     case V4L2_PIX_FMT_RGB565:
-      g = LIMIT_RGB(g_);
-      *f_odd++ = (0x1F & (LIMIT_RGB(b_) >> 3)) | (0xE0 & (g << 3));
-      *f_odd++ = (0x07 & (          g   >> 5)) | (0xF8 & LIMIT_RGB(r_));
-      break;
-     case V4L2_PIX_FMT_RGB24:
-      *f_odd++ = LIMIT_RGB(b_);
-      *f_odd++ = LIMIT_RGB(g_);
-      *f_odd++ = LIMIT_RGB(r_);
-      break;
-     case V4L2_PIX_FMT_RGB32:
-      *f_odd++ = LIMIT_RGB(b_);
-      *f_odd++ = LIMIT_RGB(g_);
-      *f_odd++ = LIMIT_RGB(r_);
-      f_odd++;
-      break;
-     case V4L2_PIX_FMT_RGB555:
-      g = LIMIT_RGB(g_);
-      *f_odd++ = (0x1F & (LIMIT_RGB(b_) >> 3)) | (0xE0 & (g << 2));
-      *f_odd++ = (0x03 & (          g   >> 6)) |
-          (0x7C & (LIMIT_RGB(r_) >> 1));
-      break;
+    case V4L2_PIX_FMT_RGB565:
+     g = LIMIT_RGB(g_);
+     *f_odd++ =
+      (0x1F & LIMIT_RGB(r_)) |
+      (0xE0 & (g << 5));
+     *f_odd++ =
+      (0x07 & (g >> 3)) |
+      (0xF8 &  LIMIT_RGB(b_));
+     break;
+    case V4L2_PIX_FMT_RGB24:
+     *f_odd++ = LIMIT_RGB(r_);
+     *f_odd++ = LIMIT_RGB(g_);
+     *f_odd++ = LIMIT_RGB(b_);
+     break;
+    case V4L2_PIX_FMT_RGB32:
+     *f_odd++ = LIMIT_RGB(r_);
+     *f_odd++ = LIMIT_RGB(g_);
+     *f_odd++ = LIMIT_RGB(b_);
+     f_odd++;
+     break;
+    case V4L2_PIX_FMT_RGB555:
+     g = LIMIT_RGB(g_);
+     *f_odd++ = (0x1F & LIMIT_RGB(r_)) |
+      (0xE0 & (g << 5));
+     *f_odd++ = (0x03 & (g >> 3)) |
+      (0x7C & (LIMIT_RGB(b_) << 2));
+     break;
     }
    }
    clipmask_odd_index += clipmask_add;



-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://www.linuxtv.org/pipermail/linux-dvb/attachments/20080113/49ea7f6e/attachment-0001.htm 


More information about the linux-dvb mailing list