summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSebastian Dröge <sebastian@centricular.com>2014-08-05 16:12:19 +0200
committerSebastian Dröge <sebastian@centricular.com>2014-08-13 14:56:33 +0300
commit55010e51d7169fe30279fbae484d7773ec2017a7 (patch)
tree8efd5e0ebf48950b9b74d30fc8298e35b5b8434d
parent934b6d65c502e2de5fb7201386105e5407a479a3 (diff)
rtsp-media: Query position and stop time only on the RTP parts of the pipeline
The RTCP parts, in specific the RTCP udpsinks, are not flushed when seeking and will always continue counting the time. This leads to the NPT after a backwards seek to be something completely different to the actual seek position. https://bugzilla.gnome.org/show_bug.cgi?id=732644
-rw-r--r--gst/rtsp-server/rtsp-media.c74
-rw-r--r--gst/rtsp-server/rtsp-stream.c78
-rw-r--r--gst/rtsp-server/rtsp-stream.h6
3 files changed, 144 insertions, 14 deletions
diff --git a/gst/rtsp-server/rtsp-media.c b/gst/rtsp-server/rtsp-media.c
index 8f2078c..48868f5 100644
--- a/gst/rtsp-server/rtsp-media.c
+++ b/gst/rtsp-server/rtsp-media.c
@@ -452,28 +452,74 @@ gst_rtsp_media_set_property (GObject * object, guint propid,
}
}
+typedef struct
+{
+ gint64 position;
+ gboolean ret;
+} DoQueryPositionData;
+
+static void
+do_query_position (GstRTSPStream * stream, DoQueryPositionData * data)
+{
+ gint64 tmp;
+
+ if (gst_rtsp_stream_query_position (stream, &tmp)) {
+ data->position = MAX (data->position, tmp);
+ data->ret = TRUE;
+ }
+}
+
static gboolean
default_query_position (GstRTSPMedia * media, gint64 * position)
{
- return gst_element_query_position (media->priv->pipeline, GST_FORMAT_TIME,
- position);
+ GstRTSPMediaPrivate *priv;
+ DoQueryPositionData data;
+
+ priv = media->priv;
+
+ data.position = -1;
+ data.ret = FALSE;
+
+ g_ptr_array_foreach (priv->streams, (GFunc) do_query_position, &data);
+
+ *position = data.position;
+
+ return data.ret;
+}
+
+typedef struct
+{
+ gint64 stop;
+ gboolean ret;
+} DoQueryStopData;
+
+static void
+do_query_stop (GstRTSPStream * stream, DoQueryStopData * data)
+{
+ gint64 tmp;
+
+ if (gst_rtsp_stream_query_stop (stream, &tmp)) {
+ data->stop = MAX (data->stop, tmp);
+ data->ret = TRUE;
+ }
}
static gboolean
default_query_stop (GstRTSPMedia * media, gint64 * stop)
{
- GstQuery *query;
- gboolean res;
+ GstRTSPMediaPrivate *priv;
+ DoQueryStopData data;
- query = gst_query_new_segment (GST_FORMAT_TIME);
- if ((res = gst_element_query (media->priv->pipeline, query))) {
- GstFormat format;
- gst_query_parse_segment (query, NULL, &format, NULL, stop);
- if (format != GST_FORMAT_TIME)
- *stop = -1;
- }
- gst_query_unref (query);
- return res;
+ priv = media->priv;
+
+ data.stop = -1;
+ data.ret = FALSE;
+
+ g_ptr_array_foreach (priv->streams, (GFunc) do_query_stop, &data);
+
+ *stop = data.stop;
+
+ return data.ret;
}
static GstElement *
@@ -491,7 +537,7 @@ static void
collect_media_stats (GstRTSPMedia * media)
{
GstRTSPMediaPrivate *priv = media->priv;
- gint64 position, stop;
+ gint64 position = 0, stop = -1;
if (priv->status != GST_RTSP_MEDIA_STATUS_PREPARED &&
priv->status != GST_RTSP_MEDIA_STATUS_PREPARING)
diff --git a/gst/rtsp-server/rtsp-stream.c b/gst/rtsp-server/rtsp-stream.c
index 942b837..6a79508 100644
--- a/gst/rtsp-server/rtsp-stream.c
+++ b/gst/rtsp-server/rtsp-stream.c
@@ -2642,3 +2642,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;
+
+}
diff --git a/gst/rtsp-server/rtsp-stream.h b/gst/rtsp-server/rtsp-stream.h
index ca8be0a..1dbfdf3 100644
--- a/gst/rtsp-server/rtsp-stream.h
+++ b/gst/rtsp-server/rtsp-stream.h
@@ -147,6 +147,12 @@ GSocket * gst_rtsp_stream_get_rtcp_socket (GstRTSPStream *stream,
gboolean gst_rtsp_stream_update_crypto (GstRTSPStream * stream,
guint ssrc, GstCaps * crypto);
+
+gboolean gst_rtsp_stream_query_position (GstRTSPStream * stream,
+ gint64 * position);
+gboolean gst_rtsp_stream_query_stop (GstRTSPStream * stream,
+ gint64 * stop);
+
/**
* GstRTSPStreamTransportFilterFunc:
* @stream: a #GstRTSPStream object