Add GstVaapiImagePool and factor out GstVaapiSurfacePool from a base GstVaapiVideoPool.
authorgb <gb@5584edef-b1fe-4b99-b61b-dd2bab72e969>
Fri, 12 Mar 2010 23:47:47 +0000 (23:47 +0000)
committergb <gb@5584edef-b1fe-4b99-b61b-dd2bab72e969>
Fri, 12 Mar 2010 23:47:47 +0000 (23:47 +0000)
gst-libs/gst/vaapi/Makefile.am
gst-libs/gst/vaapi/gstvaapiimagepool.c [new file with mode: 0644]
gst-libs/gst/vaapi/gstvaapiimagepool.h [new file with mode: 0644]
gst-libs/gst/vaapi/gstvaapisurfacepool.c
gst-libs/gst/vaapi/gstvaapisurfacepool.h
gst-libs/gst/vaapi/gstvaapivideopool.c [new file with mode: 0644]
gst-libs/gst/vaapi/gstvaapivideopool.h [new file with mode: 0644]

index c8385a2..d6333d1 100644 (file)
@@ -4,10 +4,12 @@ libgstvaapi_source_c =                                \
        gstvaapidisplay.c                       \
        gstvaapiimage.c                         \
        gstvaapiimageformat.c                   \
+       gstvaapiimagepool.c                     \
        gstvaapisinkbase.c                      \
        gstvaapisubpicture.c                    \
        gstvaapisurface.c                       \
        gstvaapisurfacepool.c                   \
+       gstvaapivideopool.c                     \
        vaapi_utils.c                           \
        $(NULL)
 
@@ -15,10 +17,12 @@ libgstvaapi_source_h =                              \
        gstvaapidisplay.h                       \
        gstvaapiimage.h                         \
        gstvaapiimageformat.h                   \
+       gstvaapiimagepool.h                     \
        gstvaapisinkbase.h                      \
        gstvaapisubpicture.h                    \
        gstvaapisurface.h                       \
        gstvaapisurfacepool.h                   \
+       gstvaapivideopool.h                     \
        vaapi_debug.h                           \
        vaapi_utils.h                           \
        $(NULL)
