[FFmpeg-cvslog] lavf/subtitles: add ff_subtitles_queue_seek().

Clément Bœsch git at videolan.org
Sun Dec 2 00:19:22 CET 2012


ffmpeg | branch: master | Clément Bœsch <ubitux at gmail.com> | Fri Nov 23 21:40:46 2012 +0100| [ff3624b1ad9dc4374c9adf7ba65ac3ed6d05c0e5] | committer: Clément Bœsch

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.

> http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=ff3624b1ad9dc4374c9adf7ba65ac3ed6d05c0e5
---

 libavformat/subtitles.c |   38 ++++++++++++++++++++++++++++++++++++++
 libavformat/subtitles.h |    7 +++++++
 2 files changed, 45 insertions(+)

diff --git a/libavformat/subtitles.c b/libavformat/subtitles.c
index 1204526..290eaa0 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;
diff --git a/libavformat/subtitles.h b/libavformat/subtitles.h
index b089bb2..55e6182 100644
--- a/libavformat/subtitles.h
+++ b/libavformat/subtitles.h
@@ -55,6 +55,13 @@ void ff_subtitles_queue_finalize(FFDemuxSubtitlesQueue *q);
 int ff_subtitles_queue_read_packet(FFDemuxSubtitlesQueue *q, AVPacket *pkt);
 
 /**
+ * Update current_sub_idx to emulate a seek. Except the first parameter, it
+ * matches AVInputFormat->read_seek2 prototypes.
+ */
+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);
+
+/**
  * Remove and destroy all the subtitles packets.
  */
 void ff_subtitles_queue_clean(FFDemuxSubtitlesQueue *q);



More information about the ffmpeg-cvslog mailing list