support YUY2 convert to surface
authorWind Yuan <feng.yuan@intel.com>
Mon, 5 Dec 2011 06:23:10 +0000 (01:23 -0500)
committerZhong Cong <congx.zhong@intel.com>
Tue, 5 Feb 2013 07:37:10 +0000 (15:37 +0800)
gst-libs/gst/vaapi/gstvaapiimage.c
gst-libs/gst/vaapi/gstvaapiimage.h
gst/vaapi/gstvaapiupload.c

index ea207de..cc0ba02 100644 (file)
@@ -1310,7 +1310,7 @@ _image_convert_to_nv12(
   guint8 *src,
   guint32 width,
   guint32 height,
-  GstVaapiImageFormat src_format,
+  guint32 src_format,
   guint8 *dest,
   VAImage *va_image)
 {
@@ -1327,10 +1327,15 @@ _image_convert_to_nv12(
   g_assert(va_image->num_planes == 2);
 
   /* copy Y first */
-  for (row = 0; row < height; row++) {
-    memcpy(y_dest, y_src, width);
-    y_src += ystride;
-    y_dest += va_image->pitches[0];
+  if (GST_VAAPI_IMAGE_NV12 == src_format
+        || GST_VAAPI_IMAGE_I420 == src_format
+        || GST_VAAPI_IMAGE_YV12 == src_format)
+  {
+     for (row = 0; row < height; row++) {
+        memcpy(y_dest, y_src, width);
+        y_src += ystride;
+        y_dest += va_image->pitches[0];
+    }
   }
 
   switch (src_format) {
@@ -1381,6 +1386,40 @@ _image_convert_to_nv12(
     }
     break;
 
+    case GST_MAKE_FOURCC('Y', 'U', 'Y', '2'): {
+      const guint8 *y_next_src;
+      guint8 *y_next_dest;
+      ystride = GST_ROUND_UP_2(width)*2;
+      for (row = 0; row < height/2; row++) {
+        y_next_src = y_src + ystride;
+        y_next_dest = y_dest + va_image->pitches[0];
+        for (column = 0; column < width/2; column++) {
+          y_dest[column*2] = y_src[column*4];
+          y_dest[column*2+1] = y_src[column*4+2];
+          y_next_dest[column*2] = y_next_src[column*4];
+          y_next_dest[column*2+1] = y_next_src[column*4+2];
+          uv_dest[column*2] = (y_src[column*4+1] + y_next_src[column*4+1])>>1;
+          uv_dest[column*2+1] = (y_src[column*4+3] + y_next_src[column*4+3])>>1;
+        }
+        y_src = y_next_src + ystride;
+        y_dest = y_next_dest + va_image->pitches[0];
+        uv_dest += va_image->pitches[1];
+      }
+      /*  odd line */
+      if (height%2) {
+        y_next_dest = y_dest + va_image->pitches[0];
+        for (column = 0; column < width/2; column++) {
+          y_dest[column*2] = y_src[column*4];
+          y_dest[column*2+1] = y_src[column*4+2];
+          y_next_dest[column*2] = y_src[column*4];
+          y_next_dest[column*2+1] = y_src[column*4+2];
+          uv_dest[column*2] = y_src[column*4+1];
+          uv_dest[column*2+1] = y_src[column*4+3];
+        }
+      }
+    }
+    break;
+
     default:
       return FALSE;
   }
@@ -1392,7 +1431,7 @@ gboolean
 gst_vaapi_convert_buffer_to_image(
     GstVaapiImage *image,
     GstBuffer *inbuf, // inbuf : I420
-    GstVaapiImageFormat in_format)
+    guint32 in_format)
 {
   GstVaapiImagePrivate *priv;
   guint width, height;
@@ -1406,7 +1445,8 @@ gst_vaapi_convert_buffer_to_image(
   /* currently only support YUV convert */
   if ( (in_format != GST_VAAPI_IMAGE_NV12
         && in_format != GST_VAAPI_IMAGE_YV12
-        && in_format != GST_VAAPI_IMAGE_I420)
+        && in_format != GST_VAAPI_IMAGE_I420
+        && in_format != GST_MAKE_FOURCC('Y', 'U', 'Y', '2'))
       || (image_format != GST_VAAPI_IMAGE_NV12
         && image_format != GST_VAAPI_IMAGE_YV12
         && image_format != GST_VAAPI_IMAGE_I420)
index 46bfb19..3b41f08 100644 (file)
@@ -208,7 +208,7 @@ gboolean
 gst_vaapi_convert_buffer_to_image(
     GstVaapiImage *image,
     GstBuffer *buffer,
-    GstVaapiImageFormat in_format);
+    guint32 in_format);
 
 
 G_END_DECLS
index 3116449..f91f148 100644 (file)
@@ -24,7 +24,7 @@
  * SECTION:gstvaapiupload
  * @short_description: A video to VA flow filter
  *
- * vaapiupload converts from raw YUV pixels to VA surfaces suitable
+ * vaapiupload uploads from raw YUV pixels to VA surfaces suitable
  * for the vaapisink element, for example.
  */
 
@@ -47,7 +47,7 @@ GST_DEBUG_CATEGORY_STATIC(gst_debug_vaapiupload);
 /* ElementFactory information */
 static const GstElementDetails gst_vaapiupload_details =
     GST_ELEMENT_DETAILS(
-        "VA-API colorspace converter",
+        "VA-API colorspace uploader",
         "Filter/Converter/Video",
         GST_PLUGIN_DESC,
         "Gwenole Beauchesne <gwenole.beauchesne@intel.com>");
@@ -448,6 +448,14 @@ error_put_image:
 }
 
 static GstCaps *
+gst_vaapi_get_other_support_caps(GstVaapiConvert *upload)
+{
+  GstCaps *caps;
+  caps = gst_caps_from_string(GST_VIDEO_CAPS_YUV("YUY2"));
+  return caps;
+}
+
+static GstCaps *
 gst_vaapiupload_transform_caps(
     GstBaseTransform *trans,
     GstPadDirection   direction,
@@ -480,10 +488,14 @@ gst_vaapiupload_transform_caps(
             return NULL;
         out_caps = gst_caps_from_string(gst_vaapiupload_yuv_caps_str);
         if (upload->display) {
-            GstCaps *allowed_caps, *inter_caps;
+            GstCaps *allowed_caps, *inter_caps, *other_caps;
             allowed_caps = gst_vaapi_display_get_image_caps(upload->display);
             if (!allowed_caps)
                 return NULL;
+            /* can direct copy other YUV to va surface */
+            other_caps = gst_vaapi_get_other_support_caps(upload);
+            gst_caps_merge(allowed_caps, other_caps);
+
             inter_caps = gst_caps_intersect(out_caps, allowed_caps);
             gst_caps_unref(allowed_caps);
             gst_caps_unref(out_caps);
@@ -622,7 +634,7 @@ gst_vaapiupload_negotiate_buffers(
     if (!gst_vaapiupload_ensure_surface_pool(upload, outcaps))
         return FALSE;
 
-    if (convert->direct_rendering)
+    if (upload->direct_rendering)
         gst_vaapiupload_ensure_direct_rendering_caps(upload, incaps);
     dr = MIN(upload->direct_rendering, upload->direct_rendering_caps);
     if (upload->direct_rendering != dr) {
@@ -642,6 +654,8 @@ gst_vaapiupload_set_caps(
     if (!gst_vaapiupload_negotiate_buffers(upload, incaps, outcaps))
         return FALSE;
 
+    GST_INFO("set caps\nIN caps:\n%" GST_PTR_FORMAT "\nOUT caps:\n%" GST_PTR_FORMAT,
+             incaps, outcaps);
     return TRUE;
 }