demux_mov.c

来自「君正早期ucos系统(只有早期的才不没有打包成库),MPLAYER,文件系统,图」· C语言 代码 · 共 1,854 行 · 第 1/5 页

C
1,854
字号
     	      break;	    case MOV_FOURCC('M','4','P',' '):	      mp_msg(MSGT_DEMUX,MSGL_INFO,"ISO: File Type Major Brand: Apple iTunes AAC-LC Protected Audio\n");     	      break;	    case MOV_FOURCC('q','t',' ',' '):	      mp_msg(MSGT_DEMUX,MSGL_INFO,"ISO: File Type Major Brand: Original QuickTime\n");     	      break;	    case MOV_FOURCC('3','g','p','1'):	      mp_msg(MSGT_DEMUX,MSGL_INFO,"ISO: File Type Major Brand: 3GPP Profile 1\n");     	      break;	    case MOV_FOURCC('3','g','p','2'):	    case MOV_FOURCC('3','g','2','a'):	      mp_msg(MSGT_DEMUX,MSGL_INFO,"ISO: File Type Major Brand: 3GPP Profile 2\n");     	      break;	    case MOV_FOURCC('3','g','p','3'):	      mp_msg(MSGT_DEMUX,MSGL_INFO,"ISO: File Type Major Brand: 3GPP Profile 3\n");     	      break;	    case MOV_FOURCC('3','g','p','4'):	      mp_msg(MSGT_DEMUX,MSGL_INFO,"ISO: File Type Major Brand: 3GPP Profile 4\n");     	      break;	    case MOV_FOURCC('3','g','p','5'):	      mp_msg(MSGT_DEMUX,MSGL_INFO,"ISO: File Type Major Brand: 3GPP Profile 5\n");     	      break;	    case MOV_FOURCC('m','m','p','4'):	      mp_msg(MSGT_DEMUX,MSGL_INFO,"ISO: File Type Major Brand: Mobile ISO/IEC 14496-1 (MPEG-4 system)\n");     	      break;	    default:	      tmp = be2me_32(tmp);  	      mp_msg(MSGT_DEMUX,MSGL_WARN,"ISO: Unknown File Type Major Brand: %.4s\n",(char *)&tmp);	  }	  mp_msg(MSGT_DEMUX,MSGL_V,"ISO: File Type Minor Version: %d\n",	      stream_read_dword(demuxer->stream));	  skipped += 8;	  // List all compatible brands	  for(i = 0; i < ((len-16)/4); i++) {	    tmp = be2me_32(stream_read_dword(demuxer->stream));	    mp_msg(MSGT_DEMUX,MSGL_V,"ISO: File Type Compatible Brand #%d: %.4s\n",i,(char *)&tmp);	    skipped += 4;	  }#endif	  	  } break;	case MOV_FOURCC('m','o','o','v')://	case MOV_FOURCC('c','m','o','v'):	  mp_msg(MSGT_DEMUX,MSGL_V,"MOV: Movie header found!\n");	  priv->moov_start=(off_t)stream_tell(demuxer->stream);	  priv->moov_end=(off_t)priv->moov_start+len-skipped;	  mp_msg(MSGT_DEMUX,MSGL_DBG2,"MOV: Movie header: start: %"PRIx64" end: %"PRIx64"\n",	    (int64_t)priv->moov_start, (int64_t)priv->moov_end);	  skipped+=8;	  i = stream_read_dword(demuxer->stream)-8;	  if(stream_read_dword(demuxer->stream)==MOV_FOURCC('r','m','r','a')){	      skipped+=i;	      mp_msg(MSGT_DEMUX,MSGL_INFO,"MOV: Reference Media file!!!\n");	      //set demuxer type to playlist ...	      demuxer->type=DEMUXER_TYPE_PLAYLIST;	      while(i>0){	          int len=stream_read_dword(demuxer->stream)-8;		  int fcc=stream_read_dword(demuxer->stream);		  if(len<0) break; // EOF!?		  i-=8;//		  printf("i=%d  len=%d\n",i,len);		  switch(fcc){		  case MOV_FOURCC('r','m','d','a'):		      continue;		  case MOV_FOURCC('r','d','r','f'): {		      int tmp=stream_read_dword(demuxer->stream);		      int type=stream_read_dword_le(demuxer->stream);	              int slen=stream_read_dword(demuxer->stream);		      //char* s=malloc(slen+1);		      //stream_read(demuxer->stream,s,slen);		      		      //FIXME: also store type & data_rate ?		      ds_read_packet(demuxer->video, 			demuxer->stream,			slen,			0,			stream_tell(demuxer->stream),			0 // no flags 		      );		      flags|=4;		      mp_msg(MSGT_DEMUX,MSGL_V,"Added reference to playlist\n");		      //s[slen]=0;		      //mp_msg(MSGT_DEMUX,MSGL_INFO,"REF: [%.4s] %s\n",&type,s);		      len-=12+slen;i-=12+slen; break;		    }		  case MOV_FOURCC('r','m','d','r'): {		      int flags=stream_read_dword(demuxer->stream);		      int rate=stream_read_dword(demuxer->stream);		      mp_msg(MSGT_DEMUX,MSGL_V,"  min. data rate: %d bits/sec\n",rate);		      len-=8; i-=8; break;		    }		  case MOV_FOURCC('r','m','q','u'): {		      int q=stream_read_dword(demuxer->stream);		      mp_msg(MSGT_DEMUX,MSGL_V,"  quality index: %d\n",q);		      len-=4; i-=4; break;		    }		  }		  i-=len;stream_skip(demuxer->stream,len);	      }	  }	  flags|=1;	  break;	case MOV_FOURCC('w','i','d','e'):	  mp_msg(MSGT_DEMUX,MSGL_V,"MOV: 'WIDE' chunk found!\n");	  if(flags&2) break;	case MOV_FOURCC('m','d','a','t'):	  mp_msg(MSGT_DEMUX,MSGL_V,"MOV: Movie DATA found!\n");	  priv->mdat_start=stream_tell(demuxer->stream);	  priv->mdat_end=priv->mdat_start+len-skipped;	  mp_msg(MSGT_DEMUX,MSGL_DBG2,"MOV: Movie data: start: %"PRIx64" end: %"PRIx64"\n",	    (int64_t)priv->mdat_start, (int64_t)priv->mdat_end);	  flags|=2;	  if(flags==3){	    // if we're over the headers, then we can stop parsing here!	    demuxer->priv=priv;	    return DEMUXER_TYPE_MOV;	  }	  break;	case MOV_FOURCC('f','r','e','e'):	case MOV_FOURCC('s','k','i','p'):	case MOV_FOURCC('j','u','n','k'):	  mp_msg(MSGT_DEMUX,MSGL_DBG2,"MOV: free space (len: %"PRId64")\n", (int64_t)len);	  /* unused, if you edit a mov, you can use space provided by free atoms (redefining it) */	  break;	case MOV_FOURCC('p','n','o','t'):	case MOV_FOURCC('P','I','C','T'):	  /* dunno what, but we shoudl ignore it */	  break;	default:	  if(no==0){ free(priv); return 0;} // first chunk is bad!	  id = be2me_32(id);	  mp_msg(MSGT_DEMUX,MSGL_V,"MOV: unknown chunk: %.4s %d\n",(char *)&id,(int)len);	}//skip_chunk:	if(!stream_skip(demuxer->stream,len-skipped)) break;	++no;    }    if(flags==3){	demuxer->priv=priv;	return DEMUXER_TYPE_MOV;    }    free(priv);    if ((flags==5) || (flags==7)) // reference & header sent        return DEMUXER_TYPE_PLAYLIST;    if(flags==1)	mp_msg(MSGT_DEMUX,MSGL_WARN,"MOV: missing data (mdat) chunk! Maybe broken file...\n");    else if(flags==2)	mp_msg(MSGT_DEMUX,MSGL_WARN,"MOV: missing header (moov/cmov) chunk! Maybe broken file...\n");    return 0;}static void demux_close_mov(demuxer_t *demuxer) {  mov_priv_t* priv = demuxer->priv;  int i;  if (!priv)    return;  for (i = 0; i < MOV_MAX_TRACKS; i++) {    mov_track_t *track = priv->tracks[i];    if (track) {      free(track->tkdata);      free(track->stdata);      free(track->stream_header);      free(track->samples);      free(track->chunks);      free(track->chunkmap);      free(track->durmap);      free(track->keyframes);      free(track->editlist);      free(track->desc);      free(track);    }  }  free(priv);}unsigned int store_ughvlc(unsigned char *s, unsigned int v){  unsigned int n = 0;  while(v >= 0xff) {    *s++ = 0xff;    v -= 0xff;    n++;  }  *s = v;  n++;  return n;}static void init_vobsub(sh_sub_t *sh, mov_track_t *trak) {  int i;  uint8_t *pal = trak->stdata;  sh->type = 'v';  if (trak->stdata_len < 106)    return;  sh->has_palette = 1;  pal += 42;  for (i = 0; i < 16; i++) {    sh->palette[i] = BE_32(pal);    pal += 4;  }}static int lschunks_intrak(demuxer_t* demuxer, int level, unsigned int id,                           off_t pos, off_t len, mov_track_t* trak);static int gen_sh_audio(sh_audio_t* sh, mov_track_t* trak, int timescale) {#if 0				   		struct {		   int16_t version;		// 0 or 1 (version 1 is qt3.0+)		   int16_t revision;		// 0		   int32_t vendor_id;		// 0		   int16_t channels;		// 1 or 2  (Mono/Stereo)		   int16_t samplesize;		// 8 or 16 (8Bit/16Bit)			   int16_t compression_id;	// if version 0 then 0		  				// if version 1 and vbr then -2 else 0		   int16_t packet_size;		// 0		   uint16_t sample_rate;	// samplerate (Hz)		   // qt3.0+ (version == 1)		   uint32_t samples_per_packet;	// 0 or num uncompressed samples in a packet		   				// if 0 below three values are also 0		   uint32_t bytes_per_packet;	// 0 or num compressed bytes for one channel		   uint32_t bytes_per_frame;	// 0 or num compressed bytes for all channels		   				// (channels * bytes_per_packet)		   uint32_t bytes_per_sample;	// 0 or size of uncompressed sample		   // if samples_per_packet and bytes_per_packet are constant (CBR)		   // then bytes_per_frame and bytes_per_sample must be 0 (else is VBR)		   // ---		   // optional additional atom-based fields		   // ([int32_t size,int32_t type,some data ],repeat)		} my_stdata;		  #endif				int version, adjust;		int is_vorbis = 0;		sh->format=trak->fourcc;		// crude audio delay from editlist0 hack ::atm		if(trak->editlist_size>=1) {		    if(trak->editlist[0].pos == -1) {			sh->stream_delay = (float)trak->editlist[0].dur/(float)timescale;	    		mp_msg(MSGT_DEMUX,MSGL_V,"MOV: Initial Audio-Delay: %.3f sec\n", sh->stream_delay);		    }		}		switch( sh->format ) {		    case 0x726D6173: /* samr */			/* amr narrowband */			trak->samplebytes=sh->samplesize=1;			trak->nchannels=sh->channels=1;			sh->samplerate=8000;			break;					    case 0x62776173: /* sawb */			/* amr wideband */			trak->samplebytes=sh->samplesize=1;			trak->nchannels=sh->channels=1;			sh->samplerate=16000;			break;		    default:			// assumptions for below table: short is 16bit, int is 32bit, intfp is 16bit// XXX: 32bit fixed point numbers (intfp) are only 2 Byte!		// short values are usually one byte leftpadded by zero		//   int values are usually two byte leftpadded by zero		//  stdata[]://	8   short	version//	10  short	revision//	12  int		vendor_id//	16  short	channels//	18  short	samplesize//	20  short	compression_id//	22  short	packet_size (==0)//	24  intfp	sample_rate//     (26  short)	unknown (==0)//    ---- qt3.0+ (version>=1)//	28  int		samples_per_packet//	32  int		bytes_per_packet//	36  int		bytes_per_frame//	40  int		bytes_per_sample// there may be additional atoms following at 28 (version 0)// or 44 (version 1), eg. esds atom of .MP4 files		// esds atom://      28  int		atom size (bytes of int size, int type and data)//      32  char[4]	atom type (fourc charater code -> esds)		//      36  char[]  	atom data (len=size-8)// TODO: fix parsing for files using version 2.		version=char2short(trak->stdata,8);		if (version > 1)		  mp_msg(MSGT_DEMUX, MSGL_WARN, "MOV: version %d sound atom may not parse correctly!\n", version);		trak->samplebytes=sh->samplesize=char2short(trak->stdata,18)/8;		/* I can't find documentation, but so far this is the case. -Corey */		switch (char2short(trak->stdata,16)) {		  case 1:		    trak->nchannels = 1; break;		  case 2:		    trak->nchannels = 2; break;		  case 3:		    trak->nchannels = 6; break;		  default:		    mp_msg(MSGT_DEMUX, MSGL_WARN,			"MOV: unable to determine audio channels, assuming 2 (got %d)\n",			char2short(trak->stdata,16));		    trak->nchannels = 2;		}		sh->channels = trak->nchannels;		/*printf("MOV: timescale: %d samplerate: %d durmap: %d (%d) -> %d (%d)\n",		    trak->timescale, char2short(trak->stdata,24), trak->durmap[0].dur,		    trak->durmap[0].num, trak->timescale/trak->durmap[0].dur,		    char2short(trak->stdata,24)/trak->durmap[0].dur);*/		sh->samplerate=char2short(trak->stdata,24);		if((sh->samplerate < 7000) && trak->durmap && trak->durmap[0].dur > 1) {		  switch(char2short(trak->stdata,24)/trak->durmap[0].dur) {		    // TODO: add more cases.		    case 31:		      sh->samplerate = 32000; break;		    case 43:		      sh->samplerate = 44100; break;		    case 47:		      sh->samplerate = 48000; break;		    default:		      mp_msg(MSGT_DEMUX, MSGL_WARN,			  "MOV: unable to determine audio samplerate, "			  "assuming 44.1kHz (got %d)\n",			  char2short(trak->stdata,24)/trak->durmap[0].dur);		      sh->samplerate = 44100;		  }  		}  		}		mp_msg(MSGT_DEMUX, MSGL_V, "Audio bits: %d  chans: %d  rate: %d\n",		    sh->samplesize*8,sh->channels,sh->samplerate);		if(trak->stdata_len >= 44 && trak->stdata[9]>=1){		  mp_msg(MSGT_DEMUX,MSGL_V,"Audio header: samp/pack=%d bytes/pack=%d bytes/frame=%d bytes/samp=%d  \n",		    char2int(trak->stdata,28),		    char2int(trak->stdata,32),		    char2int(trak->stdata,36),		    char2int(trak->stdata,40));		  if(trak->stdata_len>=44+8){		    int len=char2int(trak->stdata,44);		    int fcc=char2int(trak->stdata,48);		    // we have extra audio headers!!!		    mp_msg(MSGT_DEMUX,MSGL_V,"Audio extra header: len=%d  fcc=0x%X\n",len,fcc);		    if((len >= 4) && 		       (char2int(trak->stdata,52) >= 12) &&		       (char2int(trak->stdata,52+4) == MOV_FOURCC('f','r','m','a'))) {			switch(char2int(trak->stdata,52+8)) {			 case MOV_FOURCC('a','l','a','c'):			  if (len >= 36 + char2int(trak->stdata,52)) {			    sh->codecdata_len = char2int(trak->stdata,52+char2int(trak->stdata,52));			    mp_msg(MSGT_DEMUX, MSGL_V, "MOV: Found alac atom (%d)!\n", sh->codecdata_len);			    sh->codecdata = malloc(sh->codecdata_len);			    sh->codecdatatype = 1;			    memcpy(sh->codecdata, &trak->stdata[52+char2int(trak->stdata,52)], sh->codecdata_len);			  }			  break;			 case MOV_FOURCC('i','n','2','4'):			 case MOV_FOURCC('i','n','3','2'):			 case MOV_FOURCC('f','l','3','2'):			 case MOV_FOURCC('f','l','6','4'):			  if ((len >= 22) &&			      (char2int(trak->stdata,52+16)==MOV_FOURCC('e','n','d','a')) &&			      (char2short(trak->stdata,52+20))) {

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?