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
1111 typedef struct
1212 {
1313 int16_t *buffer;
14− size_t samples;
14+ size_t samples; /* channels included, byte size = samples*sizeof(int16_t) */
1515 int channels, hz, layer, avg_bitrate_kbps;
1616 } mp3dec_file_info_t;
1717
@@ -220,10 +220,12 @@ void mp3dec_load_buf(mp3dec_t *dec, const uint8_t *buf, size_t buf_size, mp3dec_ · 202 unmodified lines
220220 } while (frame_info.frame_bytes);
221221 if (!samples)
222222 return;
223− size_t samples_bytes = samples*frame_info.channels*2;
224− size_t allocated = (buf_size/frame_info.frame_bytes)*samples_bytes + MINIMP3_MAX_SAMPLES_PER_FRAME*2;
223+ info->samples = samples*frame_info.channels;
224+ size_t allocated = (buf_size/frame_info.frame_bytes)*info->samples*2 + MINIMP3_MAX_SAMPLES_PER_FRAME*2;
225225 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;
227229 /* save info */
228230 info->channels = frame_info.channels;
229231 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
233235 /* decode rest frames */
234236 do
235237 {
236− if ((allocated - samples_bytes) < MINIMP3_MAX_SAMPLES_PER_FRAME*2)
238+ if ((allocated - info->samples*2) < MINIMP3_MAX_SAMPLES_PER_FRAME*2)
237239 {
238240 allocated *= 2;
239241 info->buffer = realloc(info->buffer, allocated);
240242 }
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);
242244 if (samples)
243245 {
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;
245249 avg_bitrate_kbps += frame_info.bitrate_kbps;
246− samples_bytes += samples*frame_info.channels*2;
250+ frames++;
247251 }
248252 buf += frame_info.frame_bytes;
249253 buf_size -= frame_info.frame_bytes;
250254 } while (frame_info.frame_bytes);
251255 /* reallocate to normal buffer size */
252− if (allocated != samples_bytes)
253− info->buffer = realloc(info->buffer, samples_bytes);
256+ if (allocated != info->samples*2)
257+ info->buffer = realloc(info->buffer, info->samples*2);
254258 info->avg_bitrate_kbps = avg_bitrate_kbps/frames;
255259 }
256260
@@ -262,6 +266,7 @@ void mp3dec_iterate_buf(const uint8_t *buf, size_t buf_size, MP3D_ITERATE_CB cal · 5 unmodified lines
262266 size_t id3v2size = mp3dec_skip_id3v2(buf, buf_size);
263267 if (id3v2size > buf_size)
264268 return;
269+ const uint8_t *orig_buf = buf;
265270 buf += id3v2size;
266271 buf_size -= id3v2size;
267272 do
@@ -274,7 +279,14 @@ void mp3dec_iterate_buf(const uint8_t *buf, size_t buf_size, MP3D_ITERATE_CB cal · 6 unmodified lines
274279 continue;
275280 if (!frame_size)
276281 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;
278290 buf += frame_size;
279291 buf_size -= frame_size;
280292 } while (1);
minimp3_test.c+63−68
@@ -2,7 +2,7 @@ · 1 unmodified line
22 /*#define MINIMP3_ONLY_SIMD*/
33 /*#define MINIMP3_NONSTANDARD_BUT_LOGICAL*/
44 #define MINIMP3_IMPLEMENTATION
5−#include "minimp3.h"
5+#include "minimp3_ex.h"
66 #include <stdio.h>
77 #include <math.h>
88 #include <string.h>
@@ -58,76 +58,81 @@ static unsigned char *preload(FILE *file, int *data_size) · 49 unmodified lines
5858 return data;
5959 }
6060
61−static 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
62+typedef struct
6263 {
63− static mp3dec_t mp3d;
64− mp3dec_frame_info_t info;
65− int i, data_bytes, samples, total_samples = 0, maxdiff = 0;
66− double MSE = 0.0, psnr;
64+ mp3dec_t *mp3d;
65+ mp3dec_file_info_t *info;
66+ size_t allocated;
67+} frames_iterate_data;
6768
68− if (mp3_size > 10 && !strncmp((char *)buf_mp3, "ID3", 3))
69+static 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)
6978 {
70− int id3v2size = (((buf_mp3[6] & 0x7f) << 21) | ((buf_mp3[7] & 0x7f) << 14) |
71− ((buf_mp3[8] & 0x7f) << 7) | (buf_mp3[9] & 0x7f)) + 10;
72− if (mp3_size >= id3v2size)
73− {
74− printf("info: skipping %d bytes of id3v2\n", id3v2size);
75− buf_mp3 += id3v2size;
76− mp3_size -= id3v2size;
77− }
79+ if (!d->allocated)
80+ d->allocated = 1024*1024;
81+ else
82+ d->allocated *= 2;
83+ d->info->buffer = realloc(d->info->buffer, d->allocated);
7884 }
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
7993
80− mp3dec_init(&mp3d);
94+static 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;
81101 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+ }
82113 #ifndef MINIMP3_NO_WAV
83114 if (wave_out && file_out)
84115 fwrite(wav_header(0, 0, 0, 0), 1, 44, file_out);
85116 #endif
86− do
117+ if (info.samples)
87118 {
88− short pcm[MINIMP3_MAX_SAMPLES_PER_FRAME];
89−#ifdef MP4_MODE
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)
119+ total_samples += info.samples;
120+ if (buf_ref)
111121 {
112− total_samples += samples*info.channels;
113− if (buf_ref && ref_size >= samples*info.channels*2)
122+ int max_samples = MINIMP3_MIN((size_t)ref_size/2, info.samples);
123+ for (i = 0; i < max_samples; i++)
114124 {
115− for (i = 0; i < samples*info.channels; i++)
116− {
117− int MSEtemp = abs((int)pcm[i] - (int)(short)read16le(&buf_ref[i*sizeof(short)]));
118− if (MSEtemp > maxdiff)
119− maxdiff = MSEtemp;
120− MSE += (float)MSEtemp*(float)MSEtemp;
121− }
122− buf_ref += samples*info.channels*2;
123− ref_size -= samples*info.channels*2;
125+ int MSEtemp = abs((int)info.buffer[i] - (int)(short)read16le(&buf_ref[i*sizeof(short)]));
126+ if (MSEtemp > maxdiff)
127+ maxdiff = MSEtemp;
128+ MSE += (float)MSEtemp*(float)MSEtemp;
124129 }
125− if (file_out)
126− fwrite(pcm, samples, 2*info.channels, file_out);
127130 }
128− buf_mp3 += info.frame_bytes;
129− mp3_size -= info.frame_bytes;
130− } while (info.frame_bytes);
131+ if (file_out)
132+ fwrite(info.buffer, info.samples, sizeof(int16_t), file_out);
133+ free(info.buffer);
134+ }
135+
131136 #ifndef LIBFUZZER
132137 MSE /= total_samples ? total_samples : 1;
133138 if (0 == MSE)
@@ -173,7 +178,7 @@ int main2(int argc, char *argv[]) · 39 unmodified lines
173178 int main(int argc, char *argv[])
174179 #endif
175180 {
176− int wave_out = 0, ref_size, mp3_size;
181+ int wave_out = 0, ref_size;
177182 char *ref_file_name = (argc > 2) ? argv[2] : NULL;
178183 char *output_file_name = (argc > 3) ? argv[3] : NULL;
179184 FILE *file_out = NULL;
@@ -200,17 +205,7 @@ int main(int argc, char *argv[]) · 20 unmodified lines
200205 printf("error: no file names given\n");
201206 return 1;
202207 }
203− FILE *file_mp3 = fopen(input_file_name, "rb");
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);
208+ decode_file(input_file_name, buf_ref, ref_size, file_out, wave_out);
214209 #ifdef __AFL_HAVE_MANUAL_CONTROL
215210 }
216211 #endif
scripts/build.sh+1−1
@@ -31,7 +31,7 @@ scripts/test.sh · 30 unmodified lines
3131
3232 echo testing arm w/o neon...
3333 arm-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 \
3535 -ffunction-sections -fdata-sections -Wl,--gc-sections -o minimp3_arm minimp3_test.c --specs=rdimon.specs -lm
3636 qemu-arm ./minimp3_arm
3737

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