mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-02-20 04:56:24 +00:00
matroskademux: push mode: increase segment accuracy following seek
Conflicts: gst/matroska/matroska-demux.c
This commit is contained in:
parent
ea0729ff32
commit
1a46572aaa
2 changed files with 37 additions and 19 deletions
|
@ -445,6 +445,8 @@ gst_matroska_demux_reset (GstElement * element)
|
||||||
demux->index_offset = 0;
|
demux->index_offset = 0;
|
||||||
demux->seekable = FALSE;
|
demux->seekable = FALSE;
|
||||||
demux->need_segment = FALSE;
|
demux->need_segment = FALSE;
|
||||||
|
demux->requested_seek_time = GST_CLOCK_TIME_NONE;
|
||||||
|
demux->seek_offset = -1;
|
||||||
demux->building_index = FALSE;
|
demux->building_index = FALSE;
|
||||||
if (demux->seek_event) {
|
if (demux->seek_event) {
|
||||||
gst_event_unref (demux->seek_event);
|
gst_event_unref (demux->seek_event);
|
||||||
|
@ -2077,9 +2079,10 @@ finish:
|
||||||
|
|
||||||
if (demux->streaming) {
|
if (demux->streaming) {
|
||||||
GST_OBJECT_LOCK (demux);
|
GST_OBJECT_LOCK (demux);
|
||||||
/* now update the real segment info */
|
/* track real position we should start at */
|
||||||
GST_DEBUG_OBJECT (demux, "Committing new seek segment");
|
GST_DEBUG_OBJECT (demux, "storing segment start");
|
||||||
memcpy (&demux->common.segment, &seeksegment, sizeof (GstSegment));
|
demux->requested_seek_time = seeksegment.position;
|
||||||
|
demux->seek_offset = entry->pos + demux->common.ebml_segment_start;
|
||||||
GST_OBJECT_UNLOCK (demux);
|
GST_OBJECT_UNLOCK (demux);
|
||||||
/* need to seek to cluster start to pick up cluster time */
|
/* need to seek to cluster start to pick up cluster time */
|
||||||
/* upstream takes care of flushing and all that
|
/* upstream takes care of flushing and all that
|
||||||
|
@ -3440,7 +3443,7 @@ gst_matroska_demux_parse_blockgroup_or_simpleblock (GstMatroskaDemux * demux,
|
||||||
/* need to refresh segment info ASAP */
|
/* need to refresh segment info ASAP */
|
||||||
if (GST_CLOCK_TIME_IS_VALID (lace_time) && demux->need_segment) {
|
if (GST_CLOCK_TIME_IS_VALID (lace_time) && demux->need_segment) {
|
||||||
GstSegment *segment = &demux->common.segment;
|
GstSegment *segment = &demux->common.segment;
|
||||||
guint64 segment_duration = 0;
|
guint64 clace_time;
|
||||||
|
|
||||||
if (!GST_CLOCK_TIME_IS_VALID (demux->stream_start_time)) {
|
if (!GST_CLOCK_TIME_IS_VALID (demux->stream_start_time)) {
|
||||||
demux->stream_start_time = lace_time;
|
demux->stream_start_time = lace_time;
|
||||||
|
@ -3448,23 +3451,22 @@ gst_matroska_demux_parse_blockgroup_or_simpleblock (GstMatroskaDemux * demux,
|
||||||
"Setting stream start time to %" GST_TIME_FORMAT,
|
"Setting stream start time to %" GST_TIME_FORMAT,
|
||||||
GST_TIME_ARGS (lace_time));
|
GST_TIME_ARGS (lace_time));
|
||||||
}
|
}
|
||||||
if (demux->common.segment.start == 0) {
|
clace_time = MAX (lace_time, demux->stream_start_time);
|
||||||
/* set segment fields only if they weren't already set by seek handling
|
if (GST_CLOCK_TIME_IS_VALID (demux->common.segment.position) &&
|
||||||
* code
|
demux->common.segment.position != 0) {
|
||||||
*/
|
|
||||||
if (GST_CLOCK_TIME_IS_VALID (segment->stop))
|
|
||||||
segment_duration = segment->stop - segment->start;
|
|
||||||
else if (GST_CLOCK_TIME_IS_VALID (segment->position))
|
|
||||||
segment_duration = segment->position - segment->start;
|
|
||||||
segment->base += segment_duration / fabs (segment->rate);
|
|
||||||
segment->start = MAX (lace_time, demux->stream_start_time);
|
|
||||||
segment->stop = GST_CLOCK_TIME_NONE;
|
|
||||||
segment->time = segment->start - demux->stream_start_time;
|
|
||||||
segment->position = segment->start - demux->stream_start_time;
|
|
||||||
GST_DEBUG_OBJECT (demux,
|
GST_DEBUG_OBJECT (demux,
|
||||||
"generated segment starting at %" GST_TIME_FORMAT ": %"
|
"using stored seek position %" GST_TIME_FORMAT,
|
||||||
GST_SEGMENT_FORMAT, GST_TIME_ARGS (lace_time), segment);
|
GST_TIME_ARGS (demux->common.segment.position));
|
||||||
|
clace_time = demux->common.segment.position + demux->stream_start_time;
|
||||||
|
segment->position = GST_CLOCK_TIME_NONE;
|
||||||
}
|
}
|
||||||
|
segment->start = clace_time;
|
||||||
|
segment->stop = GST_CLOCK_TIME_NONE;
|
||||||
|
segment->time = segment->start - demux->stream_start_time;
|
||||||
|
segment->position = segment->start - demux->stream_start_time;
|
||||||
|
GST_DEBUG_OBJECT (demux,
|
||||||
|
"generated segment starting at %" GST_TIME_FORMAT ": %"
|
||||||
|
GST_SEGMENT_FORMAT, GST_TIME_ARGS (lace_time), segment);
|
||||||
/* now convey our segment notion downstream */
|
/* now convey our segment notion downstream */
|
||||||
gst_matroska_demux_send_event (demux, gst_event_new_segment (segment));
|
gst_matroska_demux_send_event (demux, gst_event_new_segment (segment));
|
||||||
demux->need_segment = FALSE;
|
demux->need_segment = FALSE;
|
||||||
|
@ -4755,6 +4757,11 @@ gst_matroska_demux_handle_sink_event (GstPad * pad, GstObject * parent,
|
||||||
gst_adapter_clear (demux->common.adapter);
|
gst_adapter_clear (demux->common.adapter);
|
||||||
/* and some streaming setup */
|
/* and some streaming setup */
|
||||||
demux->common.offset = segment->start;
|
demux->common.offset = segment->start;
|
||||||
|
/* accumulate base based on current position */
|
||||||
|
if (GST_CLOCK_TIME_IS_VALID (demux->common.segment.position))
|
||||||
|
demux->common.segment.base +=
|
||||||
|
(MAX (demux->common.segment.position, demux->stream_start_time)
|
||||||
|
- demux->stream_start_time) / fabs (demux->common.segment.rate);
|
||||||
/* do not know where we are;
|
/* do not know where we are;
|
||||||
* need to come across a cluster and generate segment */
|
* need to come across a cluster and generate segment */
|
||||||
demux->common.segment.position = GST_CLOCK_TIME_NONE;
|
demux->common.segment.position = GST_CLOCK_TIME_NONE;
|
||||||
|
@ -4763,6 +4770,15 @@ gst_matroska_demux_handle_sink_event (GstPad * pad, GstObject * parent,
|
||||||
demux->need_segment = TRUE;
|
demux->need_segment = TRUE;
|
||||||
/* but keep some of the upstream segment */
|
/* but keep some of the upstream segment */
|
||||||
demux->common.segment.rate = segment->rate;
|
demux->common.segment.rate = segment->rate;
|
||||||
|
/* also check if need to keep some of the requested seek position */
|
||||||
|
if (demux->seek_offset == segment->start) {
|
||||||
|
GST_DEBUG_OBJECT (demux, "position matches requested seek");
|
||||||
|
demux->common.segment.position = demux->requested_seek_time;
|
||||||
|
} else {
|
||||||
|
GST_DEBUG_OBJECT (demux, "unexpected segment position");
|
||||||
|
}
|
||||||
|
demux->requested_seek_time = GST_CLOCK_TIME_NONE;
|
||||||
|
demux->seek_offset = -1;
|
||||||
GST_OBJECT_UNLOCK (demux);
|
GST_OBJECT_UNLOCK (demux);
|
||||||
exit:
|
exit:
|
||||||
/* chain will send initial segment after pads have been added,
|
/* chain will send initial segment after pads have been added,
|
||||||
|
|
|
@ -81,6 +81,8 @@ typedef struct _GstMatroskaDemux {
|
||||||
guint64 cluster_offset;
|
guint64 cluster_offset;
|
||||||
guint64 first_cluster_offset;
|
guint64 first_cluster_offset;
|
||||||
guint64 next_cluster_offset;
|
guint64 next_cluster_offset;
|
||||||
|
GstClockTime requested_seek_time;
|
||||||
|
guint64 seek_offset;
|
||||||
|
|
||||||
/* index stuff */
|
/* index stuff */
|
||||||
gboolean seekable;
|
gboolean seekable;
|
||||||
|
|
Loading…
Reference in a new issue