diff --git a/gst-libs/gst/vaapi/gstvaapiimagepool.c b/gst-libs/gst/vaapi/gstvaapiimagepool.c
new file mode 100644 (file)
index 0000000..9d7170d
--- /dev/null
@@ -0,0 +1,111 @@
+/*
+ *  gstvaapiimagepool.c - Gst VA image pool
+ *
+ *  gstreamer-vaapi (C) 2010 Splitted-Desktop Systems
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
+ */
+
+#include "config.h"
+#include "gstvaapiimagepool.h"
+
+#define DEBUG 1
+#include "vaapi_debug.h"
+
+G_DEFINE_TYPE(
+    GstVaapiImagePool,
+    gst_vaapi_image_pool,
+    GST_VAAPI_TYPE_VIDEO_POOL);
+
+#define GST_VAAPI_IMAGE_POOL_GET_PRIVATE(obj)                   \
+    (G_TYPE_INSTANCE_GET_PRIVATE((obj),                         \
+                                 GST_VAAPI_TYPE_IMAGE_POOL,    \
+                                 GstVaapiImagePoolPrivate))
+
+struct _GstVaapiImagePoolPrivate {
+    GstVaapiImageFormat format;
+    guint               width;
+    guint               height;
+};
+
+static void
+gst_vaapi_image_pool_set_caps(GstVaapiVideoPool *pool, GstCaps *caps)
+{
+    GstVaapiImagePoolPrivate * const priv = GST_VAAPI_IMAGE_POOL(pool)->priv;
+    GstStructure *structure;
+    gint width, height;
+
+    structure = gst_caps_get_structure(caps, 0);
+    gst_structure_get_int(structure, "width", &width);
+    gst_structure_get_int(structure, "height", &height);
+
+    priv->format        = gst_vaapi_image_format_from_caps(caps);
+    priv->width         = width;
+    priv->height        = height;
+}
+
+gpointer
+gst_vaapi_image_pool_alloc_object(
+    GstVaapiVideoPool *pool,
+    GstVaapiDisplay   *display
+)
+{
+    GstVaapiImagePoolPrivate * const priv = GST_VAAPI_IMAGE_POOL(pool)->priv;
+
+    return gst_vaapi_image_new(display,
+                               priv->format,
+                               priv->width,
+                               priv->height);
+}
+
+static void
+gst_vaapi_image_pool_finalize(GObject *object)
+{
+    G_OBJECT_CLASS(gst_vaapi_image_pool_parent_class)->finalize(object);
+}
+
+static void
+gst_vaapi_image_pool_class_init(GstVaapiImagePoolClass *klass)
+{
+    GObjectClass * const object_class = G_OBJECT_CLASS(klass);
+    GstVaapiVideoPoolClass * const pool_class = GST_VAAPI_VIDEO_POOL_CLASS(klass);
+
+    g_type_class_add_private(klass, sizeof(GstVaapiImagePoolPrivate));
+
+    object_class->finalize      = gst_vaapi_image_pool_finalize;
+
+    pool_class->set_caps        = gst_vaapi_image_pool_set_caps;
+    pool_class->alloc_object    = gst_vaapi_image_pool_alloc_object;
+}
+
+static void
+gst_vaapi_image_pool_init(GstVaapiImagePool *pool)
+{
+    GstVaapiImagePoolPrivate *priv = GST_VAAPI_IMAGE_POOL_GET_PRIVATE(pool);
+
+    pool->priv          = priv;
+    priv->format        = 0;
+    priv->width         = 0;
+    priv->height        = 0;
+}
+
+GstVaapiVideoPool *
+gst_vaapi_image_pool_new(GstVaapiDisplay *display, GstCaps *caps)
+{
+    return g_object_new(GST_VAAPI_TYPE_IMAGE_POOL,
+                        "display", display,
+                        "caps",    caps,
+                        NULL);
+}
diff --git a/gst-libs/gst/vaapi/gstvaapiimagepool.h b/gst-libs/gst/vaapi/gstvaapiimagepool.h
new file mode 100644 (file)
index 0000000..67d0086
--- /dev/null
@@ -0,0 +1,77 @@
+/*
+ *  gstvaapiimagepool.h - Gst VA image pool
+ *
+ *  gstreamer-vaapi (C) 2010 Splitted-Desktop Systems
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
+ */
+
+#ifndef GST_VAAPI_IMAGE_POOL_H
+#define GST_VAAPI_IMAGE_POOL_H
+
+#include <gst/vaapi/gstvaapiimage.h>
+#include <gst/vaapi/gstvaapivideopool.h>
+
+G_BEGIN_DECLS
+
+#define GST_VAAPI_TYPE_IMAGE_POOL \
+    (gst_vaapi_image_pool_get_type())
+
+#define GST_VAAPI_IMAGE_POOL(obj)                               \
+    (G_TYPE_CHECK_INSTANCE_CAST((obj),                          \
+                                GST_VAAPI_TYPE_IMAGE_POOL,      \
+                                GstVaapiImagePool))
+
+#define GST_VAAPI_IMAGE_POOL_CLASS(klass)                       \
+    (G_TYPE_CHECK_CLASS_CAST((klass),                           \
+                             GST_VAAPI_TYPE_IMAGE_POOL,         \
+                             GstVaapiImagePoolClass))
+
+#define GST_VAAPI_IS_IMAGE_POOL(obj) \
+    (G_TYPE_CHECK_INSTANCE_TYPE((obj), GST_VAAPI_TYPE_IMAGE_POOL))
+
+#define GST_VAAPI_IS_IMAGE_POOL_CLASS(klass) \
+    (G_TYPE_CHECK_CLASS_TYPE((klass), GST_VAAPI_TYPE_IMAGE_POOL))
+
+#define GST_VAAPI_IMAGE_POOL_GET_CLASS(obj)                     \
+    (G_TYPE_INSTANCE_GET_CLASS((obj),                           \
+                               GST_VAAPI_TYPE_IMAGE_POOL,       \
+                               GstVaapiImagePoolClass))
+
+typedef struct _GstVaapiImagePool               GstVaapiImagePool;
+typedef struct _GstVaapiImagePoolPrivate        GstVaapiImagePoolPrivate;
+typedef struct _GstVaapiImagePoolClass          GstVaapiImagePoolClass;
+
+struct _GstVaapiImagePool {
+    /*< private >*/
+    GstVaapiVideoPool parent_instance;
+
+    GstVaapiImagePoolPrivate *priv;
+};
+
+struct _GstVaapiImagePoolClass {
+    /*< private >*/
+    GstVaapiVideoPoolClass parent_class;
+};
+
+GType
+gst_vaapi_image_pool_get_type(void);
+
+GstVaapiVideoPool *
+gst_vaapi_image_pool_new(GstVaapiDisplay *display, GstCaps *caps);
+
+G_END_DECLS
+
+#endif /* GST_VAAPI_IMAGE_POOL_H */
index e389f4b..0c9ee5b 100644 (file)
 #define DEBUG 1
 #include "vaapi_debug.h"
 
