#ifndef GST_DISABLE_GST_DEBUG
static const char *const snap_types[2][2] = {
- {"any", "before"},
- {"after", "nearest"},
+ {"any", "after"},
+ {"before", "nearest"},
};
#endif
* @avi: Avi object
* @stream: the stream
* @time: a time position
+ * @next: whether to look for entry before or after @time
*
- * Finds the index entry which time is less or equal than the requested time.
+ * Finds the index entry which time is less/more or equal than the requested time.
* Try to avoid binary search when we can convert the time to an index
* position directly (for example for video frames with a fixed duration).
*
*/
static guint
gst_avi_demux_index_for_time (GstAviDemux * avi,
- GstAviStream * stream, guint64 time)
+ GstAviStream * stream, guint64 time, gboolean next)
{
guint index = -1;
guint64 total;
total = avi_stream_convert_time_to_frames_unchecked (stream, time);
} else {
index = avi_stream_convert_time_to_frames_unchecked (stream, time);
+ /* this entry typically undershoots the target time,
+ * so check a bit more if next needed */
+ if (next) {
+ GstClockTime itime =
+ avi_stream_convert_frames_to_time_unchecked (stream, index);
+ if (itime < time && index + 1 < stream->idx_n)
+ index++;
+ }
}
} else if (stream->strh->type == GST_RIFF_FCC_auds) {
/* constant rate stream */
entry = gst_util_array_binary_search (stream->index,
stream->idx_n, sizeof (GstAviIndexEntry),
(GCompareDataFunc) gst_avi_demux_index_entry_search,
- GST_SEARCH_MODE_BEFORE, &total, NULL);
+ next ? GST_SEARCH_MODE_AFTER : GST_SEARCH_MODE_BEFORE, &total, NULL);
if (entry == NULL) {
GST_LOG_OBJECT (avi, "not found, assume index 0");
gboolean keyframe, before, after;
guint i, index;
GstAviStream *stream;
+ gboolean next;
seek_time = segment->position;
keyframe = ! !(flags & GST_SEEK_FLAG_KEY_UNIT);
* which is mostly correct... */
stream = &avi->stream[avi->main_stream];
+ next = after && !before;
+ if (segment->rate < 0)
+ next = !next;
+
/* get the entry index for the requested position */
- index = gst_avi_demux_index_for_time (avi, stream, seek_time);
+ index = gst_avi_demux_index_for_time (avi, stream, seek_time, next);
GST_DEBUG_OBJECT (avi, "Got entry %u", index);
if (index == -1)
return FALSE;
/* check if we are already on a keyframe */
if (!ENTRY_IS_KEYFRAME (&stream->index[index])) {
- gboolean next;
-
- next = after && !before;
- if (segment->rate < 0)
- next = !next;
-
if (next) {
GST_DEBUG_OBJECT (avi, "not keyframe, searching forward");
/* now go to the next keyframe, this is where we should start
continue;
/* get the entry index for the requested position */
- index = gst_avi_demux_index_for_time (avi, ostream, seek_time);
+ index = gst_avi_demux_index_for_time (avi, ostream, seek_time, FALSE);
if (index == -1)
continue;
GstSeekFlags flags;
GstSeekType cur_type = GST_SEEK_TYPE_NONE, stop_type;
gint64 cur, stop;
- gboolean keyframe, before, after;
+ gboolean keyframe, before, after, next;
GstAviStream *stream;
guint index;
guint n, str_num;
str_num = avi->main_stream;
stream = &avi->stream[str_num];
+ next = after && !before;
+ if (seeksegment.rate < 0)
+ next = !next;
+
/* get the entry index for the requested position */
- index = gst_avi_demux_index_for_time (avi, stream, cur);
+ index = gst_avi_demux_index_for_time (avi, stream, cur, next);
GST_DEBUG_OBJECT (avi, "str %u: Found entry %u for %" GST_TIME_FORMAT,
str_num, index, GST_TIME_ARGS (cur));
if (index == -1)
/* check if we are already on a keyframe */
if (!ENTRY_IS_KEYFRAME (&stream->index[index])) {
- gboolean next;
-
- next = after && !before;
- if (seeksegment.rate < 0)
- next = !next;
-
if (next) {
GST_DEBUG_OBJECT (avi, "Entry is not a keyframe - searching forward");
/* now go to the next keyframe, this is where we should start
continue;
/* get the entry index for the requested position */
- idx = gst_avi_demux_index_for_time (avi, str, cur);
+ idx = gst_avi_demux_index_for_time (avi, str, cur, FALSE);
GST_DEBUG_OBJECT (avi, "str %u: Found entry %u for %" GST_TIME_FORMAT, n,
idx, GST_TIME_ARGS (cur));
if (idx == -1)
/* check if we are already on a keyframe */
if (!ENTRY_IS_KEYFRAME (&str->index[idx])) {
- if (after && !before) {
+ if (next) {
GST_DEBUG_OBJECT (avi, "Entry is not a keyframe - searching forward");
/* now go to the next keyframe, this is where we should start
* decoding from. */