mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-28 04:31:06 +00:00
Add a means to cap the number of objects allocated in the pool.
This commit is contained in:
parent
30fbcb1ee8
commit
b0493e729c
2 changed files with 197 additions and 9 deletions
|
@ -41,6 +41,8 @@ struct _GstVaapiVideoPoolPrivate {
|
|||
GQueue free_objects;
|
||||
GList *used_objects;
|
||||
GstCaps *caps;
|
||||
guint used_count;
|
||||
guint capacity;
|
||||
};
|
||||
|
||||
enum {
|
||||
|
@ -48,11 +50,20 @@ 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)
|
||||
{
|
||||
|
@ -114,6 +125,9 @@ gst_vaapi_video_pool_set_property(
|
|||
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;
|
||||
|
@ -137,6 +151,9 @@ gst_vaapi_video_pool_get_property(
|
|||
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;
|
||||
|
@ -181,6 +198,21 @@ gst_vaapi_video_pool_class_init(GstVaapiVideoPoolClass *klass)
|
|||
"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
|
||||
|
@ -192,6 +224,8 @@ gst_vaapi_video_pool_init(GstVaapiVideoPool *pool)
|
|||
priv->display = NULL;
|
||||
priv->used_objects = NULL;
|
||||
priv->caps = NULL;
|
||||
priv->used_count = 0;
|
||||
priv->capacity = 0;
|
||||
|
||||
g_queue_init(&priv->free_objects);
|
||||
}
|
||||
|
@ -245,32 +279,36 @@ gst_vaapi_video_pool_set_caps(GstVaapiVideoPool *pool, GstCaps *caps)
|
|||
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)
|
||||
|
@ -287,6 +325,137 @@ 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;
|
||||
}
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
#ifndef GST_VAAPI_VIDEO_POOL_H
|
||||
#define GST_VAAPI_VIDEO_POOL_H
|
||||
|
||||
#include <glib.h>
|
||||
#include <gst/gstcaps.h>
|
||||
#include <gst/vaapi/gstvaapidisplay.h>
|
||||
|
||||
|
@ -95,6 +96,24 @@ gst_vaapi_video_pool_get_object(GstVaapiVideoPool *pool);
|
|||
void
|
||||
gst_vaapi_video_pool_put_object(GstVaapiVideoPool *pool, gpointer object);
|
||||
|
||||
gboolean
|
||||
gst_vaapi_video_pool_add_object(GstVaapiVideoPool *pool, gpointer object);
|
||||
|
||||
gboolean
|
||||
gst_vaapi_video_pool_add_objects(GstVaapiVideoPool *pool, GPtrArray *objects);
|
||||
|
||||
guint
|
||||
gst_vaapi_video_pool_get_size(GstVaapiVideoPool *pool);
|
||||
|
||||
gboolean
|
||||
gst_vaapi_video_pool_reserve(GstVaapiVideoPool *pool, guint n);
|
||||
|
||||
guint
|
||||
gst_vaapi_video_pool_get_capacity(GstVaapiVideoPool *pool);
|
||||
|
||||
void
|
||||
gst_vaapi_video_pool_set_capacity(GstVaapiVideoPool *pool, guint capacity);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* GST_VAAPI_VIDEO_POOL_H */
|
||||
|
|
Loading…
Reference in a new issue