[mp3_afh]: Ignore junk at the end of an mp3 file.
authorAndre Noll <maan@systemlinux.org>
Thu, 23 Apr 2009 11:39:04 +0000 (13:39 +0200)
committerAndre Noll <maan@systemlinux.org>
Thu, 23 Apr 2009 11:39:04 +0000 (13:39 +0200)
There are mp3 files containing large areas of zeros at the end of the
file. The old code in mp3_afh.c would include these zeros in the last
chunk of the file.

This leads to unnecessary network traffic as including this area in
a chunk means that useless data is going to be sent to the client.
More importantly, it causes the udp sender to bail out because such
large chunks can not be fec-encoded, even with the maximal number
of slices.

This patch uses frame_start+frame_length instead of the file size as
the end of the last chunk which avoids this particular problem.

mp3_afh.c

index 8eec436cffd3fed1c3f8c2f59a7468ebc17c7788..c62a523af473b6fe8cc215545d878ef7f5752547 100644 (file)
--- a/mp3_afh.c
+++ b/mp3_afh.c
@@ -395,7 +395,7 @@ static int mp3_read_info(unsigned char *map, size_t numbytes, int fd,
                struct afh_info *afhi)
 {
        uint64_t freq_sum = 0, br_sum = 0;
-       int ret, len = 0, old_br = -1, vbr = 0;
+       int fl = 0, ret, len = 0, old_br = -1, vbr = 0;
        struct timeval total_time = {0, 0};
        unsigned chunk_table_size = 1000; /* gets increased on demand */
        off_t fpos = 0;
@@ -406,12 +406,20 @@ static int mp3_read_info(unsigned char *map, size_t numbytes, int fd,
        afhi->chunk_table = para_malloc(chunk_table_size * sizeof(uint32_t));
        taginfo = mp3_get_id3(map, numbytes, fd);
        while (1) {
-               int freq, br, fl;
+               int freq, br;
                struct timeval tmp, cct; /* current chunk time */
                fpos += len;
                len = find_valid_start(map, numbytes, &fpos, &header);
-               if (len <= 0)
+               if (len <= 0) {
+                       uint32_t end;
+                       ret = -E_MP3_INFO;
+                       if (!afhi->chunks_total)
+                               goto err_out;
+                       end = afhi->chunk_table[afhi->chunks_total - 1] + fl;
+                       afhi->chunk_table[afhi->chunks_total]
+                               = PARA_MIN(end, numbytes);
                        break;
+               }
                ret = header_frequency(&header);
                if (ret < 0)
                        continue;
@@ -443,9 +451,8 @@ static int mp3_read_info(unsigned char *map, size_t numbytes, int fd,
                old_br = br;
        }
        ret = -E_MP3_INFO;
-       if (!afhi->chunks_total || !freq_sum || !br_sum)
+       if (!freq_sum || !br_sum)
                goto err_out;
-       afhi->chunk_table[afhi->chunks_total] = numbytes - 1;
        afhi->bitrate = br_sum / afhi->chunks_total;
        afhi->frequency = freq_sum / afhi->chunks_total;
        afhi->channels = header_channels(&header);