mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-03-28 11:55:39 +00:00
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
This commit is contained in:
parent
04e69cf83b
commit
6ba5ca447f
3 changed files with 144 additions and 14 deletions
|
@ -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)
|
||||
|
|
|
@ -2730,3 +2730,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;
|
||||
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue