mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-02-17 11:45:25 +00:00
testbinsrc: Handle setting URI on the fly
Reusing existing streams when possible Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-bad/-/merge_requests/2210>
This commit is contained in:
parent
711008674b
commit
61a04cf51f
1 changed files with 86 additions and 20 deletions
|
@ -76,6 +76,7 @@ struct _GstTestSrcBin
|
|||
GstStreamCollection *collection;
|
||||
gint group_id;
|
||||
GstFlowCombiner *flow_combiner;
|
||||
GstCaps *streams_def;
|
||||
};
|
||||
|
||||
enum
|
||||
|
@ -125,7 +126,7 @@ _probe_data_new (GstEvent * stream_start, GstStreamCollection * collection)
|
|||
{
|
||||
ProbeData *data = g_malloc0 (sizeof (ProbeData));
|
||||
|
||||
data->stream_start = gst_event_ref (stream_start);
|
||||
data->stream_start = stream_start;
|
||||
data->collection = gst_object_ref (collection);
|
||||
|
||||
return data;
|
||||
|
@ -196,6 +197,9 @@ static gboolean
|
|||
gst_test_src_bin_set_element_property (GQuark property_id, const GValue * value,
|
||||
GObject * element)
|
||||
{
|
||||
if (property_id == g_quark_from_static_string ("__streamobj__"))
|
||||
return TRUE;
|
||||
|
||||
if (G_VALUE_HOLDS_STRING (value))
|
||||
gst_util_set_object_arg (element, g_quark_to_string (property_id),
|
||||
g_value_get_string (value));
|
||||
|
@ -266,11 +270,13 @@ gst_test_src_bin_setup_src (GstTestSrcBin * self, const gchar * srcfactory,
|
|||
gst_event_set_stream (stream_start, stream);
|
||||
gst_event_set_group_id (stream_start, self->group_id);
|
||||
|
||||
gst_structure_set (props, "__streamobj__", GST_TYPE_STREAM, stream, NULL);
|
||||
gst_stream_collection_add_stream (collection, stream);
|
||||
|
||||
gst_pad_add_probe (pad, (GstPadProbeType) GST_PAD_PROBE_TYPE_EVENT_DOWNSTREAM,
|
||||
(GstPadProbeCallback) src_pad_probe_cb, _probe_data_new (stream_start,
|
||||
collection), (GDestroyNotify) _probe_data_free);
|
||||
|
||||
gst_stream_collection_add_stream (collection, stream);
|
||||
g_free (stream_id);
|
||||
|
||||
gst_bin_add (GST_BIN (self), src);
|
||||
|
@ -289,14 +295,58 @@ gst_test_src_bin_setup_src (GstTestSrcBin * self, const gchar * srcfactory,
|
|||
gst_object_unref (pad);
|
||||
gst_element_sync_state_with_parent (src);
|
||||
*n_stream += 1;
|
||||
|
||||
gst_structure_set (props, "__src__", GST_TYPE_OBJECT, src, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
gst_test_src_bin_remove_child (GValue * val, GstBin * self)
|
||||
gst_test_src_bin_remove_child (GstElement * self, GstElement * child)
|
||||
{
|
||||
GstElement *child = g_value_get_object (val);
|
||||
GstPad *pad = gst_element_get_static_pad (child, "src");
|
||||
GstPad *ghost =
|
||||
GST_PAD (gst_proxy_pad_get_internal (GST_PROXY_PAD (gst_pad_get_peer
|
||||
(pad))));
|
||||
|
||||
gst_bin_remove (self, child);
|
||||
|
||||
gst_element_set_locked_state (child, FALSE);
|
||||
gst_element_set_state (child, GST_STATE_NULL);
|
||||
gst_bin_remove (GST_BIN (self), child);
|
||||
gst_element_remove_pad (self, ghost);
|
||||
}
|
||||
|
||||
static GstStream *
|
||||
gst_test_check_prev_stream_def (GstTestSrcBin * self, GstCaps * prev_streams,
|
||||
GstStructure * stream_def)
|
||||
{
|
||||
gint i;
|
||||
|
||||
if (!prev_streams)
|
||||
return NULL;
|
||||
|
||||
for (i = 0; i < gst_caps_get_size (prev_streams); i++) {
|
||||
GstStructure *prev_stream = gst_caps_get_structure (prev_streams, i);
|
||||
GstElement *e = NULL;
|
||||
GstStream *stream = NULL;
|
||||
|
||||
gst_structure_get (prev_stream, "__src__", GST_TYPE_OBJECT, &e,
|
||||
"__streamobj__", GST_TYPE_STREAM, &stream, NULL);
|
||||
gst_structure_remove_fields (prev_stream, "__src__", "__streamobj__", NULL);
|
||||
if (gst_structure_is_equal (prev_stream, stream_def)) {
|
||||
g_assert (stream);
|
||||
|
||||
gst_caps_remove_structure (prev_streams, i);
|
||||
gst_structure_set (stream_def, "__src__", GST_TYPE_OBJECT, e,
|
||||
"__streamobj__", GST_TYPE_STREAM, stream, NULL);
|
||||
|
||||
g_assert (stream);
|
||||
return stream;
|
||||
}
|
||||
|
||||
gst_structure_set (stream_def, "__src__", GST_TYPE_OBJECT, e,
|
||||
"__streamobj__", GST_TYPE_STREAM, stream, NULL);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
|
@ -307,31 +357,34 @@ gst_test_src_bin_uri_handler_set_uri (GstURIHandler * handler,
|
|||
gchar *tmp, *location = gst_uri_get_location (uri);
|
||||
gint i, n_audio = 0, n_video = 0;
|
||||
GstStreamCollection *collection = gst_stream_collection_new (NULL);
|
||||
GstIterator *it;
|
||||
GstCaps *streams_defs;
|
||||
GstCaps *streams_def, *prev_streams = self->streams_def;
|
||||
|
||||
for (tmp = location; *tmp != '\0'; tmp++)
|
||||
if (*tmp == '+')
|
||||
*tmp = ';';
|
||||
|
||||
streams_defs = gst_caps_from_string (location);
|
||||
streams_def = gst_caps_from_string (location);
|
||||
g_free (location);
|
||||
|
||||
if (!streams_defs)
|
||||
if (!streams_def)
|
||||
goto failed;
|
||||
|
||||
/* Clear us up */
|
||||
it = gst_bin_iterate_elements (GST_BIN (self));
|
||||
while (gst_iterator_foreach (it,
|
||||
(GstIteratorForeachFunction) gst_test_src_bin_remove_child,
|
||||
self) == GST_ITERATOR_RESYNC)
|
||||
gst_iterator_resync (it);
|
||||
|
||||
gst_iterator_free (it);
|
||||
|
||||
self->group_id = gst_util_group_id_next ();
|
||||
for (i = 0; i < gst_caps_get_size (streams_defs); i++) {
|
||||
GstStructure *stream_def = gst_caps_get_structure (streams_defs, i);
|
||||
for (i = 0; i < gst_caps_get_size (streams_def); i++) {
|
||||
GstStream *stream;
|
||||
GstStructure *stream_def = gst_caps_get_structure (streams_def, i);
|
||||
|
||||
if ((stream =
|
||||
gst_test_check_prev_stream_def (self, prev_streams, stream_def))) {
|
||||
GST_INFO_OBJECT (self,
|
||||
"Reusing already existing stream: %" GST_PTR_FORMAT, stream_def);
|
||||
gst_stream_collection_add_stream (collection, stream);
|
||||
if (gst_structure_has_name (stream_def, "video"))
|
||||
n_video++;
|
||||
else
|
||||
n_audio++;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (gst_structure_has_name (stream_def, "video"))
|
||||
gst_test_src_bin_setup_src (self, "videotestsrc", &video_src_template,
|
||||
|
@ -343,6 +396,18 @@ gst_test_src_bin_uri_handler_set_uri (GstURIHandler * handler,
|
|||
GST_ERROR_OBJECT (self, "Unknown type %s",
|
||||
gst_structure_get_name (stream_def));
|
||||
}
|
||||
self->streams_def = streams_def;
|
||||
|
||||
if (prev_streams) {
|
||||
for (i = 0; i < gst_caps_get_size (prev_streams); i++) {
|
||||
GstStructure *prev_stream = gst_caps_get_structure (prev_streams, i);
|
||||
GstElement *child;
|
||||
|
||||
gst_structure_get (prev_stream, "__src__", GST_TYPE_OBJECT, &child, NULL);
|
||||
gst_test_src_bin_remove_child (GST_ELEMENT (self), child);
|
||||
}
|
||||
gst_clear_caps (&prev_streams);
|
||||
}
|
||||
|
||||
if (!n_video && !n_audio)
|
||||
goto failed;
|
||||
|
@ -454,6 +519,7 @@ gst_test_src_bin_finalize (GObject * object)
|
|||
GstTestSrcBin *self = GST_TEST_SRC_BIN (object);
|
||||
|
||||
g_free (self->uri);
|
||||
gst_clear_caps (&self->streams_def);
|
||||
gst_flow_combiner_free (self->flow_combiner);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue