comparison mp3.c @ 2662:08b1ac852321 libavformat

add support for reading duration from Xing-tag in mp3 files
author andoma
date Tue, 23 Oct 2007 13:35:20 +0000
parents c63b1bd7be16
children be889462edfc
comparison
equal deleted inserted replaced
2661:bed166d88f63 2662:08b1ac852321
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20 */ 20 */
21 #include "avformat.h" 21 #include "avformat.h"
22 #include "mpegaudio.h" 22 #include "mpegaudio.h"
23 #include "avstring.h" 23 #include "avstring.h"
24 #include "mpegaudiodecheader.h"
24 25
25 #define ID3v2_HEADER_SIZE 10 26 #define ID3v2_HEADER_SIZE 10
26 #define ID3v1_TAG_SIZE 128 27 #define ID3v1_TAG_SIZE 128
27 28
28 #define ID3v1_GENRE_MAX 125 29 #define ID3v1_GENRE_MAX 125
422 else if(max_frames>=3) return AVPROBE_SCORE_MAX/4; 423 else if(max_frames>=3) return AVPROBE_SCORE_MAX/4;
423 else if(max_frames>=1) return 1; 424 else if(max_frames>=1) return 1;
424 else return 0; 425 else return 0;
425 } 426 }
426 427
428 /**
429 * Try to extract a xing tag from the stream and if found, decode it
430 */
431 static void mp3_parse_xing(AVFormatContext *s, AVStream *st)
432 {
433 uint32_t v, frames, spf;
434 const offset_t offtbl[2][2] = {{32, 17}, {17,9}};
435 MPADecodeContext c;
436
437 ff_mpegaudio_decode_header(&c, get_be32(&s->pb));
438 url_fseek(&s->pb, offtbl[c.lsf == 1][c.nb_channels == 1], SEEK_CUR);
439 v = get_be32(&s->pb);
440 if(c.layer != 3 ||
441 (v != MKBETAG('X', 'i', 'n', 'g') &&
442 v != MKBETAG('I', 'n', 'f', 'o')))
443 return;
444
445 v = get_be32(&s->pb);
446 if(v & 0x1) {
447 frames = get_be32(&s->pb); /* Total number of frames in file */
448 spf = c.lsf ? 576 : 1152; /* Samples per frame, layer 3 */
449
450 st->duration = av_rescale_q(frames, (AVRational){spf, c.sample_rate},
451 st->time_base);
452 }
453 }
454
427 static int mp3_read_header(AVFormatContext *s, 455 static int mp3_read_header(AVFormatContext *s,
428 AVFormatParameters *ap) 456 AVFormatParameters *ap)
429 { 457 {
430 AVStream *st; 458 AVStream *st;
431 uint8_t buf[ID3v1_TAG_SIZE]; 459 uint8_t buf[ID3v1_TAG_SIZE];
432 int len, ret, filesize; 460 int len, ret, filesize;
461 offset_t off;
433 462
434 st = av_new_stream(s, 0); 463 st = av_new_stream(s, 0);
435 if (!st) 464 if (!st)
436 return AVERROR(ENOMEM); 465 return AVERROR(ENOMEM);
437 466
466 (buf[9] & 0x7f); 495 (buf[9] & 0x7f);
467 id3v2_parse(s, len, buf[3], buf[5]); 496 id3v2_parse(s, len, buf[3], buf[5]);
468 } else { 497 } else {
469 url_fseek(&s->pb, 0, SEEK_SET); 498 url_fseek(&s->pb, 0, SEEK_SET);
470 } 499 }
500
501 off = url_ftell(&s->pb);
502 mp3_parse_xing(s, st);
503 url_fseek(&s->pb, off, SEEK_SET);
471 504
472 /* the parameters will be extracted from the compressed bitstream */ 505 /* the parameters will be extracted from the compressed bitstream */
473 return 0; 506 return 0;
474 } 507 }
475 508