ffmpegcolorspace: Add conversion from/to YVYU colorspace
authorSebastian Dröge <sebastian.droege@collabora.co.uk>
Tue, 24 Feb 2009 13:06:38 +0000 (14:06 +0100)
committerSebastian Dröge <sebastian.droege@collabora.co.uk>
Tue, 24 Feb 2009 13:06:38 +0000 (14:06 +0100)
Fixes bug #572872.

gst/ffmpegcolorspace/avcodec.h
gst/ffmpegcolorspace/gstffmpegcodecmap.c
gst/ffmpegcolorspace/imgconvert.c

index ec42eb0..f786a75 100644 (file)
@@ -84,6 +84,7 @@ enum PixelFormat {
     PIX_FMT_XVMC_MPEG2_MC,///< XVideo Motion Acceleration via common packet passing(xvmc_render.h)
     PIX_FMT_XVMC_MPEG2_IDCT,
     PIX_FMT_UYVY422,   ///< Packed pixel, Cb Y0 Cr Y1 
+    PIX_FMT_YVYU422,   ///< Packed pixel, Y0 Cr Y1 Cb 
     PIX_FMT_UYVY411,   ///< Packed pixel, Cb Y0 Y1 Cr Y2 Y3
     PIX_FMT_V308,      ///< Packed pixel, Y0 Cb Cr
 
index 8ce9c24..0a11659 100644 (file)
@@ -182,6 +182,9 @@ gst_ffmpeg_pixfmt_to_caps (enum PixelFormat pix_fmt, AVCodecContext * context)
     case PIX_FMT_UYVY422:
       fmt = GST_MAKE_FOURCC ('U', 'Y', 'V', 'Y');
       break;
+    case PIX_FMT_YVYU422:
+      fmt = GST_MAKE_FOURCC ('Y', 'V', 'Y', 'U');
+      break;
     case PIX_FMT_UYVY411:
       fmt = GST_MAKE_FOURCC ('I', 'Y', 'U', '1');
       break;
@@ -590,6 +593,9 @@ gst_ffmpeg_caps_to_pixfmt (const GstCaps * caps,
         case GST_MAKE_FOURCC ('U', 'Y', 'V', 'Y'):
           context->pix_fmt = PIX_FMT_UYVY422;
           break;
+        case GST_MAKE_FOURCC ('Y', 'V', 'Y', 'U'):
+          context->pix_fmt = PIX_FMT_YVYU422;
+          break;
         case GST_MAKE_FOURCC ('I', 'Y', 'U', '1'):
           context->pix_fmt = PIX_FMT_UYVY411;
           break;
@@ -856,6 +862,7 @@ gst_ffmpegcsp_avpicture_fill (AVPicture * picture,
     case PIX_FMT_RGB565:
     case PIX_FMT_YUV422:
     case PIX_FMT_UYVY422:
+    case PIX_FMT_YVYU422:
       stride = GST_ROUND_UP_4 (width * 2);
       size = stride * height;
       picture->data[0] = ptr;
index 33b3430..5e72e14 100644 (file)
@@ -130,6 +130,17 @@ static PixFmtInfo pix_fmt_info[PIX_FMT_NB] = {
         /* .y_chroma_shift = */ 0,
         /* .depth          = */ 8,
       },
+  /* [PIX_FMT_YVYU422] = */ {
+        /* .format         = */ PIX_FMT_YVYU422,
+        /* .name           = */ "yvyu422",
+        /* .nb_channels    = */ 1,
+        /* .color_type     = */ FF_COLOR_YUV,
+        /* .pixel_type     = */ FF_PIXEL_PACKED,
+        /* .is_alpha       = */ 0,
+        /* .x_chroma_shift = */ 1,
+        /* .y_chroma_shift = */ 0,
+        /* .depth          = */ 8,
+      },
   /* [PIX_FMT_V308] = */ {
         /* .format         = */ PIX_FMT_V308,
         /* .name           = */ "v308",
@@ -601,6 +612,7 @@ avg_bits_per_pixel (int pix_fmt)
       switch (pix_fmt) {
         case PIX_FMT_YUV422:
         case PIX_FMT_UYVY422:
+        case PIX_FMT_YVYU422:
         case PIX_FMT_RGB565:
         case PIX_FMT_RGB555:
           bits = 16;
@@ -718,6 +730,7 @@ img_copy (AVPicture * dst, const AVPicture * src,
       switch (pix_fmt) {
         case PIX_FMT_YUV422:
         case PIX_FMT_UYVY422:
+        case PIX_FMT_YVYU422:
         case PIX_FMT_RGB565:
         case PIX_FMT_RGB555:
           bits = 16;
@@ -935,6 +948,122 @@ uyvy422_to_yuv422p (AVPicture * dst, const AVPicture * src,
   }
 }
 
+static void
+yvyu422_to_gray (AVPicture * dst, const AVPicture * src, int width, int height)
+{
+  const uint8_t *p, *p1;
+  uint8_t *lum, *lum1;
+  int w;
+
+  p1 = src->data[0];
+  lum1 = dst->data[0];
+  for (; height > 0; height--) {
+    p = p1;
+    lum = lum1;
+
+    for (w = width; w >= 2; w -= 2) {
+      lum[0] = p[0];
+      lum[1] = p[2];
+      p += 4;
+      lum += 2;
+    }
+    p1 += src->linesize[0];
+    lum1 += dst->linesize[0];
+  }
+}
+
+
+static void
+yvyu422_to_yuv420p (AVPicture * dst, const AVPicture * src,
+    int width, int height)
+{
+  const uint8_t *p, *p1;
+  uint8_t *lum, *cr, *cb, *lum1, *cr1, *cb1;
+  int w;
+
+  p1 = src->data[0];
+
+  lum1 = dst->data[0];
+  cb1 = dst->data[1];
+  cr1 = dst->data[2];
+
+  for (; height >= 1; height -= 2) {
+    p = p1;
+    lum = lum1;
+    cb = cb1;
+    cr = cr1;
+    for (w = width; w >= 2; w -= 2) {
+      lum[0] = p[0];
+      cb[0] = p[3];
+      lum[1] = p[2];
+      cr[0] = p[1];
+      p += 4;
+      lum += 2;
+      cb++;
+      cr++;
+    }
+    if (w) {
+      lum[0] = p[0];
+      cb[0] = p[3];
+      cr[0] = p[1];
+      cb++;
+      cr++;
+    }
+    p1 += src->linesize[0];
+    lum1 += dst->linesize[0];
+    if (height > 1) {
+      p = p1;
+      lum = lum1;
+      for (w = width; w >= 2; w -= 2) {
+        lum[0] = p[0];
+        lum[1] = p[2];
+        p += 4;
+        lum += 2;
+      }
+      if (w) {
+        lum[0] = p[0];
+      }
+      p1 += src->linesize[0];
+      lum1 += dst->linesize[0];
+    }
+    cb1 += dst->linesize[1];
+    cr1 += dst->linesize[2];
+  }
+}
+
+static void
+yvyu422_to_yuv422p (AVPicture * dst, const AVPicture * src,
+    int width, int height)
+{
+  const uint8_t *p, *p1;
+  uint8_t *lum, *cr, *cb, *lum1, *cr1, *cb1;
+  int w;
+
+  p1 = src->data[0];
+  lum1 = dst->data[0];
+  cb1 = dst->data[1];
+  cr1 = dst->data[2];
+  for (; height > 0; height--) {
+    p = p1;
+    lum = lum1;
+    cb = cb1;
+    cr = cr1;
+    for (w = width; w >= 2; w -= 2) {
+      lum[0] = p[0];
+      cb[0] = p[3];
+      lum[1] = p[2];
+      cr[0] = p[1];
+      p += 4;
+      lum += 2;
+      cb++;
+      cr++;
+    }
+    p1 += src->linesize[0];
+    lum1 += dst->linesize[0];
+    cb1 += dst->linesize[1];
+    cr1 += dst->linesize[2];
+  }
+}
 
 static void
 yuv422_to_yuv422p (AVPicture * dst, const AVPicture * src,
@@ -1043,6 +1172,40 @@ yuv422p_to_uyvy422 (AVPicture * dst, const AVPicture * src,
 }
 
 static void
+yuv422p_to_yvyu422 (AVPicture * dst, const AVPicture * src,
+    int width, int height)
+{
+  uint8_t *p, *p1;
+  const uint8_t *lum, *cr, *cb, *lum1, *cr1, *cb1;
+  int w;
+
+  p1 = dst->data[0];
+  lum1 = src->data[0];
+  cb1 = src->data[1];
+  cr1 = src->data[2];
+  for (; height > 0; height--) {
+    p = p1;
+    lum = lum1;
+    cb = cb1;
+    cr = cr1;
+    for (w = width; w >= 2; w -= 2) {
+      p[0] = lum[0];
+      p[3] = cb[0];
+      p[2] = lum[1];
+      p[1] = cr[0];
+      p += 4;
+      lum += 2;
+      cb++;
+      cr++;
+    }
+    p1 += dst->linesize[0];
+    lum1 += src->linesize[0];
+    cb1 += src->linesize[1];
+    cr1 += src->linesize[2];
+  }
+}
+
+static void
 uyvy411_to_yuv411p (AVPicture * dst, const AVPicture * src,
     int width, int height)
 {
@@ -1078,7 +1241,6 @@ uyvy411_to_yuv411p (AVPicture * dst, const AVPicture * src,
   }
 }
 
-
 static void
 yuv420p_to_yuv422 (AVPicture * dst, const AVPicture * src,
     int width, int height)
@@ -2174,6 +2336,7 @@ static ConvertEntry convert_table[] = {
 
   {PIX_FMT_YUV422P, PIX_FMT_YUV422, yuv422p_to_yuv422},
   {PIX_FMT_YUV422P, PIX_FMT_UYVY422, yuv422p_to_uyvy422},
+  {PIX_FMT_YUV422P, PIX_FMT_YVYU422, yuv422p_to_yvyu422},
 
   {PIX_FMT_YUV444P, PIX_FMT_RGB24, yuv444p_to_rgb24},
 
@@ -2199,6 +2362,10 @@ static ConvertEntry convert_table[] = {
   {PIX_FMT_UYVY422, PIX_FMT_YUV422P, uyvy422_to_yuv422p},
   {PIX_FMT_UYVY422, PIX_FMT_GRAY8, uyvy422_to_gray},
 
+  {PIX_FMT_YVYU422, PIX_FMT_YUV420P, yvyu422_to_yuv420p},
+  {PIX_FMT_YVYU422, PIX_FMT_YUV422P, yvyu422_to_yuv422p},
+  {PIX_FMT_YVYU422, PIX_FMT_GRAY8, yvyu422_to_gray},
+
   {PIX_FMT_RGB24, PIX_FMT_YUV420P, rgb24_to_yuv420p},
   {PIX_FMT_RGB24, PIX_FMT_NV12, rgb24_to_nv12},
   {PIX_FMT_RGB24, PIX_FMT_NV21, rgb24_to_nv21},
@@ -2581,7 +2748,8 @@ no_chroma_filter:
   if (src_pix_fmt == PIX_FMT_YUV422 || dst_pix_fmt == PIX_FMT_YUV422) {
     /* specific case: convert to YUV422P first */
     int_pix_fmt = PIX_FMT_YUV422P;
-  } else if (src_pix_fmt == PIX_FMT_UYVY422 || dst_pix_fmt == PIX_FMT_UYVY422) {
+  } else if (src_pix_fmt == PIX_FMT_UYVY422 || dst_pix_fmt == PIX_FMT_UYVY422 ||
+      src_pix_fmt == PIX_FMT_YVYU422 || dst_pix_fmt == PIX_FMT_YVYU422) {
     /* specific case: convert to YUV422P first */
     int_pix_fmt = PIX_FMT_YUV422P;
   } else if (src_pix_fmt == PIX_FMT_UYVY411 || dst_pix_fmt == PIX_FMT_UYVY411) {