From 809933a46ba7354824bb2a82cdb8e431217e201c Mon Sep 17 00:00:00 2001 From: gb Date: Fri, 12 Mar 2010 23:47:47 +0000 Subject: [PATCH] Add GstVaapiImagePool and factor out GstVaapiSurfacePool from a base GstVaapiVideoPool. --- gst-libs/gst/vaapi/Makefile.am | 4 + gst-libs/gst/vaapi/gstvaapiimagepool.c | 111 ++++++++++++++ gst-libs/gst/vaapi/gstvaapiimagepool.h | 77 ++++++++++ gst-libs/gst/vaapi/gstvaapisurfacepool.c | 222 ++++----------------------- gst-libs/gst/vaapi/gstvaapisurfacepool.h | 30 +--- gst-libs/gst/vaapi/gstvaapivideopool.c | 249 +++++++++++++++++++++++++++++++ gst-libs/gst/vaapi/gstvaapivideopool.h | 86 +++++++++++ 7 files changed, 562 insertions(+), 217 deletions(-) create mode 100644 gst-libs/gst/vaapi/gstvaapiimagepool.c create mode 100644 gst-libs/gst/vaapi/gstvaapiimagepool.h create mode 100644 gst-libs/gst/vaapi/gstvaapivideopool.c create mode 100644 gst-libs/gst/vaapi/gstvaapivideopool.h diff --git a/gst-libs/gst/vaapi/Makefile.am b/gst-libs/gst/vaapi/Makefile.am index c8385a2..d6333d1 100644 --- a/gst-libs/gst/vaapi/Makefile.am +++ b/gst-libs/gst/vaapi/Makefile.am @@ -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 index 0000000..9d7170d --- /dev/null +++ b/gst-libs/gst/vaapi/gstvaapiimagepool.c @@ -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 index 0000000..67d0086 --- /dev/null +++ b/gst-libs/gst/vaapi/gstvaapiimagepool.h @@ -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 +#include + +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 */ diff --git a/gst-libs/gst/vaapi/gstvaapisurfacepool.c b/gst-libs/gst/vaapi/gstvaapisurfacepool.c index e389f4b..0c9ee5b 100644 --- a/gst-libs/gst/vaapi/gstvaapisurfacepool.c +++ b/gst-libs/gst/vaapi/gstvaapisurfacepool.c @@ -24,7 +24,10 @@ #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); -} diff --git a/gst-libs/gst/vaapi/gstvaapisurfacepool.h b/gst-libs/gst/vaapi/gstvaapisurfacepool.h index 4777e29..16b2bc1 100644 --- a/gst-libs/gst/vaapi/gstvaapisurfacepool.h +++ b/gst-libs/gst/vaapi/gstvaapisurfacepool.h @@ -21,9 +21,8 @@ #ifndef GST_VAAPI_SURFACE_POOL_H #define GST_VAAPI_SURFACE_POOL_H -#include -#include #include +#include 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 index 0000000..bf8d41a --- /dev/null +++ b/gst-libs/gst/vaapi/gstvaapivideopool.c @@ -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 index 0000000..1d3b91a --- /dev/null +++ b/gst-libs/gst/vaapi/gstvaapivideopool.h @@ -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 +#include + +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 */ -- 2.7.4