summaryrefslogtreecommitdiff
path: root/libavformat/mp3dec.c
diff options
context:
space:
mode:
Diffstat (limited to 'libavformat/mp3dec.c')
-rw-r--r--libavformat/mp3dec.c40
1 files changed, 20 insertions, 20 deletions
diff --git a/libavformat/mp3dec.c b/libavformat/mp3dec.c
index 32ca00c6a5..526f780a20 100644
--- a/libavformat/mp3dec.c
+++ b/libavformat/mp3dec.c
@@ -115,7 +115,8 @@ static void read_xing_toc(AVFormatContext *s, int64_t filesize, int64_t duration
{
int i;
MP3DecContext *mp3 = s->priv_data;
- int fill_index = mp3->usetoc == 1 && duration > 0;
+ int fast_seek = s->flags & AVFMT_FLAG_FAST_SEEK;
+ int fill_index = (mp3->usetoc || fast_seek) && duration > 0;
if (!filesize &&
!(filesize = avio_size(s->pb))) {
@@ -344,9 +345,6 @@ static int mp3_read_header(AVFormatContext *s)
int ret;
int i;
- if (mp3->usetoc < 0)
- mp3->usetoc = (s->flags & AVFMT_FLAG_FAST_SEEK) ? 1 : 2;
-
st = avformat_new_stream(s, NULL);
if (!st)
return AVERROR(ENOMEM);
@@ -501,35 +499,37 @@ static int mp3_seek(AVFormatContext *s, int stream_index, int64_t timestamp,
MP3DecContext *mp3 = s->priv_data;
AVIndexEntry *ie, ie1;
AVStream *st = s->streams[0];
- int64_t ret = av_index_search_timestamp(st, timestamp, flags);
int64_t best_pos;
- int fast_seek = (s->flags & AVFMT_FLAG_FAST_SEEK) ? 1 : 0;
+ int fast_seek = s->flags & AVFMT_FLAG_FAST_SEEK;
int64_t filesize = mp3->header_filesize;
- if (mp3->usetoc == 2)
- return -1; // generic index code
-
if (filesize <= 0) {
int64_t size = avio_size(s->pb);
if (size > 0 && size > s->internal->data_offset)
filesize = size - s->internal->data_offset;
}
- if ( (mp3->is_cbr || fast_seek)
- && (mp3->usetoc == 0 || !mp3->xing_toc)
- && st->duration > 0
- && filesize > 0) {
- ie = &ie1;
- timestamp = av_clip64(timestamp, 0, st->duration);
- ie->timestamp = timestamp;
- ie->pos = av_rescale(timestamp, filesize, st->duration) + s->internal->data_offset;
- } else if (mp3->xing_toc) {
+ if (mp3->xing_toc && (mp3->usetoc || (fast_seek && !mp3->is_cbr))) {
+ int64_t ret = av_index_search_timestamp(st, timestamp, flags);
+
+ // NOTE: The MP3 TOC is not a precise lookup table. Accuracy is worse
+ // for bigger files.
+ av_log(s, AV_LOG_WARNING, "Using MP3 TOC to seek; may be imprecise.\n");
+
if (ret < 0)
return ret;
ie = &st->index_entries[ret];
+ } else if (fast_seek && st->duration > 0 && filesize > 0) {
+ if (!mp3->is_cbr)
+ av_log(s, AV_LOG_WARNING, "Using scaling to seek VBR MP3; may be imprecise.\n");
+
+ ie = &ie1;
+ timestamp = av_clip64(timestamp, 0, st->duration);
+ ie->timestamp = timestamp;
+ ie->pos = av_rescale(timestamp, filesize, st->duration) + s->internal->data_offset;
} else {
- return -1;
+ return -1; // generic index code
}
best_pos = mp3_sync(s, ie->pos, flags);
@@ -546,7 +546,7 @@ static int mp3_seek(AVFormatContext *s, int stream_index, int64_t timestamp,
}
static const AVOption options[] = {
- { "usetoc", "use table of contents", offsetof(MP3DecContext, usetoc), AV_OPT_TYPE_INT, {.i64 = -1}, -1, 2, AV_OPT_FLAG_DECODING_PARAM},
+ { "usetoc", "use table of contents", offsetof(MP3DecContext, usetoc), AV_OPT_TYPE_INT, {.i64 = 0}, 0, 1, AV_OPT_FLAG_DECODING_PARAM},
{ NULL },
};