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;
|
guint64 dropped;
|
||||||
|
|
||||||
GstClockTime position_out;
|
GstClockTime position_out;
|
||||||
|
|
||||||
|
GstBufferPool *srcpool;
|
||||||
};
|
};
|
||||||
|
|
||||||
static GstElementClass *parent_class = NULL;
|
static GstElementClass *parent_class = NULL;
|
||||||
|
@ -742,6 +744,84 @@ done:
|
||||||
return caps;
|
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
|
/* function triggered when the in and out caps are negotiated and need
|
||||||
* to be configured in the subclass. */
|
* to be configured in the subclass. */
|
||||||
static gboolean
|
static gboolean
|
||||||
|
@ -781,6 +861,11 @@ gst_base_transform_configure_caps (GstBaseTransform * trans, GstCaps * in,
|
||||||
ret = klass->set_caps (trans, in, out);
|
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;
|
trans->negotiated = ret;
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -1204,12 +1289,20 @@ gst_base_transform_query (GstPad * pad, GstQuery * query)
|
||||||
switch (GST_QUERY_TYPE (query)) {
|
switch (GST_QUERY_TYPE (query)) {
|
||||||
case GST_QUERY_ALLOCATION:
|
case GST_QUERY_ALLOCATION:
|
||||||
{
|
{
|
||||||
|
gboolean passthrough;
|
||||||
|
|
||||||
/* can only be done on the sinkpad */
|
/* can only be done on the sinkpad */
|
||||||
if (!GST_PAD_IS_SINK (pad))
|
if (!GST_PAD_IS_SINK (pad))
|
||||||
goto done;
|
goto done;
|
||||||
|
|
||||||
/* if we negotiated passthrough */
|
GST_BASE_TRANSFORM_LOCK (trans);
|
||||||
ret = FALSE;
|
passthrough = trans->passthrough;
|
||||||
|
GST_BASE_TRANSFORM_UNLOCK (trans);
|
||||||
|
|
||||||
|
if (passthrough)
|
||||||
|
ret = gst_pad_peer_query (otherpad, query);
|
||||||
|
else
|
||||||
|
ret = FALSE;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case GST_QUERY_POSITION:
|
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 */
|
/* figure out how to allocate a buffer based on the current configuration */
|
||||||
if (trans->passthrough) {
|
if (trans->passthrough) {
|
||||||
GST_DEBUG_OBJECT (trans, "doing passthrough alloc");
|
GST_DEBUG_OBJECT (trans, "doing passthrough alloc");
|
||||||
/* passthrough, we don't really need to call pad alloc but we still need to
|
/* passthrough, the output size is the same as the input size. */
|
||||||
* in order to get upstream negotiation. The output size is the same as the
|
|
||||||
* input size. */
|
|
||||||
outsize = insize;
|
outsize = insize;
|
||||||
} else {
|
} else {
|
||||||
gboolean want_in_place = (bclass->transform_ip != NULL)
|
gboolean want_in_place = (bclass->transform_ip != NULL)
|
||||||
|
@ -1345,12 +1436,19 @@ gst_base_transform_prepare_output_buffer (GstBaseTransform * trans,
|
||||||
if (trans->passthrough) {
|
if (trans->passthrough) {
|
||||||
GST_DEBUG_OBJECT (trans, "Avoiding pad alloc");
|
GST_DEBUG_OBJECT (trans, "Avoiding pad alloc");
|
||||||
*out_buf = in_buf;
|
*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 {
|
} else {
|
||||||
GST_DEBUG_OBJECT (trans, "doing alloc of size %u", outsize);
|
GST_DEBUG_OBJECT (trans, "doing alloc of size %u", outsize);
|
||||||
*out_buf = gst_buffer_new_and_alloc (outsize);
|
*out_buf = gst_buffer_new_and_alloc (outsize);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (ret != GST_FLOW_OK)
|
||||||
|
goto alloc_failed;
|
||||||
|
|
||||||
/* must always have a buffer by now */
|
/* must always have a buffer by now */
|
||||||
if (*out_buf == NULL)
|
if (*out_buf == NULL)
|
||||||
goto no_buffer;
|
goto no_buffer;
|
||||||
|
|
Loading…
Reference in a new issue