Commit ac3ef4a4 authored by Alex Converse's avatar Alex Converse

Fix probing of files with ID3v2 tags. Discussed at

http://lists.mplayerhq.hu/pipermail/ffmpeg-devel/2009-January/059302.html

Originally committed as revision 16688 to svn://svn.ffmpeg.org/ffmpeg/trunk
parent 2f642393
...@@ -8,7 +8,7 @@ HEADERS = avformat.h avio.h rtsp.h rtspcodes.h ...@@ -8,7 +8,7 @@ HEADERS = avformat.h avio.h rtsp.h rtspcodes.h
OBJS = allformats.o cutils.o metadata.o metadata_compat.o options.o os_support.o sdp.o utils.o OBJS = allformats.o cutils.o metadata.o metadata_compat.o options.o os_support.o sdp.o utils.o
# muxers/demuxers # muxers/demuxers
OBJS-$(CONFIG_AAC_DEMUXER) += raw.o OBJS-$(CONFIG_AAC_DEMUXER) += raw.o id3v2.o
OBJS-$(CONFIG_AC3_DEMUXER) += raw.o OBJS-$(CONFIG_AC3_DEMUXER) += raw.o
OBJS-$(CONFIG_AC3_MUXER) += raw.o OBJS-$(CONFIG_AC3_MUXER) += raw.o
OBJS-$(CONFIG_ADTS_MUXER) += adtsenc.o OBJS-$(CONFIG_ADTS_MUXER) += adtsenc.o
...@@ -97,7 +97,7 @@ OBJS-$(CONFIG_MP2_MUXER) += mp3.o ...@@ -97,7 +97,7 @@ OBJS-$(CONFIG_MP2_MUXER) += mp3.o
OBJS-$(CONFIG_MP3_DEMUXER) += mp3.o id3v2.o OBJS-$(CONFIG_MP3_DEMUXER) += mp3.o id3v2.o
OBJS-$(CONFIG_MP3_MUXER) += mp3.o OBJS-$(CONFIG_MP3_MUXER) += mp3.o
OBJS-$(CONFIG_MP4_MUXER) += movenc.o riff.o isom.o avc.o OBJS-$(CONFIG_MP4_MUXER) += movenc.o riff.o isom.o avc.o
OBJS-$(CONFIG_MPC_DEMUXER) += mpc.o OBJS-$(CONFIG_MPC_DEMUXER) += mpc.o id3v2.o
OBJS-$(CONFIG_MPC8_DEMUXER) += mpc8.o OBJS-$(CONFIG_MPC8_DEMUXER) += mpc8.o
OBJS-$(CONFIG_MPEG1SYSTEM_MUXER) += mpegenc.o OBJS-$(CONFIG_MPEG1SYSTEM_MUXER) += mpegenc.o
OBJS-$(CONFIG_MPEG1VCD_MUXER) += mpegenc.o OBJS-$(CONFIG_MPEG1VCD_MUXER) += mpegenc.o
......
...@@ -33,3 +33,15 @@ int ff_id3v2_match(const uint8_t *buf) ...@@ -33,3 +33,15 @@ int ff_id3v2_match(const uint8_t *buf)
(buf[8] & 0x80) == 0 && (buf[8] & 0x80) == 0 &&
(buf[9] & 0x80) == 0; (buf[9] & 0x80) == 0;
} }
int ff_id3v2_tag_len(const uint8_t * buf)
{
int len = ((buf[6] & 0x7f) << 21) +
((buf[7] & 0x7f) << 14) +
((buf[8] & 0x7f) << 7) +
(buf[9] & 0x7f) +
ID3v2_HEADER_SIZE;
if (buf[5] & 0x10)
len += ID3v2_HEADER_SIZE;
return len;
}
...@@ -32,4 +32,11 @@ ...@@ -32,4 +32,11 @@
*/ */
int ff_id3v2_match(const uint8_t *buf); int ff_id3v2_match(const uint8_t *buf);
/**
* Gets the length of an ID3v2 tag.
* @buf must be ID3v2_HEADER_SIZE bytes long and point to the start of an
* already detected ID3v2 tag
*/
int ff_id3v2_tag_len(const uint8_t *buf);
#endif /* AVFORMAT_ID3V2_H */ #endif /* AVFORMAT_ID3V2_H */
...@@ -354,14 +354,16 @@ static int mp3_read_probe(AVProbeData *p) ...@@ -354,14 +354,16 @@ static int mp3_read_probe(AVProbeData *p)
int max_frames, first_frames = 0; int max_frames, first_frames = 0;
int fsize, frames, sample_rate; int fsize, frames, sample_rate;
uint32_t header; uint32_t header;
uint8_t *buf, *buf2, *end; uint8_t *buf, *buf0, *buf2, *end;
AVCodecContext avctx; AVCodecContext avctx;
if(ff_id3v2_match(p->buf)) buf0 = p->buf;
return AVPROBE_SCORE_MAX/2+1; // this must be less than mpeg-ps because some retards put id3v2 tags before mpeg-ps files if(ff_id3v2_match(buf0)) {
buf0 += ff_id3v2_tag_len(buf0);
}
max_frames = 0; max_frames = 0;
buf = p->buf; buf = buf0;
end = buf + p->buf_size - sizeof(uint32_t); end = buf + p->buf_size - sizeof(uint32_t);
for(; buf < end; buf= buf2+1) { for(; buf < end; buf= buf2+1) {
...@@ -375,7 +377,7 @@ static int mp3_read_probe(AVProbeData *p) ...@@ -375,7 +377,7 @@ static int mp3_read_probe(AVProbeData *p)
buf2 += fsize; buf2 += fsize;
} }
max_frames = FFMAX(max_frames, frames); max_frames = FFMAX(max_frames, frames);
if(buf == p->buf) if(buf == buf0)
first_frames= frames; first_frames= frames;
} }
if (first_frames>=3) return AVPROBE_SCORE_MAX/2+1; if (first_frames>=3) return AVPROBE_SCORE_MAX/2+1;
......
...@@ -21,6 +21,7 @@ ...@@ -21,6 +21,7 @@
#include "libavcodec/bitstream.h" #include "libavcodec/bitstream.h"
#include "avformat.h" #include "avformat.h"
#include "id3v2.h"
#define MPC_FRAMESIZE 1152 #define MPC_FRAMESIZE 1152
#define DELAY_FRAMES 32 #define DELAY_FRAMES 32
...@@ -43,10 +44,12 @@ typedef struct { ...@@ -43,10 +44,12 @@ typedef struct {
static int mpc_probe(AVProbeData *p) static int mpc_probe(AVProbeData *p)
{ {
const uint8_t *d = p->buf; const uint8_t *d = p->buf;
if (ff_id3v2_match(d)) {
d += ff_id3v2_tag_len(d);
}
if (d+3 < p->buf+p->buf_size)
if (d[0] == 'M' && d[1] == 'P' && d[2] == '+' && (d[3] == 0x17 || d[3] == 0x7)) if (d[0] == 'M' && d[1] == 'P' && d[2] == '+' && (d[3] == 0x17 || d[3] == 0x7))
return AVPROBE_SCORE_MAX; return AVPROBE_SCORE_MAX;
if (d[0] == 'I' && d[1] == 'D' && d[2] == '3')
return AVPROBE_SCORE_MAX / 2;
return 0; return 0;
} }
......
...@@ -26,6 +26,7 @@ ...@@ -26,6 +26,7 @@
#include "libavcodec/bytestream.h" #include "libavcodec/bytestream.h"
#include "avformat.h" #include "avformat.h"
#include "raw.h" #include "raw.h"
#include "id3v2.h"
/* simple formats */ /* simple formats */
#if CONFIG_FLAC_MUXER #if CONFIG_FLAC_MUXER
...@@ -582,9 +583,15 @@ static int adts_aac_probe(AVProbeData *p) ...@@ -582,9 +583,15 @@ static int adts_aac_probe(AVProbeData *p)
{ {
int max_frames = 0, first_frames = 0; int max_frames = 0, first_frames = 0;
int fsize, frames; int fsize, frames;
uint8_t *buf0 = p->buf;
uint8_t *buf2; uint8_t *buf2;
uint8_t *buf = p->buf; uint8_t *buf;
uint8_t *end = buf + p->buf_size - 7; uint8_t *end = buf0 + p->buf_size - 7;
if (ff_id3v2_match(buf0)) {
buf0 += ff_id3v2_tag_len(buf0);
}
buf = buf0;
for(; buf < end; buf= buf2+1) { for(; buf < end; buf= buf2+1) {
buf2 = buf; buf2 = buf;
...@@ -599,7 +606,7 @@ static int adts_aac_probe(AVProbeData *p) ...@@ -599,7 +606,7 @@ static int adts_aac_probe(AVProbeData *p)
buf2 += fsize; buf2 += fsize;
} }
max_frames = FFMAX(max_frames, frames); max_frames = FFMAX(max_frames, frames);
if(buf == p->buf) if(buf == buf0)
first_frames= frames; first_frames= frames;
} }
if (first_frames>=3) return AVPROBE_SCORE_MAX/2+1; if (first_frames>=3) return AVPROBE_SCORE_MAX/2+1;
......
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