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;
* 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);
}
/* 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");
}
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;
/* 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);
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;
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;
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);