[FFmpeg-devel] [PATCH] avformat/mp3dec: Make MP3 seek fast

Tsung-Hung Wu tsunghung at chromium.org
Tue Sep 1 20:35:17 CEST 2015


Hi FFmpeg developers,

I am trying to solve an issue: seeking a large MP3 file is slow. This
happens when play Podcast audio, for example
http://podcastdownload.npr.org/anon.npr-podcasts/podcast/344098539/430765119/npr_430765119.mp3
It works not so good in less computing power mobile devices, especially
under slow network environment.
My goal is to improve the usability, although it may sacrifice the accuracy.

I noticed that FFmpeg has AVFMT_FLAG_FAST_SEEK flag. That's exactly what I
need, sacrifices the accuracy of playback time in exchange for
responsiveness. However, it does not work as my expectation. I made some
changes to fulfill my needs. Please find the attachment for the patch.
Just to be clear, I put some comments below for discussions, which are not
in the patch.

Could you please kindly review the attached patch? Let me know if you have
any comments. Thank you so much for your help.

Best Regards,
Andy

---
 libavformat/mp3dec.c | 14 ++++++++------
 1 file changed, 8 insertions(+), 6 deletions(-)

diff --git a/libavformat/mp3dec.c b/libavformat/mp3dec.c
index 007c6ea..7f675ab 100644
--- a/libavformat/mp3dec.c
+++ b/libavformat/mp3dec.c
@@ -342,7 +342,7 @@ static int mp3_read_header(AVFormatContext *s)
     int i;

     if (mp3->usetoc < 0)
-        mp3->usetoc = (s->flags & AVFMT_FLAG_FAST_SEEK) ? 0 : 2;
+        mp3->usetoc = (s->flags & AVFMT_FLAG_FAST_SEEK) ? 1 : 2;

/*
Should usetoc be 0 when AVFMT_FLAG_FAST_SEEK is enabled? When usetoc is 0,
seeking a VBR mp3 is slow, even if it contains a TOC.
Thus, I think 1 is a more proper selection.
*/

     st = avformat_new_stream(s, NULL);
     if (!st)
@@ -489,19 +489,21 @@ static int mp3_seek(AVFormatContext *s, int
stream_index, int64_t timestamp,
     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;
+    int64_t filesize = mp3->header_filesize > 0 ? mp3->header_filesize
+                            : avio_size(s->pb) - s->internal->data_offset;

/*
Many MP3 files in Podcast does not have VBRI, LAME, or XING tag, so
header_filesize is not always available. (file size - data offset) could be
a good estimation.
*/


     if (mp3->usetoc == 2)
         return -1; // generic index code

-    if (   mp3->is_cbr
+    if (   (mp3->is_cbr || fast_seek)
         && (mp3->usetoc == 0 || !mp3->xing_toc)
         && st->duration > 0
-        && mp3->header_filesize > s->internal->data_offset
-        && mp3->frames) {
+        && filesize > 0) {
/*
Not sure why (mp3->header_filesize > s->internal->data_offset) has to be
true. What if a MP3 file contains a short audio and a large picture?
Again, mp3->frames is not always available. Do we really need it here? I
move the check to below.
*/
         ie = &ie1;
         timestamp = av_clip64(timestamp, 0, st->duration);
         ie->timestamp = timestamp;
-        ie->pos       = av_rescale(timestamp, mp3->header_filesize,
st->duration) + s->internal->data_offset;
+        ie->pos       = av_rescale(timestamp, filesize, st->duration) +
s->internal->data_offset;
     } else if (mp3->xing_toc) {
         if (ret < 0)
             return ret;
@@ -515,7 +517,7 @@ static int mp3_seek(AVFormatContext *s, int
stream_index, int64_t timestamp,
     if (best_pos < 0)
         return best_pos;

-    if (mp3->is_cbr && ie == &ie1) {
+    if (mp3->is_cbr && ie == &ie1 && mp3->frames) {
         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);
     }
-- 
2.5.0.457.gab17608
-------------- next part --------------
A non-text attachment was scrubbed...
Name: 0001-avformat-mp3dec-Make-MP3-seek-fast.patch
Type: text/x-patch
Size: 2854 bytes
Desc: not available
URL: <http://ffmpeg.org/pipermail/ffmpeg-devel/attachments/20150901/38b1ae3a/attachment.bin>


More information about the ffmpeg-devel mailing list