Commit 72840a55 authored by andoma's avatar andoma

add support for reading duration from Xing-tag in mp3 files



git-svn-id: file:///var/local/repositories/ffmpeg/trunk@10845 9553f0bf-9b14-0410-a0b8-cfaf0461ba5b
parent 268a0894
...@@ -21,6 +21,7 @@ ...@@ -21,6 +21,7 @@
#include "avformat.h" #include "avformat.h"
#include "mpegaudio.h" #include "mpegaudio.h"
#include "avstring.h" #include "avstring.h"
#include "mpegaudiodecheader.h"
#define ID3v2_HEADER_SIZE 10 #define ID3v2_HEADER_SIZE 10
#define ID3v1_TAG_SIZE 128 #define ID3v1_TAG_SIZE 128
...@@ -424,12 +425,40 @@ static int mp3_read_probe(AVProbeData *p) ...@@ -424,12 +425,40 @@ static int mp3_read_probe(AVProbeData *p)
else return 0; 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, static int mp3_read_header(AVFormatContext *s,
AVFormatParameters *ap) AVFormatParameters *ap)
{ {
AVStream *st; AVStream *st;
uint8_t buf[ID3v1_TAG_SIZE]; uint8_t buf[ID3v1_TAG_SIZE];
int len, ret, filesize; int len, ret, filesize;
offset_t off;
st = av_new_stream(s, 0); st = av_new_stream(s, 0);
if (!st) if (!st)
...@@ -469,6 +498,10 @@ static int mp3_read_header(AVFormatContext *s, ...@@ -469,6 +498,10 @@ static int mp3_read_header(AVFormatContext *s,
url_fseek(&s->pb, 0, SEEK_SET); 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 */ /* the parameters will be extracted from the compressed bitstream */
return 0; return 0;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment