2 * gstvaapivideopool.c - Video object pool abstraction
4 * Copyright (C) 2010-2011 Splitted-Desktop Systems
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public License
8 * as published by the Free Software Foundation; either version 2.1
9 * of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free
18 * Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19 * Boston, MA 02110-1301 USA
23 * SECTION:gstvaapivideopool
24 * @short_description: Video object pool abstraction
28 #include "gstvaapivideopool.h"
31 #include "gstvaapidebug.h"
33 G_DEFINE_TYPE(GstVaapiVideoPool, gst_vaapi_video_pool, G_TYPE_OBJECT);
35 #define GST_VAAPI_VIDEO_POOL_GET_PRIVATE(obj) \
36 (G_TYPE_INSTANCE_GET_PRIVATE((obj), \
37 GST_VAAPI_TYPE_VIDEO_POOL, \
38 GstVaapiVideoPoolPrivate))
40 #define VAAPI_VIDEO_POOL_LOCK(mutex) g_static_rec_mutex_lock(mutex)
41 #define VAAPI_VIDEO_POOL_UNLOCK(mutex) g_static_rec_mutex_unlock(mutex)
44 struct _GstVaapiVideoPoolPrivate {
45 GstVaapiDisplay *display;
52 GStaticRecMutex mutex;
64 gst_vaapi_video_pool_set_caps(GstVaapiVideoPool *pool, GstCaps *caps);
66 static inline gpointer
67 gst_vaapi_video_pool_alloc_object(GstVaapiVideoPool *pool)
69 GstVaapiVideoPoolClass * const klass = GST_VAAPI_VIDEO_POOL_GET_CLASS(pool);
71 return klass->alloc_object(pool, pool->priv->display);
75 gst_vaapi_video_pool_clear(GstVaapiVideoPool *pool)
77 GstVaapiVideoPoolPrivate * const priv = pool->priv;
81 for (list = priv->used_objects; list; list = next) {
83 g_object_unref(list->data);
86 priv->used_objects = NULL;
88 while ((object = g_queue_pop_head(&priv->free_objects)))
89 g_object_unref(object);
93 gst_vaapi_video_pool_destroy(GstVaapiVideoPool *pool)
95 GstVaapiVideoPoolPrivate * const priv = pool->priv;
97 gst_vaapi_video_pool_clear(pool);
100 gst_caps_unref(priv->caps);
104 g_clear_object(&priv->display);
108 gst_vaapi_video_pool_finalize(GObject *object)
110 gst_vaapi_video_pool_destroy(GST_VAAPI_VIDEO_POOL(object));
112 G_OBJECT_CLASS(gst_vaapi_video_pool_parent_class)->finalize(object);
116 gst_vaapi_video_pool_set_property(
123 GstVaapiVideoPool * const pool = GST_VAAPI_VIDEO_POOL(object);
127 pool->priv->display = g_object_ref(g_value_get_object(value));
130 gst_vaapi_video_pool_set_caps(pool, g_value_get_pointer(value));
133 gst_vaapi_video_pool_set_capacity(pool, g_value_get_uint(value));
136 G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
142 gst_vaapi_video_pool_get_property(
149 GstVaapiVideoPool * const pool = GST_VAAPI_VIDEO_POOL(object);
153 g_value_set_object(value, gst_vaapi_video_pool_get_display(pool));
156 g_value_set_pointer(value, gst_vaapi_video_pool_get_caps(pool));
159 g_value_set_uint(value, gst_vaapi_video_pool_get_capacity(pool));
162 G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
168 gst_vaapi_video_pool_class_init(GstVaapiVideoPoolClass *klass)
170 GObjectClass * const object_class = G_OBJECT_CLASS(klass);
172 g_type_class_add_private(klass, sizeof(GstVaapiVideoPoolPrivate));
174 object_class->finalize = gst_vaapi_video_pool_finalize;
175 object_class->set_property = gst_vaapi_video_pool_set_property;
176 object_class->get_property = gst_vaapi_video_pool_get_property;
179 * GstVaapiVideoPool:display:
181 * The #GstVaapiDisplay this pool is bound to.
183 g_object_class_install_property
186 g_param_spec_object("display",
188 "The GstVaapiDisplay this pool is bound to",
189 GST_VAAPI_TYPE_DISPLAY,
190 G_PARAM_READWRITE|G_PARAM_CONSTRUCT_ONLY));
193 * GstVaapiVidePool:caps:
195 * The video object capabilities represented as a #GstCaps. This
196 * shall hold at least the "width" and "height" properties.
198 g_object_class_install_property
201 g_param_spec_pointer("caps",
203 "The video object capabilities",
204 G_PARAM_READWRITE|G_PARAM_CONSTRUCT_ONLY));
207 * GstVaapiVidePool:capacity:
209 * The maximum number of objects in the pool. Or zero, the pool
210 * will allocate as many objects as possible.
212 g_object_class_install_property
215 g_param_spec_uint("capacity",
217 "The maximum number of objects in the pool",
223 gst_vaapi_video_pool_init(GstVaapiVideoPool *pool)
225 GstVaapiVideoPoolPrivate *priv = GST_VAAPI_VIDEO_POOL_GET_PRIVATE(pool);
228 priv->display = NULL;
229 priv->used_objects = NULL;
231 priv->used_count = 0;
234 g_queue_init(&priv->free_objects);
235 g_static_rec_mutex_init(&priv->mutex);
239 * gst_vaapi_video_pool_get_display:
240 * @pool: a #GstVaapiVideoPool
242 * Retrieves the #GstVaapiDisplay the @pool is bound to. The @pool
243 * owns the returned object and it shall not be unref'ed.
245 * Return value: the #GstVaapiDisplay the @pool is bound to
248 gst_vaapi_video_pool_get_display(GstVaapiVideoPool *pool)
250 g_return_val_if_fail(GST_VAAPI_IS_VIDEO_POOL(pool), NULL);
252 return pool->priv->display;
256 * gst_vaapi_video_pool_get_caps:
257 * @pool: a #GstVaapiVideoPool
259 * Retrieves the #GstCaps the @pool was created with. The @pool owns
260 * the returned object and it shall not be unref'ed.
262 * Return value: the #GstCaps the @pool was created with
265 gst_vaapi_video_pool_get_caps(GstVaapiVideoPool *pool)
267 g_return_val_if_fail(GST_VAAPI_IS_VIDEO_POOL(pool), NULL);
269 return pool->priv->caps;
273 * gst_vaapi_video_pool_set_caps:
274 * @pool: a #GstVaapiVideoPool
277 * Binds new @caps to the @pool and notify the sub-classes.
280 gst_vaapi_video_pool_set_caps(GstVaapiVideoPool *pool, GstCaps *caps)
282 GstVaapiVideoPoolClass * const klass = GST_VAAPI_VIDEO_POOL_GET_CLASS(pool);
284 pool->priv->caps = gst_caps_ref(caps);
287 klass->set_caps(pool, caps);
291 * gst_vaapi_video_pool_get_object:
292 * @pool: a #GstVaapiVideoPool
294 * Retrieves a new object from the @pool, or allocates a new one if
295 * none was found. The @pool holds a reference on the returned object
296 * and thus shall be released through gst_vaapi_video_pool_put_object()
297 * when it's no longer needed.
299 * Return value: a possibly newly allocated object, or %NULL on error
302 gst_vaapi_video_pool_get_object(GstVaapiVideoPool *pool)
304 GstVaapiVideoPoolPrivate *priv;
305 gpointer object = NULL;
307 g_return_val_if_fail(GST_VAAPI_IS_VIDEO_POOL(pool), NULL);
311 VAAPI_VIDEO_POOL_LOCK(&priv->mutex);
312 if (priv->capacity && priv->used_count >= priv->capacity)
315 object = g_queue_pop_head(&priv->free_objects);
317 VAAPI_VIDEO_POOL_UNLOCK(&priv->mutex);
318 object = gst_vaapi_video_pool_alloc_object(pool);
319 VAAPI_VIDEO_POOL_LOCK(&priv->mutex);
325 priv->used_objects = g_list_prepend(priv->used_objects, object);
326 g_object_ref(object);
329 VAAPI_VIDEO_POOL_UNLOCK(&priv->mutex);
334 * gst_vaapi_video_pool_put_object:
335 * @pool: a #GstVaapiVideoPool
336 * @object: the object to add back to the pool
338 * Pushes the @object back into the pool. The @object shall be
339 * obtained from the @pool through gst_vaapi_video_pool_get_object().
340 * Calling this function with an arbitrary object yields undefined
344 gst_vaapi_video_pool_put_object(GstVaapiVideoPool *pool, gpointer object)
346 GstVaapiVideoPoolPrivate *priv;
349 g_return_if_fail(GST_VAAPI_IS_VIDEO_POOL(pool));
350 g_return_if_fail(G_IS_OBJECT(object));
354 VAAPI_VIDEO_POOL_LOCK(&priv->mutex);
355 elem = g_list_find(priv->used_objects, object);
359 g_object_unref(object);
361 priv->used_objects = g_list_delete_link(priv->used_objects, elem);
362 g_queue_push_tail(&priv->free_objects, object);
365 VAAPI_VIDEO_POOL_UNLOCK(&priv->mutex);
369 * gst_vaapi_video_pool_add_object:
370 * @pool: a #GstVaapiVideoPool
371 * @object: the object to add to the pool
373 * Adds the @object to the pool. The pool then holds a reference on
374 * the @object. This operation does not change the capacity of the
377 * Return value: %TRUE on success.
380 gst_vaapi_video_pool_add_object(GstVaapiVideoPool *pool, gpointer object)
382 g_return_val_if_fail(GST_VAAPI_IS_VIDEO_POOL(pool), FALSE);
383 g_return_val_if_fail(G_IS_OBJECT(object), FALSE);
385 VAAPI_VIDEO_POOL_LOCK(&pool->priv->mutex);
386 g_queue_push_tail(&pool->priv->free_objects, g_object_ref(object));
387 VAAPI_VIDEO_POOL_UNLOCK(&pool->priv->mutex);
393 * gst_vaapi_video_pool_add_objects:
394 * @pool: a #GstVaapiVideoPool
395 * @objects: a #GPtrArray of objects
397 * Adds the @objects to the pool. The pool then holds a reference on
398 * the @objects. This operation does not change the capacity of the
399 * pool and is just a wrapper around gst_vaapi_video_pool_add_object().
401 * Return value: %TRUE on success.
404 gst_vaapi_video_pool_add_objects(GstVaapiVideoPool *pool, GPtrArray *objects)
408 g_return_val_if_fail(GST_VAAPI_IS_VIDEO_POOL(pool), FALSE);
410 for (i = 0; i < objects->len; i++) {
411 gpointer const object = g_ptr_array_index(objects, i);
412 if (!gst_vaapi_video_pool_add_object(pool, object))
419 * gst_vaapi_video_pool_get_size:
420 * @pool: a #GstVaapiVideoPool
422 * Returns the number of free objects available in the pool.
424 * Return value: number of free objects in the pool
427 gst_vaapi_video_pool_get_size(GstVaapiVideoPool *pool)
430 g_return_val_if_fail(GST_VAAPI_IS_VIDEO_POOL(pool), 0);
433 VAAPI_VIDEO_POOL_LOCK(&pool->priv->mutex);
434 size = g_queue_get_length(&pool->priv->free_objects);
435 VAAPI_VIDEO_POOL_UNLOCK(&pool->priv->mutex);
440 * gst_vaapi_video_pool_reserve:
441 * @pool: a #GstVaapiVideoPool
442 * @n: the number of objects to pre-allocate
444 * Pre-allocates up to @n objects in the pool. If @n is less than or
445 * equal to the number of free and used objects in the pool, this call
446 * has no effect. Otherwise, it is a request for allocation of
447 * additional objects.
449 * Return value: %TRUE on success
452 gst_vaapi_video_pool_reserve(GstVaapiVideoPool *pool, guint n)
454 guint i, num_allocated;
457 g_return_val_if_fail(GST_VAAPI_IS_VIDEO_POOL(pool), 0);
459 VAAPI_VIDEO_POOL_LOCK(&pool->priv->mutex);
461 num_allocated = gst_vaapi_video_pool_get_size(pool) + pool->priv->used_count;
462 if (n < num_allocated)
465 if ((n -= num_allocated) > pool->priv->capacity)
466 n = pool->priv->capacity;
468 for (i = num_allocated; i < n; i++) {
469 gpointer const object = gst_vaapi_video_pool_alloc_object(pool);
474 g_queue_push_tail(&pool->priv->free_objects, object);
478 VAAPI_VIDEO_POOL_UNLOCK(&pool->priv->mutex);
483 * gst_vaapi_video_pool_get_capacity:
484 * @pool: a #GstVaapiVideoPool
486 * Returns the maximum number of objects in the pool. i.e. the maximum
487 * number of objects that can be returned by gst_vaapi_video_pool_get_object().
489 * Return value: the capacity of the pool
492 gst_vaapi_video_pool_get_capacity(GstVaapiVideoPool *pool)
495 g_return_val_if_fail(GST_VAAPI_IS_VIDEO_POOL(pool), 0);
496 VAAPI_VIDEO_POOL_LOCK(&pool->priv->mutex);
497 capacity = pool->priv->capacity;
498 VAAPI_VIDEO_POOL_UNLOCK(&pool->priv->mutex);
503 * gst_vaapi_video_pool_set_capacity:
504 * @pool: a #GstVaapiVideoPool
505 * @capacity: the maximal capacity of the pool
507 * Sets the maximum number of objects that can be allocated in the pool.
510 gst_vaapi_video_pool_set_capacity(GstVaapiVideoPool *pool, guint capacity)
512 g_return_if_fail(GST_VAAPI_IS_VIDEO_POOL(pool));
513 VAAPI_VIDEO_POOL_LOCK(&pool->priv->mutex);
514 pool->priv->capacity = capacity;
515 VAAPI_VIDEO_POOL_UNLOCK(&pool->priv->mutex);