rtsp-stream: Remove the multicast group udp sources when removing from the bin
[platform/upstream/gstreamer.git] / gst / rtsp-server / rtsp-stream.c
index 9ed194f..68d7bec 100644 (file)
@@ -1949,6 +1949,7 @@ gst_rtsp_stream_leave_bin (GstRTSPStream * stream, GstBin * bin,
 {
   GstRTSPStreamPrivate *priv;
   gint i;
+  GList *l;
 
   g_return_val_if_fail (GST_IS_RTSP_STREAM (stream), FALSE);
   g_return_val_if_fail (GST_IS_BIN (bin), FALSE);
@@ -1999,6 +2000,18 @@ gst_rtsp_stream_leave_bin (GstRTSPStream * stream, GstBin * bin,
       gst_element_set_state (priv->udpsrc_v6[i], GST_STATE_NULL);
       gst_bin_remove (bin, priv->udpsrc_v6[i]);
     }
+
+    for (l = priv->transport_sources; l; l = l->next) {
+      GstRTSPMulticastTransportSource *s = l->data;
+
+      if (!s->udpsrc[i])
+        continue;
+
+      gst_element_set_locked_state (s->udpsrc[i], FALSE);
+      gst_element_set_state (s->udpsrc[i], GST_STATE_NULL);
+      gst_bin_remove (bin, s->udpsrc[i]);
+    }
+
     if (priv->udpsink[i])
       gst_bin_remove (bin, priv->udpsink[i]);
     if (priv->appsrc[i])
@@ -2025,6 +2038,14 @@ gst_rtsp_stream_leave_bin (GstRTSPStream * stream, GstBin * bin,
     priv->tee[i] = NULL;
     priv->funnel[i] = NULL;
   }
+
+  for (l = priv->transport_sources; l; l = l->next) {
+    GstRTSPMulticastTransportSource *s = l->data;
+    g_slice_free (GstRTSPMulticastTransportSource, s);
+  }
+  g_list_free (priv->transport_sources);
+  priv->transport_sources = NULL;
+
   gst_object_unref (priv->send_src[0]);
   priv->send_src[0] = NULL;
 
@@ -2730,3 +2751,81 @@ gst_rtsp_stream_is_blocking (GstRTSPStream * stream)
 
   return result;
 }
+
+/**
+ * gst_rtsp_stream_query_position:
+ * @stream: a #GstRTSPStream
+ *
+ * Query the position of the stream in %GST_FORMAT_TIME. This only considers
+ * the RTP parts of the pipeline and not the RTCP parts.
+ *
+ * Returns: %TRUE if the position could be queried
+ */
+gboolean
+gst_rtsp_stream_query_position (GstRTSPStream * stream, gint64 * position)
+{
+  GstRTSPStreamPrivate *priv;
+  GstElement *sink;
+  gboolean ret;
+
+  g_return_val_if_fail (GST_IS_RTSP_STREAM (stream), FALSE);
+
+  priv = stream->priv;
+
+  g_mutex_lock (&priv->lock);
+  if ((sink = priv->udpsink[0]))
+    gst_object_ref (sink);
+  g_mutex_unlock (&priv->lock);
+
+  if (!sink)
+    return FALSE;
+
+  ret = gst_element_query_position (sink, GST_FORMAT_TIME, position);
+  gst_object_unref (sink);
+
+  return ret;
+}
+
+/**
+ * gst_rtsp_stream_query_stop:
+ * @stream: a #GstRTSPStream
+ *
+ * Query the stop of the stream in %GST_FORMAT_TIME. This only considers
+ * the RTP parts of the pipeline and not the RTCP parts.
+ *
+ * Returns: %TRUE if the stop could be queried
+ */
+gboolean
+gst_rtsp_stream_query_stop (GstRTSPStream * stream, gint64 * stop)
+{
+  GstRTSPStreamPrivate *priv;
+  GstElement *sink;
+  GstQuery *query;
+  gboolean ret;
+
+  g_return_val_if_fail (GST_IS_RTSP_STREAM (stream), FALSE);
+
+  priv = stream->priv;
+
+  g_mutex_lock (&priv->lock);
+  if ((sink = priv->udpsink[0]))
+    gst_object_ref (sink);
+  g_mutex_unlock (&priv->lock);
+
+  if (!sink)
+    return FALSE;
+
+  query = gst_query_new_segment (GST_FORMAT_TIME);
+  if ((ret = gst_element_query (sink, query))) {
+    GstFormat format;
+
+    gst_query_parse_segment (query, NULL, &format, NULL, stop);
+    if (format != GST_FORMAT_TIME)
+      *stop = -1;
+  }
+  gst_query_unref (query);
+  gst_object_unref (sink);
+
+  return ret;
+
+}