History

high-level API passes test

lieff committed 8 years ago

Commit 45a1de91 parent 4b51e003 files · +87 −80Browse files

Unified · Split

3 files
  1. minimp3_ex.h +23 −11
  2. minimp3_test.c +63 −68
  3. scripts/build.sh +1 −1
minimp3_ex.h+23−11
@@ -11,7 +11,7 @@ · 10 unmodified lines
11typedef struct11typedef struct
12{12{
13 int16_t *buffer;13 int16_t *buffer;
14 size_t samples;14 size_t samples; /* channels included, byte size = samples*sizeof(int16_t) */
15 int channels, hz, layer, avg_bitrate_kbps;15 int channels, hz, layer, avg_bitrate_kbps;
16} mp3dec_file_info_t;16} mp3dec_file_info_t;
17 17
@@ -220,10 +220,12 @@ void mp3dec_load_buf(mp3dec_t *dec, const uint8_t *buf, size_t buf_size, mp3dec_ · 202 unmodified lines
220 } while (frame_info.frame_bytes);220 } while (frame_info.frame_bytes);
221 if (!samples)221 if (!samples)
222 return;222 return;
223 size_t samples_bytes = samples*frame_info.channels*2;223 info->samples = samples*frame_info.channels;
224 size_t allocated = (buf_size/frame_info.frame_bytes)*samples_bytes + MINIMP3_MAX_SAMPLES_PER_FRAME*2;224 size_t allocated = (buf_size/frame_info.frame_bytes)*info->samples*2 + MINIMP3_MAX_SAMPLES_PER_FRAME*2;
225 info->buffer = malloc(allocated);225 info->buffer = malloc(allocated);
226 memcpy(info->buffer, pcm, samples_bytes);226 memcpy(info->buffer, pcm, info->samples*2);
227 if (!info->buffer)
228 return;
227 /* save info */229 /* save info */
228 info->channels = frame_info.channels;230 info->channels = frame_info.channels;
229 info->hz = frame_info.hz;231 info->hz = frame_info.hz;
@@ -233,24 +235,26 @@ void mp3dec_load_buf(mp3dec_t *dec, const uint8_t *buf, size_t buf_size, mp3dec_ · 3 unmodified lines
233 /* decode rest frames */235 /* decode rest frames */
234 do236 do
235 {237 {
236 if ((allocated - samples_bytes) < MINIMP3_MAX_SAMPLES_PER_FRAME*2)238 if ((allocated - info->samples*2) < MINIMP3_MAX_SAMPLES_PER_FRAME*2)
237 {239 {
238 allocated *= 2;240 allocated *= 2;
239 info->buffer = realloc(info->buffer, allocated);241 info->buffer = realloc(info->buffer, allocated);
240 }242 }
241 samples = mp3dec_decode_frame(dec, buf, buf_size, (int16_t*)((int8_t *)info->buffer + samples_bytes), &frame_info);243 samples = mp3dec_decode_frame(dec, buf, buf_size, info->buffer + info->samples, &frame_info);
242 if (samples)244 if (samples)
243 {245 {
244 info->samples += samples;246 if (info->hz != frame_info.hz || info->layer != frame_info.layer)
247 break;
248 info->samples += samples*frame_info.channels;
245 avg_bitrate_kbps += frame_info.bitrate_kbps;249 avg_bitrate_kbps += frame_info.bitrate_kbps;
246 samples_bytes += samples*frame_info.channels*2;250 frames++;
247 }251 }
248 buf += frame_info.frame_bytes;252 buf += frame_info.frame_bytes;
249 buf_size -= frame_info.frame_bytes;253 buf_size -= frame_info.frame_bytes;
250 } while (frame_info.frame_bytes);254 } while (frame_info.frame_bytes);
251 /* reallocate to normal buffer size */255 /* reallocate to normal buffer size */
252 if (allocated != samples_bytes)256 if (allocated != info->samples*2)
253 info->buffer = realloc(info->buffer, samples_bytes);257 info->buffer = realloc(info->buffer, info->samples*2);
254 info->avg_bitrate_kbps = avg_bitrate_kbps/frames;258 info->avg_bitrate_kbps = avg_bitrate_kbps/frames;
255}259}
256 260
@@ -262,6 +266,7 @@ void mp3dec_iterate_buf(const uint8_t *buf, size_t buf_size, MP3D_ITERATE_CB cal · 5 unmodified lines
262 size_t id3v2size = mp3dec_skip_id3v2(buf, buf_size);266 size_t id3v2size = mp3dec_skip_id3v2(buf, buf_size);
263 if (id3v2size > buf_size)267 if (id3v2size > buf_size)
264 return;268 return;
269 const uint8_t *orig_buf = buf;
265 buf += id3v2size;270 buf += id3v2size;
266 buf_size -= id3v2size;271 buf_size -= id3v2size;
267 do272 do
@@ -274,7 +279,14 @@ void mp3dec_iterate_buf(const uint8_t *buf, size_t buf_size, MP3D_ITERATE_CB cal · 6 unmodified lines
274 continue;279 continue;
275 if (!frame_size)280 if (!frame_size)
276 break;281 break;
277 callback(user_data, buf + i, frame_size, i, &frame_info);282 const uint8_t *hdr = buf;
283 frame_info.channels = HDR_IS_MONO(hdr) ? 1 : 2;
284 frame_info.hz = hdr_sample_rate_hz(hdr);
285 frame_info.layer = 4 - HDR_GET_LAYER(hdr);
286 frame_info.bitrate_kbps = hdr_bitrate_kbps(hdr);
287
288 if (callback(user_data, hdr, frame_size, hdr - orig_buf, &frame_info))
289 break;
278 buf += frame_size;290 buf += frame_size;
279 buf_size -= frame_size;291 buf_size -= frame_size;
280 } while (1);292 } while (1);
minimp3_test.c+63−68
@@ -2,7 +2,7 @@ · 1 unmodified line
2/*#define MINIMP3_ONLY_SIMD*/2/*#define MINIMP3_ONLY_SIMD*/
3/*#define MINIMP3_NONSTANDARD_BUT_LOGICAL*/3/*#define MINIMP3_NONSTANDARD_BUT_LOGICAL*/
4#define MINIMP3_IMPLEMENTATION4#define MINIMP3_IMPLEMENTATION
5#include "minimp3.h"5#include "minimp3_ex.h"
6#include <stdio.h>6#include <stdio.h>
7#include <math.h>7#include <math.h>
8#include <string.h>8#include <string.h>
@@ -58,76 +58,81 @@ static unsigned char *preload(FILE *file, int *data_size) · 49 unmodified lines
58 return data;58 return data;
59}59}
60 60
61static void decode_file(const unsigned char *buf_mp3, int mp3_size, const unsigned char *buf_ref, int ref_size, FILE *file_out, const int wave_out)61#ifdef MP4_MODE
62typedef struct
62{63{
63 static mp3dec_t mp3d;64 mp3dec_t *mp3d;
64 mp3dec_frame_info_t info;65 mp3dec_file_info_t *info;
65 int i, data_bytes, samples, total_samples = 0, maxdiff = 0;66 size_t allocated;
66 double MSE = 0.0, psnr;67} frames_iterate_data;
67 68
68 if (mp3_size > 10 && !strncmp((char *)buf_mp3, "ID3", 3))69static int frames_iterate_cb(void *user_data, const uint8_t *frame, int frame_size, size_t offset, mp3dec_frame_info_t *info)
70{
71 (void)offset;
72 frames_iterate_data *d = user_data;
73 d->info->channels = info->channels;
74 d->info->hz = info->hz;
75 d->info->layer = info->layer;
76 /*printf("%d %d %d\n", frame_size, (int)offset, info->channels);*/
77 if ((d->allocated - d->info->samples*2) < MINIMP3_MAX_SAMPLES_PER_FRAME*2)
69 {78 {
70 int id3v2size = (((buf_mp3[6] & 0x7f) << 21) | ((buf_mp3[7] & 0x7f) << 14) |79 if (!d->allocated)
71 ((buf_mp3[8] & 0x7f) << 7) | (buf_mp3[9] & 0x7f)) + 10;80 d->allocated = 1024*1024;
72 if (mp3_size >= id3v2size)81 else
73 {82 d->allocated *= 2;
74 printf("info: skipping %d bytes of id3v2\n", id3v2size);83 d->info->buffer = realloc(d->info->buffer, d->allocated);
75 buf_mp3 += id3v2size;
76 mp3_size -= id3v2size;
77 }
78 }84 }
85 int samples = mp3dec_decode_frame(d->mp3d, frame, frame_size, d->info->buffer + d->info->samples, info);
86 if (samples)
87 {
88 d->info->samples += samples*info->channels;
89 }
90 return 0;
91}
92#endif
79 93
80 mp3dec_init(&mp3d);94static void decode_file(const char *input_file_name, const unsigned char *buf_ref, int ref_size, FILE *file_out, const int wave_out)
95{
96 mp3dec_t mp3d;
97 int i, data_bytes, total_samples = 0, maxdiff = 0;
98 double MSE = 0.0, psnr;
99
100 mp3dec_file_info_t info;
81 memset(&info, 0, sizeof(info));101 memset(&info, 0, sizeof(info));
102#ifdef MP4_MODE
103 frames_iterate_data d = { &mp3d, &info, 0 };
104 mp3dec_init(&mp3d);
105 if (mp3dec_iterate(input_file_name, frames_iterate_cb, &d))
106#else
107 if (mp3dec_load(&mp3d, input_file_name, &info))
108#endif
109 {
110 printf("error: file not found or read error");
111 exit(1);
112 }
82#ifndef MINIMP3_NO_WAV113#ifndef MINIMP3_NO_WAV
83 if (wave_out && file_out)114 if (wave_out && file_out)
84 fwrite(wav_header(0, 0, 0, 0), 1, 44, file_out);115 fwrite(wav_header(0, 0, 0, 0), 1, 44, file_out);
85#endif116#endif
86 do117 if (info.samples)
87 {118 {
88 short pcm[MINIMP3_MAX_SAMPLES_PER_FRAME];119 total_samples += info.samples;
89#ifdef MP4_MODE120 if (buf_ref)
90 int free_format_bytes = 0, frame_size = 0;
91 i = mp3d_find_frame(buf_mp3, mp3_size, &free_format_bytes, &frame_size);
92 buf_mp3 += i;
93 mp3_size -= i;
94 if (i && !frame_size)
95 {
96 printf("warning: skipping %d bytes, frame_size=%d\n", i, frame_size);
97 continue;
98 }
99 if (frame_size > mp3_size)
100 {
101 printf("error: demux mp3 frame failed: i=%d, frame_size=%d\n", i, frame_size);
102 exit(1);
103 }
104 if (!frame_size)
105 break;
106 samples = mp3dec_decode_frame(&mp3d, buf_mp3, frame_size, pcm, &info);
107#else
108 samples = mp3dec_decode_frame(&mp3d, buf_mp3, mp3_size, pcm, &info);
109#endif
110 if (samples)
111 {121 {
112 total_samples += samples*info.channels;122 int max_samples = MINIMP3_MIN((size_t)ref_size/2, info.samples);
113 if (buf_ref && ref_size >= samples*info.channels*2)123 for (i = 0; i < max_samples; i++)
114 {124 {
115 for (i = 0; i < samples*info.channels; i++)125 int MSEtemp = abs((int)info.buffer[i] - (int)(short)read16le(&buf_ref[i*sizeof(short)]));
116 {126 if (MSEtemp > maxdiff)
117 int MSEtemp = abs((int)pcm[i] - (int)(short)read16le(&buf_ref[i*sizeof(short)]));127 maxdiff = MSEtemp;
118 if (MSEtemp > maxdiff)128 MSE += (float)MSEtemp*(float)MSEtemp;
119 maxdiff = MSEtemp;
120 MSE += (float)MSEtemp*(float)MSEtemp;
121 }
122 buf_ref += samples*info.channels*2;
123 ref_size -= samples*info.channels*2;
124 }129 }
125 if (file_out)
126 fwrite(pcm, samples, 2*info.channels, file_out);
127 }130 }
128 buf_mp3 += info.frame_bytes;131 if (file_out)
129 mp3_size -= info.frame_bytes;132 fwrite(info.buffer, info.samples, sizeof(int16_t), file_out);
130 } while (info.frame_bytes);133 free(info.buffer);
134 }
135
131#ifndef LIBFUZZER136#ifndef LIBFUZZER
132 MSE /= total_samples ? total_samples : 1;137 MSE /= total_samples ? total_samples : 1;
133 if (0 == MSE)138 if (0 == MSE)
@@ -173,7 +178,7 @@ int main2(int argc, char *argv[]) · 39 unmodified lines
173int main(int argc, char *argv[])178int main(int argc, char *argv[])
174#endif179#endif
175{180{
176 int wave_out = 0, ref_size, mp3_size;181 int wave_out = 0, ref_size;
177 char *ref_file_name = (argc > 2) ? argv[2] : NULL;182 char *ref_file_name = (argc > 2) ? argv[2] : NULL;
178 char *output_file_name = (argc > 3) ? argv[3] : NULL;183 char *output_file_name = (argc > 3) ? argv[3] : NULL;
179 FILE *file_out = NULL;184 FILE *file_out = NULL;
@@ -200,17 +205,7 @@ int main(int argc, char *argv[]) · 20 unmodified lines
200 printf("error: no file names given\n");205 printf("error: no file names given\n");
201 return 1;206 return 1;
202 }207 }
203 FILE *file_mp3 = fopen(input_file_name, "rb");208 decode_file(input_file_name, buf_ref, ref_size, file_out, wave_out);
204 unsigned char *buf_mp3 = preload(file_mp3, &mp3_size);
205 if (file_mp3)
206 fclose(file_mp3);
207 if (!buf_mp3 || !mp3_size)
208 {
209 printf("error: no input data\n");
210 return 1;
211 }
212 decode_file(buf_mp3, mp3_size, buf_ref, ref_size, file_out, wave_out);
213 free(buf_mp3);
214#ifdef __AFL_HAVE_MANUAL_CONTROL209#ifdef __AFL_HAVE_MANUAL_CONTROL
215 }210 }
216#endif211#endif
scripts/build.sh+1−1
@@ -31,7 +31,7 @@ scripts/test.sh · 30 unmodified lines
31 31
32echo testing arm w/o neon...32echo testing arm w/o neon...
33arm-none-eabi-gcc -O2 -std=c89 -Wall -Wextra -Wmissing-prototypes -Werror -fno-asynchronous-unwind-tables -fno-stack-protector \33arm-none-eabi-gcc -O2 -std=c89 -Wall -Wextra -Wmissing-prototypes -Werror -fno-asynchronous-unwind-tables -fno-stack-protector \
34-mthumb -mcpu=cortex-m4 \34-mthumb -mcpu=arm9e \
35-ffunction-sections -fdata-sections -Wl,--gc-sections -o minimp3_arm minimp3_test.c --specs=rdimon.specs -lm35-ffunction-sections -fdata-sections -Wl,--gc-sections -o minimp3_arm minimp3_test.c --specs=rdimon.specs -lm
36qemu-arm ./minimp3_arm36qemu-arm ./minimp3_arm
37 37

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t