| @@ -1,5 +1,5 @@ | |||
| /* | |||
| * Copyright (c) 2012 Clément Bœsch | |||
| * Copyright (c) 2012-2013 Clément Bœsch <u pkh me> | |||
| * | |||
| * This file is part of FFmpeg. | |||
| * | |||
| @@ -94,6 +94,28 @@ int ff_subtitles_queue_read_packet(FFDemuxSubtitlesQueue *q, AVPacket *pkt) | |||
| return 0; | |||
| } | |||
| static int search_sub_ts(const FFDemuxSubtitlesQueue *q, int64_t ts) | |||
| { | |||
| int s1 = 0, s2 = q->nb_subs - 1; | |||
| if (s2 < s1) | |||
| return AVERROR(ERANGE); | |||
| for (;;) { | |||
| int mid; | |||
| if (s1 == s2) | |||
| return s1; | |||
| if (s1 == s2 - 1) | |||
| return q->subs[s1].pts <= q->subs[s2].pts ? s1 : s2; | |||
| mid = (s1 + s2) / 2; | |||
| if (q->subs[mid].pts <= ts) | |||
| s1 = mid; | |||
| else | |||
| s2 = mid; | |||
| } | |||
| } | |||
| int ff_subtitles_queue_seek(FFDemuxSubtitlesQueue *q, AVFormatContext *s, int stream_index, | |||
| int64_t min_ts, int64_t ts, int64_t max_ts, int flags) | |||
| { | |||
| @@ -104,23 +126,23 @@ int ff_subtitles_queue_seek(FFDemuxSubtitlesQueue *q, AVFormatContext *s, int st | |||
| return AVERROR(ERANGE); | |||
| q->current_sub_idx = ts; | |||
| } else { | |||
| int i, idx = -1; | |||
| int64_t min_ts_diff = INT64_MAX; | |||
| int i, idx = search_sub_ts(q, ts); | |||
| int64_t ts_selected; | |||
| /* TODO: q->subs[] is sorted by pts so we could do a binary search */ | |||
| for (i = 0; i < q->nb_subs; i++) { | |||
| int64_t pts = q->subs[i].pts; | |||
| uint64_t ts_diff = FFABS(pts - ts); | |||
| if ((stream_index == -1 || q->subs[i].stream_index == stream_index) && | |||
| pts >= min_ts && pts <= max_ts && ts_diff < min_ts_diff) { | |||
| min_ts_diff = ts_diff; | |||
| idx = i; | |||
| } | |||
| } | |||
| if (idx < 0) | |||
| return idx; | |||
| for (i = idx; i < q->nb_subs && q->subs[i].pts < min_ts; i++) | |||
| if (stream_index == -1 || q->subs[i].stream_index == stream_index) | |||
| idx = i; | |||
| for (i = idx; i > 0 && q->subs[i].pts > max_ts; i--) | |||
| if (stream_index == -1 || q->subs[i].stream_index == stream_index) | |||
| idx = i; | |||
| ts_selected = q->subs[idx].pts; | |||
| if (ts_selected < min_ts || ts_selected > max_ts) | |||
| return AVERROR(ERANGE); | |||
| /* look back in the latest subtitles for overlapping subtitles */ | |||
| ts_selected = q->subs[idx].pts; | |||
| for (i = idx - 1; i >= 0; i--) { | |||
| int64_t pts = q->subs[i].pts; | |||
| if (q->subs[i].duration <= 0 || | |||