mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-03-30 12:49:40 +00:00
rtsp-media: Try to get dynamic payloaders by name from their bin first
First try "pay", then "pay_%s" (where %s == pad name). And only then fall back to the code that simply takes the first payloader that is found. The current code usually works (but is racy) because it will always take the payloader that was last added (due to g_list_prepend() when adding elements) in pad-added and that's usually the correct one. But if a new payloader is added between pad-added and us trying to get it, we would get the wrong payloader.
This commit is contained in:
parent
507e6f1db2
commit
446315b36c
2 changed files with 49 additions and 16 deletions
|
@ -465,7 +465,7 @@ pad_added_cb (GstElement * uribin, GstPad * pad, GstElement * element)
|
|||
GstCaps *caps;
|
||||
GstPad *sinkpad, *srcpad, *ghostpad;
|
||||
GstElement *convert;
|
||||
gchar *padname;
|
||||
gchar *padname, *payloader_name;
|
||||
|
||||
GST_DEBUG ("added pad %s:%s", GST_DEBUG_PAD_NAME (pad));
|
||||
|
||||
|
@ -521,7 +521,9 @@ pad_added_cb (GstElement * uribin, GstPad * pad, GstElement * element)
|
|||
GST_DEBUG ("found payloader factory %s",
|
||||
gst_plugin_feature_get_name (GST_PLUGIN_FEATURE (factory)));
|
||||
|
||||
payloader = gst_element_factory_create (factory, NULL);
|
||||
payloader_name = g_strdup_printf ("pay_%s", padname);
|
||||
payloader = gst_element_factory_create (factory, payloader_name);
|
||||
g_free (payloader_name);
|
||||
if (payloader == NULL)
|
||||
goto no_payloader;
|
||||
|
||||
|
|
|
@ -235,7 +235,7 @@ static gboolean default_handle_sdp (GstRTSPMedia * media, GstSDPMessage * sdp);
|
|||
|
||||
static gboolean wait_preroll (GstRTSPMedia * media);
|
||||
|
||||
static GstElement *find_payload_element (GstElement * payloader);
|
||||
static GstElement *find_payload_element (GstElement * payloader, GstPad * pad);
|
||||
|
||||
static guint gst_rtsp_media_signals[SIGNAL_LAST] = { 0 };
|
||||
|
||||
|
@ -2046,7 +2046,7 @@ gst_rtsp_media_collect_streams (GstRTSPMedia * media)
|
|||
pad = gst_element_get_static_pad (elem, "src");
|
||||
|
||||
/* find the real payload element in case elem is a GstBin */
|
||||
pay = find_payload_element (elem);
|
||||
pay = find_payload_element (elem, pad);
|
||||
|
||||
/* create the stream */
|
||||
if (pay == NULL) {
|
||||
|
@ -2213,7 +2213,8 @@ gst_rtsp_media_create_stream (GstRTSPMedia * media, GstElement * payloader,
|
|||
g_mutex_lock (&priv->lock);
|
||||
idx = priv->streams->len;
|
||||
|
||||
GST_DEBUG ("media %p: creating stream with index %d", media, idx);
|
||||
GST_DEBUG ("media %p: creating stream with index %d and payloader %"
|
||||
GST_PTR_FORMAT, media, idx, payloader);
|
||||
|
||||
if (GST_PAD_IS_SRC (pad))
|
||||
name = g_strdup_printf ("src_%u", idx);
|
||||
|
@ -3148,27 +3149,57 @@ watch_destroyed (GstRTSPMedia * media)
|
|||
g_object_unref (media);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
is_payloader (GstElement * element)
|
||||
{
|
||||
GstElementClass *eclass = GST_ELEMENT_GET_CLASS (element);
|
||||
const gchar *klass;
|
||||
|
||||
klass = gst_element_class_get_metadata (eclass, GST_ELEMENT_METADATA_KLASS);
|
||||
if (klass == NULL)
|
||||
return FALSE;
|
||||
|
||||
if (strstr (klass, "Payloader") && strstr (klass, "RTP")) {
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static GstElement *
|
||||
find_payload_element (GstElement * payloader)
|
||||
find_payload_element (GstElement * payloader, GstPad * pad)
|
||||
{
|
||||
GstElement *pay = NULL;
|
||||
|
||||
if (GST_IS_BIN (payloader)) {
|
||||
GstIterator *iter;
|
||||
GValue item = { 0 };
|
||||
gchar *pad_name, *payloader_name;
|
||||
GstElement *element;
|
||||
|
||||
if ((element = gst_bin_get_by_name (GST_BIN (payloader), "pay"))) {
|
||||
if (is_payloader (element))
|
||||
return element;
|
||||
gst_object_unref (element);
|
||||
}
|
||||
|
||||
pad_name = gst_object_get_name (GST_OBJECT (pad));
|
||||
payloader_name = g_strdup_printf ("pay_%s", pad_name);
|
||||
g_free (pad_name);
|
||||
if ((element = gst_bin_get_by_name (GST_BIN (payloader), payloader_name))) {
|
||||
g_free (payloader_name);
|
||||
if (is_payloader (element))
|
||||
return element;
|
||||
gst_object_unref (element);
|
||||
} else {
|
||||
g_free (payloader_name);
|
||||
}
|
||||
|
||||
iter = gst_bin_iterate_recurse (GST_BIN (payloader));
|
||||
while (gst_iterator_next (iter, &item) == GST_ITERATOR_OK) {
|
||||
GstElement *element = (GstElement *) g_value_get_object (&item);
|
||||
GstElementClass *eclass = GST_ELEMENT_GET_CLASS (element);
|
||||
const gchar *klass;
|
||||
element = (GstElement *) g_value_get_object (&item);
|
||||
|
||||
klass =
|
||||
gst_element_class_get_metadata (eclass, GST_ELEMENT_METADATA_KLASS);
|
||||
if (klass == NULL)
|
||||
continue;
|
||||
|
||||
if (strstr (klass, "Payloader") && strstr (klass, "RTP")) {
|
||||
if (is_payloader (element)) {
|
||||
pay = gst_object_ref (element);
|
||||
g_value_unset (&item);
|
||||
break;
|
||||
|
@ -3192,7 +3223,7 @@ pad_added_cb (GstElement * element, GstPad * pad, GstRTSPMedia * media)
|
|||
GstElement *pay;
|
||||
|
||||
/* find the real payload element */
|
||||
pay = find_payload_element (element);
|
||||
pay = find_payload_element (element, pad);
|
||||
stream = gst_rtsp_media_create_stream (media, pay, pad);
|
||||
gst_object_unref (pay);
|
||||
|
||||
|
|
Loading…
Reference in a new issue