mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-27 12:11:13 +00:00
rtspsrc: clip output segment on accurate seeks
The output segment is only used in ONVIF mode. The previous behaviour was to output a segment computed from the Range response sent by the server. In ONVIF mode, servers will start serving from the appropriate synchronization point (keyframe), and the Range in response will start at that position. This means rtspsrc can now perform truly accurate seeks in that mode, by clipping the output segment to the values requested in the seek. The decoder will then discard out of segment buffers and playback will start without artefacts at the exact requested position, similar to the behaviour of a demuxer when an accurate seek is requested.
This commit is contained in:
parent
0017115494
commit
37eca8a12c
2 changed files with 21 additions and 0 deletions
|
@ -2452,6 +2452,7 @@ gst_rtspsrc_cleanup (GstRTSPSrc * src)
|
|||
}
|
||||
|
||||
src->need_segment = FALSE;
|
||||
src->clip_out_segment = FALSE;
|
||||
|
||||
if (src->provided_clock) {
|
||||
gst_object_unref (src->provided_clock);
|
||||
|
@ -2900,6 +2901,10 @@ gst_rtspsrc_perform_seek (GstRTSPSrc * src, GstEvent * event)
|
|||
seek_style = "Next";
|
||||
}
|
||||
|
||||
/* If an accurate seek was requested, we want to clip the segment we
|
||||
* output in ONVIF mode to the requested bounds */
|
||||
src->clip_out_segment = flags & GST_SEEK_FLAG_ACCURATE;
|
||||
|
||||
if (playing)
|
||||
gst_rtspsrc_play (src, &seeksegment, FALSE, seek_style);
|
||||
|
||||
|
@ -8433,6 +8438,7 @@ gst_rtspsrc_play (GstRTSPSrc * src, GstSegment * segment, gboolean async,
|
|||
gchar *hval;
|
||||
gint hval_idx;
|
||||
const gchar *control;
|
||||
GstSegment requested;
|
||||
|
||||
GST_DEBUG_OBJECT (src, "PLAY...");
|
||||
|
||||
|
@ -8449,6 +8455,8 @@ restart:
|
|||
if (!src->conninfo.connection || !src->conninfo.connected)
|
||||
goto done;
|
||||
|
||||
requested = *segment;
|
||||
|
||||
/* send some dummy packets before we activate the receive in the
|
||||
* udp sources */
|
||||
gst_rtspsrc_send_dummy_packets (src);
|
||||
|
@ -8644,6 +8652,18 @@ restart:
|
|||
|
||||
memcpy (&src->out_segment, segment, sizeof (GstSegment));
|
||||
|
||||
if (src->clip_out_segment) {
|
||||
/* Only clip the output segment when the server has answered with valid
|
||||
* values, we cannot know otherwise whether the requested bounds were
|
||||
* available */
|
||||
if (GST_CLOCK_TIME_IS_VALID (src->segment.start) &&
|
||||
GST_CLOCK_TIME_IS_VALID (requested.start))
|
||||
src->out_segment.start = MAX (src->out_segment.start, requested.start);
|
||||
if (GST_CLOCK_TIME_IS_VALID (src->segment.stop) &&
|
||||
GST_CLOCK_TIME_IS_VALID (requested.stop))
|
||||
src->out_segment.stop = MIN (src->out_segment.stop, requested.stop);
|
||||
}
|
||||
|
||||
/* configure the caps of the streams after we parsed all headers. Only reset
|
||||
* the manager object when we set a new Range header (we did a seek) */
|
||||
gst_rtspsrc_configure_caps (src, segment, src->need_range);
|
||||
|
|
|
@ -211,6 +211,7 @@ struct _GstRTSPSrc {
|
|||
GstClockTime trickmode_interval;
|
||||
gint free_channel;
|
||||
gboolean need_segment;
|
||||
gboolean clip_out_segment;
|
||||
GstSegment out_segment;
|
||||
GstClockTime base_time;
|
||||
|
||||
|
|
Loading…
Reference in a new issue