-G_DEFINE_TYPE(GstVaapiSurfacePool, gst_vaapi_surface_pool, G_TYPE_OBJECT);
+G_DEFINE_TYPE(
+    GstVaapiSurfacePool,
+    gst_vaapi_surface_pool,
+    GST_VAAPI_TYPE_VIDEO_POOL);
 
 #define GST_VAAPI_SURFACE_POOL_GET_PRIVATE(obj)                 \
     (G_TYPE_INSTANCE_GET_PRIVATE((obj),                         \
@@ -32,139 +35,59 @@ G_DEFINE_TYPE(GstVaapiSurfacePool, gst_vaapi_surface_pool, G_TYPE_OBJECT);
                                  GstVaapiSurfacePoolPrivate))
 
 struct _GstVaapiSurfacePoolPrivate {
-    GstVaapiDisplay    *display;
-    GQueue              free_surfaces;
-    GList              *used_surfaces;
-    GstCaps            *caps;
     GstVaapiChromaType  chroma_type;
     guint               width;
     guint               height;
 };
 
-enum {
-    PROP_0,
-
-    PROP_DISPLAY,
-    PROP_CAPS,
-};
-
 static void
-gst_vaapi_surface_pool_clear(GstVaapiSurfacePool *pool)
+gst_vaapi_surface_pool_set_caps(GstVaapiVideoPool *pool, GstCaps *caps)
 {
-    GstVaapiSurfacePoolPrivate * const priv = pool->priv;
-    GstVaapiSurface *surface;
-    GList *list, *next;
+    GstVaapiSurfacePoolPrivate *priv = GST_VAAPI_SURFACE_POOL(pool)->priv;
+    GstStructure *structure;
+    gint width, height;
 
-    for (list = priv->used_surfaces; list; list = next) {
-        next = list->next;
-        g_object_unref(list->data);
-        g_list_free_1(list);
-    }
-    priv->used_surfaces = NULL;
+    structure = gst_caps_get_structure(caps, 0);
+    gst_structure_get_int(structure, "width", &width);
+    gst_structure_get_int(structure, "height", &height);
 
-    while ((surface = g_queue_pop_head(&priv->free_surfaces)))
-        g_object_unref(surface);
+    priv->chroma_type   = GST_VAAPI_CHROMA_TYPE_YUV420;
+    priv->width         = width;
+    priv->height        = height;
 }
 
-static void
-gst_vaapi_surface_pool_destroy(GstVaapiSurfacePool *pool)
+gpointer
+gst_vaapi_surface_pool_alloc_object(
+    GstVaapiVideoPool *pool,
+    GstVaapiDisplay   *display
+)
 {
-    GstVaapiSurfacePoolPrivate * const priv = pool->priv;
+    GstVaapiSurfacePoolPrivate *priv = GST_VAAPI_SURFACE_POOL(pool)->priv;
 
-    gst_vaapi_surface_pool_clear(pool);
-
-    if (priv->caps) {
-        gst_caps_unref(priv->caps);
-        priv->caps = NULL;
-    }
-
-    if (priv->display) {
-        g_object_unref(priv->display);
-        priv->display = NULL;
-    }
+    return gst_vaapi_surface_new(display,
+                                 priv->chroma_type,
+                                 priv->width,
+                                 priv->height);
 }
 
 static void
 gst_vaapi_surface_pool_finalize(GObject *object)
 {
-    gst_vaapi_surface_pool_destroy(GST_VAAPI_SURFACE_POOL(object));
-
     G_OBJECT_CLASS(gst_vaapi_surface_pool_parent_class)->finalize(object);
 }
 
 static void
