vaapiupload: use new GstVaapiUploader helper.
authorZhao Halley <halley.zhao@intel.com>
Tue, 20 Nov 2012 13:32:40 +0000 (14:32 +0100)
committerWei,changzhi <changzhix.wei@intel.com>
Wed, 17 Apr 2013 08:16:30 +0000 (16:16 +0800)
Use GstVaapiUploader helper that automatically handles direct rendering
mode, thus making the "direct-rendering" property obsolete and hence it
is now removed.

The "direct-rendering" level 2, i.e. exposing VA surface buffers, was never
really well supported and it could actually trigger degraded performance.

Signed-off-by: Gwenole Beauchesne <gwenole.beauchesne@intel.com>
gst/vaapi/gstvaapiupload.c
gst/vaapi/gstvaapiupload.h

index 9e90d48..d75fc57 100644 (file)
@@ -1,5 +1,5 @@
 /*
- *  gstvaapiupload.c - VA-API video uploader
+ *  gstvaapiupload.c - VA-API video upload element
  *
  *  Copyright (C) 2010-2011 Splitted-Desktop Systems
  *  Copyright (C) 2011-2012 Intel Corporation
@@ -92,20 +92,6 @@ G_DEFINE_TYPE_WITH_CODE(
     G_IMPLEMENT_INTERFACE(GST_TYPE_VIDEO_CONTEXT,
                           gst_video_context_interface_init))
 
-/*
- * Direct rendering levels (direct-rendering)
- * 0: upstream allocated YUV pixels
- * 1: vaapiupload allocated YUV pixels (mapped from VA image)
- * 2: vaapiupload allocated YUV pixels (mapped from VA surface)
- */
-#define DIRECT_RENDERING_DEFAULT 2
-
-enum {
-    PROP_0,
-
-    PROP_DIRECT_RENDERING,
-};
-
 static gboolean
 gst_vaapiupload_start(GstBaseTransform *trans);
 
@@ -187,8 +173,12 @@ static void
 gst_vaapiupload_set_video_context(GstVideoContext *context, const gchar *type,
     const GValue *value)
 {
-  GstVaapiUpload *upload = GST_VAAPIUPLOAD (context);
-  gst_vaapi_set_display (type, value, &upload->display);
+    GstVaapiUpload * const upload = GST_VAAPIUPLOAD(context);
+
+    gst_vaapi_set_display(type, value, &upload->display);
+
+    if (upload->uploader)
+        gst_vaapi_uploader_ensure_display(upload->uploader, upload->display);
 }
 
 static void
@@ -200,8 +190,7 @@ gst_video_context_interface_init(GstVideoContextInterface *iface)
 static void
 gst_vaapiupload_destroy(GstVaapiUpload *upload)
 {
-    g_clear_object(&upload->images);
-    g_clear_object(&upload->surfaces);
+    g_clear_object(&upload->uploader);
     g_clear_object(&upload->display);
 }
 
@@ -213,49 +202,6 @@ gst_vaapiupload_finalize(GObject *object)
     G_OBJECT_CLASS(gst_vaapiupload_parent_class)->finalize(object);
 }
 
-
-static void
-gst_vaapiupload_set_property(
-    GObject      *object,
-    guint         prop_id,
-    const GValue *value,
-    GParamSpec   *pspec
-)
-{
-    GstVaapiUpload * const upload = GST_VAAPIUPLOAD(object);
-
-    switch (prop_id) {
-    case PROP_DIRECT_RENDERING:
-        GST_OBJECT_LOCK(upload);
-        upload->direct_rendering = g_value_get_uint(value);
-        GST_OBJECT_UNLOCK(upload);
-        break;
-    default:
-        G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
-        break;
-    }
-}
-
-static void
-gst_vaapiupload_get_property(
-    GObject    *object,
-    guint       prop_id,
-    GValue     *value,
-    GParamSpec *pspec
-)
-{
-    GstVaapiUpload * const upload = GST_VAAPIUPLOAD(object);
-
-    switch (prop_id) {
-    case PROP_DIRECT_RENDERING:
-        g_value_set_uint(value, upload->direct_rendering);
-        break;
-    default:
-        G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
-        break;
-    }
-}
-
 static void
 gst_vaapiupload_class_init(GstVaapiUploadClass *klass)
 {
@@ -268,8 +214,6 @@ gst_vaapiupload_class_init(GstVaapiUploadClass *klass)
                             GST_PLUGIN_NAME, 0, GST_PLUGIN_DESC);
 
     object_class->finalize      = gst_vaapiupload_finalize;
