Rationale: recent libavformat versions now assume there can be an ID3
header in _anything_ and try to skip it before real probing, instead of
assuming anything with and ID3 header is an mp3. This leads to problems
with identifying mp3 files with ID3v2 headers bigger than our current
buffer size.

Patch shamelessly adapted from MPlayer's demux_lavf
---
 src/decoder/ffmpeg_decoder_plugin.c |   42 +++++++++++++++++++---------------
 1 files changed, 23 insertions(+), 19 deletions(-)

diff --git a/src/decoder/ffmpeg_decoder_plugin.c 
b/src/decoder/ffmpeg_decoder_plugin.c
index d473565..b6fed88 100644
--- a/src/decoder/ffmpeg_decoder_plugin.c
+++ b/src/decoder/ffmpeg_decoder_plugin.c
@@ -251,30 +251,34 @@ static AVInputFormat *
 ffmpeg_probe(struct decoder *decoder, struct input_stream *is)
 {
        enum {
-               BUFFER_SIZE = 16384,
-               PADDING = 16,
+               PROBE_INITIAL_SIZE = 16384,
+               PROBE_MAX_SIZE     = 1024*1024,
        };
-
-       unsigned char *buffer = g_malloc(BUFFER_SIZE);
-       size_t nbytes = decoder_read(decoder, is, buffer, BUFFER_SIZE);
-       if (nbytes <= PADDING || !input_stream_seek(is, 0, SEEK_SET, NULL)) {
-               g_free(buffer);
-               return NULL;
-       }
-
-       /* some ffmpeg parsers (e.g. ac3_parser.c) read a few bytes
-          beyond the declared buffer limit, which makes valgrind
-          angry; this workaround removes some padding from the buffer
-          size */
-       nbytes -= PADDING;
-
+       unsigned char *buffer  = g_malloc(PROBE_MAX_SIZE + 
FF_INPUT_BUFFER_PADDING_SIZE);
+       size_t read_size       = PROBE_INITIAL_SIZE;
+       size_t probe_data_size = 0;
+       int score;
        AVProbeData avpd = {
                .buf = buffer,
-               .buf_size = nbytes,
                .filename = is->uri,
        };
+       AVInputFormat *format;
 
-       AVInputFormat *format = av_probe_input_format(&avpd, true);
+       do {
+               read_size = decoder_read(decoder, is, buffer + probe_data_size, 
read_size);
+               if (read_size <= FF_INPUT_BUFFER_PADDING_SIZE ||
+                       !input_stream_seek(is, 0, SEEK_SET, NULL)) {
+                       g_free(buffer);
+                       return NULL;
+               }
+               probe_data_size += read_size;
+               avpd.buf_size    = probe_data_size;
+
+               score = 0;
+               format = av_probe_input_format2(&avpd, true, &score);
+               read_size = FFMIN(2*read_size, PROBE_MAX_SIZE - 
probe_data_size);
+       } while (score <= AVPROBE_SCORE_MAX / 4 && read_size > 0 &&
+                        probe_data_size < PROBE_MAX_SIZE);
        g_free(buffer);
 
        return format;
-- 
1.7.2.3


------------------------------------------------------------------------------
Nokia and AT&T present the 2010 Calling All Innovators-North America contest
Create new apps & games for the Nokia N8 for consumers in  U.S. and Canada
$10 million total in prizes - $4M cash, 500 devices, nearly $6M in marketing
Develop with Nokia Qt SDK, Web Runtime, or Java and Publish to Ovi Store 
http://p.sf.net/sfu/nokia-dev2dev
_______________________________________________
Musicpd-dev-team mailing list
Musicpd-dev-team@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/musicpd-dev-team

Reply via email to