~medibuntu-maintainers/mplayer/medibuntu.precise

« back to all changes in this revision

Viewing changes to libmpdemux/demux_audio.c

  • Committer: Package Import Robot
  • Author(s): Reinhard Tartler
  • Date: 2012-01-12 22:23:28 UTC
  • mfrom: (0.4.7 sid)
  • mto: This revision was merged to the branch mainline in revision 76.
  • Revision ID: package-import@ubuntu.com-20120112222328-8jqdyodym3p84ygu
Tags: 2:1.0~rc4.dfsg1+svn34540-1
* New upstream snapshot
* upload to unstable

Show diffs side-by-side

added added

removed removed

Lines of Context:
260
260
}
261
261
#endif
262
262
 
 
263
/**
 
264
 * @brief Determine the number of frames of a file encoded with
 
265
 *        variable bitrate mode (VBR).
 
266
 *
 
267
 * @param s stream to be read
 
268
 * @param off offset in stream to start reading from
 
269
 *
 
270
 * @return 0 (error or no variable bitrate mode) or number of frames
 
271
 */
 
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}};
 
274
  unsigned int data;
 
275
  unsigned char hdr[4];
 
276
  int framesize, chans, spf, layer;
 
277
 
 
278
  if ((s->flags & MP_STREAM_SEEK) == MP_STREAM_SEEK) {
 
279
 
 
280
    if (!stream_seek(s, off)) return 0;
 
281
 
 
282
    data = stream_read_dword(s);
 
283
    hdr[0] = data >> 24;
 
284
    hdr[1] = data >> 16;
 
285
    hdr[2] = data >> 8;
 
286
    hdr[3] = data;
 
287
 
 
288
    if (!mp_check_mp3_header(data)) return 0;
 
289
 
 
290
    framesize = mp_get_mp3_header(hdr, &chans, NULL, &spf, &layer, NULL);
 
291
 
 
292
    if (framesize == -1 || layer != 3) return 0;
 
293
 
 
294
    /* Xing / Info (at variable position: 32, 17 or 9 bytes after header) */
 
295
 
 
296
    if (!stream_skip(s, xing_offset[spf < 1152][chans == 1])) return 0;
 
297
 
 
298
    data = stream_read_dword(s);
 
299
 
 
300
    if (data == MKBETAG('X','i','n','g') || data == MKBETAG('I','n','f','o')) {
 
301
      data = stream_read_dword(s);
 
302
 
 
303
      if (data & 0x1)                   // frames field is present
 
304
        return stream_read_dword(s);    // frames
 
305
    }
 
306
 
 
307
    /* VBRI (at fixed position: 32 bytes after header) */
 
308
 
 
309
    if (!stream_seek(s, off + 4 + 32)) return 0;
 
310
 
 
311
    data = stream_read_dword(s);
 
312
 
 
313
    if (data == MKBETAG('V','B','R','I')) {
 
314
      data = stream_read_word(s);
 
315
 
 
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
 
319
      }
 
320
    }
 
321
  }
 
322
 
 
323
  return 0;
 
324
}
 
325
 
263
326
static int demux_audio_open(demuxer_t* demuxer) {
264
327
  stream_t *s;
265
328
  sh_audio_t* sh_audio;
269
332
  // mp3_hdrs list is sorted first by next_frame_pos and then by frame_pos
270
333
  mp3_hdr_t *mp3_hdrs = NULL, *mp3_found = NULL;
271
334
  da_priv_t* priv;
 
335
  double duration;
 
336
  int found_WAVE = 0;
272
337
 
273
338
  s = demuxer->stream;
274
339
 
298
363
      len = (hdr[0]<<21) | (hdr[1]<<14) | (hdr[2]<<7) | hdr[3];
299
364
      stream_skip(s,len);
300
365
      step = 4;
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] == ' ' ) {
302
367
      frmt = WAV;
303
368
      break;
304
369
    } else if((mp3_flen = mp_get_mp3_header(hdr, &mp3_chans, &mp3_freq,
314
379
      if (!mp3_hdrs || mp3_hdrs->cons_hdrs < 3)
315
380
        break;
316
381
    }
 
382
    found_WAVE = hdr[0] == 'W' && hdr[1] == 'A' && hdr[2] == 'V' && hdr[3] == 'E';
317
383
    // Add here some other audio format detection
318
384
    if(step < HDR_SIZE)
319
385
      memmove(hdr,&hdr[step],HDR_SIZE-step);
332
398
  case MP3:
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;
348
415
    free(mp3_found);
349
416
    mp3_found = NULL;
350
417
    if(s->end_pos && (s->flags & MP_STREAM_SEEK) == MP_STREAM_SEEK) {
352
419
      stream_seek(s,s->end_pos-128);
353
420
      stream_read(s,tag,3);
354
421
      tag[3] = '\0';
355
 
      if(strcmp(tag,"TAG"))
356
 
        demuxer->movi_end = s->end_pos;
357
 
      else {
 
422
      if(!strcmp(tag,"TAG")) {
358
423
        char buf[31];
359
424
        uint8_t g;
360
425
        demuxer->movi_end = stream_tell(s)-3;
382
447
        demux_info_add(demuxer,"Genre",genres[g]);
383
448
      }
384
449
    }
 
450
    if (duration && demuxer->movi_end && demuxer->movi_end > demuxer->movi_start) sh_audio->wf->nAvgBytesPerSec = (demuxer->movi_end - demuxer->movi_start) / duration;
 
451
    sh_audio->i_bps = sh_audio->wf->nAvgBytesPerSec;
385
452
    break;
386
453
  case WAV: {
387
454
    unsigned int chunk_type;