From a1a03deed278a865bdc7d3394cda838543c8b03c Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Tue, 13 Apr 2010 07:51:29 +0200 Subject: decoder/mad: properly calculate ID3 size without libid3tag Without libid3tag, we were trying to skip the ID3 frame (since 0.15.2). Its length however was not calculated at all, we were just dropping everything from the current input buffer. This lead to the first few seconds of the file being skipped. This patch attempts to calculate the ID3v2 frame size with the formula from: http://www.id3.org/id3v2.4.0-structure 3.1 and 6.2 --- NEWS | 2 ++ src/decoder/mad_plugin.c | 30 +++++++++++++++++++++++++----- 2 files changed, 27 insertions(+), 5 deletions(-) diff --git a/NEWS b/NEWS index 70179b14d..b69bd18f1 100644 --- a/NEWS +++ b/NEWS @@ -1,4 +1,6 @@ ver 0.15.10 (2010/??/??) +* decoders: + - mad: properly calculate ID3 size without libid3tag ver 0.15.9 (2010/03/21) diff --git a/src/decoder/mad_plugin.c b/src/decoder/mad_plugin.c index 7cc78a0d2..1bda418e0 100644 --- a/src/decoder/mad_plugin.c +++ b/src/decoder/mad_plugin.c @@ -425,7 +425,27 @@ static void mp3_parse_id3(struct mp3_data *data, size_t tagsize, /* This code is enabled when libid3tag is disabled. Instead of parsing the ID3 frame, it just skips it. */ - mad_stream_skip(&data->stream, tagsize); + size_t count = data->stream.bufend - data->stream.this_frame; + + if (tagsize <= count) { + mad_stream_skip(&data->stream, tagsize); + } else { + mad_stream_skip(&data->stream, count); + + while (count < tagsize) { + size_t len = tagsize - count; + if (len > sizeof(buffer)) + len = sizeof(buffer); + + char ignored[1024]; + len = decoder_read(data->decoder, data->input_stream, + ignored, len); + if (len == 0) + break; + else + count += len; + } + } #endif } @@ -433,16 +453,16 @@ static void mp3_parse_id3(struct mp3_data *data, size_t tagsize, /** * This function emulates libid3tag when it is disabled. Instead of * doing a real analyzation of the frame, it just checks whether the - * frame begins with the string "ID3". If so, it returns the full - * length. + * frame begins with the string "ID3". If so, it returns the length + * of the ID3 frame. */ static signed long id3_tag_query(const void *p0, size_t length) { const char *p = p0; - return length > 3 && memcmp(p, "ID3", 3) == 0 - ? length + return length >= 10 && memcmp(p, "ID3", 3) == 0 + ? (p[8] << 7) + p[9] + 10 : 0; } #endif /* !HAVE_ID3TAG */ -- cgit v1.2.3