mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-24 02:31:03 +00:00
matroska: implement forward snapping keyframe seeking
Requires an index.
This commit is contained in:
parent
cfd0da4146
commit
93ce50f9b9
4 changed files with 26 additions and 15 deletions
|
@ -1925,7 +1925,7 @@ gst_matroska_demux_handle_seek_event (GstMatroskaDemux * demux,
|
|||
GstSeekFlags flags;
|
||||
GstSeekType cur_type, stop_type;
|
||||
GstFormat format;
|
||||
gboolean flush, keyunit;
|
||||
gboolean flush, keyunit, before, after, snap_next;
|
||||
gdouble rate;
|
||||
gint64 cur, stop;
|
||||
GstMatroskaTrackContext *track = NULL;
|
||||
|
@ -1975,8 +1975,10 @@ gst_matroska_demux_handle_seek_event (GstMatroskaDemux * demux,
|
|||
* would be determined again when parsing, but anyway ... */
|
||||
seeksegment.duration = demux->common.segment.duration;
|
||||
|
||||
flush = ! !(flags & GST_SEEK_FLAG_FLUSH);
|
||||
keyunit = ! !(flags & GST_SEEK_FLAG_KEY_UNIT);
|
||||
flush = !!(flags & GST_SEEK_FLAG_FLUSH);
|
||||
keyunit = !!(flags & GST_SEEK_FLAG_KEY_UNIT);
|
||||
after = !!(flags & GST_SEEK_FLAG_SNAP_AFTER);
|
||||
before = !!(flags & GST_SEEK_FLAG_SNAP_BEFORE);
|
||||
|
||||
GST_DEBUG_OBJECT (demux, "New segment %" GST_SEGMENT_FORMAT, &seeksegment);
|
||||
|
||||
|
@ -1989,11 +1991,14 @@ gst_matroska_demux_handle_seek_event (GstMatroskaDemux * demux,
|
|||
}
|
||||
|
||||
/* check sanity before we start flushing and all that */
|
||||
snap_next = after && !before;
|
||||
if (seeksegment.rate < 0)
|
||||
snap_next = !snap_next;
|
||||
GST_OBJECT_LOCK (demux);
|
||||
track = gst_matroska_read_common_get_seek_track (&demux->common, track);
|
||||
if ((entry = gst_matroska_read_common_do_index_seek (&demux->common, track,
|
||||
seeksegment.position, &demux->seek_index, &demux->seek_entry)) ==
|
||||
NULL) {
|
||||
seeksegment.position, &demux->seek_index, &demux->seek_entry,
|
||||
snap_next)) == NULL) {
|
||||
/* pull mode without index can scan later on */
|
||||
if (demux->streaming) {
|
||||
GST_DEBUG_OBJECT (demux, "No matching seek entry in index");
|
||||
|
@ -2053,8 +2058,9 @@ next:
|
|||
}
|
||||
|
||||
if (keyunit) {
|
||||
GST_DEBUG_OBJECT (demux, "seek to key unit, adjusting segment start to %"
|
||||
GST_TIME_FORMAT, GST_TIME_ARGS (entry->time));
|
||||
GST_DEBUG_OBJECT (demux, "seek to key unit, adjusting segment start from %"
|
||||
GST_TIME_FORMAT " to %" GST_TIME_FORMAT,
|
||||
GST_TIME_ARGS (seeksegment.start), GST_TIME_ARGS (entry->time));
|
||||
seeksegment.start = MAX (entry->time, demux->stream_start_time);
|
||||
seeksegment.position = seeksegment.start;
|
||||
seeksegment.time = seeksegment.start - demux->stream_start_time;
|
||||
|
|
|
@ -1364,8 +1364,8 @@ gst_matroska_parse_handle_seek_event (GstMatroskaParse * parse,
|
|||
/* check sanity before we start flushing and all that */
|
||||
GST_OBJECT_LOCK (parse);
|
||||
if ((entry = gst_matroska_read_common_do_index_seek (&parse->common, track,
|
||||
seeksegment.position, &parse->seek_index, &parse->seek_entry)) ==
|
||||
NULL) {
|
||||
seeksegment.position, &parse->seek_index, &parse->seek_entry,
|
||||
FALSE)) == NULL) {
|
||||
/* pull mode without index can scan later on */
|
||||
GST_DEBUG_OBJECT (parse, "No matching seek entry in index");
|
||||
GST_OBJECT_UNLOCK (parse);
|
||||
|
|
|
@ -365,7 +365,7 @@ gst_matroska_index_seek_find (GstMatroskaIndex * i1, GstClockTime * time,
|
|||
GstMatroskaIndex *
|
||||
gst_matroska_read_common_do_index_seek (GstMatroskaReadCommon * common,
|
||||
GstMatroskaTrackContext * track, gint64 seek_pos, GArray ** _index,
|
||||
gint * _entry_index)
|
||||
gint * _entry_index, gboolean next)
|
||||
{
|
||||
GstMatroskaIndex *entry = NULL;
|
||||
GArray *index;
|
||||
|
@ -382,11 +382,16 @@ gst_matroska_read_common_do_index_seek (GstMatroskaReadCommon * common,
|
|||
entry =
|
||||
gst_util_array_binary_search (index->data, index->len,
|
||||
sizeof (GstMatroskaIndex),
|
||||
(GCompareDataFunc) gst_matroska_index_seek_find, GST_SEARCH_MODE_BEFORE,
|
||||
&seek_pos, NULL);
|
||||
(GCompareDataFunc) gst_matroska_index_seek_find,
|
||||
next ? GST_SEARCH_MODE_AFTER : GST_SEARCH_MODE_BEFORE, &seek_pos, NULL);
|
||||
|
||||
if (entry == NULL)
|
||||
entry = &g_array_index (index, GstMatroskaIndex, 0);
|
||||
if (entry == NULL) {
|
||||
if (next) {
|
||||
return NULL;
|
||||
} else {
|
||||
entry = &g_array_index (index, GstMatroskaIndex, 0);
|
||||
}
|
||||
}
|
||||
|
||||
if (_index)
|
||||
*_index = index;
|
||||
|
|
|
@ -106,7 +106,7 @@ gint gst_matroska_index_seek_find (GstMatroskaIndex * i1, GstClockTime * time,
|
|||
gpointer user_data);
|
||||
GstMatroskaIndex * gst_matroska_read_common_do_index_seek (
|
||||
GstMatroskaReadCommon * common, GstMatroskaTrackContext * track, gint64
|
||||
seek_pos, GArray ** _index, gint * _entry_index);
|
||||
seek_pos, GArray ** _index, gint * _entry_index, gboolean next);
|
||||
void gst_matroska_read_common_found_global_tag (GstMatroskaReadCommon * common,
|
||||
GstElement * el, GstTagList * taglist);
|
||||
gint64 gst_matroska_read_common_get_length (GstMatroskaReadCommon * common);
|
||||
|
|
Loading…
Reference in a new issue