plugins: factor out construction of template caps.
authorGwenole Beauchesne <gwenole.beauchesne@intel.com>
Sat, 21 Dec 2013 09:41:22 +0000 (10:41 +0100)
committerGwenole Beauchesne <gwenole.beauchesne@intel.com>
Sat, 21 Dec 2013 11:35:24 +0000 (12:35 +0100)
Add new helper functions to build video template caps.
- gst_vaapi_video_format_new_template_caps():
  create GstCaps with size, frame rate and PAR to full range
- gst_vaapi_video_format_new_template_caps_from_list():
  try to create a "simplified" list from the supplied formats

gst/vaapi/gstvaapidownload.c
gst/vaapi/gstvaapipluginutil.c
gst/vaapi/gstvaapipluginutil.h
gst/vaapi/gstvaapiuploader.c

index 904570b..9a9a3ca 100644 (file)
@@ -389,10 +389,9 @@ gst_vaapidownload_transform_caps(
 {
     GstVaapiDownload * const download = GST_VAAPIDOWNLOAD(trans);
     GstPad *srcpad;
-    GstCaps *allowed_caps, *inter_caps, *out_caps = NULL;
+    GstCaps *allowed_caps, *tmp_caps, *out_caps = NULL;
     GstStructure *structure;
     GArray *formats;
-    guint i;
 
     g_return_val_if_fail(GST_IS_CAPS(caps), NULL);
 
@@ -411,35 +410,31 @@ gst_vaapidownload_transform_caps(
         if (download->allowed_caps)
             allowed_caps = gst_caps_ref(download->allowed_caps);
         else {
-            allowed_caps = gst_caps_new_empty();
-            if (!allowed_caps)
-                return NULL;
-
             formats = gst_vaapi_display_get_image_formats(
                 GST_VAAPI_PLUGIN_BASE_DISPLAY(download));
-            if (formats) {
-                for (i = 0; i < formats->len; i++) {
-                    const GstVideoFormat format =
-                        g_array_index(formats, GstVideoFormat, i);
-                    gst_caps_merge(allowed_caps,
-                        gst_vaapi_video_format_to_caps(format));
-                }
+            if (G_UNLIKELY(!formats))
+                allowed_caps = gst_caps_new_empty();
+            else {
+                allowed_caps =
+                    gst_vaapi_video_format_new_template_caps_from_list(formats);
                 g_array_unref(formats);
             }
+            if (!allowed_caps)
+                return NULL;
         }
-        inter_caps = gst_caps_intersect(out_caps, allowed_caps);
+        tmp_caps = gst_caps_intersect(out_caps, allowed_caps);
         gst_caps_unref(allowed_caps);
         gst_caps_unref(out_caps);
-        out_caps = inter_caps;
+        out_caps = tmp_caps;
 
         /* Intersect with allowed caps from the peer, if any */
         srcpad = gst_element_get_static_pad(GST_ELEMENT(download), "src");
         allowed_caps = gst_pad_peer_get_caps(srcpad);
         if (allowed_caps) {
-            inter_caps = gst_caps_intersect(out_caps, allowed_caps);
+            tmp_caps = gst_caps_intersect(out_caps, allowed_caps);
             gst_caps_unref(allowed_caps);
             gst_caps_unref(out_caps);
-            out_caps = inter_caps;
+            out_caps = tmp_caps;
         }
     }
     else {
index c4652b8..2971168 100644 (file)
@@ -404,6 +404,77 @@ gst_vaapi_value_set_format_list (GValue * value, GArray * formats)
   return TRUE;
 }
 
+void
+set_video_template_caps (GstCaps * caps)
+{
+  GstStructure *const structure = gst_caps_get_structure (caps, 0);
+
+  gst_structure_set (structure,
+      "width", GST_TYPE_INT_RANGE, 1, G_MAXINT,
+      "height", GST_TYPE_INT_RANGE, 1, G_MAXINT,
+      "framerate", GST_TYPE_FRACTION_RANGE, 0, 1, G_MAXINT, 1,
+      "pixel-aspect-ratio", GST_TYPE_FRACTION_RANGE, 0, 1, G_MAXINT, 1, NULL);
+}
+
+GstCaps *
+gst_vaapi_video_format_new_template_caps (GstVideoFormat format)
+{
+#if GST_CHECK_VERSION(1,0,0)
+  GstCaps *caps;
+
+  g_return_val_if_fail (format != GST_VIDEO_FORMAT_UNKNOWN, NULL);
+
+  caps = gst_caps_new_empty_simple ("video/x-raw");
+  if (!caps)
+    return NULL;
+
+  gst_caps_set_simple (caps,
+      "format", G_TYPE_STRING, gst_video_format_to_string (format), NULL);
+  set_video_template_caps (caps);
+  return caps;
+#else
+  return gst_video_format_new_template_caps (format);
+#endif
+}
+
+GstCaps *
+gst_vaapi_video_format_new_template_caps_from_list (GArray * formats)
+{
+#if GST_CHECK_VERSION(1,0,0)
+  GValue v_formats = G_VALUE_INIT;
+  GstCaps *caps;
+
+  caps = gst_caps_new_empty_simple ("video/x-raw");
+  if (!caps)
+    return NULL;
+
+  if (!gst_vaapi_value_set_format_list (&v_formats, formats)) {
+    gst_caps_unref (caps);
+    return NULL;
+  }
+
+  gst_caps_set_value (caps, "format", &v_formats);
+  set_video_template_caps (caps);
+#else
+  GstCaps *caps, *tmp_caps;
+  guint i;
+
+  g_return_val_if_fail (formats != NULL, NULL);
+
+  caps = gst_caps_new_empty ();
+  if (!caps)
+    return NULL;
+
+  for (i = 0; i < formats->len; i++) {
+    const GstVideoFormat format = g_array_index (formats, GstVideoFormat, i);
+    tmp_caps = gst_vaapi_video_format_new_template_caps (format);
+    if (tmp_caps)
+      gst_caps_append (caps, tmp_caps);
+  }
+#endif
+  return caps;
+}
+
 gboolean
 gst_caps_set_interlaced (GstCaps * caps, GstVideoInfo * vip)
 {
index 3d04588..0c6e557 100644 (file)
@@ -64,6 +64,15 @@ G_GNUC_INTERNAL
 gboolean
 gst_vaapi_value_set_format_list (GValue * value, GArray * formats);
 
+/* Helpers to build video caps */
+G_GNUC_INTERNAL
+GstCaps *
+gst_vaapi_video_format_new_template_caps (GstVideoFormat format);
+
+G_GNUC_INTERNAL
+GstCaps *
+gst_vaapi_video_format_new_template_caps_from_list (GArray * formats);
+
 /* Helpers to handle interlaced contents */
 #if GST_CHECK_VERSION(1,0,0)
 # define GST_CAPS_INTERLACED_MODES \
index b28cfe8..6d99c85 100644 (file)
@@ -30,6 +30,7 @@
 #include <gst/vaapi/gstvaapisurfacepool.h>
 
 #include "gstvaapiuploader.h"
+#include "gstvaapipluginutil.h"
 #include "gstvaapivideobuffer.h"
 
 #define GST_HELPER_NAME "vaapiupload"
@@ -112,7 +113,7 @@ ensure_allowed_caps(GstVaapiUploader *uploader)
 {
     GstVaapiUploaderPrivate * const priv = uploader->priv;
     GstVaapiSurface *surface = NULL;
-    GArray *image_formats = NULL;
+    GArray *formats = NULL, *out_formats = NULL;
     GstCaps *out_caps;
     guint i;
     gboolean success = FALSE;
@@ -122,22 +123,23 @@ ensure_allowed_caps(GstVaapiUploader *uploader)
     if (priv->allowed_caps)
         return TRUE;
 
-    out_caps = gst_caps_new_empty();
-    if (!out_caps)
-        return FALSE;
+    formats = gst_vaapi_display_get_image_formats(priv->display);
+    if (!formats)
+        goto cleanup;
 
-    image_formats = gst_vaapi_display_get_image_formats(priv->display);
-    if (!image_formats)
-        goto end;
+    out_formats = g_array_sized_new(FALSE, FALSE, sizeof(GstVideoFormat),
+        formats->len);
+    if (!out_formats)
+        goto cleanup;
 
     surface = gst_vaapi_surface_new(priv->display,
         GST_VAAPI_CHROMA_TYPE_YUV420, WIDTH, HEIGHT);
     if (!surface)
-        goto end;
+        goto cleanup;
 
-    for (i = 0; i < image_formats->len; i++) {
+    for (i = 0; i < formats->len; i++) {
         const GstVideoFormat format =
-            g_array_index(image_formats, GstVideoFormat, i);
+            g_array_index(formats, GstVideoFormat, i);
         GstVaapiImage *image;
 
         if (format == GST_VIDEO_FORMAT_UNKNOWN)
@@ -146,17 +148,23 @@ ensure_allowed_caps(GstVaapiUploader *uploader)
         if (!image)
             continue;
         if (ensure_image(image) && gst_vaapi_surface_put_image(surface, image))
-            gst_caps_append(out_caps, gst_vaapi_video_format_to_caps(format));
+            g_array_append_val(out_formats, format);
         gst_vaapi_object_unref(image);
     }
 
+    out_caps = gst_vaapi_video_format_new_template_caps_from_list(out_formats);
+    if (!out_caps)
+        goto cleanup;
+
     gst_caps_replace(&priv->allowed_caps, out_caps);
+    gst_caps_unref(out_caps);
     success = TRUE;
 
-end:
-    gst_caps_unref(out_caps);
-    if (image_formats)
-        g_array_unref(image_formats);
+cleanup:
+    if (out_formats)
+        g_array_unref(out_formats);
+    if (formats)
+        g_array_unref(formats);
     if (surface)
         gst_vaapi_object_unref(surface);
     return success;