[Libva] [PATCH 2/2] Make vaapidownload element capable of passthrough

Simon Farnsworth simon.farnsworth at onelan.co.uk
Thu Sep 6 08:11:54 PDT 2012


It's helpful to have an element that takes in both YUV and VA-API surfaces,
and guarantees a YUV surface out. This lets you design pipelines that feed
into an element like vp8enc (which needs YUV in), without worrying about
whether you're feeding it from a vaapidecode or a software decoder.

Make vaapidownload into that element; with this change, it now accepts both
YUV and VA-API surfaces on its sink (input), and always outputs a YUV
surface suitable for software encoder elements.

Signed-off-by: Simon Farnsworth <simon.farnsworth at onelan.co.uk>
---

Again, patch made against the 0.3 branch, but should apply to master. I'm
not too worried if this patch gets dropped - it's more for consistency with
the changed vaapiupload than anything else.

 gst/vaapi/gstvaapidownload.c | 63 ++++++++++++++++++++++++++------------------
 1 file changed, 38 insertions(+), 25 deletions(-)

diff --git a/gst/vaapi/gstvaapidownload.c b/gst/vaapi/gstvaapidownload.c
index 63f2afe..d0eaca5 100644
--- a/gst/vaapi/gstvaapidownload.c
+++ b/gst/vaapi/gstvaapidownload.c
@@ -69,12 +69,18 @@ static const char gst_vaapidownload_yuv_caps_str[] =
 static const char gst_vaapidownload_vaapi_caps_str[] =
     GST_VAAPI_SURFACE_CAPS;
 
+static const char gst_vaapidownload_sink_caps_str[] =
+    GST_VAAPI_SURFACE_CAPS "; "
+    "video/x-raw-yuv, "
+    "width  = (int) [ 1, MAX ], "
+    "height = (int) [ 1, MAX ]; ";
+
 static GstStaticPadTemplate gst_vaapidownload_sink_factory =
     GST_STATIC_PAD_TEMPLATE(
         "sink",
         GST_PAD_SINK,
         GST_PAD_ALWAYS,
-        GST_STATIC_CAPS(gst_vaapidownload_vaapi_caps_str));
+        GST_STATIC_CAPS(gst_vaapidownload_sink_caps_str));
 
 static GstStaticPadTemplate gst_vaapidownload_src_factory =
     GST_STATIC_PAD_TEMPLATE(
@@ -260,6 +266,7 @@ gst_vaapidownload_class_init(GstVaapiDownloadClass *klass)
     trans_class->transform_caps   = gst_vaapidownload_transform_caps;
     trans_class->transform_size   = gst_vaapidownload_transform_size;
     trans_class->set_caps         = gst_vaapidownload_set_caps;
+    trans_class->passthrough_on_same_caps = TRUE;
 
     gst_element_class_set_details_simple(
         element_class,
@@ -462,36 +469,40 @@ gst_vaapidownload_transform_caps(
     structure = gst_caps_get_structure(caps, 0);
 
     if (direction == GST_PAD_SINK) {
-        if (!gst_structure_has_name(structure, GST_VAAPI_SURFACE_CAPS_NAME))
-            return NULL;
-        if (!gst_vaapi_ensure_display(download, &download->display))
-            return NULL;
-        out_caps = gst_caps_from_string(gst_vaapidownload_yuv_caps_str);
-
-        /* Build up allowed caps */
-        /* XXX: we don't know the decoded surface format yet so we
-           expose whatever VA images we support */
-        if (download->allowed_caps)
-            allowed_caps = gst_caps_ref(download->allowed_caps);
-        else {
-            allowed_caps = gst_vaapi_display_get_image_caps(download->display);
-            if (!allowed_caps)
+        if (gst_structure_has_name(structure, GST_VAAPI_SURFACE_CAPS_NAME)) {
+            if (!gst_vaapi_ensure_display(download, &download->display))
                 return NULL;
-        }
-        inter_caps = gst_caps_intersect(out_caps, allowed_caps);
-        gst_caps_unref(allowed_caps);
-        gst_caps_unref(out_caps);
-        out_caps = inter_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) {
+            out_caps = gst_caps_from_string(gst_vaapidownload_yuv_caps_str);
+
+            /* Build up allowed caps */
+            /* XXX: we don't know the decoded surface format yet so we
+               expose whatever VA images we support */
+            if (download->allowed_caps)
+                allowed_caps = gst_caps_ref(download->allowed_caps);
+            else {
+                allowed_caps = gst_vaapi_display_get_image_caps(download->display);
+                if (!allowed_caps)
+                    return NULL;
+            }
             inter_caps = gst_caps_intersect(out_caps, allowed_caps);
             gst_caps_unref(allowed_caps);
             gst_caps_unref(out_caps);
             out_caps = inter_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);
+                gst_caps_unref(allowed_caps);
+                gst_caps_unref(out_caps);
+                out_caps = inter_caps;
+            }
         }
+        else if (gst_structure_has_name(structure, "video/x-raw-yuv"))
+            out_caps = gst_caps_copy(caps);
+        else
+            return NULL;
     }
     else {
         if (!gst_structure_has_name(structure, "video/x-raw-yuv"))
@@ -505,6 +516,8 @@ gst_vaapidownload_transform_caps(
             "opengl", G_TYPE_BOOLEAN, USE_VAAPI_GLX,
             NULL
         );
+        gst_caps_ref(caps);
+        gst_caps_merge(out_caps, caps);
     }
 
     if (!gst_vaapi_append_surface_caps(out_caps, caps)) {
-- 
1.7.11.2



More information about the Libva mailing list