summaryrefslogtreecommitdiff
path: root/libavformat/subtitles.c
diff options
context:
space:
mode:
authorClément Bœsch <ubitux@gmail.com>2012-11-23 21:40:46 +0100
committerClément Bœsch <ubitux@gmail.com>2012-12-02 00:06:03 +0100
commitff3624b1ad9dc4374c9adf7ba65ac3ed6d05c0e5 (patch)
tree28584a27b9fa6278fda392c1ca7bf1d3d0191300 /libavformat/subtitles.c
parentb684f744ac1e4c5cbd6ac91d2be6098e1b122288 (diff)
lavf/subtitles: add ff_subtitles_queue_seek().
This function is almost identical to lavf/assdec:read_seek2(). It performs a generic seek for text subtitles demuxers for the new seeking API. The only difference with assdec:read_seek2 is the ts_diff being unsigned to avoid overflows. The seek callback in the ASS demuxer will be removed when it is redesigned to use FFDemuxSubtitlesQueue.
Diffstat (limited to 'libavformat/subtitles.c')
-rw-r--r--libavformat/subtitles.c38
1 files changed, 38 insertions, 0 deletions
diff --git a/libavformat/subtitles.c b/libavformat/subtitles.c
index 12045262eb..290eaa02aa 100644
--- a/libavformat/subtitles.c
+++ b/libavformat/subtitles.c
@@ -91,6 +91,44 @@ int ff_subtitles_queue_read_packet(FFDemuxSubtitlesQueue *q, AVPacket *pkt)
return 0;
}
+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)
+{
+ if (flags & AVSEEK_FLAG_BYTE) {
+ return AVERROR(ENOSYS);
+ } else if (flags & AVSEEK_FLAG_FRAME) {
+ if (ts < 0 || ts >= q->nb_subs)
+ return AVERROR(ERANGE);
+ q->current_sub_idx = ts;
+ } else {
+ int i, idx = -1;
+ int64_t min_ts_diff = INT64_MAX;
+ if (stream_index == -1) {
+ AVRational time_base = s->streams[0]->time_base;
+ ts = av_rescale_q(ts, AV_TIME_BASE_Q, time_base);
+ min_ts = av_rescale_rnd(min_ts, time_base.den,
+ time_base.num * (int64_t)AV_TIME_BASE,
+ AV_ROUND_UP);
+ max_ts = av_rescale_rnd(max_ts, time_base.den,
+ time_base.num * (int64_t)AV_TIME_BASE,
+ AV_ROUND_DOWN);
+ }
+ /* 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 (pts >= min_ts && pts <= max_ts && ts_diff < min_ts_diff) {
+ min_ts_diff = ts_diff;
+ idx = i;
+ }
+ }
+ if (idx < 0)
+ return AVERROR(ERANGE);
+ q->current_sub_idx = idx;
+ }
+ return 0;
+}
+
void ff_subtitles_queue_clean(FFDemuxSubtitlesQueue *q)
{
int i;