Mercurial > libavformat.hg
comparison mp3.c @ 4148:33f55d10246d libavformat
If we find a VBR tag at the beginning of the file don't attempt to
parse it as a valid frame.
patch by (Yoav Steinberg yoav out monfort in co in il)
author | michael |
---|---|
date | Sun, 04 Jan 2009 16:23:18 +0000 |
parents | bfc790ab375f |
children | c3102b189cb6 |
comparison
equal
deleted
inserted
replaced
4147:b3d75fa26b5c | 4148:33f55d10246d |
---|---|
400 } | 400 } |
401 | 401 |
402 /** | 402 /** |
403 * Try to find Xing/Info/VBRI tags and compute duration from info therein | 403 * Try to find Xing/Info/VBRI tags and compute duration from info therein |
404 */ | 404 */ |
405 static void mp3_parse_vbr_tags(AVFormatContext *s, AVStream *st, int64_t base) | 405 static int mp3_parse_vbr_tags(AVFormatContext *s, AVStream *st, int64_t base) |
406 { | 406 { |
407 uint32_t v, spf; | 407 uint32_t v, spf; |
408 int frames = -1; /* Total number of frames in file */ | 408 int frames = -1; /* Total number of frames in file */ |
409 const int64_t xing_offtbl[2][2] = {{32, 17}, {17,9}}; | 409 const int64_t xing_offtbl[2][2] = {{32, 17}, {17,9}}; |
410 MPADecodeContext c; | 410 MPADecodeContext c; |
411 int vbrtag_size = 0; | |
411 | 412 |
412 v = get_be32(s->pb); | 413 v = get_be32(s->pb); |
413 if(ff_mpa_check_header(v) < 0) | 414 if(ff_mpa_check_header(v) < 0) |
414 return; | 415 return -1; |
415 | 416 |
416 ff_mpegaudio_decode_header(&c, v); | 417 if (ff_mpegaudio_decode_header(&c, v) == 0) |
418 vbrtag_size = c.frame_size; | |
417 if(c.layer != 3) | 419 if(c.layer != 3) |
418 return; | 420 return -1; |
419 | 421 |
420 /* Check for Xing / Info tag */ | 422 /* Check for Xing / Info tag */ |
421 url_fseek(s->pb, xing_offtbl[c.lsf == 1][c.nb_channels == 1], SEEK_CUR); | 423 url_fseek(s->pb, xing_offtbl[c.lsf == 1][c.nb_channels == 1], SEEK_CUR); |
422 v = get_be32(s->pb); | 424 v = get_be32(s->pb); |
423 if(v == MKBETAG('X', 'i', 'n', 'g') || v == MKBETAG('I', 'n', 'f', 'o')) { | 425 if(v == MKBETAG('X', 'i', 'n', 'g') || v == MKBETAG('I', 'n', 'f', 'o')) { |
437 frames = get_be32(s->pb); | 439 frames = get_be32(s->pb); |
438 } | 440 } |
439 } | 441 } |
440 | 442 |
441 if(frames < 0) | 443 if(frames < 0) |
442 return; | 444 return -1; |
445 | |
446 /* Skip the vbr tag frame */ | |
447 url_fseek(s->pb, base + vbrtag_size, SEEK_SET); | |
443 | 448 |
444 spf = c.lsf ? 576 : 1152; /* Samples per frame, layer 3 */ | 449 spf = c.lsf ? 576 : 1152; /* Samples per frame, layer 3 */ |
445 st->duration = av_rescale_q(frames, (AVRational){spf, c.sample_rate}, | 450 st->duration = av_rescale_q(frames, (AVRational){spf, c.sample_rate}, |
446 st->time_base); | 451 st->time_base); |
452 return 0; | |
447 } | 453 } |
448 | 454 |
449 static int mp3_read_header(AVFormatContext *s, | 455 static int mp3_read_header(AVFormatContext *s, |
450 AVFormatParameters *ap) | 456 AVFormatParameters *ap) |
451 { | 457 { |
491 } else { | 497 } else { |
492 url_fseek(s->pb, 0, SEEK_SET); | 498 url_fseek(s->pb, 0, SEEK_SET); |
493 } | 499 } |
494 | 500 |
495 off = url_ftell(s->pb); | 501 off = url_ftell(s->pb); |
496 mp3_parse_vbr_tags(s, st, off); | 502 if (mp3_parse_vbr_tags(s, st, off) < 0) |
497 url_fseek(s->pb, off, SEEK_SET); | 503 url_fseek(s->pb, off, SEEK_SET); |
498 | 504 |
499 /* the parameters will be extracted from the compressed bitstream */ | 505 /* the parameters will be extracted from the compressed bitstream */ |
500 return 0; | 506 return 0; |
501 } | 507 } |
502 | 508 |