summaryrefslogtreecommitdiff
path: root/gst/rtsp-server
diff options
context:
space:
mode:
Diffstat (limited to 'gst/rtsp-server')
-rw-r--r--gst/rtsp-server/rtsp-media.c28
-rw-r--r--gst/rtsp-server/rtsp-stream.c59
-rw-r--r--gst/rtsp-server/rtsp-stream.h3
3 files changed, 73 insertions, 17 deletions
diff --git a/gst/rtsp-server/rtsp-media.c b/gst/rtsp-server/rtsp-media.c
index 159dd3d..0f8a194 100644
--- a/gst/rtsp-server/rtsp-media.c
+++ b/gst/rtsp-server/rtsp-media.c
@@ -705,6 +705,23 @@ check_seekable (GstRTSPMedia * media)
gst_query_unref (query);
}
+/* must be called with state lock */
+static gboolean
+check_complete (GstRTSPMedia * media)
+{
+ GstRTSPMediaPrivate *priv = media->priv;
+
+ guint i, n = priv->streams->len;
+
+ for (i = 0; i < n; i++) {
+ GstRTSPStream *stream = g_ptr_array_index (priv->streams, i);
+
+ if (gst_rtsp_stream_is_complete (stream))
+ return TRUE;
+ }
+
+ return FALSE;
+}
/* must be called with state lock */
static void
@@ -2209,6 +2226,11 @@ gst_rtsp_media_seek_full (GstRTSPMedia * media, GstRTSPTimeRange * range,
if (priv->status != GST_RTSP_MEDIA_STATUS_PREPARED)
goto not_prepared;
+ /* check if the media pipeline is complete in order to perform a
+ * seek operation on it */
+ if (!check_complete (media))
+ goto not_complete;
+
/* Update the seekable state of the pipeline in case it changed */
check_seekable (media);
@@ -2322,6 +2344,12 @@ not_prepared:
GST_INFO ("media %p is not prepared", media);
return FALSE;
}
+not_complete:
+ {
+ g_rec_mutex_unlock (&priv->state_lock);
+ GST_INFO ("pipeline is not complete");
+ return FALSE;
+ }
not_seekable:
{
g_rec_mutex_unlock (&priv->state_lock);
diff --git a/gst/rtsp-server/rtsp-stream.c b/gst/rtsp-server/rtsp-stream.c
index 9a8f1c2..67c02d1 100644
--- a/gst/rtsp-server/rtsp-stream.c
+++ b/gst/rtsp-server/rtsp-stream.c
@@ -77,6 +77,9 @@ struct _GstRTSPStreamPrivate
gboolean client_side;
gchar *control;
+ /* TRUE if stream is complete. This means that the receiver and the sender
+ * parts are present in the stream. */
+ gboolean is_complete;
GstRTSPProfile profiles;
GstRTSPLowerTrans protocols;
@@ -273,6 +276,7 @@ gst_rtsp_stream_finalize (GObject * obj)
{
GstRTSPStream *stream;
GstRTSPStreamPrivate *priv;
+ guint i;
stream = GST_RTSP_STREAM (obj);
priv = stream->priv;
@@ -295,22 +299,16 @@ gst_rtsp_stream_finalize (GObject * obj)
if (priv->rtxsend)
g_object_unref (priv->rtxsend);
- if (priv->socket_v4[0])
- g_object_unref (priv->socket_v4[0]);
- if (priv->socket_v4[1])
- g_object_unref (priv->socket_v4[1]);
- if (priv->socket_v6[0])
- g_object_unref (priv->socket_v6[0]);
- if (priv->socket_v6[1])
- g_object_unref (priv->socket_v6[1]);
- if (priv->mcast_socket_v4[0])
- g_object_unref (priv->mcast_socket_v4[0]);
- if (priv->mcast_socket_v4[1])
- g_object_unref (priv->mcast_socket_v4[1]);
- if (priv->mcast_socket_v6[0])
- g_object_unref (priv->mcast_socket_v6[0]);
- if (priv->mcast_socket_v6[1])
- g_object_unref (priv->mcast_socket_v6[1]);
+ for (i = 0; i < 2; i++) {
+ if (priv->socket_v4[i])
+ g_object_unref (priv->socket_v4[i]);
+ if (priv->socket_v6[i])
+ g_object_unref (priv->socket_v6[i]);
+ if (priv->mcast_socket_v4[i])
+ g_object_unref (priv->mcast_socket_v4[i]);
+ if (priv->mcast_socket_v6[i])
+ g_object_unref (priv->mcast_socket_v6[i]);
+ }
g_free (priv->multicast_iface);
@@ -4455,7 +4453,7 @@ gst_rtsp_stream_query_stop (GstRTSPStream * stream, gint64 * stop)
* Add a receiver and sender part to the pipeline based on the transport from
* SETUP.
*
- * Returns: %TRUE if the pipeline has been sucessfully updated.
+ * Returns: %TRUE if the stream has been sucessfully updated.
*/
gboolean
gst_rtsp_stream_complete_stream (GstRTSPStream * stream,
@@ -4480,6 +4478,7 @@ gst_rtsp_stream_complete_stream (GstRTSPStream * stream,
if (!create_sender_part (stream, transport))
goto create_sender_error;
+ priv->is_complete = TRUE;
g_mutex_unlock (&priv->lock);
GST_DEBUG_OBJECT (stream, "pipeline sucsessfully updated");
@@ -4493,3 +4492,29 @@ unallowed_transport:
return FALSE;
}
}
+
+/**
+ * gst_rtsp_stream_is_complete:
+ * @stream: a #GstRTSPStream
+ *
+ * Checks whether the stream is complete, contains the receiver and the sender
+ * parts. As the stream contains sink(s) element(s), it's possible to perform
+ * seek operations on it.
+ *
+ * Returns: %TRUE if the stream contains at least one sink element.
+ */
+gboolean
+gst_rtsp_stream_is_complete (GstRTSPStream * stream)
+{
+ GstRTSPStreamPrivate *priv;
+ gboolean ret = FALSE;
+
+ g_return_val_if_fail (GST_IS_RTSP_STREAM (stream), FALSE);
+
+ priv = stream->priv;
+ g_mutex_lock (&priv->lock);
+ ret = priv->is_complete;
+ g_mutex_unlock (&priv->lock);
+
+ return ret;
+}
diff --git a/gst/rtsp-server/rtsp-stream.h b/gst/rtsp-server/rtsp-stream.h
index add1a88..37a8275 100644
--- a/gst/rtsp-server/rtsp-stream.h
+++ b/gst/rtsp-server/rtsp-stream.h
@@ -287,6 +287,9 @@ GstRTSPPublishClockMode gst_rtsp_stream_get_publish_clock_mode (GstRTSPStream *
GST_EXPORT
gboolean gst_rtsp_stream_complete_stream (GstRTSPStream * stream, const GstRTSPTransport * transport);
+GST_EXPORT
+gboolean gst_rtsp_stream_is_complete (GstRTSPStream * stream);
+
/**
* GstRTSPStreamTransportFilterFunc:
* @stream: a #GstRTSPStream object