mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-02-22 05:56:31 +00:00
rtsp-stream: collect rtp info when blocking
We don't unblock the stream anymore before replying to the
play request (883ddc72bb
),
so the sinks don't have a last-sample after potentially flush
seeking. seek_trickmode waits for preroll however, which means
the stream will block and wait for a first buffer. Subsequent
calls to get_rtpinfo() can thus make use of the information.
See https://gitlab.freedesktop.org/gstreamer/gst-rtsp-server/-/issues/115
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-rtsp-server/-/merge_requests/160>
This commit is contained in:
parent
6a1e121a54
commit
a446ba4fb0
1 changed files with 56 additions and 3 deletions
|
@ -214,7 +214,12 @@ struct _GstRTSPStreamPrivate
|
||||||
|
|
||||||
GstRTSPPublishClockMode publish_clock_mode;
|
GstRTSPPublishClockMode publish_clock_mode;
|
||||||
GThreadPool *send_pool;
|
GThreadPool *send_pool;
|
||||||
guint32 last_seqnum;
|
|
||||||
|
/* Used to provide accurate rtpinfo when the stream is blocking */
|
||||||
|
gboolean blocked_buffer;
|
||||||
|
guint32 blocked_seqnum;
|
||||||
|
guint32 blocked_rtptime;
|
||||||
|
GstClockTime blocked_running_time;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define DEFAULT_CONTROL NULL
|
#define DEFAULT_CONTROL NULL
|
||||||
|
@ -4285,6 +4290,25 @@ gst_rtsp_stream_get_rtpinfo (GstRTSPStream * stream,
|
||||||
} else {
|
} else {
|
||||||
gst_sample_unref (last_sample);
|
gst_sample_unref (last_sample);
|
||||||
}
|
}
|
||||||
|
} else if (priv->blocking) {
|
||||||
|
if (seq) {
|
||||||
|
if (!priv->blocked_buffer)
|
||||||
|
goto stats;
|
||||||
|
*seq = priv->blocked_seqnum;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rtptime) {
|
||||||
|
if (!priv->blocked_buffer)
|
||||||
|
goto stats;
|
||||||
|
*rtptime = priv->blocked_rtptime;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (running_time) {
|
||||||
|
if (!GST_CLOCK_TIME_IS_VALID (priv->blocked_running_time))
|
||||||
|
goto stats;
|
||||||
|
*running_time = priv->blocked_running_time;
|
||||||
|
}
|
||||||
|
goto done;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5194,6 +5218,7 @@ pad_blocking (GstPad * pad, GstPadProbeInfo * info, gpointer user_data)
|
||||||
GstRTSPStream *stream;
|
GstRTSPStream *stream;
|
||||||
GstBuffer *buffer = NULL;
|
GstBuffer *buffer = NULL;
|
||||||
GstPadProbeReturn ret = GST_PAD_PROBE_OK;
|
GstPadProbeReturn ret = GST_PAD_PROBE_OK;
|
||||||
|
GstEvent *event;
|
||||||
|
|
||||||
stream = user_data;
|
stream = user_data;
|
||||||
priv = stream->priv;
|
priv = stream->priv;
|
||||||
|
@ -5201,11 +5226,27 @@ pad_blocking (GstPad * pad, GstPadProbeInfo * info, gpointer user_data)
|
||||||
g_mutex_lock (&priv->lock);
|
g_mutex_lock (&priv->lock);
|
||||||
|
|
||||||
if ((info->type & GST_PAD_PROBE_TYPE_BUFFER)) {
|
if ((info->type & GST_PAD_PROBE_TYPE_BUFFER)) {
|
||||||
|
GstRTPBuffer rtp = GST_RTP_BUFFER_INIT;
|
||||||
|
|
||||||
buffer = gst_pad_probe_info_get_buffer (info);
|
buffer = gst_pad_probe_info_get_buffer (info);
|
||||||
|
if (gst_rtp_buffer_map (buffer, GST_MAP_READ, &rtp)) {
|
||||||
|
priv->blocked_buffer = TRUE;
|
||||||
|
priv->blocked_seqnum = gst_rtp_buffer_get_seq (&rtp);
|
||||||
|
priv->blocked_rtptime = gst_rtp_buffer_get_timestamp (&rtp);
|
||||||
|
gst_rtp_buffer_unmap (&rtp);
|
||||||
|
}
|
||||||
priv->position = GST_BUFFER_TIMESTAMP (buffer);
|
priv->position = GST_BUFFER_TIMESTAMP (buffer);
|
||||||
} else if ((info->type & GST_PAD_PROBE_TYPE_BUFFER_LIST)) {
|
} else if ((info->type & GST_PAD_PROBE_TYPE_BUFFER_LIST)) {
|
||||||
|
GstRTPBuffer rtp = GST_RTP_BUFFER_INIT;
|
||||||
|
|
||||||
GstBufferList *list = gst_pad_probe_info_get_buffer_list (info);
|
GstBufferList *list = gst_pad_probe_info_get_buffer_list (info);
|
||||||
buffer = gst_buffer_list_get (list, 0);
|
buffer = gst_buffer_list_get (list, 0);
|
||||||
|
if (gst_rtp_buffer_map (buffer, GST_MAP_READ, &rtp)) {
|
||||||
|
priv->blocked_buffer = TRUE;
|
||||||
|
priv->blocked_seqnum = gst_rtp_buffer_get_seq (&rtp);
|
||||||
|
priv->blocked_rtptime = gst_rtp_buffer_get_timestamp (&rtp);
|
||||||
|
gst_rtp_buffer_unmap (&rtp);
|
||||||
|
}
|
||||||
priv->position = GST_BUFFER_TIMESTAMP (buffer);
|
priv->position = GST_BUFFER_TIMESTAMP (buffer);
|
||||||
} else if ((info->type & GST_PAD_PROBE_TYPE_EVENT_DOWNSTREAM)) {
|
} else if ((info->type & GST_PAD_PROBE_TYPE_EVENT_DOWNSTREAM)) {
|
||||||
if (GST_EVENT_TYPE (info->data) == GST_EVENT_GAP) {
|
if (GST_EVENT_TYPE (info->data) == GST_EVENT_GAP) {
|
||||||
|
@ -5219,6 +5260,16 @@ pad_blocking (GstPad * pad, GstPadProbeInfo * info, gpointer user_data)
|
||||||
g_assert_not_reached ();
|
g_assert_not_reached ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
event = gst_pad_get_sticky_event (pad, GST_EVENT_SEGMENT, 0);
|
||||||
|
if (event) {
|
||||||
|
const GstSegment *segment;
|
||||||
|
|
||||||
|
gst_event_parse_segment (event, &segment);
|
||||||
|
priv->blocked_running_time =
|
||||||
|
gst_segment_to_stream_time (segment, GST_FORMAT_TIME, priv->position);
|
||||||
|
gst_event_unref (event);
|
||||||
|
}
|
||||||
|
|
||||||
priv->blocking = TRUE;
|
priv->blocking = TRUE;
|
||||||
|
|
||||||
GST_DEBUG_OBJECT (pad, "Now blocking");
|
GST_DEBUG_OBJECT (pad, "Now blocking");
|
||||||
|
@ -5257,6 +5308,8 @@ set_blocked (GstRTSPStream * stream, gboolean blocked)
|
||||||
continue;
|
continue;
|
||||||
if (priv->send_src[i]) {
|
if (priv->send_src[i]) {
|
||||||
priv->blocking = FALSE;
|
priv->blocking = FALSE;
|
||||||
|
priv->blocked_buffer = FALSE;
|
||||||
|
priv->blocked_running_time = GST_CLOCK_TIME_NONE;
|
||||||
priv->blocked_id[i] = gst_pad_add_probe (priv->send_src[i],
|
priv->blocked_id[i] = gst_pad_add_probe (priv->send_src[i],
|
||||||
GST_PAD_PROBE_TYPE_BLOCK | GST_PAD_PROBE_TYPE_BUFFER |
|
GST_PAD_PROBE_TYPE_BLOCK | GST_PAD_PROBE_TYPE_BUFFER |
|
||||||
GST_PAD_PROBE_TYPE_BUFFER_LIST |
|
GST_PAD_PROBE_TYPE_BUFFER_LIST |
|
||||||
|
@ -6146,8 +6199,8 @@ gst_rtsp_stream_set_rate_control (GstRTSPStream * stream, gboolean enabled)
|
||||||
if (stream->priv->appsink[0])
|
if (stream->priv->appsink[0])
|
||||||
g_object_set (stream->priv->appsink[0], "sync", enabled, NULL);
|
g_object_set (stream->priv->appsink[0], "sync", enabled, NULL);
|
||||||
if (stream->priv->payloader
|
if (stream->priv->payloader
|
||||||
&& g_object_class_find_property (G_OBJECT_GET_CLASS (stream->priv->
|
&& g_object_class_find_property (G_OBJECT_GET_CLASS (stream->
|
||||||
payloader), "onvif-no-rate-control"))
|
priv->payloader), "onvif-no-rate-control"))
|
||||||
g_object_set (stream->priv->payloader, "onvif-no-rate-control", !enabled,
|
g_object_set (stream->priv->payloader, "onvif-no-rate-control", !enabled,
|
||||||
NULL);
|
NULL);
|
||||||
if (stream->priv->session) {
|
if (stream->priv->session) {
|
||||||
|
|
Loading…
Reference in a new issue