mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-19 14:56:36 +00:00
basetransform: WIP handle bufferpool
This commit is contained in:
parent
4e13568d27
commit
1cb7523efa
1 changed files with 103 additions and 5 deletions
|
@ -251,6 +251,8 @@ struct _GstBaseTransformPrivate
|
|||
guint64 dropped;
|
||||
|
||||
GstClockTime position_out;
|
||||
|
||||
GstBufferPool *srcpool;
|
||||
};
|
||||
|
||||
static GstElementClass *parent_class = NULL;
|
||||
|
@ -742,6 +744,84 @@ done:
|
|||
return caps;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gst_base_transform_do_bufferpool (GstBaseTransform * trans, GstCaps * outcaps)
|
||||
{
|
||||
GstQuery *query;
|
||||
GstBufferPool *pool = NULL, *oldpool;
|
||||
guint size, min, max, prefix, alignment;
|
||||
|
||||
/* there are these possibilities:
|
||||
*
|
||||
* 1) we negotiated passthrough, we can proxy the bufferpool directly.
|
||||
* 2)
|
||||
*/
|
||||
|
||||
/* clear old pool */
|
||||
oldpool = trans->priv->srcpool;
|
||||
if (oldpool) {
|
||||
gst_buffer_pool_set_active (oldpool, FALSE);
|
||||
gst_object_unref (oldpool);
|
||||
trans->priv->srcpool = oldpool = NULL;
|
||||
}
|
||||
|
||||
if (trans->passthrough) {
|
||||
/* we are in passthrough, the input buffer is never copied and always passed
|
||||
* along. We never allocate an output buffer on the srcpad. What we do is
|
||||
* let the upstream element decide if it wants to use a bufferpool and
|
||||
* then we will proxy the downstream pool */
|
||||
GST_DEBUG_OBJECT (trans, "we're passthough, delay bufferpool");
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* not passthrough, we need to allocate */
|
||||
/* find a pool for the negotiated caps now */
|
||||
query = gst_query_new_allocation (outcaps, TRUE);
|
||||
|
||||
if (gst_pad_peer_query (trans->srcpad, query))
|
||||
goto query_failed;
|
||||
|
||||
/* we got configuration from our peer, parse them */
|
||||
gst_query_parse_allocation_params (query, &size, &min, &max, &prefix,
|
||||
&alignment, &pool);
|
||||
gst_query_unref (query);
|
||||
|
||||
if (pool == NULL) {
|
||||
GstStructure *config;
|
||||
|
||||
/* we did not get a pool, make one ourselves then */
|
||||
pool = gst_buffer_pool_new ();
|
||||
|
||||
config = gst_buffer_pool_get_config (pool);
|
||||
gst_buffer_pool_config_set (config, outcaps, size, min, max, prefix, 0,
|
||||
alignment);
|
||||
gst_buffer_pool_set_config (pool, config);
|
||||
}
|
||||
|
||||
/* activate */
|
||||
if (!gst_buffer_pool_set_active (pool, TRUE))
|
||||
goto activate_failed;
|
||||
|
||||
/* and store */
|
||||
trans->priv->srcpool = pool;
|
||||
|
||||
return TRUE;
|
||||
|
||||
/* ERRORS */
|
||||
query_failed:
|
||||
{
|
||||
GST_DEBUG_OBJECT (trans, "allocation query failed");
|
||||
gst_query_unref (query);
|
||||
return FALSE;
|
||||
}
|
||||
activate_failed:
|
||||
{
|
||||
GST_ERROR_OBJECT (trans, "failed to activate bufferpool.");
|
||||
gst_object_unref (pool);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
/* function triggered when the in and out caps are negotiated and need
|
||||
* to be configured in the subclass. */
|
||||
static gboolean
|
||||
|
@ -781,6 +861,11 @@ gst_base_transform_configure_caps (GstBaseTransform * trans, GstCaps * in,
|
|||
ret = klass->set_caps (trans, in, out);
|
||||
}
|
||||
|
||||
if (ret) {
|
||||
/* try to get a pool when needed */
|
||||
gst_base_transform_do_bufferpool (trans, out);
|
||||
}
|
||||
|
||||
trans->negotiated = ret;
|
||||
|
||||
return ret;
|
||||
|
@ -1204,12 +1289,20 @@ gst_base_transform_query (GstPad * pad, GstQuery * query)
|
|||
switch (GST_QUERY_TYPE (query)) {
|
||||
case GST_QUERY_ALLOCATION:
|
||||
{
|
||||
gboolean passthrough;
|
||||
|
||||
/* can only be done on the sinkpad */
|
||||
if (!GST_PAD_IS_SINK (pad))
|
||||
goto done;
|
||||
|
||||
/* if we negotiated passthrough */
|
||||
ret = FALSE;
|
||||
GST_BASE_TRANSFORM_LOCK (trans);
|
||||
passthrough = trans->passthrough;
|
||||
GST_BASE_TRANSFORM_UNLOCK (trans);
|
||||
|
||||
if (passthrough)
|
||||
ret = gst_pad_peer_query (otherpad, query);
|
||||
else
|
||||
ret = FALSE;
|
||||
break;
|
||||
}
|
||||
case GST_QUERY_POSITION:
|
||||
|
@ -1287,9 +1380,7 @@ gst_base_transform_prepare_output_buffer (GstBaseTransform * trans,
|
|||
/* figure out how to allocate a buffer based on the current configuration */
|
||||
if (trans->passthrough) {
|
||||
GST_DEBUG_OBJECT (trans, "doing passthrough alloc");
|
||||
/* passthrough, we don't really need to call pad alloc but we still need to
|
||||
* in order to get upstream negotiation. The output size is the same as the
|
||||
* input size. */
|
||||
/* passthrough, the output size is the same as the input size. */
|
||||
outsize = insize;
|
||||
} else {
|
||||
gboolean want_in_place = (bclass->transform_ip != NULL)
|
||||
|
@ -1345,12 +1436,19 @@ gst_base_transform_prepare_output_buffer (GstBaseTransform * trans,
|
|||
if (trans->passthrough) {
|
||||
GST_DEBUG_OBJECT (trans, "Avoiding pad alloc");
|
||||
*out_buf = in_buf;
|
||||
} else if (trans->priv->srcpool) {
|
||||
GST_DEBUG_OBJECT (trans, "using pool alloc");
|
||||
ret =
|
||||
gst_buffer_pool_acquire_buffer (trans->priv->srcpool, out_buf, NULL);
|
||||
} else {
|
||||
GST_DEBUG_OBJECT (trans, "doing alloc of size %u", outsize);
|
||||
*out_buf = gst_buffer_new_and_alloc (outsize);
|
||||
}
|
||||
}
|
||||
|
||||
if (ret != GST_FLOW_OK)
|
||||
goto alloc_failed;
|
||||
|
||||
/* must always have a buffer by now */
|
||||
if (*out_buf == NULL)
|
||||
goto no_buffer;
|
||||
|
|
Loading…
Reference in a new issue