[Libva] [PATCH 1/2] Make vaapiupload element capable of passthrough

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


It's helpful to have an element that takes in both YUV and VA-API surfaces,
and guarantees a VA-API surface out. This lets you design video sink bins
that end in a vaapisink regardless of the source of the video buffer
(vaapidecode or a pure software decoder like vp8dec).

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

With code from "Zhao, Halley" <halley.zhao at intel.com> that fixes buffer
management when in passthrough.

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

This is the patch I need; it's against the 0.3 branch of gstreamer-vaapie,
but should apply OK to master, too.

 gst/vaapi/gstvaapiupload.c | 47 +++++++++++++++++++++++++++++++++++-----------
 1 file changed, 36 insertions(+), 11 deletions(-)

diff --git a/gst/vaapi/gstvaapiupload.c b/gst/vaapi/gstvaapiupload.c
index 0762279..a8e2c6a 100644
--- a/gst/vaapi/gstvaapiupload.c
+++ b/gst/vaapi/gstvaapiupload.c
@@ -67,6 +67,12 @@ static const char gst_vaapiupload_yuv_caps_str[] =
     "width  = (int) [ 1, MAX ], "
     "height = (int) [ 1, MAX ]; ";
 
+static const char gst_vaapiupload_sink_caps_str[] =
+    "video/x-raw-yuv, "
+    "width  = (int) [ 1, MAX ], "
+    "height = (int) [ 1, MAX ]; "
+    GST_VAAPI_SURFACE_CAPS;
+
 static const char gst_vaapiupload_vaapi_caps_str[] =
     GST_VAAPI_SURFACE_CAPS;
 
@@ -75,7 +81,7 @@ static GstStaticPadTemplate gst_vaapiupload_sink_factory =
         "sink",
         GST_PAD_SINK,
         GST_PAD_ALWAYS,
-        GST_STATIC_CAPS(gst_vaapiupload_yuv_caps_str));
+        GST_STATIC_CAPS(gst_vaapiupload_sink_caps_str));
 
 static GstStaticPadTemplate gst_vaapiupload_src_factory =
     GST_STATIC_PAD_TEMPLATE(
@@ -297,6 +303,7 @@ gst_vaapiupload_class_init(GstVaapiUploadClass *klass)
     trans_class->set_caps       = gst_vaapiupload_set_caps;
     trans_class->get_unit_size  = gst_vaapiupload_get_unit_size;
     trans_class->prepare_output_buffer = gst_vaapiupload_prepare_output_buffer;
+    trans_class->passthrough_on_same_caps = TRUE;
 
     gst_element_class_set_details_simple(
         element_class,
@@ -476,17 +483,21 @@ gst_vaapiupload_transform_caps(
     structure = gst_caps_get_structure(caps, 0);
 
     if (direction == GST_PAD_SINK) {
-        if (!gst_structure_has_name(structure, "video/x-raw-yuv"))
+        if (gst_structure_has_name(structure, "video/x-raw-yuv")) {
+            out_caps = gst_caps_from_string(gst_vaapiupload_vaapi_caps_str);
+
+            structure = gst_caps_get_structure(out_caps, 0);
+            gst_structure_set(
+                structure,
+                "type", G_TYPE_STRING, "vaapi",
+                "opengl", G_TYPE_BOOLEAN, USE_VAAPI_GLX,
+                NULL
+            );
+        }
+        else if (gst_structure_has_name(structure, GST_VAAPI_SURFACE_CAPS_NAME))
+            out_caps = gst_caps_copy(caps);
+        else
             return NULL;
-        out_caps = gst_caps_from_string(gst_vaapiupload_vaapi_caps_str);
-
-        structure = gst_caps_get_structure(out_caps, 0);
-        gst_structure_set(
-            structure,
-            "type", G_TYPE_STRING, "vaapi",
-            "opengl", G_TYPE_BOOLEAN, USE_VAAPI_GLX,
-            NULL
-        );
     }
     else {
         if (!gst_structure_has_name(structure, GST_VAAPI_SURFACE_CAPS_NAME))
@@ -502,6 +513,7 @@ gst_vaapiupload_transform_caps(
             gst_caps_unref(out_caps);
             out_caps = inter_caps;
         }
+        gst_caps_append(out_caps, gst_caps_from_string(gst_vaapiupload_vaapi_caps_str));
     }
 
     if (!gst_vaapi_append_surface_caps(out_caps, caps)) {
@@ -655,6 +667,9 @@ gst_vaapiupload_set_caps(
 {
     GstVaapiUpload * const upload = GST_VAAPIUPLOAD(trans);
 
+    if (gst_caps_is_equal(incaps, outcaps))
+        return TRUE;
+
     if (!gst_vaapiupload_negotiate_buffers(upload, incaps, outcaps))
         return FALSE;
 
@@ -696,6 +711,11 @@ gst_vaapiupload_buffer_alloc(
     GstVaapiSurface *surface = NULL;
     GstVaapiVideoBuffer *vbuffer;
 
+    *pbuf = NULL;
+    if (gst_base_transform_is_passthrough(trans)) {
+        return GST_FLOW_OK;
+    }
+
     /* Check if we can use direct-rendering */
     if (!gst_vaapiupload_negotiate_buffers(upload, caps, caps))
         goto error;
@@ -785,6 +805,11 @@ gst_vaapiupload_prepare_output_buffer(
     GstVaapiUpload * const upload = GST_VAAPIUPLOAD(trans);
     GstBuffer *buffer = NULL;
 
+    *poutbuf = NULL;
+    if (gst_base_transform_is_passthrough(trans)) {
+        return GST_FLOW_OK;
+    }
+
     if (upload->direct_rendering == 2) {
         if (GST_VAAPI_IS_VIDEO_BUFFER(inbuf)) {
             buffer = gst_vaapi_video_buffer_new_from_buffer(inbuf);
-- 
1.7.11.2



More information about the Libva mailing list