Mercurial > mplayer.hg
comparison libmpdemux/demux_mov.c @ 5301:d72c3169a343
Improved MP4 parsing (finally)
author | atmos4 |
---|---|
date | Sun, 24 Mar 2002 02:25:41 +0000 |
parents | 1823c7dff423 |
children | 6dc0ac26eb0e |
comparison
equal
deleted
inserted
replaced
5300:5d7bd47b46ef | 5301:d72c3169a343 |
---|---|
28 #include "stheader.h" | 28 #include "stheader.h" |
29 | 29 |
30 #include "bswap.h" | 30 #include "bswap.h" |
31 | 31 |
32 #include "qtpalette.h" | 32 #include "qtpalette.h" |
33 #include "parse_mp4.h" // MP3 specific stuff | |
33 | 34 |
34 #ifdef HAVE_ZLIB | 35 #ifdef HAVE_ZLIB |
35 #include <zlib.h> | 36 #include <zlib.h> |
36 #endif | 37 #endif |
37 | 38 |
38 #include <fcntl.h> | 39 #include <fcntl.h> |
39 | 40 |
40 #define BE_16(x) (be2me_16(*(unsigned short *)(x))) | 41 #define BE_16(x) (be2me_16(*(unsigned short *)(x))) |
41 #define BE_32(x) (be2me_32(*(unsigned int *)(x))) | 42 #define BE_32(x) (be2me_32(*(unsigned int *)(x))) |
42 | 43 |
44 #ifndef WORDS_BIGENDIAN | |
43 #define char2short(x,y) ((x[y]<<8)|x[y+1]) | 45 #define char2short(x,y) ((x[y]<<8)|x[y+1]) |
44 #define char2int(x,y) ((x[y]<<24)|(x[y+1]<<16)|(x[y+2]<<8)|x[y+3]) | 46 #define char2int(x,y) ((x[y]<<24)|(x[y+1]<<16)|(x[y+2]<<8)|x[y+3]) |
47 #else | |
48 #warning Check the implementation of char2short and char2int on BIGENDIAN!!! | |
49 #define char2short(x,y) (x[y]|(x[y+1]<<8)) | |
50 #define char2int(x,y) (x[y]|(x[y+1]<<8)|(x[y+2]<<16)|(x[y+3]<<24)) | |
51 #endif | |
45 | 52 |
46 typedef struct { | 53 typedef struct { |
47 unsigned int pts; // duration | 54 unsigned int pts; // duration |
48 unsigned int size; | 55 unsigned int size; |
49 off_t pos; | 56 off_t pos; |
669 /*printf("MOV: timescale: %d samplerate: %d durmap: %d (%d) -> %d (%d)\n", | 676 /*printf("MOV: timescale: %d samplerate: %d durmap: %d (%d) -> %d (%d)\n", |
670 trak->timescale, char2short(trak->stdata,24), trak->durmap[0].dur, | 677 trak->timescale, char2short(trak->stdata,24), trak->durmap[0].dur, |
671 trak->durmap[0].num, trak->timescale/trak->durmap[0].dur, | 678 trak->durmap[0].num, trak->timescale/trak->durmap[0].dur, |
672 char2short(trak->stdata,24)/trak->durmap[0].dur);*/ | 679 char2short(trak->stdata,24)/trak->durmap[0].dur);*/ |
673 sh->samplerate=char2short(trak->stdata,24); | 680 sh->samplerate=char2short(trak->stdata,24); |
674 if((sh->samplerate < 8000) && trak->durmap) { | 681 if((sh->samplerate < 7000) && trak->durmap) { |
675 switch(char2short(trak->stdata,24)/trak->durmap[0].dur) { | 682 switch(char2short(trak->stdata,24)/trak->durmap[0].dur) { |
676 // TODO: add more cases. | 683 // TODO: add more cases. |
677 case 31: | 684 case 31: |
678 sh->samplerate = 32000; break; | 685 sh->samplerate = 32000; break; |
679 case 43: | 686 case 43: |
694 mp_msg(MSGT_DEMUX, MSGL_INFO, "Audio sample rate: %d\n", | 701 mp_msg(MSGT_DEMUX, MSGL_INFO, "Audio sample rate: %d\n", |
695 sh->samplerate/*char2short(trak->stdata,24)*/); | 702 sh->samplerate/*char2short(trak->stdata,24)*/); |
696 if((trak->stdata[9]==0) && trak->stdata_len >= 36) { // version 0 with extra atoms | 703 if((trak->stdata[9]==0) && trak->stdata_len >= 36) { // version 0 with extra atoms |
697 int atom_len = char2int(trak->stdata,28); | 704 int atom_len = char2int(trak->stdata,28); |
698 switch(char2int(trak->stdata,32)) { // atom type | 705 switch(char2int(trak->stdata,32)) { // atom type |
699 case MOV_FOURCC('e','s','d','s'): | 706 case MOV_FOURCC('e','s','d','s'): { |
707 esds_t *esds; | |
700 mp_msg(MSGT_DEMUX, MSGL_INFO, "MOV: Found MPEG4 audio Elementary Stream Descriptor atom (%d)!\n", atom_len); | 708 mp_msg(MSGT_DEMUX, MSGL_INFO, "MOV: Found MPEG4 audio Elementary Stream Descriptor atom (%d)!\n", atom_len); |
701 if(atom_len >= 28) | 709 if(atom_len >= 8) { |
702 mp_msg(MSGT_DEMUX, MSGL_INFO, "Audio compressed datarate: %dkbit/s\n", | 710 if(!mp4_parse_esds(&trak->stdata[36], atom_len-8, esds)) { |
703 char2int(trak->stdata,62)/1000); | 711 |
704 sh->i_bps=char2int(trak->stdata,62)/8; | 712 sh->i_bps = esds->avgBitrate/8; |
705 break; | 713 |
714 // dump away the codec specific configuration for the AAC decoder | |
715 sh->codecdata_len = esds->decoderConfigLen; | |
716 sh->codecdata = (unsigned char *)malloc(sh->codecdata_len); | |
717 memcpy(sh->codecdata, esds->decoderConfig, sh->codecdata_len); | |
718 } | |
719 #if 0 | |
720 { FILE* f=fopen("esds.dat","wb"); | |
721 fwrite(&trak->stdata[36],atom_len-8,1,f); | |
722 fclose(f); } | |
723 #endif | |
724 } | |
725 } break; | |
706 default: | 726 default: |
707 mp_msg(MSGT_DEMUX, MSGL_INFO, "MOV: Found unknown audio atom %c%c%c%c (%d)!\n", | 727 mp_msg(MSGT_DEMUX, MSGL_INFO, "MOV: Found unknown audio atom %c%c%c%c (%d)!\n", |
708 trak->stdata[32],trak->stdata[33],trak->stdata[34],trak->stdata[35], | 728 trak->stdata[32],trak->stdata[33],trak->stdata[34],trak->stdata[35], |
709 atom_len); | 729 atom_len); |
710 } | 730 } |