mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-02-17 11:45:25 +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;
|
GstSeekFlags flags;
|
||||||
GstSeekType cur_type, stop_type;
|
GstSeekType cur_type, stop_type;
|
||||||
GstFormat format;
|
GstFormat format;
|
||||||
gboolean flush, keyunit;
|
gboolean flush, keyunit, before, after, snap_next;
|
||||||
gdouble rate;
|
gdouble rate;
|
||||||
gint64 cur, stop;
|
gint64 cur, stop;
|
||||||
GstMatroskaTrackContext *track = NULL;
|
GstMatroskaTrackContext *track = NULL;
|
||||||
|
@ -1975,8 +1975,10 @@ gst_matroska_demux_handle_seek_event (GstMatroskaDemux * demux,
|
||||||
* would be determined again when parsing, but anyway ... */
|
* would be determined again when parsing, but anyway ... */
|
||||||
seeksegment.duration = demux->common.segment.duration;
|
seeksegment.duration = demux->common.segment.duration;
|
||||||
|
|
||||||
flush = ! !(flags & GST_SEEK_FLAG_FLUSH);
|
flush = !!(flags & GST_SEEK_FLAG_FLUSH);
|
||||||
keyunit = ! !(flags & GST_SEEK_FLAG_KEY_UNIT);
|
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);
|
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 */
|
/* 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);
|
GST_OBJECT_LOCK (demux);
|
||||||
track = gst_matroska_read_common_get_seek_track (&demux->common, track);
|
track = gst_matroska_read_common_get_seek_track (&demux->common, track);
|
||||||
if ((entry = gst_matroska_read_common_do_index_seek (&demux->common, track,
|
if ((entry = gst_matroska_read_common_do_index_seek (&demux->common, track,
|
||||||
seeksegment.position, &demux->seek_index, &demux->seek_entry)) ==
|
seeksegment.position, &demux->seek_index, &demux->seek_entry,
|
||||||
NULL) {
|
snap_next)) == NULL) {
|
||||||
/* pull mode without index can scan later on */
|
/* pull mode without index can scan later on */
|
||||||
if (demux->streaming) {
|
if (demux->streaming) {
|
||||||
GST_DEBUG_OBJECT (demux, "No matching seek entry in index");
|
GST_DEBUG_OBJECT (demux, "No matching seek entry in index");
|
||||||
|
@ -2053,8 +2058,9 @@ next:
|
||||||
}
|
}
|
||||||
|
|
||||||
if (keyunit) {
|
if (keyunit) {
|
||||||
GST_DEBUG_OBJECT (demux, "seek to key unit, adjusting segment start to %"
|
GST_DEBUG_OBJECT (demux, "seek to key unit, adjusting segment start from %"
|
||||||
GST_TIME_FORMAT, GST_TIME_ARGS (entry->time));
|
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.start = MAX (entry->time, demux->stream_start_time);
|
||||||
seeksegment.position = seeksegment.start;
|
seeksegment.position = seeksegment.start;
|
||||||
seeksegment.time = seeksegment.start - demux->stream_start_time;
|
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 */
|
/* check sanity before we start flushing and all that */
|
||||||
GST_OBJECT_LOCK (parse);
|
GST_OBJECT_LOCK (parse);
|
||||||
if ((entry = gst_matroska_read_common_do_index_seek (&parse->common, track,
|
if ((entry = gst_matroska_read_common_do_index_seek (&parse->common, track,
|
||||||
seeksegment.position, &parse->seek_index, &parse->seek_entry)) ==
|
seeksegment.position, &parse->seek_index, &parse->seek_entry,
|
||||||
NULL) {
|
FALSE)) == NULL) {
|
||||||
/* pull mode without index can scan later on */
|
/* pull mode without index can scan later on */
|
||||||
GST_DEBUG_OBJECT (parse, "No matching seek entry in index");
|
GST_DEBUG_OBJECT (parse, "No matching seek entry in index");
|
||||||
GST_OBJECT_UNLOCK (parse);
|
GST_OBJECT_UNLOCK (parse);
|
||||||
|
|
|
@ -365,7 +365,7 @@ gst_matroska_index_seek_find (GstMatroskaIndex * i1, GstClockTime * time,
|
||||||
GstMatroskaIndex *
|
GstMatroskaIndex *
|
||||||
gst_matroska_read_common_do_index_seek (GstMatroskaReadCommon * common,
|
gst_matroska_read_common_do_index_seek (GstMatroskaReadCommon * common,
|
||||||
GstMatroskaTrackContext * track, gint64 seek_pos, GArray ** _index,
|
GstMatroskaTrackContext * track, gint64 seek_pos, GArray ** _index,
|
||||||
gint * _entry_index)
|
gint * _entry_index, gboolean next)
|
||||||
{
|
{
|
||||||
GstMatroskaIndex *entry = NULL;
|
GstMatroskaIndex *entry = NULL;
|
||||||
GArray *index;
|
GArray *index;
|
||||||
|
@ -382,11 +382,16 @@ gst_matroska_read_common_do_index_seek (GstMatroskaReadCommon * common,
|
||||||
entry =
|
entry =
|
||||||
gst_util_array_binary_search (index->data, index->len,
|
gst_util_array_binary_search (index->data, index->len,
|
||||||
sizeof (GstMatroskaIndex),
|
sizeof (GstMatroskaIndex),
|
||||||
(GCompareDataFunc) gst_matroska_index_seek_find, GST_SEARCH_MODE_BEFORE,
|
(GCompareDataFunc) gst_matroska_index_seek_find,
|
||||||
&seek_pos, NULL);
|
next ? GST_SEARCH_MODE_AFTER : GST_SEARCH_MODE_BEFORE, &seek_pos, NULL);
|
||||||
|
|
||||||
if (entry == NULL)
|
if (entry == NULL) {
|
||||||
entry = &g_array_index (index, GstMatroskaIndex, 0);
|
if (next) {
|
||||||
|
return NULL;
|
||||||
|
} else {
|
||||||
|
entry = &g_array_index (index, GstMatroskaIndex, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (_index)
|
if (_index)
|
||||||
*_index = index;
|
*_index = index;
|
||||||
|
|
|
@ -106,7 +106,7 @@ gint gst_matroska_index_seek_find (GstMatroskaIndex * i1, GstClockTime * time,
|
||||||
gpointer user_data);
|
gpointer user_data);
|
||||||
GstMatroskaIndex * gst_matroska_read_common_do_index_seek (
|
GstMatroskaIndex * gst_matroska_read_common_do_index_seek (
|
||||||
GstMatroskaReadCommon * common, GstMatroskaTrackContext * track, gint64
|
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,
|
void gst_matroska_read_common_found_global_tag (GstMatroskaReadCommon * common,
|
||||||
GstElement * el, GstTagList * taglist);
|
GstElement * el, GstTagList * taglist);
|
||||||
gint64 gst_matroska_read_common_get_length (GstMatroskaReadCommon * common);
|
gint64 gst_matroska_read_common_get_length (GstMatroskaReadCommon * common);
|
||||||
|
|
Loading…
Reference in a new issue