|
|
|
@ -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, |
|
|
|
|
}; |
|
|
|
|