-    object_class->set_property  = gst_vaapiupload_set_property;
-    object_class->get_property  = gst_vaapiupload_get_property;
 
     trans_class->start          = gst_vaapiupload_start;
     trans_class->stop           = gst_vaapiupload_stop;
@@ -296,35 +240,6 @@ gst_vaapiupload_class_init(GstVaapiUploadClass *klass)
     pad_template = gst_static_pad_template_get(&gst_vaapiupload_src_factory);
     gst_element_class_add_pad_template(element_class, pad_template);
     gst_object_unref(pad_template);
-
-    /**
-     * GstVaapiUpload:direct-rendering:
-     *
-     * Selects the direct rendering level.
-     * <orderedlist>
-     * <listitem override="0">
-     *   Disables direct rendering.
-     * </listitem>
-     * <listitem>
-     *   Enables direct rendering to the output buffer. i.e. this
-     *   tries to use a single buffer for both sink and src pads.
-     * </listitem>
-     * <listitem>
-     *   Enables direct rendering to the underlying surface. i.e. with
-     *   drivers supporting vaDeriveImage(), the output surface pixels
-     *   will be modified directly.
-     * </listitem>
-     * </orderedlist>
-     */
-    g_object_class_install_property
-        (object_class,
-         PROP_DIRECT_RENDERING,
-         g_param_spec_uint("direct-rendering",
-                           "Direct rendering",
-                           "Direct rendering level",
-                           0, 2,
-                           DIRECT_RENDERING_DEFAULT,
-                           G_PARAM_READWRITE));
 }
 
 static void
