mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-10-07 11:12:17 +00:00
matroskademux: improve segment handling with non-zero starting timestamp
... as well as related items, such as seeking and position reporting. https://bugzilla.gnome.org/show_bug.cgi?id=659808
This commit is contained in:
parent
73fac4e5bc
commit
be82dd8e3a
2 changed files with 39 additions and 18 deletions
|
@ -436,6 +436,7 @@ gst_matroska_demux_reset (GstElement * element)
|
||||||
gst_segment_init (&demux->common.segment, GST_FORMAT_TIME);
|
gst_segment_init (&demux->common.segment, GST_FORMAT_TIME);
|
||||||
demux->last_stop_end = GST_CLOCK_TIME_NONE;
|
demux->last_stop_end = GST_CLOCK_TIME_NONE;
|
||||||
demux->seek_block = 0;
|
demux->seek_block = 0;
|
||||||
|
demux->stream_start_time = GST_CLOCK_TIME_NONE;
|
||||||
|
|
||||||
demux->common.offset = 0;
|
demux->common.offset = 0;
|
||||||
demux->cluster_time = GST_CLOCK_TIME_NONE;
|
demux->cluster_time = GST_CLOCK_TIME_NONE;
|
||||||
|
@ -1370,10 +1371,11 @@ gst_matroska_demux_query (GstMatroskaDemux * demux, GstPad * pad,
|
||||||
if (format == GST_FORMAT_TIME) {
|
if (format == GST_FORMAT_TIME) {
|
||||||
GST_OBJECT_LOCK (demux);
|
GST_OBJECT_LOCK (demux);
|
||||||
if (context)
|
if (context)
|
||||||
gst_query_set_position (query, GST_FORMAT_TIME, context->pos);
|
gst_query_set_position (query, GST_FORMAT_TIME,
|
||||||
|
context->pos - demux->stream_start_time);
|
||||||
else
|
else
|
||||||
gst_query_set_position (query, GST_FORMAT_TIME,
|
gst_query_set_position (query, GST_FORMAT_TIME,
|
||||||
demux->common.segment.last_stop);
|
demux->common.segment.last_stop - demux->stream_start_time);
|
||||||
GST_OBJECT_UNLOCK (demux);
|
GST_OBJECT_UNLOCK (demux);
|
||||||
} else if (format == GST_FORMAT_DEFAULT && context
|
} else if (format == GST_FORMAT_DEFAULT && context
|
||||||
&& context->default_duration) {
|
&& context->default_duration) {
|
||||||
|
@ -1748,9 +1750,15 @@ gst_matroska_demux_search_pos (GstMatroskaDemux * demux, GstClockTime time)
|
||||||
|
|
||||||
retry:
|
retry:
|
||||||
GST_LOG_OBJECT (demux,
|
GST_LOG_OBJECT (demux,
|
||||||
"opos: %" G_GUINT64_FORMAT ", otime: %" GST_TIME_FORMAT, opos,
|
"opos: %" G_GUINT64_FORMAT ", otime: %" GST_TIME_FORMAT ", %"
|
||||||
GST_TIME_ARGS (otime));
|
GST_TIME_FORMAT " in stream time (start %" GST_TIME_FORMAT "), time %"
|
||||||
newpos = gst_util_uint64_scale (opos, time, otime) - chunk;
|
GST_TIME_FORMAT, opos, GST_TIME_ARGS (otime),
|
||||||
|
GST_TIME_ARGS (otime - demux->stream_start_time),
|
||||||
|
GST_TIME_ARGS (demux->stream_start_time), GST_TIME_ARGS (time));
|
||||||
|
newpos =
|
||||||
|
gst_util_uint64_scale (opos - demux->common.ebml_segment_start,
|
||||||
|
time - demux->stream_start_time,
|
||||||
|
otime - demux->stream_start_time) - chunk;
|
||||||
if (newpos < 0)
|
if (newpos < 0)
|
||||||
newpos = 0;
|
newpos = 0;
|
||||||
/* favour undershoot */
|
/* favour undershoot */
|
||||||
|
@ -1918,6 +1926,14 @@ gst_matroska_demux_handle_seek_event (GstMatroskaDemux * demux,
|
||||||
GST_DEBUG_OBJECT (demux, "configuring seek");
|
GST_DEBUG_OBJECT (demux, "configuring seek");
|
||||||
gst_segment_set_seek (&seeksegment, rate, format, flags,
|
gst_segment_set_seek (&seeksegment, rate, format, flags,
|
||||||
cur_type, cur, stop_type, stop, &update);
|
cur_type, cur, stop_type, stop, &update);
|
||||||
|
/* compensate for clip start time */
|
||||||
|
if (GST_CLOCK_TIME_IS_VALID (demux->stream_start_time)) {
|
||||||
|
seeksegment.last_stop += demux->stream_start_time;
|
||||||
|
seeksegment.start += demux->stream_start_time;
|
||||||
|
if (GST_CLOCK_TIME_IS_VALID (seeksegment.stop))
|
||||||
|
seeksegment.stop += demux->stream_start_time;
|
||||||
|
/* note that time should stay at indicated position */
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
GST_DEBUG_OBJECT (demux, "New segment %" GST_SEGMENT_FORMAT, &seeksegment);
|
GST_DEBUG_OBJECT (demux, "New segment %" GST_SEGMENT_FORMAT, &seeksegment);
|
||||||
|
@ -1988,7 +2004,7 @@ gst_matroska_demux_handle_seek_event (GstMatroskaDemux * demux,
|
||||||
GST_TIME_FORMAT, GST_TIME_ARGS (entry->time));
|
GST_TIME_FORMAT, GST_TIME_ARGS (entry->time));
|
||||||
seeksegment.start = entry->time;
|
seeksegment.start = entry->time;
|
||||||
seeksegment.last_stop = entry->time;
|
seeksegment.last_stop = entry->time;
|
||||||
seeksegment.time = entry->time;
|
seeksegment.time = entry->time - demux->stream_start_time;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (flush) {
|
if (flush) {
|
||||||
|
@ -3259,10 +3275,15 @@ gst_matroska_demux_parse_blockgroup_or_simpleblock (GstMatroskaDemux * demux,
|
||||||
GST_DEBUG_OBJECT (demux,
|
GST_DEBUG_OBJECT (demux,
|
||||||
"generating segment starting at %" GST_TIME_FORMAT,
|
"generating segment starting at %" GST_TIME_FORMAT,
|
||||||
GST_TIME_ARGS (lace_time));
|
GST_TIME_ARGS (lace_time));
|
||||||
/* pretend we seeked here */
|
if (!GST_CLOCK_TIME_IS_VALID (demux->stream_start_time)) {
|
||||||
gst_segment_set_seek (&demux->common.segment, demux->common.segment.rate,
|
demux->stream_start_time = lace_time;
|
||||||
GST_FORMAT_TIME, 0, GST_SEEK_TYPE_SET, lace_time,
|
GST_DEBUG_OBJECT (demux,
|
||||||
GST_SEEK_TYPE_SET, GST_CLOCK_TIME_NONE, NULL);
|
"Setting stream start time to %" GST_TIME_FORMAT,
|
||||||
|
GST_TIME_ARGS (lace_time));
|
||||||
|
}
|
||||||
|
gst_segment_set_newsegment (&demux->common.segment, FALSE,
|
||||||
|
demux->common.segment.rate, GST_FORMAT_TIME, lace_time,
|
||||||
|
GST_CLOCK_TIME_NONE, lace_time - demux->stream_start_time);
|
||||||
/* now convey our segment notion downstream */
|
/* now convey our segment notion downstream */
|
||||||
gst_matroska_demux_send_event (demux, gst_event_new_new_segment (FALSE,
|
gst_matroska_demux_send_event (demux, gst_event_new_new_segment (FALSE,
|
||||||
demux->common.segment.rate, demux->common.segment.format,
|
demux->common.segment.rate, demux->common.segment.format,
|
||||||
|
@ -3449,9 +3470,10 @@ gst_matroska_demux_parse_blockgroup_or_simpleblock (GstMatroskaDemux * demux,
|
||||||
|
|
||||||
GST_OBJECT_LOCK (demux);
|
GST_OBJECT_LOCK (demux);
|
||||||
if (demux->common.segment.duration == -1 ||
|
if (demux->common.segment.duration == -1 ||
|
||||||
demux->common.segment.duration < lace_time) {
|
demux->common.segment.duration <
|
||||||
|
lace_time - demux->stream_start_time) {
|
||||||
gst_segment_set_duration (&demux->common.segment, GST_FORMAT_TIME,
|
gst_segment_set_duration (&demux->common.segment, GST_FORMAT_TIME,
|
||||||
last_stop_end);
|
last_stop_end - demux->stream_start_time);
|
||||||
GST_OBJECT_UNLOCK (demux);
|
GST_OBJECT_UNLOCK (demux);
|
||||||
gst_element_post_message (GST_ELEMENT_CAST (demux),
|
gst_element_post_message (GST_ELEMENT_CAST (demux),
|
||||||
gst_message_new_duration (GST_OBJECT_CAST (demux),
|
gst_message_new_duration (GST_OBJECT_CAST (demux),
|
||||||
|
@ -4106,12 +4128,10 @@ gst_matroska_demux_parse_id (GstMatroskaDemux * demux, guint32 id,
|
||||||
demux->first_cluster_offset = demux->common.offset;
|
demux->first_cluster_offset = demux->common.offset;
|
||||||
GST_DEBUG_OBJECT (demux, "signaling no more pads");
|
GST_DEBUG_OBJECT (demux, "signaling no more pads");
|
||||||
gst_element_no_more_pads (GST_ELEMENT (demux));
|
gst_element_no_more_pads (GST_ELEMENT (demux));
|
||||||
/* send initial newsegment */
|
/* send initial newsegment - we wait till we know the first
|
||||||
gst_matroska_demux_send_event (demux,
|
incoming timestamp, so we can properly set the start of
|
||||||
gst_event_new_new_segment (FALSE, 1.0,
|
the segment. */
|
||||||
GST_FORMAT_TIME, 0,
|
demux->need_newsegment = TRUE;
|
||||||
(demux->common.segment.duration >
|
|
||||||
0) ? demux->common.segment.duration : -1, 0));
|
|
||||||
}
|
}
|
||||||
demux->cluster_time = GST_CLOCK_TIME_NONE;
|
demux->cluster_time = GST_CLOCK_TIME_NONE;
|
||||||
demux->cluster_offset = demux->common.offset;
|
demux->cluster_offset = demux->common.offset;
|
||||||
|
|
|
@ -71,6 +71,7 @@ typedef struct _GstMatroskaDemux {
|
||||||
/* keeping track of playback position */
|
/* keeping track of playback position */
|
||||||
gboolean segment_running;
|
gboolean segment_running;
|
||||||
GstClockTime last_stop_end;
|
GstClockTime last_stop_end;
|
||||||
|
GstClockTime stream_start_time;
|
||||||
|
|
||||||
GstEvent *close_segment;
|
GstEvent *close_segment;
|
||||||
GstEvent *new_segment;
|
GstEvent *new_segment;
|
||||||
|
|
Loading…
Reference in a new issue