264
* @brief Determine the number of frames of a file encoded with
265
* variable bitrate mode (VBR).
267
* @param s stream to be read
268
* @param off offset in stream to start reading from
270
* @return 0 (error or no variable bitrate mode) or number of frames
272
static unsigned int mp3_vbr_frames(stream_t *s, off_t off) {
273
static const int xing_offset[2][2] = {{32, 17}, {17, 9}};
275
unsigned char hdr[4];
276
int framesize, chans, spf, layer;
278
if ((s->flags & MP_STREAM_SEEK) == MP_STREAM_SEEK) {
280
if (!stream_seek(s, off)) return 0;
282
data = stream_read_dword(s);
288
if (!mp_check_mp3_header(data)) return 0;
290
framesize = mp_get_mp3_header(hdr, &chans, NULL, &spf, &layer, NULL);
292
if (framesize == -1 || layer != 3) return 0;
294
/* Xing / Info (at variable position: 32, 17 or 9 bytes after header) */
296
if (!stream_skip(s, xing_offset[spf < 1152][chans == 1])) return 0;
298
data = stream_read_dword(s);
300
if (data == MKBETAG('X','i','n','g') || data == MKBETAG('I','n','f','o')) {
301
data = stream_read_dword(s);
303
if (data & 0x1) // frames field is present
304
return stream_read_dword(s); // frames
307
/* VBRI (at fixed position: 32 bytes after header) */
309
if (!stream_seek(s, off + 4 + 32)) return 0;
311
data = stream_read_dword(s);
313
if (data == MKBETAG('V','B','R','I')) {
314
data = stream_read_word(s);
316
if (data == 1) { // check version
317
if (!stream_skip(s, 8)) return 0; // skip delay, quality and bytes
318
return stream_read_dword(s); // frames
263
326
static int demux_audio_open(demuxer_t* demuxer) {
265
328
sh_audio_t* sh_audio;
298
363
len = (hdr[0]<<21) | (hdr[1]<<14) | (hdr[2]<<7) | hdr[3];
299
364
stream_skip(s,len);
301
} else if( hdr[0] == 'f' && hdr[1] == 'm' && hdr[2] == 't' && hdr[3] == ' ' ) {
366
} else if( found_WAVE && hdr[0] == 'f' && hdr[1] == 'm' && hdr[2] == 't' && hdr[3] == ' ' ) {
304
369
} else if((mp3_flen = mp_get_mp3_header(hdr, &mp3_chans, &mp3_freq,
333
399
sh_audio->format = (mp3_found->mpa_layer < 3 ? 0x50 : 0x55);
334
400
demuxer->movi_start = mp3_found->frame_pos;
401
demuxer->movi_end = s->end_pos;
335
402
next_frame_pos = mp3_found->next_frame_pos;
336
403
sh_audio->audio.dwSampleSize= 0;
337
404
sh_audio->audio.dwScale = mp3_found->mpa_spf;
344
411
sh_audio->wf->nBlockAlign = mp3_found->mpa_spf;
345
412
sh_audio->wf->wBitsPerSample = 16;
346
413
sh_audio->wf->cbSize = 0;
347
sh_audio->i_bps = sh_audio->wf->nAvgBytesPerSec;
414
duration = (double) mp3_vbr_frames(s, demuxer->movi_start) * mp3_found->mpa_spf / mp3_found->mp3_freq;
349
416
mp3_found = NULL;
350
417
if(s->end_pos && (s->flags & MP_STREAM_SEEK) == MP_STREAM_SEEK) {