mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-01-12 10:25:33 +00:00
media: listen to pad-removed signals
Listen to the pad-removed signal and remove the stream associated with the removed pad. Add signal to be notified of the removed pad. Remove the fakesink in unprepare() Fix signatures of the signal methods
This commit is contained in:
parent
b614319622
commit
b80b8824be
2 changed files with 74 additions and 7 deletions
|
@ -102,6 +102,7 @@ enum
|
|||
enum
|
||||
{
|
||||
SIGNAL_NEW_STREAM,
|
||||
SIGNAL_REMOVED_STREAM,
|
||||
SIGNAL_PREPARED,
|
||||
SIGNAL_UNPREPARED,
|
||||
SIGNAL_NEW_STATE,
|
||||
|
@ -180,6 +181,12 @@ gst_rtsp_media_class_init (GstRTSPMediaClass * klass)
|
|||
G_STRUCT_OFFSET (GstRTSPMediaClass, new_stream), NULL, NULL,
|
||||
g_cclosure_marshal_generic, G_TYPE_NONE, 1, GST_TYPE_RTSP_STREAM);
|
||||
|
||||
gst_rtsp_media_signals[SIGNAL_REMOVED_STREAM] =
|
||||
g_signal_new ("removed-stream", G_TYPE_FROM_CLASS (klass),
|
||||
G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstRTSPMediaClass, removed_stream),
|
||||
NULL, NULL, g_cclosure_marshal_generic, G_TYPE_NONE, 1,
|
||||
GST_TYPE_RTSP_STREAM);
|
||||
|
||||
gst_rtsp_media_signals[SIGNAL_PREPARED] =
|
||||
g_signal_new ("prepared", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST,
|
||||
G_STRUCT_OFFSET (GstRTSPMediaClass, prepared), NULL, NULL,
|
||||
|
@ -972,6 +979,30 @@ gst_rtsp_media_create_stream (GstRTSPMedia * media, GstElement * payloader,
|
|||
return stream;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_rtsp_media_remove_stream (GstRTSPMedia * media, GstRTSPStream * stream)
|
||||
{
|
||||
GstRTSPMediaPrivate *priv;
|
||||
GstPad *srcpad;
|
||||
|
||||
priv = media->priv;
|
||||
|
||||
g_mutex_lock (&priv->lock);
|
||||
/* remove the ghostpad */
|
||||
srcpad = gst_rtsp_stream_get_srcpad (stream);
|
||||
gst_element_remove_pad (priv->element, srcpad);
|
||||
gst_object_unref (srcpad);
|
||||
/* now remove the stream */
|
||||
g_object_ref (stream);
|
||||
g_ptr_array_remove (priv->streams, stream);
|
||||
g_mutex_unlock (&priv->lock);
|
||||
|
||||
g_signal_emit (media, gst_rtsp_media_signals[SIGNAL_REMOVED_STREAM], 0,
|
||||
stream, NULL);
|
||||
|
||||
g_object_unref (stream);
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_rtsp_media_n_streams:
|
||||
* @media: a #GstRTSPMedia
|
||||
|
@ -1369,6 +1400,8 @@ pad_added_cb (GstElement * element, GstPad * pad, GstRTSPMedia * media)
|
|||
/* FIXME, element is likely not a payloader, find the payloader here */
|
||||
stream = gst_rtsp_media_create_stream (media, element, pad);
|
||||
|
||||
g_object_set_data (G_OBJECT (pad), "gst-rtsp-dynpad-stream", stream);
|
||||
|
||||
GST_INFO ("pad added %s:%s, stream %p", GST_DEBUG_PAD_NAME (pad), stream);
|
||||
|
||||
g_rec_mutex_lock (&priv->state_lock);
|
||||
|
@ -1387,13 +1420,30 @@ pad_added_cb (GstElement * element, GstPad * pad, GstRTSPMedia * media)
|
|||
}
|
||||
|
||||
static void
|
||||
no_more_pads_cb (GstElement * element, GstRTSPMedia * media)
|
||||
pad_removed_cb (GstElement * element, GstPad * pad, GstRTSPMedia * media)
|
||||
{
|
||||
GstRTSPMediaPrivate *priv = media->priv;
|
||||
GstRTSPStream *stream;
|
||||
|
||||
stream = g_object_get_data (G_OBJECT (pad), "gst-rtsp-dynpad-stream");
|
||||
if (stream == NULL)
|
||||
return;
|
||||
|
||||
GST_INFO ("pad removed %s:%s, stream %p", GST_DEBUG_PAD_NAME (pad), stream);
|
||||
|
||||
g_rec_mutex_lock (&priv->state_lock);
|
||||
gst_rtsp_stream_leave_bin (stream, GST_BIN (priv->pipeline), priv->rtpbin);
|
||||
g_rec_mutex_unlock (&priv->state_lock);
|
||||
|
||||
gst_rtsp_media_remove_stream (media, stream);
|
||||
}
|
||||
|
||||
static void
|
||||
remove_fakesink (GstRTSPMediaPrivate * priv)
|
||||
{
|
||||
GstElement *fakesink;
|
||||
|
||||
g_mutex_lock (&priv->lock);
|
||||
GST_INFO ("no more pads");
|
||||
if ((fakesink = priv->fakesink)) {
|
||||
gst_object_ref (fakesink);
|
||||
priv->fakesink = NULL;
|
||||
|
@ -1406,11 +1456,21 @@ no_more_pads_cb (GstElement * element, GstRTSPMedia * media)
|
|||
}
|
||||
}
|
||||
|
||||
static void
|
||||
no_more_pads_cb (GstElement * element, GstRTSPMedia * media)
|
||||
{
|
||||
GstRTSPMediaPrivate *priv = media->priv;
|
||||
|
||||
GST_INFO ("no more pads");
|
||||
remove_fakesink (priv);
|
||||
}
|
||||
|
||||
typedef struct _DynPaySignalHandlers DynPaySignalHandlers;
|
||||
|
||||
struct _DynPaySignalHandlers
|
||||
{
|
||||
gulong pad_added_handler;
|
||||
gulong pad_removed_handler;
|
||||
gulong no_more_pads_handler;
|
||||
};
|
||||
|
||||
|
@ -1504,6 +1564,8 @@ gst_rtsp_media_prepare (GstRTSPMedia * media)
|
|||
|
||||
handlers->pad_added_handler = g_signal_connect (elem, "pad-added",
|
||||
(GCallback) pad_added_cb, media);
|
||||
handlers->pad_removed_handler = g_signal_connect (elem, "pad-removed",
|
||||
(GCallback) pad_removed_cb, media);
|
||||
handlers->no_more_pads_handler = g_signal_connect (elem, "no-more-pads",
|
||||
(GCallback) no_more_pads_cb, media);
|
||||
|
||||
|
@ -1608,6 +1670,7 @@ finish_unprepare (GstRTSPMedia * media)
|
|||
GST_DEBUG ("shutting down");
|
||||
|
||||
gst_element_set_state (priv->pipeline, GST_STATE_NULL);
|
||||
remove_fakesink (priv);
|
||||
|
||||
for (i = 0; i < priv->streams->len; i++) {
|
||||
GstRTSPStream *stream;
|
||||
|
@ -1624,10 +1687,13 @@ finish_unprepare (GstRTSPMedia * media)
|
|||
GstElement *elem = walk->data;
|
||||
DynPaySignalHandlers *handlers;
|
||||
|
||||
handlers = g_object_steal_data (G_OBJECT (elem), "gst-rtsp-dypay-handlers");
|
||||
handlers =
|
||||
g_object_steal_data (G_OBJECT (elem), "gst-rtsp-dynpay-handlers");
|
||||
g_assert (handlers != NULL);
|
||||
|
||||
g_signal_handler_disconnect (G_OBJECT (elem), handlers->pad_added_handler);
|
||||
g_signal_handler_disconnect (G_OBJECT (elem),
|
||||
handlers->pad_removed_handler);
|
||||
g_signal_handler_disconnect (G_OBJECT (elem),
|
||||
handlers->no_more_pads_handler);
|
||||
|
||||
|
|
|
@ -102,12 +102,13 @@ struct _GstRTSPMediaClass {
|
|||
gboolean (*unprepare) (GstRTSPMedia *media);
|
||||
|
||||
/* signals */
|
||||
gboolean (*new_stream) (GstRTSPMedia *media, GstRTSPStream * stream);
|
||||
void (*new_stream) (GstRTSPMedia *media, GstRTSPStream * stream);
|
||||
void (*removed_stream) (GstRTSPMedia *media, GstRTSPStream * stream);
|
||||
|
||||
gboolean (*prepared) (GstRTSPMedia *media);
|
||||
gboolean (*unprepared) (GstRTSPMedia *media);
|
||||
void (*prepared) (GstRTSPMedia *media);
|
||||
void (*unprepared) (GstRTSPMedia *media);
|
||||
|
||||
gboolean (*new_state) (GstRTSPMedia *media, GstState state);
|
||||
void (*new_state) (GstRTSPMedia *media, GstState state);
|
||||
};
|
||||
|
||||
GType gst_rtsp_media_get_type (void);
|
||||
|
|
Loading…
Reference in a new issue