summaryrefslogtreecommitdiff
path: root/libavformat/assdec.c
diff options
context:
space:
mode:
authorAurelien Jacobs <aurel@gnuage.org>2010-07-29 22:10:22 +0000
committerAurelien Jacobs <aurel@gnuage.org>2010-07-29 22:10:22 +0000
commitac066b83e9c32cb6baee0df9e01d35a1b38b0c92 (patch)
tree19cf68e5af646eee1410adc158f8777086b40d7f /libavformat/assdec.c
parent530bbe96c7ccd1716342c1eea0e30109f8eab0d4 (diff)
add seeking support in ASS demuxer
Originally committed as revision 24578 to svn://svn.ffmpeg.org/ffmpeg/trunk
Diffstat (limited to 'libavformat/assdec.c')
-rw-r--r--libavformat/assdec.c42
1 files changed, 41 insertions, 1 deletions
diff --git a/libavformat/assdec.c b/libavformat/assdec.c
index ff1009c1ce..9f03b88491 100644
--- a/libavformat/assdec.c
+++ b/libavformat/assdec.c
@@ -162,6 +162,46 @@ static int read_packet(AVFormatContext *s, AVPacket *pkt)
return 0;
}
+static int read_seek2(AVFormatContext *s, int stream_index,
+ int64_t min_ts, int64_t ts, int64_t max_ts, int flags)
+{
+ ASSContext *ass = s->priv_data;
+
+ if (flags & AVSEEK_FLAG_BYTE) {
+ return AVERROR_NOTSUPP;
+ } else if (flags & AVSEEK_FLAG_FRAME) {
+ if (ts < 0 || ts >= ass->event_count)
+ return AVERROR(ERANGE);
+ ass->event_index = 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: ass->event[] is sorted by pts so we could do a binary search */
+ for (i=0; i<ass->event_count; i++) {
+ int64_t pts = get_pts(ass->event[i]);
+ int64_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);
+ ass->event_index = idx;
+ }
+ return 0;
+}
+
AVInputFormat ass_demuxer = {
"ass",
NULL_IF_CONFIG_SMALL("Advanced SubStation Alpha subtitle format"),
@@ -170,5 +210,5 @@ AVInputFormat ass_demuxer = {
read_header,
read_packet,
read_close,
-// read_seek,
+ .read_seek2 = read_seek2,
};