-gst_vaapi_surface_pool_set_property(
-    GObject      *object,
-    guint         prop_id,
-    const GValue *value,
-    GParamSpec   *pspec
-)
-{
-    GstVaapiSurfacePool * const pool = GST_VAAPI_SURFACE_POOL(object);
-
-    switch (prop_id) {
-    case PROP_DISPLAY:
-        pool->priv->display = g_object_ref(g_value_get_object(value));
-        break;
-    case PROP_CAPS:
-        gst_vaapi_surface_pool_set_caps(pool, g_value_get_pointer(value));
-        break;
-    default:
-        G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
-        break;
-    }
-}
-
-static void
-gst_vaapi_surface_pool_get_property(
-    GObject    *object,
-    guint       prop_id,
-    GValue     *value,
-    GParamSpec *pspec
-)
-{
-    GstVaapiSurfacePool * const pool = GST_VAAPI_SURFACE_POOL(object);
-
-    switch (prop_id) {
-    case PROP_DISPLAY:
-        g_value_set_object(value, pool->priv->display);
-        break;
-    case PROP_CAPS:
-        g_value_set_pointer(value, gst_vaapi_surface_pool_get_caps(pool));
-        break;
-    default:
-        G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
-        break;
-    }
-}
-
-static void
 gst_vaapi_surface_pool_class_init(GstVaapiSurfacePoolClass *klass)
 {
     GObjectClass * const object_class = G_OBJECT_CLASS(klass);
+    GstVaapiVideoPoolClass * const pool_class = GST_VAAPI_VIDEO_POOL_CLASS(klass);
 
     g_type_class_add_private(klass, sizeof(GstVaapiSurfacePoolPrivate));
 
     object_class->finalize      = gst_vaapi_surface_pool_finalize;
-    object_class->set_property  = gst_vaapi_surface_pool_set_property;
-    object_class->get_property  = gst_vaapi_surface_pool_get_property;
-
-    g_object_class_install_property
-        (object_class,
-         PROP_DISPLAY,
-         g_param_spec_object("display",
-                             "display",
-                             "Gstreamer/VA display",
-                             GST_VAAPI_TYPE_DISPLAY,
-                             G_PARAM_READWRITE|G_PARAM_CONSTRUCT_ONLY));
 
-    g_object_class_install_property
-        (object_class,
-         PROP_CAPS,
-         g_param_spec_pointer("caps",
-                              "surface caps",
-                              "Surface caps",
-                              G_PARAM_READWRITE));
+    pool_class->set_caps        = gst_vaapi_surface_pool_set_caps;
+    pool_class->alloc_object    = gst_vaapi_surface_pool_alloc_object;
 }
 
 static void
@@ -173,17 +96,12 @@ gst_vaapi_surface_pool_init(GstVaapiSurfacePool *pool)
     GstVaapiSurfacePoolPrivate *priv = GST_VAAPI_SURFACE_POOL_GET_PRIVATE(pool);
 
     pool->priv          = priv;
-    priv->display       = NULL;
-    priv->used_surfaces = NULL;
-    priv->caps          = NULL;
     priv->chroma_type   = 0;
     priv->width         = 0;
     priv->height        = 0;
-
-    g_queue_init(&priv->free_surfaces);
 }
 
-GstVaapiSurfacePool *
+GstVaapiVideoPool *
 gst_vaapi_surface_pool_new(GstVaapiDisplay *display, GstCaps *caps)
 {
     return g_object_new(GST_VAAPI_TYPE_SURFACE_POOL,
@@ -191,87 +109,3 @@ gst_vaapi_surface_pool_new(GstVaapiDisplay *display, GstCaps *caps)
                         "caps",    caps,
                         NULL);
 }
