GQueue free_objects;
GList *used_objects;
GstCaps *caps;
+ guint used_count;
+ guint capacity;
};
enum {
PROP_DISPLAY,
PROP_CAPS,
+ PROP_CAPACITY
};
static void
gst_vaapi_video_pool_set_caps(GstVaapiVideoPool *pool, GstCaps *caps);
+static inline gpointer
+gst_vaapi_video_pool_alloc_object(GstVaapiVideoPool *pool)
+{
+ GstVaapiVideoPoolClass * const klass = GST_VAAPI_VIDEO_POOL_GET_CLASS(pool);
+
+ return klass->alloc_object(pool, pool->priv->display);
+}
+
static void
gst_vaapi_video_pool_clear(GstVaapiVideoPool *pool)
{
case PROP_CAPS:
gst_vaapi_video_pool_set_caps(pool, g_value_get_pointer(value));
break;
+ case PROP_CAPACITY:
+ gst_vaapi_video_pool_set_capacity(pool, g_value_get_uint(value));
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
break;
case PROP_CAPS:
g_value_set_pointer(value, gst_vaapi_video_pool_get_caps(pool));
break;
+ case PROP_CAPACITY:
+ g_value_set_uint(value, gst_vaapi_video_pool_get_capacity(pool));
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
break;
"caps",
"The video object capabilities",
G_PARAM_READWRITE|G_PARAM_CONSTRUCT_ONLY));
+
+ /**
+ * GstVaapiVidePool:capacity:
+ *
+ * The maximum number of objects in the pool. Or zero, the pool
+ * will allocate as many objects as possible.
+ */
+ g_object_class_install_property
+ (object_class,
+ PROP_CAPACITY,
+ g_param_spec_uint("capacity",
+ "capacity",
+ "The maximum number of objects in the pool",
+ 0, G_MAXUINT32, 0,
+ G_PARAM_READWRITE));
}
static void
priv->display = NULL;
priv->used_objects = NULL;
priv->caps = NULL;
+ priv->used_count = 0;
+ priv->capacity = 0;
g_queue_init(&priv->free_objects);
}
gpointer
gst_vaapi_video_pool_get_object(GstVaapiVideoPool *pool)
{
+ GstVaapiVideoPoolPrivate *priv;
gpointer object;
g_return_val_if_fail(GST_VAAPI_IS_VIDEO_POOL(pool), NULL);
- object = g_queue_pop_head(&pool->priv->free_objects);
+ priv = pool->priv;
+ if (priv->capacity && priv->used_count >= priv->capacity)
+ return NULL;
+
+ object = g_queue_pop_head(&priv->free_objects);
if (!object) {
- object = GST_VAAPI_VIDEO_POOL_GET_CLASS(pool)->alloc_object(
- pool,
- pool->priv->display
- );
+ object = gst_vaapi_video_pool_alloc_object(pool);
if (!object)
return NULL;
}
- pool->priv->used_objects = g_list_prepend(pool->priv->used_objects, object);
+ ++priv->used_count;
+ priv->used_objects = g_list_prepend(priv->used_objects, object);
return g_object_ref(object);
}
/**
* gst_vaapi_video_pool_put_object:
* @pool: a #GstVaapiVideoPool
- * @object: the object to add to the pool
+ * @object: the object to add back to the pool
*
* Pushes the @object back into the pool. The @object shall be
- * previously allocated from the @pool. Calling this function with an
- * arbitrary object yields undefined behaviour.
+ * obtained from the @pool through gst_vaapi_video_pool_get_object().
+ * Calling this function with an arbitrary object yields undefined
+ * behaviour.
*/
void
gst_vaapi_video_pool_put_object(GstVaapiVideoPool *pool, gpointer object)
return;
g_object_unref(object);
+ --priv->used_count;
priv->used_objects = g_list_delete_link(priv->used_objects, elem);
g_queue_push_tail(&priv->free_objects, object);
}
+
+/**
+ * gst_vaapi_video_pool_add_object:
+ * @pool: a #GstVaapiVideoPool
+ * @object: the object to add to the pool
+ *
+ * Adds the @object to the pool. The pool then holds a reference on
+ * the @object. This operation does not change the capacity of the
+ * pool.
+ *
+ * Return value: %TRUE on success.
+ */
+gboolean
+gst_vaapi_video_pool_add_object(GstVaapiVideoPool *pool, gpointer object)
+{
+ g_return_val_if_fail(GST_VAAPI_IS_VIDEO_POOL(pool), FALSE);
+ g_return_val_if_fail(G_IS_OBJECT(object), FALSE);
+
+ g_queue_push_tail(&pool->priv->free_objects, g_object_ref(object));
+ return TRUE;
+}
+
+/**
+ * gst_vaapi_video_pool_add_objects:
+ * @pool: a #GstVaapiVideoPool
+ * @objects: a #GPtrArray of objects
+ *
+ * Adds the @objects to the pool. The pool then holds a reference on
+ * the @objects. This operation does not change the capacity of the
+ * pool and is just a wrapper around gst_vaapi_video_pool_add_object().
+ *
+ * Return value: %TRUE on success.
+ */
+gboolean
+gst_vaapi_video_pool_add_objects(GstVaapiVideoPool *pool, GPtrArray *objects)
+{
+ guint i;
+
+ g_return_val_if_fail(GST_VAAPI_IS_VIDEO_POOL(pool), FALSE);
+
+ for (i = 0; i < objects->len; i++) {
+ gpointer const object = g_ptr_array_index(objects, i);
+ if (!gst_vaapi_video_pool_add_object(pool, object))
+ return FALSE;
+ }
+ return TRUE;
+}
+
+/**
+ * gst_vaapi_video_pool_get_size:
+ * @pool: a #GstVaapiVideoPool
+ *
+ * Returns the number of free objects available in the pool.
+ *
+ * Return value: number of free objects in the pool
+ */
+guint
+gst_vaapi_video_pool_get_size(GstVaapiVideoPool *pool)
+{
+ g_return_val_if_fail(GST_VAAPI_IS_VIDEO_POOL(pool), 0);
+
+ return g_queue_get_length(&pool->priv->free_objects);
+}
+
+/**
+ * gst_vaapi_video_pool_reserve:
+ * @pool: a #GstVaapiVideoPool
+ * @n: the number of objects to pre-allocate
+ *
+ * Pre-allocates up to @n objects in the pool. If @n is less than or
+ * equal to the number of free and used objects in the pool, this call
+ * has no effect. Otherwise, it is a request for allocation of
+ * additional objects.
+ *
+ * Return value: %TRUE on success
+ */
+gboolean
+gst_vaapi_video_pool_reserve(GstVaapiVideoPool *pool, guint n)
+{
+ guint i, num_allocated;
+
+ g_return_val_if_fail(GST_VAAPI_IS_VIDEO_POOL(pool), 0);
+
+ num_allocated = gst_vaapi_video_pool_get_size(pool) + pool->priv->used_count;
+ if (n < num_allocated)
+ return TRUE;
+
+ if ((n -= num_allocated) > pool->priv->capacity)
+ n = pool->priv->capacity;
+
+ for (i = num_allocated; i < n; i++) {
+ gpointer const object = gst_vaapi_video_pool_alloc_object(pool);
+ if (!object)
+ return FALSE;
+ g_queue_push_tail(&pool->priv->free_objects, object);
+ }
+ return TRUE;
+}
+
+/**
+ * gst_vaapi_video_pool_get_capacity:
+ * @pool: a #GstVaapiVideoPool
+ *
+ * Returns the maximum number of objects in the pool. i.e. the maximum
+ * number of objects that can be returned by gst_vaapi_video_pool_get_object().
+ *
+ * Return value: the capacity of the pool
+ */
+guint
+gst_vaapi_video_pool_get_capacity(GstVaapiVideoPool *pool)
+{
+ g_return_val_if_fail(GST_VAAPI_IS_VIDEO_POOL(pool), 0);
+
+ return pool->priv->capacity;
+}
+
+/**
+ * gst_vaapi_video_pool_set_capacity:
+ * @pool: a #GstVaapiVideoPool
+ * @capacity: the maximal capacity of the pool
+ *
+ * Sets the maximum number of objects that can be allocated in the pool.
+ */
+void
+gst_vaapi_video_pool_set_capacity(GstVaapiVideoPool *pool, guint capacity)
+{
+ g_return_if_fail(GST_VAAPI_IS_VIDEO_POOL(pool));
+
+ pool->priv->capacity = capacity;
+}