Mercurial > mplayer.hg
comparison libmpdemux/demux_mov.c @ 5236:f8a00b2c9c39
Add some atom parsing to movie trak and a bit cosmetics ;), Michael can now write esds movie header whereever he wants.
author | atmos4 |
---|---|
date | Thu, 21 Mar 2002 06:05:14 +0000 |
parents | 12f7cbbe7022 |
children | 126d5fd76a70 |
comparison
equal
deleted
inserted
replaced
5235:3e04fd1074d3 | 5236:f8a00b2c9c39 |
---|---|
1 // QuickTime MOV file parser by A'rpi | 1 // QuickTime MOV file parser by A'rpi |
2 // based on TOOLS/movinfo.c by me & Al3x | 2 // additional work by Atmos |
3 // based on TOOLS/movinfo.c by A'rpi & Al3x | |
3 // compressed header support from moov.c of the openquicktime lib. | 4 // compressed header support from moov.c of the openquicktime lib. |
4 // References: http://openquicktime.sf.net/, http://www.heroinewarrior.com/ | 5 // References: http://openquicktime.sf.net/, http://www.heroinewarrior.com/ |
5 // http://www.geocities.com/SiliconValley/Lakes/2160/fformats/files/mov.pdf | 6 // http://www.geocities.com/SiliconValley/Lakes/2160/fformats/files/mov.pdf |
7 // The QuickTime File Format PDF (QTFileFormat.pdf) from Apple: | |
8 // http://developer.apple.com/quicktime/ | |
6 | 9 |
7 #include <stdio.h> | 10 #include <stdio.h> |
8 #include <stdlib.h> | 11 #include <stdlib.h> |
9 #include <unistd.h> | 12 #include <unistd.h> |
10 | 13 |
26 | 29 |
27 #include <fcntl.h> | 30 #include <fcntl.h> |
28 | 31 |
29 #define BE_16(x) (be2me_16(*(unsigned short *)(x))) | 32 #define BE_16(x) (be2me_16(*(unsigned short *)(x))) |
30 #define BE_32(x) (be2me_32(*(unsigned int *)(x))) | 33 #define BE_32(x) (be2me_32(*(unsigned int *)(x))) |
34 | |
35 #define char2short(x,y) ((x[y]<<8)|x[y+1]) | |
36 #define char2int(x,y) ((x[y]<<24)|(x[y+1]<<16)|(x[y+2]<<8)|x[y+3]) | |
31 | 37 |
32 typedef struct { | 38 typedef struct { |
33 unsigned int pts; // duration | 39 unsigned int pts; // duration |
34 unsigned int size; | 40 unsigned int size; |
35 off_t pos; | 41 off_t pos; |
214 if(stream_eof(demuxer->stream)) break; // EOF | 220 if(stream_eof(demuxer->stream)) break; // EOF |
215 if (len == 1) /* real size is 64bits - cjb */ | 221 if (len == 1) /* real size is 64bits - cjb */ |
216 { | 222 { |
217 #ifndef _LARGEFILE_SOURCE | 223 #ifndef _LARGEFILE_SOURCE |
218 if (stream_read_dword(demuxer->stream) != 0) | 224 if (stream_read_dword(demuxer->stream) != 0) |
219 mp_msg(MSGT_DEMUX, MSGL_WARN, "64bit file, but you've MPlayer compiled without LARGEFILE support!\n"); | 225 mp_msg(MSGT_DEMUX, MSGL_WARN, "64bit file, but you've compiled MPlayer without LARGEFILE support!\n"); |
220 len = stream_read_dword(demuxer->stream); | 226 len = stream_read_dword(demuxer->stream); |
221 #else | 227 #else |
222 len = stream_read_qword(demuxer->stream); | 228 len = stream_read_qword(demuxer->stream); |
223 #endif | 229 #endif |
224 skipped += 8; | 230 skipped += 8; |
570 int16_t channels; // 1 or 2 (Mono/Stereo) | 576 int16_t channels; // 1 or 2 (Mono/Stereo) |
571 int16_t samplesize; // 8 or 16 (8Bit/16Bit) | 577 int16_t samplesize; // 8 or 16 (8Bit/16Bit) |
572 int16_t compression_id; // if version 0 then 0 | 578 int16_t compression_id; // if version 0 then 0 |
573 // if version 1 and vbr then -2 else 0 | 579 // if version 1 and vbr then -2 else 0 |
574 int16_t packet_size; // 0 | 580 int16_t packet_size; // 0 |
575 uint32_t sample_rate; // samplerate (Hz) | 581 uint16_t sample_rate; // samplerate (Hz) |
576 // qt3.0+ (version == 1) | 582 // qt3.0+ (version == 1) |
577 uint32_t samples_per_packet; // 0 or num uncompressed samples in a packet | 583 uint32_t samples_per_packet; // 0 or num uncompressed samples in a packet |
578 // if 0 below three values are also 0 | 584 // if 0 below three values are also 0 |
579 uint32_t bytes_per_packet; // 0 or num compressed bytes for one channel | 585 uint32_t bytes_per_packet; // 0 or num compressed bytes for one channel |
580 uint32_t bytes_per_frame; // 0 or num compressed bytes for all channels | 586 uint32_t bytes_per_frame; // 0 or num compressed bytes for all channels |
588 } my_stdata; | 594 } my_stdata; |
589 #endif | 595 #endif |
590 sh_audio_t* sh=new_sh_audio(demuxer,priv->track_db); | 596 sh_audio_t* sh=new_sh_audio(demuxer,priv->track_db); |
591 sh->format=trak->fourcc; | 597 sh->format=trak->fourcc; |
592 | 598 |
593 // assumptions for below table: short is 16bit, int is 32bit | 599 // assumptions for below table: short is 16bit, int is 32bit, intfp is 16bit |
600 // XXX: 32bit fixed point numbers (intfp) are only 2 Byte! | |
594 // short values are usually one byte leftpadded by zero | 601 // short values are usually one byte leftpadded by zero |
595 // int values are usually two byte leftpadded by zero | 602 // int values are usually two byte leftpadded by zero |
596 // stdata[]: | 603 // stdata[]: |
597 // 8 short version | 604 // 8 short version |
598 // 10 short revision | 605 // 10 short revision |
599 // 12 int vendor_id | 606 // 12 int vendor_id |
600 // 16 short channels | 607 // 16 short channels |
601 // 18 short samplesize | 608 // 18 short samplesize |
602 // 20 short compression_id | 609 // 20 short compression_id |
603 // 22 short packet_size (==0) | 610 // 22 short packet_size (==0) |
604 // 24 int sample_rate | 611 // 24 intfp sample_rate |
612 // (26 short) unknown (==0) | |
605 // ---- qt3.0+ | 613 // ---- qt3.0+ |
606 // 28 int samples_per_packet | 614 // 28 int samples_per_packet |
607 // 32 int bytes_per_packet | 615 // 32 int bytes_per_packet |
608 // 36 int bytes_per_frame | 616 // 36 int bytes_per_frame |
609 // 40 int bytes_per_sample | 617 // 40 int bytes_per_sample |
610 // my recoveries from .mp4 files with correct index (counting from 0): | 618 // there may be additional atoms following at 28 (version 0) |
611 // it's always start with padding/real start | 619 // or 44 (version 1), eg. esds atom of .MP4 files |
612 // 8/ 9 short version | |
613 // 10/11 short revision | |
614 // 12/14 int vendor_id | |
615 // 16/17 short channels | |
616 // 18/19 short samplesize | |
617 // 20/21 short compression_id | |
618 // 22/23 short packet_size (XXX: this overlaps with sample_rate ?) | |
619 // 22/24 int sample_rate | |
620 // esds atom: | 620 // esds atom: |
621 // 28/31 int atom size (bytes of int size, int type and data) | 621 // 28 int atom size (bytes of int size, int type and data) |
622 // 32/32 int atom type (fourc charater code -> esds) | 622 // 32 char[4] atom type (fourc charater code -> esds) |
623 // 62/63 int compressed datarate (Bits) | 623 // 62 int compressed datarate (Bits) |
624 | |
625 #define char2short(x,y) ((x[y]<<8)|x[y+1]) | |
626 #define char2int(x,y) ((x[y]<<24)|(x[y+1]<<16)|(x[y+2]<<8)|x[y+3]) | |
627 | 624 |
628 sh->samplesize=char2short(trak->stdata,18)/8; | 625 sh->samplesize=char2short(trak->stdata,18)/8; |
629 sh->channels=char2short(trak->stdata,16); | 626 sh->channels=char2short(trak->stdata,16); |
630 /*printf("MOV: timescale: %d samplerate: %d durmap: %d (%d) -> %d (%d)\n", | 627 /*printf("MOV: timescale: %d samplerate: %d durmap: %d (%d) -> %d (%d)\n", |
631 trak->timescale, char2short(trak->stdata,24), trak->durmap[0].dur, | 628 trak->timescale, char2short(trak->stdata,24), trak->durmap[0].dur, |
656 sh->samplerate/*char2short(trak->stdata,24)*/); | 653 sh->samplerate/*char2short(trak->stdata,24)*/); |
657 if((trak->stdata[9]==0) && trak->stdata_len >= 36) { // version 0 with extra atoms | 654 if((trak->stdata[9]==0) && trak->stdata_len >= 36) { // version 0 with extra atoms |
658 int atom_len = char2int(trak->stdata,28); | 655 int atom_len = char2int(trak->stdata,28); |
659 switch(char2int(trak->stdata,32)) { // atom type | 656 switch(char2int(trak->stdata,32)) { // atom type |
660 case MOV_FOURCC('e','s','d','s'): | 657 case MOV_FOURCC('e','s','d','s'): |
661 mp_msg(MSGT_DEMUX, MSGL_INFO, "MOV: MP4 esds audio atom found (%d)!\n", atom_len); | 658 mp_msg(MSGT_DEMUX, MSGL_INFO, "MOV: Found MPEG4 esds audio atom (%d)!\n", atom_len); |
662 if(atom_len >= 28) | 659 if(atom_len >= 28) |
663 mp_msg(MSGT_DEMUX, MSGL_INFO, "Audio compressed datarate: %dkbit/s\n", | 660 mp_msg(MSGT_DEMUX, MSGL_INFO, "Audio compressed datarate: %dkbit/s\n", |
664 char2int(trak->stdata,62)/1000); | 661 char2int(trak->stdata,62)/1000); |
665 sh->i_bps=char2int(trak->stdata,62)/8; | 662 sh->i_bps=char2int(trak->stdata,62)/8; |
666 break; | 663 break; |
667 default: | 664 default: |
668 mp_msg(MSGT_DEMUX, MSGL_INFO, "MOV: unknown audio atom %c%c%c%c found (%d)!\n", | 665 mp_msg(MSGT_DEMUX, MSGL_INFO, "MOV: Found unknown audio atom %c%c%c%c (%d)!\n", |
669 trak->stdata[32],trak->stdata[33],trak->stdata[34],trak->stdata[35], | 666 trak->stdata[32],trak->stdata[33],trak->stdata[34],trak->stdata[35], |
670 atom_len); | 667 atom_len); |
671 } | 668 } |
672 } | 669 } |
673 mp_msg(MSGT_DEMUX, MSGL_INFO, "Fourcc: %.4s\n",&trak->fourcc); | 670 mp_msg(MSGT_DEMUX, MSGL_INFO, "Fourcc: %.4s\n",&trak->fourcc); |
714 // 26 short height | 711 // 26 short height |
715 // 28 int h_dpi | 712 // 28 int h_dpi |
716 // 32 int v_dpi | 713 // 32 int v_dpi |
717 // 36 int 0 | 714 // 36 int 0 |
718 // 40 short frames_per_sample | 715 // 40 short frames_per_sample |
719 // 42 char[32] compressor_name | 716 // 42 char[4] compressor_name |
720 // 74 short depth | 717 // 74 short depth |
721 // 76 short color_table_id | 718 // 76 short color_table_id |
722 | 719 // additional atoms may follow, |
720 // eg esds atom from .MP4 files | |
721 // 78 int atom size | |
722 // 82 char[4] atom type | |
723 // 86 ... atom data | |
724 | |
725 | |
726 if(trak->stdata_len >= 86) { // extra atoms found | |
727 int atom_len = char2int(trak->stdata,78); | |
728 if((trak->stdata_len - atom_len) > 78) | |
729 mp_msg(MSGT_DEMUX, MSGL_WARN, "MOV: Movie stdata contains more then one atom (yet unsupported)!\n"); | |
730 // TODO: add support for multiple atoms, by analyzing stdata len | |
731 // and comparing with len of first atom ::atmos | |
732 switch(char2int(trak->stdata,82)) { // switch atom type | |
733 case MOV_FOURCC('g','a','m','a'): | |
734 // intfp with gamma value at which movie was captured | |
735 // can be used to gamma correct movie display | |
736 mp_msg(MSGT_DEMUX, MSGL_INFO, "MOV: Found unsupported Gamma-Correction movie atom (%d)!\n", | |
737 atom_len); | |
738 break; | |
739 case MOV_FOURCC('f','i','e','l'): | |
740 // 2 char-values (8bit int) that specify field handling | |
741 // see the Apple's QuickTime Fileformat PDF for more info | |
742 mp_msg(MSGT_DEMUX, MSGL_INFO, "MOV: Found unsupported Field-Handling movie atom (%d)!\n", | |
743 atom_len); | |
744 break; | |
745 case MOV_FOURCC('m','j','q','t'): | |
746 // Motion-JPEG default quantization table | |
747 mp_msg(MSGT_DEMUX, MSGL_INFO, "MOV: Found unsupported MJPEG-Quantization movie atom (%d)!\n", | |
748 atom_len); | |
749 break; | |
750 case MOV_FOURCC('m','j','h','t'): | |
751 // Motion-JPEG default huffman table | |
752 mp_msg(MSGT_DEMUX, MSGL_INFO, "MOV: Found unsupported MJPEG-Huffman movie atom (%d)!\n", | |
753 atom_len); | |
754 break; | |
755 case MOV_FOURCC('e','s','d','s'): | |
756 // MPEG4 esds header | |
757 mp_msg(MSGT_DEMUX, MSGL_INFO, "MOV: Found MPEG4 esds movie atom (%d)!\n", atom_len); | |
758 // add code here to save esds header of length atom_len-8 | |
759 // beginning at stdata[86] to some variable to pass it | |
760 // on to the decoder ::atmos | |
761 break; | |
762 default: | |
763 mp_msg(MSGT_DEMUX, MSGL_INFO, "MOV: Found unknown movie atom %c%c%c%c (%d)!\n", | |
764 trak->stdata[86],trak->stdata[87],trak->stdata[88],trak->stdata[89], | |
765 atom_len); | |
766 } | |
767 } | |
723 if(!sh->fps) sh->fps=trak->timescale; | 768 if(!sh->fps) sh->fps=trak->timescale; |
724 sh->frametime=1.0f/sh->fps; | 769 sh->frametime=1.0f/sh->fps; |
725 #if 0 | 770 #if 0 |
726 sh->disp_w=trak->tkdata[77]|(trak->tkdata[76]<<8); | 771 sh->disp_w=trak->tkdata[77]|(trak->tkdata[76]<<8); |
727 sh->disp_h=trak->tkdata[81]|(trak->tkdata[80]<<8); | 772 sh->disp_h=trak->tkdata[81]|(trak->tkdata[80]<<8); |