diff options
Diffstat (limited to 'libavformat')
-rw-r--r-- | libavformat/mp3dec.c | 40 | ||||
-rw-r--r-- | libavformat/seek-test.c | 8 |
2 files changed, 25 insertions, 23 deletions
diff --git a/libavformat/mp3dec.c b/libavformat/mp3dec.c index 32ca00c..526f780 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 }, }; diff --git a/libavformat/seek-test.c b/libavformat/seek-test.c index 1926f21..bfd06db 100644 --- a/libavformat/seek-test.c +++ b/libavformat/seek-test.c @@ -56,7 +56,7 @@ static void ts_str(char buffer[60], int64_t ts, AVRational base) int main(int argc, char **argv) { const char *filename; - AVFormatContext *ic = NULL; + AVFormatContext *ic = avformat_alloc_context(); int i, ret, stream_id; int j; int64_t timestamp; @@ -76,8 +76,10 @@ int main(int argc, char **argv) frame_count = atoi(argv[i+1]); } else if(!strcmp(argv[i], "-duration")){ duration = atoi(argv[i+1]); - } else if(!strcmp(argv[i], "-usetoc")) { - av_dict_set(&format_opts, "usetoc", argv[i+1], 0); + } else if(!strcmp(argv[i], "-fastseek")) { + if (atoi(argv[i+1])) { + ic->flags |= AVFMT_FLAG_FAST_SEEK; + } } else { argc = 1; } |