mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-18 22:36:33 +00:00
oggdemux: add non flushing time seeking in push mode
Some resetting code has to be done in the NEW_SEGMENT event handler, instead of the missing FLUSH_STOP one. Segment base was also wrongly accounted for. This was hidden by the fact that flushing resets the base. A discontinuity is now also signalled on seeking. We have to also ensure that the discontinuity "sticks" till a buffer with a valid timestamp goes out, or the audio decoder base class will ignore the discontinuity for purposes of keeping track of the current time. This allows using non flushing segment seeks for looping HTML audio in particular, and more generally non flushing seeks. https://bugzilla.gnome.org/show_bug.cgi?id=729198
This commit is contained in:
parent
ca136e3648
commit
969cf47a82
1 changed files with 42 additions and 12 deletions
|
@ -703,6 +703,8 @@ gst_ogg_demux_chain_peer (GstOggPad * pad, ogg_packet * packet,
|
|||
/* Mark discont on the buffer */
|
||||
if (pad->discont) {
|
||||
GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_DISCONT);
|
||||
if GST_BUFFER_TIMESTAMP_IS_VALID
|
||||
(buf)
|
||||
pad->discont = FALSE;
|
||||
}
|
||||
|
||||
|
@ -1012,7 +1014,8 @@ gst_ogg_pad_submit_packet (GstOggPad * pad, ogg_packet * packet)
|
|||
(gint64) packet->granulepos, granule, pad->map.accumulated_granule);
|
||||
} else {
|
||||
packet->granulepos = gst_ogg_stream_granule_to_granulepos (&pad->map,
|
||||
pad->map.accumulated_granule, pad->keyframe_granule);
|
||||
pad->map.accumulated_granule + pad->current_granule,
|
||||
pad->keyframe_granule);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
@ -1072,8 +1075,10 @@ gst_ogg_pad_submit_packet (GstOggPad * pad, ogg_packet * packet)
|
|||
GST_TIME_ARGS (start_time));
|
||||
segment.rate = ogg->push_seek_rate;
|
||||
segment.start = ogg->push_seek_time_original_target;
|
||||
segment.position = ogg->push_seek_time_original_target;
|
||||
segment.stop = ogg->push_seek_time_original_stop;
|
||||
segment.time = ogg->push_seek_time_original_target;
|
||||
segment.base = ogg->segment.base;
|
||||
event = gst_event_new_segment (&segment);
|
||||
gst_event_set_seqnum (event, ogg->push_seek_seqnum);
|
||||
ogg->push_state = PUSH_PLAYING;
|
||||
|
@ -1081,8 +1086,10 @@ gst_ogg_pad_submit_packet (GstOggPad * pad, ogg_packet * packet)
|
|||
segment.rate = ogg->segment.rate;
|
||||
segment.applied_rate = ogg->segment.applied_rate;
|
||||
segment.start = start_time;
|
||||
segment.position = start_time;
|
||||
segment.stop = chain->segment_stop;
|
||||
segment.time = segment_time;
|
||||
segment.base = ogg->segment.base;
|
||||
event = gst_event_new_segment (&segment);
|
||||
}
|
||||
GST_PUSH_UNLOCK (ogg);
|
||||
|
@ -1107,8 +1114,10 @@ gst_ogg_pad_submit_packet (GstOggPad * pad, ogg_packet * packet)
|
|||
segment.rate = ogg->segment.rate;
|
||||
segment.applied_rate = ogg->segment.applied_rate;
|
||||
segment.start = chain->segment_start;
|
||||
segment.position = chain->segment_start;
|
||||
segment.stop = chain->segment_stop;
|
||||
segment.time = chain->begin_time;
|
||||
segment.base = ogg->segment.base;
|
||||
event = gst_event_new_segment (&segment);
|
||||
}
|
||||
}
|
||||
|
@ -2194,11 +2203,13 @@ gst_ogg_demux_reset_streams (GstOggDemux * ogg)
|
|||
|
||||
stream->start_time = -1;
|
||||
stream->map.accumulated_granule = 0;
|
||||
stream->current_granule = -1;
|
||||
}
|
||||
ogg->building_chain = chain;
|
||||
GST_DEBUG_OBJECT (ogg, "Resetting current chain");
|
||||
ogg->current_chain = NULL;
|
||||
ogg->resync = TRUE;
|
||||
gst_ogg_chain_mark_discont (chain);
|
||||
|
||||
ogg->chunk_size = CHUNKSIZE;
|
||||
}
|
||||
|
@ -2249,6 +2260,28 @@ gst_ogg_demux_sink_event (GstPad * pad, GstObject * parent, GstEvent * event)
|
|||
ogg->push_seek_time_original_stop, &update);
|
||||
}
|
||||
|
||||
if (!ogg->pullmode && !(ogg->push_seek_flags & GST_SEEK_FLAG_FLUSH)) {
|
||||
int i;
|
||||
GstOggChain *chain = ogg->current_chain;
|
||||
|
||||
ogg->push_seek_flags = 0;
|
||||
if (!chain) {
|
||||
/* This will happen when we bisect, as we clear the chain when
|
||||
we do the first seek. On subsequent ones, we just reset the
|
||||
ogg sync object as we already reset the chain */
|
||||
GST_DEBUG_OBJECT (ogg, "No chain, just resetting ogg sync");
|
||||
ogg_sync_reset (&ogg->sync);
|
||||
} else {
|
||||
/* reset pad push mode seeking state */
|
||||
for (i = 0; i < chain->streams->len; i++) {
|
||||
GstOggPad *pad = g_array_index (chain->streams, GstOggPad *, i);
|
||||
pad->push_kf_time = GST_CLOCK_TIME_NONE;
|
||||
pad->push_sync_time = GST_CLOCK_TIME_NONE;
|
||||
}
|
||||
ogg_sync_reset (&ogg->sync);
|
||||
gst_ogg_demux_reset_streams (ogg);
|
||||
}
|
||||
}
|
||||
GST_PUSH_UNLOCK (ogg);
|
||||
} else {
|
||||
GST_WARNING_OBJECT (ogg, "unexpected segment format: %s",
|
||||
|
@ -3584,11 +3617,6 @@ gst_ogg_demux_perform_seek_push (GstOggDemux * ogg, GstEvent * event)
|
|||
if (stop_type == GST_SEEK_TYPE_NONE)
|
||||
stop = -1;
|
||||
|
||||
if (!(flags & GST_SEEK_FLAG_FLUSH)) {
|
||||
GST_DEBUG_OBJECT (ogg, "can only do flushing seeks");
|
||||
goto error;
|
||||
}
|
||||
|
||||
GST_DEBUG_OBJECT (ogg, "Push mode seek request: %" GST_TIME_FORMAT,
|
||||
GST_TIME_ARGS (start));
|
||||
|
||||
|
@ -3680,12 +3708,14 @@ gst_ogg_demux_perform_seek_push (GstOggDemux * ogg, GstEvent * event)
|
|||
ogg->seek_secant = FALSE;
|
||||
ogg->seek_undershot = FALSE;
|
||||
|
||||
if (flags & GST_SEEK_FLAG_FLUSH) {
|
||||
/* reset pad push mode seeking state */
|
||||
for (i = 0; i < chain->streams->len; i++) {
|
||||
GstOggPad *pad = g_array_index (chain->streams, GstOggPad *, i);
|
||||
pad->push_kf_time = GST_CLOCK_TIME_NONE;
|
||||
pad->push_sync_time = GST_CLOCK_TIME_NONE;
|
||||
}
|
||||
}
|
||||
|
||||
GST_DEBUG_OBJECT (ogg,
|
||||
"Setting up bisection search for %" G_GINT64_FORMAT " - %" G_GINT64_FORMAT
|
||||
|
|
Loading…
Reference in a new issue