#endif
#include <sys/types.h>
+#include "gstatomicqueue.h"
+#include "gstpoll.h"
#include "gstinfo.h"
#include "gstquark.h"
+#include "gstvalue.h"
#include "gstbufferpool.h"
#define GST_BUFFER_POOL_GET_PRIVATE(obj) \
(G_TYPE_INSTANCE_GET_PRIVATE ((obj), GST_TYPE_BUFFER_POOL, GstBufferPoolPrivate))
-#define GST_BUFFER_POOL_LOCK(pool) (g_static_rec_mutex_lock(&pool->priv->rec_lock))
-#define GST_BUFFER_POOL_UNLOCK(pool) (g_static_rec_mutex_unlock(&pool->priv->rec_lock))
+#define GST_BUFFER_POOL_LOCK(pool) (g_rec_mutex_lock(&pool->priv->rec_lock))
+#define GST_BUFFER_POOL_UNLOCK(pool) (g_rec_mutex_unlock(&pool->priv->rec_lock))
struct _GstBufferPoolPrivate
{
- GStaticRecMutex rec_lock;
+ GstAtomicQueue *queue;
+ GstPoll *poll;
+
+ GRecMutex rec_lock;
+
+ gboolean started;
+ gboolean active;
+ gint outstanding;
+
+ gboolean configured;
+ GstStructure *config;
+
guint size;
guint min_buffers;
guint max_buffers;
{
pool->priv = GST_BUFFER_POOL_GET_PRIVATE (pool);
- g_static_rec_mutex_init (&pool->priv->rec_lock);
+ g_rec_mutex_init (&pool->priv->rec_lock);
- pool->poll = gst_poll_new_timer ();
- pool->queue = gst_atomic_queue_new (10);
- pool->flushing = TRUE;
- pool->active = FALSE;
- pool->configured = FALSE;
- pool->started = FALSE;
- pool->config = gst_structure_new_id_empty (GST_QUARK (BUFFER_POOL_CONFIG));
- gst_buffer_pool_config_set (pool->config, NULL, 0, 0, 0, 0, 0);
- gst_poll_write_control (pool->poll);
+ pool->priv->poll = gst_poll_new_timer ();
+ pool->priv->queue = gst_atomic_queue_new (10);
+ pool->flushing = 1;
+ pool->priv->active = FALSE;
+ pool->priv->configured = FALSE;
+ pool->priv->started = FALSE;
+ pool->priv->config =
+ gst_structure_new_id_empty (GST_QUARK (BUFFER_POOL_CONFIG));
+ gst_buffer_pool_config_set (pool->priv->config, NULL, 0, 0, 0, 0, 0);
+ gst_poll_write_control (pool->priv->poll);
GST_DEBUG_OBJECT (pool, "created");
}
GST_DEBUG_OBJECT (pool, "finalize");
gst_buffer_pool_set_active (pool, FALSE);
- gst_atomic_queue_unref (pool->queue);
- gst_poll_free (pool->poll);
- gst_structure_free (pool->config);
- g_static_rec_mutex_free (&pool->priv->rec_lock);
+ gst_atomic_queue_unref (pool->priv->queue);
+ gst_poll_free (pool->priv->poll);
+ gst_structure_free (pool->priv->config);
+ g_rec_mutex_clear (&pool->priv->rec_lock);
G_OBJECT_CLASS (gst_buffer_pool_parent_class)->finalize (object);
}
static gboolean
do_start (GstBufferPool * pool)
{
- if (!pool->started) {
+ if (!pool->priv->started) {
GstBufferPoolClass *pclass;
pclass = GST_BUFFER_POOL_GET_CLASS (pool);
if (!pclass->start (pool))
return FALSE;
}
- pool->started = TRUE;
+ pool->priv->started = TRUE;
}
return TRUE;
}
pclass = GST_BUFFER_POOL_GET_CLASS (pool);
/* clear the pool */
- while ((buffer = gst_atomic_queue_pop (pool->queue))) {
+ while ((buffer = gst_atomic_queue_pop (pool->priv->queue))) {
GST_LOG_OBJECT (pool, "freeing %p", buffer);
- gst_poll_read_control (pool->poll);
+ gst_poll_read_control (pool->priv->poll);
if (G_LIKELY (pclass->free_buffer))
pclass->free_buffer (pool, buffer);
static gboolean
do_stop (GstBufferPool * pool)
{
- if (pool->started) {
+ if (pool->priv->started) {
GstBufferPoolClass *pclass;
pclass = GST_BUFFER_POOL_GET_CLASS (pool);
if (!pclass->stop (pool))
return FALSE;
}
- pool->started = FALSE;
+ pool->priv->started = FALSE;
}
return TRUE;
}
* @active: the new active state
*
* Control the active state of @pool. When the pool is active, new calls to
- * gst_buffer_pool_acquire_buffer() will return with GST_FLOW_WRONG_STATE.
+ * gst_buffer_pool_acquire_buffer() will return with GST_FLOW_FLUSHING.
*
* Activating the bufferpool will preallocate all resources in the pool based on
* the configuration of the pool.
GST_BUFFER_POOL_LOCK (pool);
/* just return if we are already in the right state */
- if (pool->active == active)
+ if (pool->priv->active == active)
goto was_ok;
/* we need to be configured */
- if (!pool->configured)
+ if (!pool->priv->configured)
goto not_configured;
if (active) {
goto start_failed;
/* unset the flushing state now */
- gst_poll_read_control (pool->poll);
- g_atomic_int_set (&pool->flushing, FALSE);
+ gst_poll_read_control (pool->priv->poll);
+ g_atomic_int_set (&pool->flushing, 0);
} else {
gint outstanding;
/* set to flushing first */
- g_atomic_int_set (&pool->flushing, TRUE);
- gst_poll_write_control (pool->poll);
+ g_atomic_int_set (&pool->flushing, 1);
+ gst_poll_write_control (pool->priv->poll);
/* when all buffers are in the pool, free them. Else they will be
* freed when they are released */
- outstanding = g_atomic_int_get (&pool->outstanding);
+ outstanding = g_atomic_int_get (&pool->priv->outstanding);
GST_LOG_OBJECT (pool, "outstanding buffers %d", outstanding);
if (outstanding == 0) {
if (!do_stop (pool))
goto stop_failed;
}
}
- pool->active = active;
+ pool->priv->active = active;
GST_BUFFER_POOL_UNLOCK (pool);
return res;
gboolean res;
GST_BUFFER_POOL_LOCK (pool);
- res = pool->active;
+ res = pool->priv->active;
GST_BUFFER_POOL_UNLOCK (pool);
return res;
GST_BUFFER_POOL_LOCK (pool);
/* can't change the settings when active */
- if (pool->active)
+ if (pool->priv->active)
goto was_active;
/* we can't change when outstanding buffers */
- if (g_atomic_int_get (&pool->outstanding) != 0)
+ if (g_atomic_int_get (&pool->priv->outstanding) != 0)
goto have_outstanding;
pclass = GST_BUFFER_POOL_GET_CLASS (pool);
result = FALSE;
if (result) {
- if (pool->config)
- gst_structure_free (pool->config);
- pool->config = config;
+ if (pool->priv->config)
+ gst_structure_free (pool->priv->config);
+ pool->priv->config = config;
/* now we are configured */
- pool->configured = TRUE;
+ pool->priv->configured = TRUE;
}
GST_BUFFER_POOL_UNLOCK (pool);
g_return_val_if_fail (GST_IS_BUFFER_POOL (pool), NULL);
GST_BUFFER_POOL_UNLOCK (pool);
- result = gst_structure_copy (pool->config);
+ result = gst_structure_copy (pool->priv->config);
GST_BUFFER_POOL_UNLOCK (pool);
return result;
void
gst_buffer_pool_config_add_option (GstStructure * config, const gchar * option)
{
- GValueArray *array;
const GValue *value;
- GValue option_value = { 0 };
- gint i;
+ GValue option_value = { 0, };
+ guint i, len;
g_return_if_fail (config != NULL);
value = gst_structure_id_get_value (config, GST_QUARK (OPTIONS));
if (value) {
- array = (GValueArray *) g_value_get_boxed (value);
+ len = gst_value_array_get_size (value);
+ for (i = 0; i < len; ++i) {
+ const GValue *nth_val = gst_value_array_get_value (value, i);
+
+ if (g_str_equal (option, g_value_get_string (nth_val)))
+ return;
+ }
} else {
GValue new_array_val = { 0, };
- array = g_value_array_new (0);
-
- g_value_init (&new_array_val, G_TYPE_VALUE_ARRAY);
- g_value_take_boxed (&new_array_val, array);
-
+ g_value_init (&new_array_val, GST_TYPE_ARRAY);
gst_structure_id_take_value (config, GST_QUARK (OPTIONS), &new_array_val);
- }
- for (i = 0; i < array->n_values; i++) {
- value = g_value_array_get_nth (array, i);
- if (g_str_equal (option, g_value_get_string (value)))
- return;
+ value = gst_structure_id_get_value (config, GST_QUARK (OPTIONS));
}
g_value_init (&option_value, G_TYPE_STRING);
g_value_set_string (&option_value, option);
- g_value_array_append (array, &option_value);
+ gst_value_array_append_value ((GValue *) value, &option_value);
g_value_unset (&option_value);
}
guint
gst_buffer_pool_config_n_options (GstStructure * config)
{
- GValueArray *array;
const GValue *value;
guint size = 0;
value = gst_structure_id_get_value (config, GST_QUARK (OPTIONS));
if (value) {
- array = (GValueArray *) g_value_get_boxed (value);
- size = array->n_values;
+ size = gst_value_array_get_size (value);
}
return size;
}
value = gst_structure_id_get_value (config, GST_QUARK (OPTIONS));
if (value) {
- GValueArray *array;
- GValue *option_value;
-
- array = (GValueArray *) g_value_get_boxed (value);
- option_value = g_value_array_get_nth (array, index);
+ const GValue *option_value;
+ option_value = gst_value_array_get_value (value, index);
if (option_value)
ret = g_value_get_string (option_value);
}
gst_buffer_pool_config_has_option (GstStructure * config, const gchar * option)
{
const GValue *value;
+ guint i, len;
g_return_val_if_fail (config != NULL, 0);
value = gst_structure_id_get_value (config, GST_QUARK (OPTIONS));
if (value) {
- GValueArray *array;
- GValue *option_value;
- gint i;
-
- array = (GValueArray *) g_value_get_boxed (value);
- for (i = 0; i < array->n_values; i++) {
- option_value = g_value_array_get_nth (array, i);
- if (g_str_equal (option, g_value_get_string (option_value)))
+ len = gst_value_array_get_size (value);
+ for (i = 0; i < len; ++i) {
+ const GValue *nth_val = gst_value_array_get_value (value, i);
+
+ if (g_str_equal (option, g_value_get_string (nth_val)))
return TRUE;
}
}
pclass = GST_BUFFER_POOL_GET_CLASS (pool);
while (TRUE) {
- if (G_UNLIKELY (g_atomic_int_get (&pool->flushing)))
+ if (G_UNLIKELY (GST_BUFFER_POOL_IS_FLUSHING (pool)))
goto flushing;
/* try to get a buffer from the queue */
- *buffer = gst_atomic_queue_pop (pool->queue);
+ *buffer = gst_atomic_queue_pop (pool->priv->queue);
if (G_LIKELY (*buffer)) {
- gst_poll_read_control (pool->poll);
+ gst_poll_read_control (pool->priv->poll);
result = GST_FLOW_OK;
GST_LOG_OBJECT (pool, "acquired buffer %p", *buffer);
break;
/* now wait */
GST_LOG_OBJECT (pool, "waiting for free buffers");
- gst_poll_wait (pool->poll, GST_CLOCK_TIME_NONE);
+ gst_poll_wait (pool->priv->poll, GST_CLOCK_TIME_NONE);
}
return result;
flushing:
{
GST_DEBUG_OBJECT (pool, "we are flushing");
- return GST_FLOW_WRONG_STATE;
+ return GST_FLOW_FLUSHING;
}
}
static inline void
dec_outstanding (GstBufferPool * pool)
{
- if (g_atomic_int_dec_and_test (&pool->outstanding)) {
+ if (g_atomic_int_dec_and_test (&pool->priv->outstanding)) {
/* all buffers are returned to the pool, see if we need to free them */
- if (g_atomic_int_get (&pool->flushing)) {
+ if (GST_BUFFER_POOL_IS_FLUSHING (pool)) {
/* take the lock so that set_active is not run concurrently */
GST_BUFFER_POOL_LOCK (pool);
/* recheck the flushing state in the lock, the pool could have been
* set to active again */
- if (g_atomic_int_get (&pool->flushing))
+ if (GST_BUFFER_POOL_IS_FLUSHING (pool))
do_stop (pool);
GST_BUFFER_POOL_UNLOCK (pool);
}
}
+static gboolean
+remove_meta_unpooled (GstBuffer * buffer, GstMeta ** meta, gpointer user_data)
+{
+ if (!GST_META_FLAG_IS_SET (*meta, GST_META_FLAG_POOLED))
+ *meta = NULL;
+ return TRUE;
+}
+
static void
default_reset_buffer (GstBufferPool * pool, GstBuffer * buffer,
GstBufferPoolParams * params)
GST_BUFFER_DURATION (buffer) = GST_CLOCK_TIME_NONE;
GST_BUFFER_OFFSET (buffer) = GST_BUFFER_OFFSET_NONE;
GST_BUFFER_OFFSET_END (buffer) = GST_BUFFER_OFFSET_NONE;
+
+ /* remove all metadata without the POOLED flag */
+ gst_buffer_foreach_meta (buffer, remove_meta_unpooled, pool);
}
/**
*
* @params can be NULL or contain optional parameters to influence the allocation.
*
- * Returns: a #GstFlowReturn such as GST_FLOW_WRONG_STATE when the pool is
+ * Returns: a #GstFlowReturn such as GST_FLOW_FLUSHING when the pool is
* inactive.
*/
GstFlowReturn
/* assume we'll have one more outstanding buffer we need to do that so
* that concurrent set_active doesn't clear the buffers */
- g_atomic_int_inc (&pool->outstanding);
+ g_atomic_int_inc (&pool->priv->outstanding);
if (G_LIKELY (pclass->acquire_buffer))
result = pclass->acquire_buffer (pool, buffer, params);
{
/* keep it around in our queue */
GST_LOG_OBJECT (pool, "released buffer %p", buffer);
- gst_atomic_queue_push (pool->queue, buffer);
- gst_poll_write_control (pool->poll);
-}
-
-static gboolean
-remove_meta_unpooled (GstBuffer * buffer, GstMeta ** meta, gpointer user_data)
-{
- if (!GST_META_FLAG_IS_SET (*meta, GST_META_FLAG_POOLED))
- *meta = NULL;
- return TRUE;
+ gst_atomic_queue_push (pool->priv->queue, buffer);
+ gst_poll_write_control (pool->priv->poll);
}
/**
/* check that the buffer is ours, all buffers returned to the pool have the
* pool member set to NULL and the pool refcount decreased */
- if (!G_ATOMIC_POINTER_COMPARE_AND_EXCHANGE (&buffer->pool, pool, NULL))
+ if (!g_atomic_pointer_compare_and_exchange (&buffer->pool, pool, NULL))
return;
- /* remove all metadata without the POOLED flag */
- gst_buffer_foreach_meta (buffer, remove_meta_unpooled, pool);
-
pclass = GST_BUFFER_POOL_GET_CLASS (pool);
if (G_LIKELY (pclass->release_buffer))