@@ -332,19 +247,6 @@ gst_vaapiupload_init(GstVaapiUpload *upload)
 {
     GstPad *sinkpad, *srcpad;
 
-    upload->display                    = NULL;
-    upload->images                     = NULL;
-    upload->images_reset               = FALSE;
-    upload->image_width                = 0;
-    upload->image_height               = 0;
-    upload->surfaces                   = NULL;
-    upload->surfaces_reset             = FALSE;
-    upload->surface_width              = 0;
-    upload->surface_height             = 0;
-    upload->direct_rendering_caps      = 0;
-    upload->direct_rendering           = G_MAXUINT32;
-    upload->need_manual_upload        = FALSE;
-
     /* Override buffer allocator on sink pad */
     sinkpad = gst_element_get_static_pad(GST_ELEMENT(upload), "sink");
     gst_pad_set_bufferalloc_function(
@@ -368,11 +270,27 @@ gst_vaapiupload_ensure_display(GstVaapiUpload *upload)
 }
 
 static gboolean
+gst_vaapiupload_ensure_uploader(GstVaapiUpload *upload)
+{
+    if (!gst_vaapiupload_ensure_display(upload))
+        return FALSE;
+
+    if (!upload->uploader) {
+        upload->uploader = gst_vaapi_uploader_new(upload->display);
+        if (!upload->uploader)
+            return FALSE;
+    }
+    if (!gst_vaapi_uploader_ensure_display(upload->uploader, upload->display))
+        return FALSE;
+    return TRUE;
+}
+
+static gboolean
 gst_vaapiupload_start(GstBaseTransform *trans)
 {
     GstVaapiUpload * const upload = GST_VAAPIUPLOAD(trans);
 
-    if (!gst_vaapiupload_ensure_display(upload))
+    if (!gst_vaapiupload_ensure_uploader(upload))
         return FALSE;
     return TRUE;
 }
@@ -395,65 +313,9 @@ gst_vaapiupload_transform(
 )
 {
     GstVaapiUpload * const upload = GST_VAAPIUPLOAD(trans);
-    GstVaapiVideoBuffer *vbuffer;
-    GstVaapiSurface *surface;
-    GstVaapiImage *image;
-    gboolean success;
-
-    vbuffer = GST_VAAPI_VIDEO_BUFFER(outbuf);
-    surface = gst_vaapi_video_buffer_get_surface(vbuffer);
-    if (!surface)
+    if (!gst_vaapi_uploader_process(upload->uploader, inbuf, outbuf))
         return GST_FLOW_UNEXPECTED;
-
-    if (upload->direct_rendering) {
-        if (!GST_VAAPI_IS_VIDEO_BUFFER(inbuf)) {
-            GST_DEBUG("GstVaapiVideoBuffer was expected");
-            return GST_FLOW_UNEXPECTED;
-        }
-
-        vbuffer = GST_VAAPI_VIDEO_BUFFER(inbuf);
-        image   = gst_vaapi_video_buffer_get_image(vbuffer);
-        if (!image)
-            return GST_FLOW_UNEXPECTED;
-        if (!gst_vaapi_image_unmap(image))
-            return GST_FLOW_UNEXPECTED;
-
-        if (upload->direct_rendering < 2) {
-            if (!gst_vaapi_surface_put_image(surface, image))
-                goto error_put_image;
-        }
-        goto flow_ok;
-    }
-
-    image = gst_vaapi_video_pool_get_object(upload->images);
-    if (!image)
-        goto error_put_image;
-
-    if (!upload->need_manual_upload) {
-        gst_vaapi_image_update_from_buffer(image, inbuf, NULL);
-    } else { /* manually copy data to image*/
-        success = gst_vaapi_convert_buffer_to_image(image, inbuf);
-        if (!success)
-            goto error_put_image;
-    }
-
-    success = gst_vaapi_surface_put_image(surface, image);
-    gst_vaapi_video_pool_put_object(upload->images, image);
-    if (!success)
-        goto error_put_image;
-
-flow_ok:
-    FPS_CALCULATION(vaapiupload);
     return GST_FLOW_OK;
-
-error_put_image:
-    {
-        GST_WARNING("failed to upload %" GST_FOURCC_FORMAT " image "
-                    "to surface 0x%08x",
-                    GST_FOURCC_ARGS(gst_vaapi_image_get_format(image)),
-                    gst_vaapi_surface_get_id(surface));
-        return GST_FLOW_OK;
-    }
 }
 
 static GstCaps *
@@ -520,238 +382,6 @@ gst_vaapiupload_transform_caps(
 }
 
 static gboolean
-gst_vaapiupload_ensure_image_pool(GstVaapiUpload *upload, GstCaps *caps)
-{
-    GstStructure * const structure = gst_caps_get_structure(caps, 0);
-    gint width, height;
-
-    gst_structure_get_int(structure, "width",  &width);
-    gst_structure_get_int(structure, "height", &height);
-
-    if (width != upload->image_width || height != upload->image_height) {
-        upload->image_width  = width;
-        upload->image_height = height;
-        g_clear_object(&upload->images);
-        upload->images = gst_vaapi_image_pool_new(upload->display, caps);
-        if (!upload->images)
-            return FALSE;
-        upload->images_reset = TRUE;
-    }
-    return TRUE;
-}
-
-static gboolean
-gst_vaapiupload_ensure_surface_pool(GstVaapiUpload *upload, GstCaps *caps)
-{
-    GstStructure * const structure = gst_caps_get_structure(caps, 0);
-    gint width, height;
-
-    gst_structure_get_int(structure, "width",  &width);
-    gst_structure_get_int(structure, "height", &height);
-
-    if (width != upload->surface_width || height != upload->surface_height) {
-        upload->surface_width  = width;
-        upload->surface_height = height;
-        g_clear_object(&upload->surfaces);
-        upload->surfaces = gst_vaapi_surface_pool_new(upload->display, caps);
-        if (!upload->surfaces)
-            return FALSE;
-        upload->surfaces_reset = TRUE;
-    }
-    return TRUE;
-}
-
-static void
-gst_vaapiupload_ensure_direct_rendering_caps(
-    GstVaapiUpload *upload,
-    GstCaps         *caps
-)
-{
-    GstVaapiSurface *surface;
-    GstVaapiImage *image;
-    GstVaapiImageFormat vaformat;
-    GstVideoFormat vformat;
-    GstStructure *structure;
-    gint width, height;
-
-    if (!upload->images_reset && !upload->surfaces_reset)
-        return;
-
-    upload->images_reset          = FALSE;
-    upload->surfaces_reset        = FALSE;
-    upload->direct_rendering_caps = 0;
-
-    structure = gst_caps_get_structure(caps, 0);
-    if (!structure)
-        return;
-    gst_structure_get_int(structure, "width",  &width);
-    gst_structure_get_int(structure, "height", &height);
-
-    /* Translate from Gst video format to VA image format */
-    if (!gst_video_format_parse_caps(caps, &vformat, NULL, NULL))
-        return;
-    if (!gst_video_format_is_yuv(vformat))
-        return;
-    vaformat = gst_vaapi_image_format_from_video(vformat);
-    if (!vaformat)
-        return;
-
-    /* Check if we can alias sink & output buffers (same data_size) */
-    image = gst_vaapi_video_pool_get_object(upload->images);
-    if (image) {
-        if (upload->direct_rendering_caps == 0 &&
-            (gst_vaapi_image_get_format(image) == vaformat &&
-             gst_vaapi_image_is_linear(image) &&
-             (gst_vaapi_image_get_data_size(image) ==
-              gst_video_format_get_size(vformat, width, height))))
-            upload->direct_rendering_caps = 1;
-        gst_vaapi_video_pool_put_object(upload->images, image);
-    }
-
-    /* Check if we can access to the surface pixels directly */
-    surface = gst_vaapi_video_pool_get_object(upload->surfaces);
-    if (surface) {
-        image = gst_vaapi_surface_derive_image(surface);
-        if (image) {
-            if (gst_vaapi_image_map(image)) {
-                if (upload->direct_rendering_caps == 1 &&
-                    (gst_vaapi_image_get_format(image) == vaformat &&
-                     gst_vaapi_image_is_linear(image) &&
-                     (gst_vaapi_image_get_data_size(image) ==
-                      gst_video_format_get_size(vformat, width, height))))
-                    upload->direct_rendering_caps = 2;
-                gst_vaapi_image_unmap(image);
-            }
-            g_object_unref(image);
-        }
-        gst_vaapi_video_pool_put_object(upload->surfaces, surface);
-    }
-}
-
-typedef enum YUV_TYPE {
-  YUV_UNKOWN = 0,
-  YUV_411    = 1,
-  YUV_422    = 2,
-  YUV_444    = 4
-} YUV_TYPE;
-
-static YUV_TYPE
-_image_format_to_yuv_type(guint32 fourcc)
-{
-    switch (fourcc) {
-        case GST_MAKE_FOURCC('N','V','1','2'):
-        case GST_MAKE_FOURCC('Y','V','1','2'):
-        case GST_MAKE_FOURCC('I','4','2','0'):
-        case GST_MAKE_FOURCC('N','V','2','1'):
-        return YUV_411;
-
-        case GST_MAKE_FOURCC('Y','U','Y','2'):
-        case GST_MAKE_FOURCC('Y','V','Y','U'):
-        return YUV_422;
-
-        case GST_MAKE_FOURCC('A','Y','U','V'):
-        return YUV_UNKOWN;
-
-        default:
-        return YUV_UNKOWN;
-    }
-}
-
-static GstCaps *
-_get_nearest_caps(GstCaps *caps_list, GstCaps *src_caps)
-{
-    GstCaps *ret = NULL;
-    GstStructure *cur_struct, *tmp_struct;
-    guint32 cur_format, dest_format, tmp_format;
-    YUV_TYPE cur_type, tmp_type;
-    const GValue*tmp_val;
-    guint  n_caps;
-    guint  i;
-    guint min_diff, tmp_diff;
-
-    cur_struct = gst_caps_get_structure(src_caps, 0);
-    tmp_val = gst_structure_get_value (cur_struct, "format");
-    if (!tmp_val)
-        return NULL;
-
-    cur_format = gst_value_get_fourcc(tmp_val);
-    if((cur_type = _image_format_to_yuv_type(cur_format)) == YUV_UNKOWN)
-        return NULL;
-
-    n_caps = gst_caps_get_size(caps_list);
-    min_diff = 100;
-    dest_format = 0;
-    for (i = 0; i < n_caps; ++i) {
-      tmp_struct = gst_caps_get_structure(caps_list, i);
-      tmp_val = gst_structure_get_value (tmp_struct, "format");
-      if (!tmp_val)
-          continue;
-      tmp_format = gst_value_get_fourcc(tmp_val);
-      if ((tmp_type = _image_format_to_yuv_type(tmp_format)) == YUV_UNKOWN)
-          continue;
-      tmp_diff = abs(tmp_type - cur_type);
-      if (tmp_diff < min_diff) {
-          min_diff = tmp_diff;
-          dest_format = tmp_format;
-      }
-    }
-
-    if (dest_format == 0)
-      return NULL;
-
-    ret = gst_caps_copy(src_caps);
-    tmp_struct = gst_caps_get_structure(ret, 0);
-    gst_structure_set(tmp_struct, "format", GST_TYPE_FOURCC, dest_format, NULL);
-    return ret;
-}
-
-static gboolean
-gst_vaapiupload_negotiate_buffers(
-    GstVaapiUpload  *upload,
-    GstCaps          *incaps,
-    GstCaps          *outcaps
-)
-{
-    guint dr;
-    gboolean ret = TRUE;
-    GstCaps *image_allowed_caps = NULL;
-    GstCaps *image_caps = NULL;
-
-    image_allowed_caps = gst_vaapi_display_get_image_caps(upload->display);
-    if (gst_caps_can_intersect(incaps, image_allowed_caps)) {
-        image_caps = gst_caps_ref(incaps);
-        upload->need_manual_upload = FALSE;
-    } else {
-        image_caps = _get_nearest_caps(image_allowed_caps, incaps);
-        upload->need_manual_upload = TRUE;
-    }
-
-    if (!gst_vaapiupload_ensure_image_pool(upload, image_caps))
-        goto failed;
-
-    if (!gst_vaapiupload_ensure_surface_pool(upload, outcaps))
-        goto failed;
-
-    if (upload->direct_rendering && !upload->need_manual_upload)
-      gst_vaapiupload_ensure_direct_rendering_caps(upload, incaps);
-    dr = MIN(upload->direct_rendering, upload->direct_rendering_caps);
-    if (upload->direct_rendering != dr) {
-        upload->direct_rendering = dr;
-        GST_DEBUG("direct-rendering level: %d", dr);
-    }
-    ret = TRUE;
-    goto end;
-
-  failed:
-    ret = FALSE;
-
-  end:
-    gst_caps_unref(image_caps);
-    gst_caps_unref(image_allowed_caps);
-    return ret;
-}
-
-static gboolean
 gst_vaapiupload_set_caps(
     GstBaseTransform *trans,
     GstCaps          *incaps,
@@ -760,7 +390,7 @@ gst_vaapiupload_set_caps(
 {
     GstVaapiUpload * const upload = GST_VAAPIUPLOAD(trans);
 
-    if (!gst_vaapiupload_negotiate_buffers(upload, incaps, outcaps))
+    if (!gst_vaapi_uploader_ensure_caps(upload->uploader, incaps, outcaps))
         return FALSE;
 
     GST_INFO("set caps\nIN caps:\n%" GST_PTR_FORMAT "\nOUT caps:\n%" GST_PTR_FORMAT,
@@ -798,68 +428,17 @@ gst_vaapiupload_buffer_alloc(
 )
 {
     GstVaapiUpload * const upload = GST_VAAPIUPLOAD(trans);
-    GstBuffer *buffer = NULL;
-    GstVaapiImage *image = NULL;
-    GstVaapiSurface *surface = NULL;
-    GstVaapiVideoBuffer *vbuffer;
+    *pbuf = NULL;
 
-    /* already checked */
-    if (!upload->direct_rendering)
-        return GST_FLOW_OK;
+    if (!gst_vaapi_uploader_ensure_display(upload->uploader, upload->display))
+        return GST_FLOW_NOT_SUPPORTED;
+    if (!gst_vaapi_uploader_ensure_caps(upload->uploader, caps, NULL))
+        return GST_FLOW_NOT_SUPPORTED;
 
-    /* Check if we can use direct-rendering */
-    if (!gst_vaapiupload_negotiate_buffers(upload, caps, caps))
-        goto error;
-    if (!upload->direct_rendering)
+    /* Allocate a regular GstBuffer if direct rendering is not supported */
+    if (!gst_vaapi_uploader_has_direct_rendering(upload->uploader))
         return GST_FLOW_OK;
-
-    switch (upload->direct_rendering) {
-    case 2:
-        buffer  = gst_vaapi_video_buffer_new_from_pool(upload->surfaces);
-        if (!buffer)
-            goto error;
-        vbuffer = GST_VAAPI_VIDEO_BUFFER(buffer);
-
-        surface = gst_vaapi_video_buffer_get_surface(vbuffer);
-        image   = gst_vaapi_surface_derive_image(surface);
-        if (image && gst_vaapi_image_get_data_size(image) == size) {
-            gst_vaapi_video_buffer_set_image(vbuffer, image);
-            g_object_unref(image); /* video buffer owns an extra reference */
-            break;
-        }
-
-        /* We can't use the derive-image optimization. Disable it. */
-        upload->direct_rendering = 1;
-        gst_buffer_unref(buffer);
-        buffer = NULL;
-
-    case 1:
-        buffer  = gst_vaapi_video_buffer_new_from_pool(upload->images);
-        if (!buffer)
-            goto error;
-        vbuffer = GST_VAAPI_VIDEO_BUFFER(buffer);
-
-        image   = gst_vaapi_video_buffer_get_image(vbuffer);
-        break;
-    }
-    g_assert(image);
-
-    if (!gst_vaapi_image_map(image))
-        goto error;
-
-    GST_BUFFER_DATA(buffer) = gst_vaapi_image_get_plane(image, 0);
-    GST_BUFFER_SIZE(buffer) = gst_vaapi_image_get_data_size(image);
-
-    gst_buffer_set_caps(buffer, caps);
-    *pbuf = buffer;
-    return GST_FLOW_OK;
-
-error:
-    /* We can't use the inout-buffers optimization. Disable it. */
-    GST_DEBUG("disable in/out buffer optimization");
-    if (buffer)
-        gst_buffer_unref(buffer);
-    upload->direct_rendering = 0;
+    *pbuf = gst_vaapi_uploader_get_buffer(upload->uploader);
     return GST_FLOW_OK;
 }
 
@@ -894,25 +473,24 @@ gst_vaapiupload_prepare_output_buffer(
 )
 {
     GstVaapiUpload * const upload = GST_VAAPIUPLOAD(trans);
-    GstBuffer *buffer = NULL;
+    GstBuffer *buffer;
 
-    if (upload->direct_rendering == 2) {
-        if (GST_VAAPI_IS_VIDEO_BUFFER(inbuf)) {
-            buffer = gst_vaapi_video_buffer_new_from_buffer(inbuf);
-            GST_BUFFER_SIZE(buffer) = size;
-        }
-        else {
-            GST_DEBUG("upstream element destroyed our in/out buffer");
-            upload->direct_rendering = 1;
-        }
-    }
+    *poutbuf = NULL;
 
-    if (!buffer) {
-        buffer = gst_vaapi_video_buffer_new_from_pool(upload->surfaces);
-        if (!buffer)
-            return GST_FLOW_UNEXPECTED;
-        gst_buffer_set_caps(buffer, caps);
-    }
+    if (!gst_vaapi_uploader_has_direct_rendering(upload->uploader))
+        buffer = gst_vaapi_uploader_get_buffer(upload->uploader);
+    else if (GST_VAAPI_IS_VIDEO_BUFFER(inbuf))
+        buffer = gst_vaapi_video_buffer_new_from_buffer(inbuf);
+    else if (GST_VAAPI_IS_VIDEO_BUFFER(inbuf->parent))
+        buffer = gst_vaapi_video_buffer_new_from_buffer(inbuf->parent);
+    else
+        buffer = NULL;
+    if (!buffer)
+        return GST_FLOW_UNEXPECTED;
+
+    gst_buffer_set_caps(buffer, caps);
+    GST_BUFFER_DATA(buffer) = NULL;
+    GST_BUFFER_SIZE(buffer) = 0;
 
     *poutbuf = buffer;
     return GST_FLOW_OK;
index c9627d2..cb22036 100644 (file)
@@ -1,5 +1,5 @@
 /*
- *  gstvaapiupload.h - VA-API video uploader
+ *  gstvaapiupload.h - VA-API video upload element
  *
  *  Copyright (C) 2010-2011 Splitted-Desktop Systems
  *  Copyright (C) 2011-2012 Intel Corporation
 #define GST_VAAPIUPLOAD_H
 
 #include <gst/base/gstbasetransform.h>
-#include <gst/vaapi/gstvaapidisplay.h>
-#include <gst/vaapi/gstvaapisurface.h>
-#include <gst/vaapi/gstvaapiimagepool.h>
-#include <gst/vaapi/gstvaapisurfacepool.h>
-#include <gst/vaapi/gstvaapivideobuffer.h>
+#include "gstvaapiuploader.h"
 
 G_BEGIN_DECLS
 
@@ -59,25 +55,12 @@ G_BEGIN_DECLS
 typedef struct _GstVaapiUpload                  GstVaapiUpload;
 typedef struct _GstVaapiUploadClass             GstVaapiUploadClass;
 
-/* Max output surfaces */
-#define GST_VAAPIUPLOAD_MAX_SURFACES 2
-
 struct _GstVaapiUpload {
     /*< private >*/
     GstBaseTransform    parent_instance;
 
     GstVaapiDisplay    *display;
-    GstVaapiVideoPool  *images;
-    guint               image_width;
-    guint               image_height;
-    GstVaapiVideoPool  *surfaces;
-    guint               surface_width;
-    guint               surface_height;
-    guint               direct_rendering_caps;
-    guint               direct_rendering;
-    unsigned int        images_reset    : 1;
-    unsigned int        surfaces_reset  : 1;
-    unsigned int        need_manual_upload : 1;
+    GstVaapiUploader   *uploader;
 };
 
 struct _GstVaapiUploadClass {