mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-04-26 06:54:49 +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;
|
GQueue free_objects;
|
||||||
GList *used_objects;
|
GList *used_objects;
|
||||||
GstCaps *caps;
|
GstCaps *caps;
|
||||||
|
guint used_count;
|
||||||
|
guint capacity;
|
||||||
};
|
};
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
|
@ -48,11 +50,20 @@ enum {
|
||||||
|
|
||||||
PROP_DISPLAY,
|
PROP_DISPLAY,
|
||||||
PROP_CAPS,
|
PROP_CAPS,
|
||||||
|
PROP_CAPACITY
|
||||||
};
|
};
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gst_vaapi_video_pool_set_caps(GstVaapiVideoPool *pool, GstCaps *caps);
|
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
|
static void
|
||||||
gst_vaapi_video_pool_clear(GstVaapiVideoPool *pool)
|
gst_vaapi_video_pool_clear(GstVaapiVideoPool *pool)
|
||||||
{
|
{
|
||||||
|
@ -114,6 +125,9 @@ gst_vaapi_video_pool_set_property(
|
||||||
case PROP_CAPS:
|
case PROP_CAPS:
|
||||||
gst_vaapi_video_pool_set_caps(pool, g_value_get_pointer(value));
|
gst_vaapi_video_pool_set_caps(pool, g_value_get_pointer(value));
|
||||||
break;
|
break;
|
||||||
|
case PROP_CAPACITY:
|
||||||
|
gst_vaapi_video_pool_set_capacity(pool, g_value_get_uint(value));
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
|
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
|
||||||
break;
|
break;
|
||||||
|
@ -137,6 +151,9 @@ gst_vaapi_video_pool_get_property(
|
||||||
case PROP_CAPS:
|
case PROP_CAPS:
|
||||||
g_value_set_pointer(value, gst_vaapi_video_pool_get_caps(pool));
|
g_value_set_pointer(value, gst_vaapi_video_pool_get_caps(pool));
|
||||||
break;
|
break;
|
||||||
|
case PROP_CAPACITY:
|
||||||
|
g_value_set_uint(value, gst_vaapi_video_pool_get_capacity(pool));
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
|
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
|
||||||
break;
|
break;
|
||||||
|
@ -181,6 +198,21 @@ gst_vaapi_video_pool_class_init(GstVaapiVideoPoolClass *klass)
|
||||||
"caps",
|
"caps",
|
||||||
"The video object capabilities",
|
"The video object capabilities",
|
||||||
G_PARAM_READWRITE|G_PARAM_CONSTRUCT_ONLY));
|
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
|
static void
|
||||||
|
@ -192,6 +224,8 @@ gst_vaapi_video_pool_init(GstVaapiVideoPool *pool)
|
||||||
priv->display = NULL;
|
priv->display = NULL;
|
||||||
priv->used_objects = NULL;
|
priv->used_objects = NULL;
|
||||||
priv->caps = NULL;
|
priv->caps = NULL;
|
||||||
|
priv->used_count = 0;
|
||||||
|
priv->capacity = 0;
|
||||||
|
|
||||||
g_queue_init(&priv->free_objects);
|
g_queue_init(&priv->free_objects);
|
||||||
}
|
}
|
||||||
|
@ -245,32 +279,36 @@ gst_vaapi_video_pool_set_caps(GstVaapiVideoPool *pool, GstCaps *caps)
|
||||||
gpointer
|
gpointer
|
||||||
gst_vaapi_video_pool_get_object(GstVaapiVideoPool *pool)
|
gst_vaapi_video_pool_get_object(GstVaapiVideoPool *pool)
|
||||||
{
|
{
|
||||||
|
GstVaapiVideoPoolPrivate *priv;
|
||||||
gpointer object;
|
gpointer object;
|
||||||
|
|
||||||
g_return_val_if_fail(GST_VAAPI_IS_VIDEO_POOL(pool), NULL);
|
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) {
|
if (!object) {
|
||||||
object = GST_VAAPI_VIDEO_POOL_GET_CLASS(pool)->alloc_object(
|
object = gst_vaapi_video_pool_alloc_object(pool);
|
||||||
pool,
|
|
||||||
pool->priv->display
|
|
||||||
);
|
|
||||||
if (!object)
|
if (!object)
|
||||||
return NULL;
|
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);
|
return g_object_ref(object);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* gst_vaapi_video_pool_put_object:
|
* gst_vaapi_video_pool_put_object:
|
||||||
* @pool: a #GstVaapiVideoPool
|
* @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
|
* Pushes the @object back into the pool. The @object shall be
|
||||||
* previously allocated from the @pool. Calling this function with an
|
* obtained from the @pool through gst_vaapi_video_pool_get_object().
|
||||||
* arbitrary object yields undefined behaviour.
|
* Calling this function with an arbitrary object yields undefined
|
||||||
|
* behaviour.
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
gst_vaapi_video_pool_put_object(GstVaapiVideoPool *pool, gpointer object)
|
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;
|
return;
|
||||||
|
|
||||||
g_object_unref(object);
|
g_object_unref(object);
|
||||||
|
--priv->used_count;
|
||||||
priv->used_objects = g_list_delete_link(priv->used_objects, elem);
|
priv->used_objects = g_list_delete_link(priv->used_objects, elem);
|
||||||
g_queue_push_tail(&priv->free_objects, object);
|
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
|
#ifndef GST_VAAPI_VIDEO_POOL_H
|
||||||
#define GST_VAAPI_VIDEO_POOL_H
|
#define GST_VAAPI_VIDEO_POOL_H
|
||||||
|
|
||||||
|
#include <glib.h>
|
||||||
#include <gst/gstcaps.h>
|
#include <gst/gstcaps.h>
|
||||||
#include <gst/vaapi/gstvaapidisplay.h>
|
#include <gst/vaapi/gstvaapidisplay.h>
|
||||||
|
|
||||||
|
@ -95,6 +96,24 @@ gst_vaapi_video_pool_get_object(GstVaapiVideoPool *pool);
|
||||||
void
|
void
|
||||||
gst_vaapi_video_pool_put_object(GstVaapiVideoPool *pool, gpointer object);
|
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
|
G_END_DECLS
|
||||||
|
|
||||||
#endif /* GST_VAAPI_VIDEO_POOL_H */
|
#endif /* GST_VAAPI_VIDEO_POOL_H */
|
||||||
|
|
Loading…
Reference in a new issue