-
-GstCaps *
-gst_vaapi_surface_pool_get_caps(GstVaapiSurfacePool *pool)
-{
-    g_return_val_if_fail(GST_VAAPI_IS_SURFACE_POOL(pool), NULL);
-
-    return pool->priv->caps;
-}
-
-void
-gst_vaapi_surface_pool_set_caps(GstVaapiSurfacePool *pool, GstCaps *caps)
-{
-    GstVaapiSurfacePoolPrivate *priv;
-    GstStructure *structure;
-    gint width, height;
-
-    g_return_if_fail(GST_VAAPI_IS_SURFACE_POOL(pool));
-    g_return_if_fail(GST_IS_CAPS(caps));
-
-    priv = pool->priv;
-
-    structure = gst_caps_get_structure(caps, 0);
-    gst_structure_get_int(structure, "width", &width);
-    gst_structure_get_int(structure, "height", &height);
-
-    /* Don't do anything if caps have not changed */
-    if (width == priv->width && height == priv->height)
-        return;
-
-    gst_vaapi_surface_pool_clear(pool);
-
-    priv->caps          = gst_caps_ref(caps);
-    priv->chroma_type   = GST_VAAPI_CHROMA_TYPE_YUV420;
-    priv->width         = width;
-    priv->height        = height;
-}
-
-GstVaapiSurface *
-gst_vaapi_surface_pool_new_surface(GstVaapiSurfacePool *pool)
-{
-    GstVaapiSurfacePoolPrivate *priv;
-    GstVaapiSurface *surface;
-
-    g_return_val_if_fail(GST_VAAPI_IS_SURFACE_POOL(pool), NULL);
-
-    priv = pool->priv;
-
-    surface = g_queue_pop_head(&priv->free_surfaces);
-    if (!surface) {
-        surface = gst_vaapi_surface_new(
-            priv->display,
-            priv->chroma_type,
-            priv->width,
-            priv->height
-        );
-        if (!surface)
-            return NULL;
-    }
-
-    priv->used_surfaces = g_list_prepend(priv->used_surfaces, surface);
-    return g_object_ref(surface);
-}
-
-void
-gst_vaapi_surface_pool_free_surface(
-    GstVaapiSurfacePool *pool,
-    GstVaapiSurface     *surface
-)
-{
-    GstVaapiSurfacePoolPrivate *priv;
-    GList *list;
-
-    g_return_if_fail(GST_VAAPI_IS_SURFACE_POOL(pool));
-    g_return_if_fail(GST_VAAPI_IS_SURFACE(surface));
-
-    priv = pool->priv;
-    list = g_list_find(priv->used_surfaces, surface);
-    if (!list)
-        return;
-
-    g_object_unref(surface);
-    priv->used_surfaces = g_list_delete_link(priv->used_surfaces, list);
-    g_queue_push_tail(&priv->free_surfaces, surface);
-}
index 4777e29..16b2bc1 100644 (file)
@@ -21,9 +21,8 @@
 #ifndef GST_VAAPI_SURFACE_POOL_H
 #define GST_VAAPI_SURFACE_POOL_H
 
-#include <gst/gstcaps.h>
-#include <gst/vaapi/gstvaapidisplay.h>
 #include <gst/vaapi/gstvaapisurface.h>
+#include <gst/vaapi/gstvaapivideopool.h>
 
 G_BEGIN_DECLS
 
@@ -51,43 +50,28 @@ G_BEGIN_DECLS
                                GST_VAAPI_TYPE_SURFACE_POOL,     \
                                GstVaapiSurfacePoolClass))
 
-typedef struct _GstVaapiSurfacePool           GstVaapiSurfacePool;
-typedef struct _GstVaapiSurfacePoolPrivate    GstVaapiSurfacePoolPrivate;
-typedef struct _GstVaapiSurfacePoolClass      GstVaapiSurfacePoolClass;
+typedef struct _GstVaapiSurfacePool             GstVaapiSurfacePool;
+typedef struct _GstVaapiSurfacePoolPrivate      GstVaapiSurfacePoolPrivate;
+typedef struct _GstVaapiSurfacePoolClass        GstVaapiSurfacePoolClass;
 
 struct _GstVaapiSurfacePool {
     /*< private >*/
-    GObject parent_instance;
+    GstVaapiVideoPool parent_instance;
 
     GstVaapiSurfacePoolPrivate *priv;
 };
 
 struct _GstVaapiSurfacePoolClass {
     /*< private >*/
-    GObjectClass parent_class;
+    GstVaapiVideoPoolClass parent_class;
 };
 
 GType
 gst_vaapi_surface_pool_get_type(void);
 
