]> git.sesse.net Git - ffmpeg/blobdiff - libavformat/mp3dec.c
avformat/mp3dec: make generic index mode the default
[ffmpeg] / libavformat / mp3dec.c
index 06bc1d0f7f8b1c51b30c20ffbbd5ec6dbc2065ad..a2d3dfe737754b24f0210824d996f04acd667229 100644 (file)
@@ -110,7 +110,7 @@ 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 && duration > 0;
+    int fill_index = mp3->usetoc == 1 && duration > 0;
 
     if (!filesize &&
         !(filesize = avio_size(s->pb))) {
@@ -228,13 +228,13 @@ static void mp3_parse_info_tag(AVFormatContext *s, AVStream *st,
 
         mp3->start_pad = v>>12;
         mp3->  end_pad = v&4095;
-        st->skip_samples = mp3->start_pad + 528 + 1;
+        st->start_skip_samples = mp3->start_pad + 528 + 1;
         if (mp3->frames) {
             st->first_discard_sample = -mp3->end_pad + 528 + 1 + mp3->frames * (int64_t)spf;
             st->last_discard_sample = mp3->frames * (int64_t)spf;
         }
         if (!st->start_time)
-            st->start_time = av_rescale_q(st->skip_samples,
+            st->start_time = av_rescale_q(st->start_skip_samples,
                                             (AVRational){1, c->sample_rate},
                                             st->time_base);
         av_log(s, AV_LOG_DEBUG, "pad %d %d\n", mp3->start_pad, mp3->  end_pad);
@@ -336,6 +336,9 @@ static int mp3_read_header(AVFormatContext *s)
     int ret;
     int i;
 
+    if (mp3->usetoc < 0)
+        mp3->usetoc = 2;
+
     st = avformat_new_stream(s, NULL);
     if (!st)
         return AVERROR(ENOMEM);
@@ -432,8 +435,11 @@ static int mp3_seek(AVFormatContext *s, int stream_index, int64_t timestamp,
     int64_t best_pos;
     int best_score;
 
+    if (mp3->usetoc == 2)
+        return -1; // generic index code
+
     if (   mp3->is_cbr
-        && (mp3->usetoc <= 0 || !mp3->xing_toc)
+        && (mp3->usetoc == 0 || !mp3->xing_toc)
         && st->duration > 0
         && mp3->header_filesize > s->internal->data_offset
         && mp3->frames) {
@@ -447,8 +453,6 @@ static int mp3_seek(AVFormatContext *s, int stream_index, int64_t timestamp,
 
         ie = &st->index_entries[ret];
     } else {
-        st->skip_samples = timestamp <= 0 ? mp3->start_pad + 528 + 1 : 0;
-
         return -1;
     }
 
@@ -489,13 +493,18 @@ static int mp3_seek(AVFormatContext *s, int stream_index, int64_t timestamp,
     ret = avio_seek(s->pb, best_pos, SEEK_SET);
     if (ret < 0)
         return ret;
+
+    if (mp3->is_cbr && ie == &ie1) {
+        int frame_duration = av_rescale(st->duration, 1, mp3->frames);
+        ie1.timestamp = frame_duration * av_rescale(best_pos - s->internal->data_offset, mp3->frames, mp3->header_filesize);
+    }
+
     ff_update_cur_dts(s, st, ie->timestamp);
-    st->skip_samples = ie->timestamp <= 0 ? mp3->start_pad + 528 + 1 : 0;
     return 0;
 }
 
 static const AVOption options[] = {
-    { "usetoc", "use table of contents", offsetof(MP3DecContext, usetoc), AV_OPT_TYPE_INT, {.i64 = -1}, -1, 1, AV_OPT_FLAG_DECODING_PARAM},
+    { "usetoc", "use table of contents", offsetof(MP3DecContext, usetoc), AV_OPT_TYPE_INT, {.i64 = -1}, -1, 2, AV_OPT_FLAG_DECODING_PARAM},
     { NULL },
 };