Unified · Split
| @@ -127,10 +127,52 @@ static void mp3dec_skip_id3(const uint8_t **pbuf, size_t *pbuf_size) · 126 unmodified lines | |||
| 127 | *pbuf_size = buf_size; | 127 | *pbuf_size = buf_size; |
| 128 | } | 128 | } |
| 129 | 129 | ||
| 130 | static int mp3dec_check_vbrtag(const uint8_t *frame, int frame_size, uint32_t *frames, int *delay, int *padding) | ||
| 131 | { | ||
| 132 | int i; | ||
| 133 | static const char g_xing_tag[4] = { 'X', 'i', 'n', 'g' }; | ||
| 134 | static const char g_info_tag[4] = { 'I', 'n', 'f', 'o' }; | ||
| 135 | #define FRAMES_FLAG 1 | ||
| 136 | #define BYTES_FLAG 2 | ||
| 137 | #define TOC_FLAG 4 | ||
| 138 | #define VBR_SCALE_FLAG 8 | ||
| 139 | /* TODO: skip side-info? | ||
| 140 | / Side info offsets afrer header: | ||
| 141 | / Mono Stereo | ||
| 142 | / MPEG1 17 32 | ||
| 143 | / MPEG2 & 2.5 9 17*/ | ||
| 144 | for (i = 5; i < frame_size - 36; i++) | ||
| 145 | { | ||
| 146 | const uint8_t *tag = frame + i; | ||
| 147 | if (memcmp(g_xing_tag, tag, 4) && memcmp(g_info_tag, tag, 4)) | ||
| 148 | continue; | ||
| 149 | int flags = tag[7]; | ||
| 150 | if (!((flags & FRAMES_FLAG))) | ||
| 151 | break; | ||
| 152 | tag += 8; | ||
| 153 | (*frames) = (uint32_t)(tag[0] << 24) | (tag[1] << 16) | (tag[2] << 8) | tag[3]; | ||
| 154 | tag += 4; | ||
| 155 | if (flags & BYTES_FLAG) | ||
| 156 | tag += 4; | ||
| 157 | if (flags & TOC_FLAG) | ||
| 158 | tag += 100; | ||
| 159 | if (flags & VBR_SCALE_FLAG) | ||
| 160 | tag += 4; | ||
| 161 | tag += 21; | ||
| 162 | if (tag - frame + 2 >= frame_size) | ||
| 163 | break; | ||
| 164 | *delay = ((tag[0] << 4) | (tag[1] >> 4)) + (528 + 1); | ||
| 165 | *padding = (((tag[1] & 0xF) << 8) | tag[2]) - (528 + 1); | ||
| 166 | return 1; | ||
| 167 | } | ||
| 168 | return 0; | ||
| 169 | } | ||
| 170 | |||
| 130 | void mp3dec_load_buf(mp3dec_t *dec, const uint8_t *buf, size_t buf_size, mp3dec_file_info_t *info, MP3D_PROGRESS_CB progress_cb, void *user_data) | 171 | void mp3dec_load_buf(mp3dec_t *dec, const uint8_t *buf, size_t buf_size, mp3dec_file_info_t *info, MP3D_PROGRESS_CB progress_cb, void *user_data) |
| 131 | { | 172 | { |
| 173 | uint64_t detected_samples = 0; | ||
| 132 | size_t orig_buf_size = buf_size; | 174 | size_t orig_buf_size = buf_size; |
| 133 | mp3d_sample_t pcm[MINIMP3_MAX_SAMPLES_PER_FRAME]; | 175 | int to_skip = 0; |
| 134 | mp3dec_frame_info_t frame_info; | 176 | mp3dec_frame_info_t frame_info; |
| 135 | memset(info, 0, sizeof(*info)); | 177 | memset(info, 0, sizeof(*info)); |
| 136 | memset(&frame_info, 0, sizeof(frame_info)); | 178 | memset(&frame_info, 0, sizeof(frame_info)); |
| @@ -138,33 +180,57 @@ void mp3dec_load_buf(mp3dec_t *dec, const uint8_t *buf, size_t buf_size, mp3dec_ · 1 unmodified line | |||
| 138 | mp3dec_skip_id3(&buf, &buf_size); | 180 | mp3dec_skip_id3(&buf, &buf_size); |
| 139 | if (!buf_size) | 181 | if (!buf_size) |
| 140 | return; | 182 | return; |
| 141 | /* try to make allocation size assumption by first frame */ | 183 | /* try to make allocation size assumption by first frame or vbr tag */ |
| 142 | mp3dec_init(dec); | 184 | mp3dec_init(dec); |
| 143 | int samples; | 185 | int samples; |
| 144 | do | 186 | do |
| 145 | { | 187 | { |
| 146 | samples = mp3dec_decode_frame(dec, buf, MINIMP3_MIN(buf_size, (size_t)INT_MAX), pcm, &frame_info); | 188 | uint32_t frames; |
| 147 | buf += frame_info.frame_bytes; | 189 | int delay, padding, free_format_bytes = 0, frame_size = 0; |
| 148 | buf_size -= frame_info.frame_bytes; | 190 | int i = mp3d_find_frame(buf, buf_size, &free_format_bytes, &frame_size); |
| 149 | if (samples) | 191 | buf += i; |
| 150 | break; | 192 | buf_size -= i; |
| 151 | } while (frame_info.frame_bytes); | 193 | if (i && !frame_size) |
| 152 | if (!samples) | 194 | continue; |
| 153 | return; | 195 | if (!frame_size) |
| 154 | samples *= frame_info.channels; | 196 | return; |
| 155 | size_t allocated = (buf_size/frame_info.frame_bytes)*samples*sizeof(mp3d_sample_t) + MINIMP3_MAX_SAMPLES_PER_FRAME*sizeof(mp3d_sample_t); | 197 | const uint8_t *hdr = buf; |
| 198 | frame_info.channels = HDR_IS_MONO(hdr) ? 1 : 2; | ||
| 199 | frame_info.hz = hdr_sample_rate_hz(hdr); | ||
| 200 | frame_info.layer = 4 - HDR_GET_LAYER(hdr); | ||
| 201 | frame_info.bitrate_kbps = hdr_bitrate_kbps(hdr); | ||
| 202 | frame_info.frame_bytes = frame_size; | ||
| 203 | samples = hdr_frame_samples(hdr)*frame_info.channels; | ||
| 204 | if (mp3dec_check_vbrtag(hdr, frame_size, &frames, &delay, &padding)) | ||
| 205 | { | ||
| 206 | padding *= frame_info.channels; | ||
| 207 | to_skip = delay*frame_info.channels; | ||
| 208 | detected_samples = samples*(uint64_t)frames; | ||
| 209 | if (detected_samples >= (uint64_t)to_skip) | ||
| 210 | detected_samples -= to_skip; | ||
| 211 | if (padding > 0 && detected_samples >= (uint64_t)padding) | ||
| 212 | detected_samples -= padding; | ||
| 213 | if (!detected_samples) | ||
| 214 | return; | ||
| 215 | buf += frame_size; | ||
| 216 | buf_size -= frame_size; | ||
| 217 | } | ||
| 218 | break; | ||
| 219 | } while(1); | ||
| 220 | size_t allocated = MINIMP3_MAX_SAMPLES_PER_FRAME*sizeof(mp3d_sample_t); | ||
| 221 | if (detected_samples) | ||
| 222 | allocated += detected_samples*sizeof(mp3d_sample_t); | ||
| 223 | else | ||
| 224 | allocated += (buf_size/frame_info.frame_bytes)*samples*sizeof(mp3d_sample_t); | ||
| 156 | info->buffer = (mp3d_sample_t*)malloc(allocated); | 225 | info->buffer = (mp3d_sample_t*)malloc(allocated); |
| 157 | if (!info->buffer) | 226 | if (!info->buffer) |
| 158 | return; | 227 | return; |
| 159 | info->samples = samples; | ||
| 160 | memcpy(info->buffer, pcm, info->samples*sizeof(mp3d_sample_t)); | ||
| 161 | /* save info */ | 228 | /* save info */ |
| 162 | info->channels = frame_info.channels; | 229 | info->channels = frame_info.channels; |
| 163 | info->hz = frame_info.hz; | 230 | info->hz = frame_info.hz; |
| 164 | info->layer = frame_info.layer; | 231 | info->layer = frame_info.layer; |
| 165 | size_t avg_bitrate_kbps = frame_info.bitrate_kbps; | 232 | /* decode all frames */ |
| 166 | size_t frames = 1; | 233 | size_t avg_bitrate_kbps = 0, frames = 0; |
| 167 | /* decode rest frames */ | ||
| 168 | int frame_bytes; | 234 | int frame_bytes; |
| 169 | do | 235 | do |
| 170 | { | 236 | { |
| @@ -187,17 +253,28 @@ void mp3dec_load_buf(mp3dec_t *dec, const uint8_t *buf, size_t buf_size, mp3dec_ · 16 unmodified lines | |||
| 187 | #else | 253 | #else |
| 188 | break; | 254 | break; |
| 189 | #endif | 255 | #endif |
| 190 | info->samples += samples*frame_info.channels; | 256 | samples *= frame_info.channels; |
| 257 | if (to_skip) | ||
| 258 | { | ||
| 259 | size_t skip = MINIMP3_MIN(samples, to_skip); | ||
| 260 | to_skip -= skip; | ||
| 261 | samples -= skip; | ||
| 262 | memmove(info->buffer, info->buffer + skip, samples); | ||
| 263 | } | ||
| 264 | info->samples += samples; | ||
| 191 | avg_bitrate_kbps += frame_info.bitrate_kbps; | 265 | avg_bitrate_kbps += frame_info.bitrate_kbps; |
| 192 | frames++; | 266 | frames++; |
| 193 | if (progress_cb) | 267 | if (progress_cb) |
| 194 | progress_cb(user_data, orig_buf_size, orig_buf_size - buf_size, &frame_info); | 268 | progress_cb(user_data, orig_buf_size, orig_buf_size - buf_size, &frame_info); |
| 195 | } | 269 | } |
| 196 | } while (frame_bytes); | 270 | } while (frame_bytes); |
| 271 | if (detected_samples) | ||
| 272 | info->samples = detected_samples; | ||
| 197 | /* reallocate to normal buffer size */ | 273 | /* reallocate to normal buffer size */ |
| 198 | if (allocated != info->samples*sizeof(mp3d_sample_t)) | 274 | if (allocated != info->samples*sizeof(mp3d_sample_t)) |
| 199 | info->buffer = (mp3d_sample_t*)realloc(info->buffer, info->samples*sizeof(mp3d_sample_t)); | 275 | info->buffer = (mp3d_sample_t*)realloc(info->buffer, info->samples*sizeof(mp3d_sample_t)); |
| 200 | info->avg_bitrate_kbps = avg_bitrate_kbps/frames; | 276 | if (frames) |
| 277 | info->avg_bitrate_kbps = avg_bitrate_kbps/frames; | ||
| 201 | } | 278 | } |
| 202 | 279 | ||
| 203 | size_t mp3dec_iterate_buf(const uint8_t *buf, size_t buf_size, MP3D_ITERATE_CB callback, void *user_data) | 280 | size_t mp3dec_iterate_buf(const uint8_t *buf, size_t buf_size, MP3D_ITERATE_CB callback, void *user_data) |
| @@ -241,61 +318,29 @@ size_t mp3dec_iterate_buf(const uint8_t *buf, size_t buf_size, MP3D_ITERATE_CB c · 37 unmodified lines | |||
| 241 | 318 | ||
| 242 | static int mp3dec_load_index(void *user_data, const uint8_t *frame, int frame_size, int free_format_bytes, size_t buf_size, size_t offset, mp3dec_frame_info_t *info) | 319 | static int mp3dec_load_index(void *user_data, const uint8_t *frame, int frame_size, int free_format_bytes, size_t buf_size, size_t offset, mp3dec_frame_info_t *info) |
| 243 | { | 320 | { |
| 244 | static const char g_xing_tag[4] = { 'X', 'i', 'n', 'g' }; | ||
| 245 | static const char g_info_tag[4] = { 'I', 'n', 'f', 'o' }; | ||
| 246 | mp3dec_frame_t *idx_frame; | 321 | mp3dec_frame_t *idx_frame; |
| 247 | mp3dec_ex_t *dec = (mp3dec_ex_t *)user_data; | 322 | mp3dec_ex_t *dec = (mp3dec_ex_t *)user_data; |
| 248 | if (!dec->index.frames && !dec->vbr_tag_found) | 323 | if (!dec->index.frames && !dec->vbr_tag_found) |
| 249 | { /* detect VBR tag and try to avoid full scan */ | 324 | { /* detect VBR tag and try to avoid full scan */ |
| 250 | int i; | 325 | uint32_t frames; |
| 326 | int delay, padding; | ||
| 251 | dec->info = *info; | 327 | dec->info = *info; |
| 252 | dec->start_offset = dec->offset = offset; | 328 | dec->start_offset = dec->offset = offset; |
| 253 | dec->end_offset = offset + buf_size; | 329 | dec->end_offset = offset + buf_size; |
| 254 | dec->free_format_bytes = free_format_bytes; /* should not change */ | 330 | dec->free_format_bytes = free_format_bytes; /* should not change */ |
| 255 | /* TODO: skip side-info? | 331 | if (mp3dec_check_vbrtag(frame, frame_size, &frames, &delay, &padding)) |
| 256 | / Side info offsets afrer header: | ||
| 257 | / Mono Stereo | ||
| 258 | / MPEG1 17 32 | ||
| 259 | / MPEG2 & 2.5 9 17*/ | ||
| 260 | for (i = 5; i < frame_size - 36; i++) | ||
| 261 | { | 332 | { |
| 262 | const uint8_t *tag = frame + i; | 333 | padding *= info->channels; |
| 263 | if (!memcmp(g_xing_tag, tag, 4) || !memcmp(g_info_tag, tag, 4)) | 334 | dec->start_delay = dec->to_skip = delay*info->channels; |
| 264 | { | 335 | dec->samples = hdr_frame_samples(frame)*info->channels*(uint64_t)frames; |
| 265 | #define FRAMES_FLAG 1 | 336 | if (dec->samples >= (uint64_t)dec->start_delay) |
| 266 | #define BYTES_FLAG 2 | 337 | dec->samples -= dec->start_delay; |
| 267 | #define TOC_FLAG 4 | 338 | if (padding > 0 && dec->samples >= (uint64_t)padding) |
| 268 | #define VBR_SCALE_FLAG 8 | 339 | dec->samples -= padding; |
| 269 | int flags = tag[7], delay, padding; | 340 | dec->detected_samples = dec->samples; |
| 270 | uint32_t frames; | 341 | dec->start_offset = dec->offset = offset + frame_size; |
| 271 | if (!((flags & FRAMES_FLAG))) | 342 | dec->vbr_tag_found = 1; |
| 272 | break; | 343 | return 1; |
| 273 | tag += 8; | ||
| 274 | frames = (uint32_t)(tag[0] << 24) | (tag[1] << 16) | (tag[2] << 8) | tag[3]; | ||
| 275 | tag += 4; | ||
| 276 | if (flags & BYTES_FLAG) | ||
| 277 | tag += 4; | ||
| 278 | if (flags & TOC_FLAG) | ||
| 279 | tag += 100; | ||
| 280 | if (flags & VBR_SCALE_FLAG) | ||
| 281 | tag += 4; | ||
| 282 | tag += 21; | ||
| 283 | if (tag - frame + 2 >= frame_size) | ||
| 284 | break; | ||
| 285 | delay = (((tag[0] << 4) | (tag[1] >> 4)) + (528 + 1))*info->channels; | ||
| 286 | padding = ((((tag[1] & 0xF) << 8) | tag[2]) - (528 + 1))*info->channels; | ||
| 287 | |||
| 288 | dec->start_delay = dec->to_skip = delay; | ||
| 289 | dec->samples = hdr_frame_samples(frame)*info->channels*(uint64_t)frames; | ||
| 290 | if (dec->samples >= (uint64_t)dec->start_delay) | ||
| 291 | dec->samples -= dec->start_delay; | ||
| 292 | if (padding > 0 && dec->samples >= (uint64_t)padding) | ||
| 293 | dec->samples -= padding; | ||
| 294 | dec->detected_samples = dec->samples; | ||
| 295 | dec->start_offset = dec->offset = offset + frame_size; | ||
| 296 | dec->vbr_tag_found = 1; | ||
| 297 | return 1; | ||
| 298 | } | ||
| 299 | } | 344 | } |
| 300 | } | 345 | } |
| 301 | if (dec->index.num_frames + 1 > dec->index.capacity) | 346 | if (dec->index.num_frames + 1 > dec->index.capacity) |
| @@ -13,7 +13,7 @@ vectors/l3-sin1k0db.bit vectors/l3-test45.bit vectors/l3-test46.bit vectors/M2L3 · 12 unmodified lines | |||
| 13 | vectors/M2L3_bitrate_22_all.bit vectors/M2L3_bitrate_24_all.bit vectors/M2L3_compl24.bit vectors/M2L3_noise.bit \ | 13 | vectors/M2L3_bitrate_22_all.bit vectors/M2L3_bitrate_24_all.bit vectors/M2L3_compl24.bit vectors/M2L3_noise.bit \ |
| 14 | vectors/l3-nonstandard-id3v1.bit vectors/l3-nonstandard-id3v2.bit vectors/l1-fl1.bit vectors/l2-fl10.bit" | 14 | vectors/l3-nonstandard-id3v1.bit vectors/l3-nonstandard-id3v2.bit vectors/l1-fl1.bit vectors/l2-fl10.bit" |
| 15 | if [ "$MODE" = "2" ]; then | 15 | if [ "$MODE" = "2" ]; then |
| 16 | VECTORS+=" vectors/vbrtag/l3-nonstandard-sin1k0db_lame_tag.bit" | 16 | VECTORS+=" vectors/l3-nonstandard-sin1k0db_lame_vbrtag.bit" |
| 17 | fi | 17 | fi |
| 18 | 18 | ||
| 19 | set +e | 19 | set +e |
File renamed without changes.
File renamed without changes.