-GstVaapiSurfacePool *
+GstVaapiVideoPool *
 gst_vaapi_surface_pool_new(GstVaapiDisplay *display, GstCaps *caps);
 
-GstCaps *
-gst_vaapi_surface_pool_get_caps(GstVaapiSurfacePool *pool);
-
-void
-gst_vaapi_surface_pool_set_caps(GstVaapiSurfacePool *pool, GstCaps *caps);
-
-GstVaapiSurface *
-gst_vaapi_surface_pool_new_surface(GstVaapiSurfacePool *pool);
-
-void
-gst_vaapi_surface_pool_free_surface(
-    GstVaapiSurfacePool *pool,
-    GstVaapiSurface     *surface
-);
-
 G_END_DECLS
 
 #endif /* GST_VAAPI_SURFACE_POOL_H */
diff --git a/gst-libs/gst/vaapi/gstvaapivideopool.c b/gst-libs/gst/vaapi/gstvaapivideopool.c
new file mode 100644 (file)
index 0000000..bf8d41a
--- /dev/null
@@ -0,0 +1,249 @@
+/*
+ *  gstvaapivideopool.c - Video object pool abstraction
+ *
+ *  gstreamer-vaapi (C) 2010 Splitted-Desktop Systems
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
+ */
+
+#include "config.h"
+#include "gstvaapivideopool.h"
+
+#define DEBUG 1
+#include "vaapi_debug.h"
+
+G_DEFINE_TYPE(GstVaapiVideoPool, gst_vaapi_video_pool, G_TYPE_OBJECT);
+
+#define GST_VAAPI_VIDEO_POOL_GET_PRIVATE(obj)                   \
+    (G_TYPE_INSTANCE_GET_PRIVATE((obj),                         \
+                                 GST_VAAPI_TYPE_VIDEO_POOL,    \
+                                 GstVaapiVideoPoolPrivate))
+
+struct _GstVaapiVideoPoolPrivate {
+    GstVaapiDisplay    *display;
+    GQueue              free_objects;
+    GList              *used_objects;
+    GstCaps            *caps;
+};
+
+enum {
+    PROP_0,
+
+    PROP_DISPLAY,
+    PROP_CAPS,
+};
+
+static void
+gst_vaapi_video_pool_set_caps(GstVaapiVideoPool *pool, GstCaps *caps);
+
+static void
+gst_vaapi_video_pool_clear(GstVaapiVideoPool *pool)
+{
+    GstVaapiVideoPoolPrivate * const priv = pool->priv;
+    gpointer object;
+    GList *list, *next;
+
+    for (list = priv->used_objects; list; list = next) {
+        next = list->next;
+        g_object_unref(list->data);
+        g_list_free_1(list);
+    }
+    priv->used_objects = NULL;
+
+    while ((object = g_queue_pop_head(&priv->free_objects)))
+        g_object_unref(object);
+}
+
+static void
+gst_vaapi_video_pool_destroy(GstVaapiVideoPool *pool)
+{
+    GstVaapiVideoPoolPrivate * const priv = pool->priv;
+
+    gst_vaapi_video_pool_clear(pool);
+
+    if (priv->caps) {
+        gst_caps_unref(priv->caps);
+        priv->caps = NULL;
+    }
+
+    if (priv->display) {
+        g_object_unref(priv->display);
+        priv->display = NULL;
+    }
+}
+
+static void
+gst_vaapi_video_pool_finalize(GObject *object)
+{
+    gst_vaapi_video_pool_destroy(GST_VAAPI_VIDEO_POOL(object));
+
+    G_OBJECT_CLASS(gst_vaapi_video_pool_parent_class)->finalize(object);
+}
+
+static void
+gst_vaapi_video_pool_set_property(
+    GObject      *object,
+    guint         prop_id,
+    const GValue *value,
+    GParamSpec   *pspec
+)
+{
+    GstVaapiVideoPool * const pool = GST_VAAPI_VIDEO_POOL(object);
+
+    switch (prop_id) {
+    case PROP_DISPLAY:
+        pool->priv->display = g_object_ref(g_value_get_object(value));
+        break;
+    case PROP_CAPS:
+        gst_vaapi_video_pool_set_caps(pool, g_value_get_pointer(value));
+        break;
+    default:
+        G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
+        break;
+    }
+}
+
+static void
+gst_vaapi_video_pool_get_property(
+    GObject    *object,
+    guint       prop_id,
+    GValue     *value,
+    GParamSpec *pspec
+)
+{
+    GstVaapiVideoPool * const pool = GST_VAAPI_VIDEO_POOL(object);
+
+    switch (prop_id) {
+    case PROP_DISPLAY:
+        g_value_set_object(value, pool->priv->display);
+        break;
+    case PROP_CAPS:
+        g_value_set_pointer(value, gst_vaapi_video_pool_get_caps(pool));
+        break;
+    default:
+        G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
+        break;
+    }
+}
+
+static void
+gst_vaapi_video_pool_class_init(GstVaapiVideoPoolClass *klass)
+{
+    GObjectClass * const object_class = G_OBJECT_CLASS(klass);
+
+    g_type_class_add_private(klass, sizeof(GstVaapiVideoPoolPrivate));
+
+    object_class->finalize      = gst_vaapi_video_pool_finalize;
+    object_class->set_property  = gst_vaapi_video_pool_set_property;
+    object_class->get_property  = gst_vaapi_video_pool_get_property;
+
+    g_object_class_install_property
+        (object_class,
+         PROP_DISPLAY,
+         g_param_spec_object("display",
+                             "display",
+                             "Gstreamer/VA display",
+                             GST_VAAPI_TYPE_DISPLAY,
+                             G_PARAM_READWRITE|G_PARAM_CONSTRUCT_ONLY));
+
+    g_object_class_install_property
+        (object_class,
+         PROP_CAPS,
+         g_param_spec_pointer("caps",
+                              "caps",
+                              "Caps",
+                              G_PARAM_READWRITE|G_PARAM_CONSTRUCT_ONLY));
+}
+
+static void
+gst_vaapi_video_pool_init(GstVaapiVideoPool *pool)
+{
+    GstVaapiVideoPoolPrivate *priv = GST_VAAPI_VIDEO_POOL_GET_PRIVATE(pool);
+
+    pool->priv          = priv;
+    priv->display       = NULL;
+    priv->used_objects  = NULL;
+    priv->caps          = NULL;
+
+    g_queue_init(&priv->free_objects);
+}
+
+GstVaapiVideoPool *
+gst_vaapi_video_pool_new(GstVaapiDisplay *display, GstCaps *caps)
+{
+    return g_object_new(GST_VAAPI_TYPE_VIDEO_POOL,
+                        "display", display,
+                        "caps",    caps,
+                        NULL);
+}
+
+GstCaps *
+gst_vaapi_video_pool_get_caps(GstVaapiVideoPool *pool)
+{
+    g_return_val_if_fail(GST_VAAPI_IS_VIDEO_POOL(pool), NULL);
+
+    return pool->priv->caps;
+}
+
+void
+gst_vaapi_video_pool_set_caps(GstVaapiVideoPool *pool, GstCaps *caps)
+{
+    GstVaapiVideoPoolClass * const klass = GST_VAAPI_VIDEO_POOL_GET_CLASS(pool);
+
+    pool->priv->caps = gst_caps_ref(caps);
+
+    if (klass->set_caps)
+        klass->set_caps(pool, caps);
+}
+
+gpointer
+gst_vaapi_video_pool_get_object(GstVaapiVideoPool *pool)
+{
+    gpointer object;
+
+    g_return_val_if_fail(GST_VAAPI_IS_VIDEO_POOL(pool), NULL);
+
+    object = g_queue_pop_head(&pool->priv->free_objects);
+    if (!object) {
+        object = GST_VAAPI_VIDEO_POOL_GET_CLASS(pool)->alloc_object(
+            pool,
+            pool->priv->display
+        );
+        if (!object)
+            return NULL;
+    }
+
+    pool->priv->used_objects = g_list_prepend(pool->priv->used_objects, object);
+    return g_object_ref(object);
+}
+
+void
+gst_vaapi_video_pool_put_object(GstVaapiVideoPool *pool, gpointer object)
+{
+    GstVaapiVideoPoolPrivate *priv;
+    GList *elem;
+
+    g_return_if_fail(GST_VAAPI_IS_VIDEO_POOL(pool));
+    g_return_if_fail(G_IS_OBJECT(object));
+
+    priv = pool->priv;
+    elem = g_list_find(priv->used_objects, object);
+    if (!elem)
+        return;
+
+    g_object_unref(object);
+    priv->used_objects = g_list_delete_link(priv->used_objects, elem);
+    g_queue_push_tail(&priv->free_objects, object);
+}
diff --git a/gst-libs/gst/vaapi/gstvaapivideopool.h b/gst-libs/gst/vaapi/gstvaapivideopool.h
new file mode 100644 (file)
index 0000000..1d3b91a
--- /dev/null
@@ -0,0 +1,86 @@
+/*
+ *  gstvaapivideopool.h - Video object pool abstraction
+ *
+ *  gstreamer-vaapi (C) 2010 Splitted-Desktop Systems
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
+ */
+
+#ifndef GST_VAAPI_VIDEO_POOL_H
+#define GST_VAAPI_VIDEO_POOL_H
+
+#include <gst/gstcaps.h>
+#include <gst/vaapi/gstvaapidisplay.h>
+
+G_BEGIN_DECLS
+
+#define GST_VAAPI_TYPE_VIDEO_POOL \
+    (gst_vaapi_video_pool_get_type())
+
+#define GST_VAAPI_VIDEO_POOL(obj)                               \
+    (G_TYPE_CHECK_INSTANCE_CAST((obj),                          \
+                                GST_VAAPI_TYPE_VIDEO_POOL,      \
+                                GstVaapiVideoPool))
+
+#define GST_VAAPI_VIDEO_POOL_CLASS(klass)                       \
+    (G_TYPE_CHECK_CLASS_CAST((klass),                           \
+                             GST_VAAPI_TYPE_VIDEO_POOL,         \
+                             GstVaapiVideoPoolClass))
+
+#define GST_VAAPI_IS_VIDEO_POOL(obj) \
+    (G_TYPE_CHECK_INSTANCE_TYPE((obj), GST_VAAPI_TYPE_VIDEO_POOL))
+
+#define GST_VAAPI_IS_VIDEO_POOL_CLASS(klass) \
+    (G_TYPE_CHECK_CLASS_TYPE((klass), GST_VAAPI_TYPE_VIDEO_POOL))
+
+#define GST_VAAPI_VIDEO_POOL_GET_CLASS(obj)                     \
+    (G_TYPE_INSTANCE_GET_CLASS((obj),                           \
+                               GST_VAAPI_TYPE_VIDEO_POOL,       \
+                               GstVaapiVideoPoolClass))
+
+typedef struct _GstVaapiVideoPool               GstVaapiVideoPool;
+typedef struct _GstVaapiVideoPoolPrivate        GstVaapiVideoPoolPrivate;
+typedef struct _GstVaapiVideoPoolClass          GstVaapiVideoPoolClass;
+
+struct _GstVaapiVideoPool {
+    /*< private >*/
+    GObject parent_instance;
+
+    GstVaapiVideoPoolPrivate *priv;
+};
+
+struct _GstVaapiVideoPoolClass {
+    /*< private >*/
+    GObjectClass parent_class;
+
+    void     (*set_caps)    (GstVaapiVideoPool *pool, GstCaps *caps);
+    gpointer (*alloc_object)(GstVaapiVideoPool *pool, GstVaapiDisplay *display);
+};
+
+GType
+gst_vaapi_video_pool_get_type(void);
+
+GstCaps *
+gst_vaapi_video_pool_get_caps(GstVaapiVideoPool *pool);
+
+gpointer
+gst_vaapi_video_pool_get_object(GstVaapiVideoPool *pool);
+
+void
+gst_vaapi_video_pool_put_object(GstVaapiVideoPool *pool, gpointer object);
+
+G_END_DECLS
+
+#endif /* GST_VAAPI_VIDEO_POOL_H */