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);