diff options
author | Andreas Öman <andreas@lonelycoder.com> | 2007-10-23 13:35:20 +0000 |
---|---|---|
committer | Andreas Öman <andreas@lonelycoder.com> | 2007-10-23 13:35:20 +0000 |
commit | ca851a3a082f3678c5f0e7e8dc24480a5f483ec6 (patch) | |
tree | 163d764c0b83d529644f22494b33bd2ef93086e6 /libavformat | |
parent | 71fa13e8757700d817ae3058fac3c5c55eaed839 (diff) | |
download | ffmpeg-ca851a3a082f3678c5f0e7e8dc24480a5f483ec6.tar.gz |
add support for reading duration from Xing-tag in mp3 files
Originally committed as revision 10845 to svn://svn.ffmpeg.org/ffmpeg/trunk
Diffstat (limited to 'libavformat')
-rw-r--r-- | libavformat/mp3.c | 33 |
1 files changed, 33 insertions, 0 deletions
diff --git a/libavformat/mp3.c b/libavformat/mp3.c index 6173be225e..b2bc89587a 100644 --- a/libavformat/mp3.c +++ b/libavformat/mp3.c @@ -21,6 +21,7 @@ #include "avformat.h" #include "mpegaudio.h" #include "avstring.h" +#include "mpegaudiodecheader.h" #define ID3v2_HEADER_SIZE 10 #define ID3v1_TAG_SIZE 128 @@ -424,12 +425,40 @@ static int mp3_read_probe(AVProbeData *p) else return 0; } +/** + * Try to extract a xing tag from the stream and if found, decode it + */ +static void mp3_parse_xing(AVFormatContext *s, AVStream *st) +{ + uint32_t v, frames, spf; + const offset_t offtbl[2][2] = {{32, 17}, {17,9}}; + MPADecodeContext c; + + ff_mpegaudio_decode_header(&c, get_be32(&s->pb)); + url_fseek(&s->pb, offtbl[c.lsf == 1][c.nb_channels == 1], SEEK_CUR); + v = get_be32(&s->pb); + if(c.layer != 3 || + (v != MKBETAG('X', 'i', 'n', 'g') && + v != MKBETAG('I', 'n', 'f', 'o'))) + return; + + v = get_be32(&s->pb); + if(v & 0x1) { + frames = get_be32(&s->pb); /* Total number of frames in file */ + spf = c.lsf ? 576 : 1152; /* Samples per frame, layer 3 */ + + st->duration = av_rescale_q(frames, (AVRational){spf, c.sample_rate}, + st->time_base); + } +} + static int mp3_read_header(AVFormatContext *s, AVFormatParameters *ap) { AVStream *st; uint8_t buf[ID3v1_TAG_SIZE]; int len, ret, filesize; + offset_t off; st = av_new_stream(s, 0); if (!st) @@ -469,6 +498,10 @@ static int mp3_read_header(AVFormatContext *s, url_fseek(&s->pb, 0, SEEK_SET); } + off = url_ftell(&s->pb); + mp3_parse_xing(s, st); + url_fseek(&s->pb, off, SEEK_SET); + /* the parameters will be extracted from the compressed bitstream */ return 0; } |