/** * gst_buffer_pool_set_config: * @pool: a #GstBufferPool * @config: (transfer full): a #GstStructure * * Set the configuration of the pool. The pool must be inactive and all buffers * allocated form this pool must be returned or else this function will do * nothing and return FALSE. * * @config is a #GstStructure that contains the configuration parameters for * the pool. A default and mandatory set of parameters can be configured with * gst_buffer_pool_config_set_params(), gst_buffer_pool_config_set_allocator() * and gst_buffer_pool_config_add_option(). * * If the parameters in @config can not be set exactly, this function returns * FALSE and will try to update as much state as possible. The new state can * then be retrieved and refined with gst_buffer_pool_get_config(). * * This function takes ownership of @config. * * Returns: TRUE when the configuration could be set. */ gboolean gst_buffer_pool_set_config (GstBufferPool * pool, GstStructure * config) { gboolean result; GstBufferPoolClass *pclass; GstBufferPoolPrivate *priv; g_return_val_if_fail (GST_IS_BUFFER_POOL (pool), FALSE); g_return_val_if_fail (config != NULL, FALSE); priv = pool->priv; GST_BUFFER_POOL_LOCK (pool); /* can't change the settings when active */ if (priv->active) goto was_active; /* we can't change when outstanding buffers */ if (g_atomic_int_get (&priv->outstanding) != 0) goto have_outstanding; pclass = GST_BUFFER_POOL_GET_CLASS (pool); /* set the new config */ if (G_LIKELY (pclass->set_config)) result = pclass->set_config (pool, config); else result = FALSE; if (result) { if (priv->config) gst_structure_free (priv->config); priv->config = config; /* now we are configured */ priv->configured = TRUE; } else { gst_structure_free (config); } GST_BUFFER_POOL_UNLOCK (pool); return result; /* ERRORS */ was_active: { gst_structure_free (config); GST_WARNING_OBJECT (pool, "can't change config, we are active"); GST_BUFFER_POOL_UNLOCK (pool); return FALSE; } have_outstanding: { gst_structure_free (config); GST_WARNING_OBJECT (pool, "can't change config, have outstanding buffers"); GST_BUFFER_POOL_UNLOCK (pool); return FALSE; } }
/** * gst_buffer_pool_is_active: * @pool: a #GstBufferPool * * Check if @pool is active. A pool can be activated with the * gst_buffer_pool_set_active() call. * * Returns: %TRUE when the pool is active. */ gboolean gst_buffer_pool_is_active (GstBufferPool * pool) { gboolean res; GST_BUFFER_POOL_LOCK (pool); res = pool->priv->active; GST_BUFFER_POOL_UNLOCK (pool); return res; }
/** * gst_buffer_pool_get_config: * @pool: a #GstBufferPool * * Get a copy of the current configuration of the pool. This configuration * can either be modified and used for the gst_buffer_pool_set_config() call * or it must be freed after usage. * * Returns: (transfer full): a copy of the current configuration of @pool. use * gst_structure_free() after usage or gst_buffer_pool_set_config(). */ GstStructure * gst_buffer_pool_get_config (GstBufferPool * pool) { GstStructure *result; g_return_val_if_fail (GST_IS_BUFFER_POOL (pool), NULL); GST_BUFFER_POOL_LOCK (pool); result = gst_structure_copy (pool->priv->config); GST_BUFFER_POOL_UNLOCK (pool); return result; }
static inline void dec_outstanding (GstBufferPool * pool) { 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 (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 (GST_BUFFER_POOL_IS_FLUSHING (pool)) do_stop (pool); GST_BUFFER_POOL_UNLOCK (pool); } } }
static inline void dec_outstanding (GstBufferPool * pool) { 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 (GST_BUFFER_POOL_IS_FLUSHING (pool)) { /* take the lock so that set_active is not run concurrently */ GST_BUFFER_POOL_LOCK (pool); /* now that we have the lock, check if we have been de-activated with * outstanding buffers */ if (!pool->priv->active) do_stop (pool); GST_BUFFER_POOL_UNLOCK (pool); } } }
/** * gst_buffer_pool_set_flushing: * @pool: a #GstBufferPool * @flushing: whether to start or stop flushing * * Enable or disable the flushing state of a @pool without freeing or * allocating buffers. * * Since: 1.4 */ void gst_buffer_pool_set_flushing (GstBufferPool * pool, gboolean flushing) { GstBufferPoolPrivate *priv; g_return_if_fail (GST_IS_BUFFER_POOL (pool)); GST_LOG_OBJECT (pool, "flushing %d", flushing); priv = pool->priv; GST_BUFFER_POOL_LOCK (pool); if (!priv->active) { GST_WARNING_OBJECT (pool, "can't change flushing state of inactive pool"); goto done; } do_set_flushing (pool, flushing); done: GST_BUFFER_POOL_UNLOCK (pool); }
/** * gst_buffer_pool_set_active: * @pool: a #GstBufferPool * @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_FLUSHING. * * Activating the bufferpool will preallocate all resources in the pool based on * the configuration of the pool. * * Deactivating will free the resources again when there are no outstanding * buffers. When there are outstanding buffers, they will be freed as soon as * they are all returned to the pool. * * Returns: %FALSE when the pool was not configured or when preallocation of the * buffers failed. */ gboolean gst_buffer_pool_set_active (GstBufferPool * pool, gboolean active) { gboolean res = TRUE; GstBufferPoolPrivate *priv; g_return_val_if_fail (GST_IS_BUFFER_POOL (pool), FALSE); GST_LOG_OBJECT (pool, "active %d", active); priv = pool->priv; GST_BUFFER_POOL_LOCK (pool); /* just return if we are already in the right state */ if (priv->active == active) goto was_ok; /* we need to be configured */ if (!priv->configured) goto not_configured; if (active) { if (!do_start (pool)) goto start_failed; /* unset the flushing state now */ gst_poll_read_control (priv->poll); g_atomic_int_set (&pool->flushing, 0); } else { gint outstanding; /* set to flushing first */ g_atomic_int_set (&pool->flushing, 1); gst_poll_write_control (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 (&priv->outstanding); GST_LOG_OBJECT (pool, "outstanding buffers %d", outstanding); if (outstanding == 0) { if (!do_stop (pool)) goto stop_failed; } } priv->active = active; GST_BUFFER_POOL_UNLOCK (pool); return res; was_ok: { GST_DEBUG_OBJECT (pool, "pool was in the right state"); GST_BUFFER_POOL_UNLOCK (pool); return TRUE; } not_configured: { GST_ERROR_OBJECT (pool, "pool was not configured"); GST_BUFFER_POOL_UNLOCK (pool); return FALSE; } start_failed: { GST_ERROR_OBJECT (pool, "start failed"); GST_BUFFER_POOL_UNLOCK (pool); return FALSE; } stop_failed: { GST_WARNING_OBJECT (pool, "stop failed"); GST_BUFFER_POOL_UNLOCK (pool); return FALSE; } }
/** * gst_buffer_pool_set_config: * @pool: a #GstBufferPool * @config: (transfer full): a #GstStructure * * Set the configuration of the pool. If the pool is already configured, and * the configuration haven't change, this function will return %TRUE. If the * pool is active, this method will return %FALSE and active configuration * will remain. Buffers allocated form this pool must be returned or else this * function will do nothing and return %FALSE. * * @config is a #GstStructure that contains the configuration parameters for * the pool. A default and mandatory set of parameters can be configured with * gst_buffer_pool_config_set_params(), gst_buffer_pool_config_set_allocator() * and gst_buffer_pool_config_add_option(). * * If the parameters in @config can not be set exactly, this function returns * %FALSE and will try to update as much state as possible. The new state can * then be retrieved and refined with gst_buffer_pool_get_config(). * * This function takes ownership of @config. * * Returns: %TRUE when the configuration could be set. */ gboolean gst_buffer_pool_set_config (GstBufferPool * pool, GstStructure * config) { gboolean result; GstBufferPoolClass *pclass; GstBufferPoolPrivate *priv; g_return_val_if_fail (GST_IS_BUFFER_POOL (pool), FALSE); g_return_val_if_fail (config != NULL, FALSE); priv = pool->priv; GST_BUFFER_POOL_LOCK (pool); /* nothing to do if config is unchanged */ if (priv->configured && gst_structure_is_equal (config, priv->config)) goto config_unchanged; /* can't change the settings when active */ if (priv->active) goto was_active; /* we can't change when outstanding buffers */ if (g_atomic_int_get (&priv->outstanding) != 0) goto have_outstanding; pclass = GST_BUFFER_POOL_GET_CLASS (pool); /* set the new config */ if (G_LIKELY (pclass->set_config)) result = pclass->set_config (pool, config); else result = FALSE; /* save the config regardless of the result so user can read back the * modified config and evaluate if the changes are acceptable */ if (priv->config) gst_structure_free (priv->config); priv->config = config; if (result) { /* now we are configured */ priv->configured = TRUE; } GST_BUFFER_POOL_UNLOCK (pool); return result; config_unchanged: { gst_structure_free (config); GST_BUFFER_POOL_UNLOCK (pool); return TRUE; } /* ERRORS */ was_active: { gst_structure_free (config); GST_INFO_OBJECT (pool, "can't change config, we are active"); GST_BUFFER_POOL_UNLOCK (pool); return FALSE; } have_outstanding: { gst_structure_free (config); GST_WARNING_OBJECT (pool, "can't change config, have outstanding buffers"); GST_BUFFER_POOL_UNLOCK (pool); return FALSE; } }