rtsp-media: seek on media pipelines that are complete

Make sure that a seek is performed on pipelines that
contain at least one sink element.

Change-Id: Icf398e10add3191d104b1289de612412da326819

https://bugzilla.gnome.org/show_bug.cgi?id=788340
This commit is contained in:
Patricia Muscalu 2017-10-23 09:49:09 +02:00 committed by Sebastian Dröge
parent a7732a68e8
commit efdb795c86
3 changed files with 73 additions and 17 deletions

View file

@ -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);

View file

@ -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;
}

View file

@ -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