⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 demux_mov.c

📁 自己移植的linux下的流媒体播放器原代码,支持mms协议,支持ftp和http协议.
💻 C
📖 第 1 页 / 共 5 页
字号:
		trak->keyframes=malloc(sizeof(unsigned int)*entries);		for (i=0;i<entries;i++)		    trak->keyframes[i]=stream_read_dword(demuxer->stream)-1;//		for (i=0;i<entries;i++) printf("%3d: %d\n",i,trak->keyframes[i]);		break;	    }	    case MOV_FOURCC('m','d','i','a'): {		mp_msg(MSGT_DEMUX,MSGL_V,"MOV: %*sMedia stream!\n",level,"");		lschunks(demuxer,level+1,pos+len,trak);		break;	    }	    case MOV_FOURCC('m','i','n','f'): {		mp_msg(MSGT_DEMUX,MSGL_V,"MOV: %*sMedia info!\n",level,"");		lschunks(demuxer,level+1,pos+len,trak);		break;	    }	    case MOV_FOURCC('s','t','b','l'): {		mp_msg(MSGT_DEMUX,MSGL_V,"MOV: %*sSample info!\n",level,"");		lschunks(demuxer,level+1,pos+len,trak);		break;	    }	    case MOV_FOURCC('e','d','t','s'): {		mp_msg(MSGT_DEMUX, MSGL_V, "MOV: %*sEdit atom!\n", level, "");		lschunks(demuxer,level+1,pos+len,trak);		break;	    }	    case MOV_FOURCC('e','l','s','t'): {		int temp=stream_read_dword(demuxer->stream);		int entries=stream_read_dword(demuxer->stream);		int ver = (temp << 24);		int flags = (temp << 16)|(temp<<8)|temp;		int i;			mp_msg(MSGT_DEMUX, MSGL_V,"MOV: %*sEdit list table (%d entries) (ver:%d,flags:%ld)\n",		    level, "",entries, ver, flags);#if 1		trak->editlist_size=entries;		trak->editlist=malloc(trak->editlist_size*sizeof(mov_editlist_t));		for (i=0;i<entries;i++)		{		    int dur=stream_read_dword(demuxer->stream);		    int mt=stream_read_dword(demuxer->stream);		    int mr=stream_read_dword(demuxer->stream); // 16.16fp		    trak->editlist[i].dur=dur;		    trak->editlist[i].pos=mt;		    trak->editlist[i].speed=mr;		    mp_msg(MSGT_DEMUX, MSGL_V,"MOV: %*s  entry#%d: duration: %d  start time: %d  speed: %3.1fx\n",level,"",			i,			dur,mt,(float)mr/65536.0f);		}#endif		break;	    }	    case MOV_FOURCC('c','o','d','e'):	    {	    /* XXX: Implement atom 'code' for FLASH support */	    }	    default:		id = be2me_32(id);		mp_msg(MSGT_DEMUX,MSGL_V,"MOV: unknown chunk: %.4s %d\n",&id,(int)len);		break;	  }//switch(id)	} else { /* not in track */	  switch(id) {	    case MOV_FOURCC('m','v','h','d'): {		stream_skip(demuxer->stream,12);		priv->timescale=stream_read_dword(demuxer->stream);		priv->duration=stream_read_dword(demuxer->stream);		mp_msg(MSGT_DEMUX, MSGL_V,"MOV: %*sMovie header (%d bytes): tscale=%d  dur=%d\n",level,"",(int)len,		    (int)priv->timescale,(int)priv->duration);		break;	    }	    case MOV_FOURCC('t','r','a','k'): {//	    if(trak) printf("MOV: Warning! trak in trak?\n");	    if(priv->track_db>=MOV_MAX_TRACKS){		mp_msg(MSGT_DEMUX,MSGL_WARN,MSGTR_MOVtooManyTrk);		return;	    }	    if(!priv->track_db) mp_msg(MSGT_DEMUX, MSGL_INFO, "--------------\n");	    trak=malloc(sizeof(mov_track_t));	    memset(trak,0,sizeof(mov_track_t));	    mp_msg(MSGT_DEMUX,MSGL_V,"MOV: Track #%d:\n",priv->track_db);	    trak->id=priv->track_db;	    priv->tracks[priv->track_db]=trak;	    lschunks(demuxer,level+1,pos+len,trak);	    mov_build_index(trak,priv->timescale);	    switch(trak->type){	    case MOV_TRAK_AUDIO: {#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				sh_audio_t* sh=new_sh_audio(demuxer,priv->track_db);		sh->format=trak->fourcc;		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)		trak->samplebytes=sh->samplesize=char2short(trak->stdata,18)/8;		trak->nchannels=sh->channels=char2short(trak->stdata,16);		/*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) {		  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_INFO, "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!!!		    printf("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')) &&		       (char2int(trak->stdata,52+8) == MOV_FOURCC('a','l','a','c')) &&		       (len >= 36 + char2int(trak->stdata,52))) {			    sh->codecdata_len = char2int(trak->stdata,52+char2int(trak->stdata,52));			    mp_msg(MSGT_DEMUX, MSGL_INFO, "MOV: Found alac atom (%d)!\n", sh->codecdata_len);			    sh->codecdata = (unsigned char *)malloc(sh->codecdata_len);			    memcpy(sh->codecdata, &trak->stdata[52+char2int(trak->stdata,52)], sh->codecdata_len);		    } else {		    sh->codecdata_len = len-8;		    sh->codecdata = trak->stdata+44+8;		    }		  }		}		if((trak->stdata[9]==0 || trak->stdata[9]==1) && trak->stdata_len >= 36) { // version 0 with extra atoms        int adjust = (trak->stdata[9]==1)?48:0;		    int atom_len = char2int(trak->stdata,28+adjust);		    switch(char2int(trak->stdata,32+adjust)) { // atom type		      case MOV_FOURCC('e','s','d','s'): {			mp_msg(MSGT_DEMUX, MSGL_INFO, "MOV: Found MPEG4 audio Elementary Stream Descriptor atom (%d)!\n", atom_len);			if(atom_len > 8) {			  esds_t esds; 				  			  if(!mp4_parse_esds(&trak->stdata[36+adjust], atom_len-8, &esds)) {			    			    sh->i_bps = esds.avgBitrate/8; //			    printf("######## audio format = %d ########\n",esds.objectTypeId);			    if(esds.objectTypeId==MP4OTI_MPEG1Audio || esds.objectTypeId==MP4OTI_MPEG2AudioPart3)				sh->format=0x55; // .mp3			    // dump away the codec specific configuration for the AAC decoder			    if(esds.decoderConfigLen){			    if( (esds.decoderConfig[0]>>3) == 29 )			    	sh->format = 0x1d61346d; // request multi-channel mp3 decoder			    sh->codecdata_len = esds.decoderConfigLen;			    sh->codecdata = (unsigned char *)malloc(sh->codecdata_len);			    memcpy(sh->codecdata, esds.decoderConfig, sh->codecdata_len);			    }			  }			  mp4_free_esds(&esds); // freeup esds mem#if 0	  		  { FILE* f=fopen("esds.dat","wb");			  fwrite(&trak->stdata[36],atom_len-8,1,f);			  fclose(f); }#endif			  			}		      } break;		      case MOV_FOURCC('a','l','a','c'): {			mp_msg(MSGT_DEMUX, MSGL_INFO, "MOV: Found alac atom (%d)!\n", atom_len);			if(atom_len > 8) {			    // copy all the atom (not only payload) for lavc alac decoder			    sh->codecdata_len = atom_len;			    sh->codecdata = (unsigned char *)malloc(sh->codecdata_len);			    memcpy(sh->codecdata, &trak->stdata[28], sh->codecdata_len);			}		      } break;		      default:			mp_msg(MSGT_DEMUX, MSGL_INFO, "MOV: Found unknown audio atom %c%c%c%c (%d)!\n",			    trak->stdata[32+adjust],trak->stdata[33+adjust],trak->stdata[34+adjust],trak->stdata[35+adjust],			    atom_len);		    }		}  		mp_msg(MSGT_DEMUX, MSGL_INFO, "Fourcc: %.4s\n",&trak->fourcc);#if 0		{ FILE* f=fopen("stdata.dat","wb");		  fwrite(trak->stdata,trak->stdata_len,1,f);		  fclose(f); }		{ FILE* f=fopen("tkdata.dat","wb");		  fwrite(trak->tkdata,trak->tkdata_len,1,f);		  fclose(f); }#endif		// Emulate WAVEFORMATEX struct:		sh->wf=malloc(sizeof(WAVEFORMATEX));		memset(sh->wf,0,sizeof(WAVEFORMATEX));		sh->wf->nChannels=sh->channels;		sh->wf->wBitsPerSample=(trak->stdata[18]<<8)+trak->stdata[19];		// sh->wf->nSamplesPerSec=trak->timescale;		sh->wf->nSamplesPerSec=(trak->stdata[24]<<8)+trak->stdata[25];		if(trak->stdata_len >= 44 && trak->stdata[9]>=1 && char2int(trak->stdata,28)>0){		//Audio header: samp/pack=4096 bytes/pack=743 bytes/frame=1486 bytes/samp=2		  sh->wf->nAvgBytesPerSec=(sh->wf->nChannels*sh->wf->nSamplesPerSec*		      char2int(trak->stdata,32)+char2int(trak->stdata,28)/2)		      /char2int(trak->stdata,28);		  sh->wf->nBlockAlign=char2int(trak->stdata,36);		} else {		  sh->wf->nAvgBytesPerSec=sh->wf->nChannels*sh->wf->wBitsPerSample*sh->wf->nSamplesPerSec/8;		  // workaround for ms11 ima4		  if (sh->format == 0x1100736d && trak->stdata_len >= 36)		      sh->wf->nBlockAlign=char2int(trak->stdata,36);		}		// Selection://		if(demuxer->audio->id==-1 || demuxer->audio->id==priv->track_db){//		    // (auto)selected audio track://		    demuxer->audio->id=priv->track_db;//		    demuxer->audio->sh=sh; sh->ds=demuxer->audio;//		}		break;	    }	    case MOV_TRAK_VIDEO: {		int i, entry;		int flag, start, count_flag, end, palette_count, gray;		int hdr_ptr = 76;  // the byte just after depth		unsigned char *palette_map;		sh_video_t* sh=new_sh_video(demuxer,priv->track_db);		int depth = trak->stdata[75]|(trak->stdata[74]<<8);		sh->format=trak->fourcc;//  stdata[]://	8   short	version//	10  short	revision//	12  int		vendor_id//	16  int		temporal_quality//	20  int		spatial_quality//	24  short	width//	26  short	height//	28  int		h_dpi//	32  int		v_dpi//	36  int		0//	40  short	frames_per_sample//	42  char[4]	compressor_name//	74  short	depth//	76  short	color_table_id// additional atoms may follow,// eg esds atom from .MP4 files//      78  int		atom size//      82  char[4]	atom type//	86  ...		atom data	{	ImageDescription* id=malloc(8+trak->stdata_len);		trak->desc=id;		id->idSize=8+trak->stdata_len;//		id->cType=bswap_32(trak->fourcc);		id->cType=le2me_32(trak->fourcc);		id->version=char2short(trak->stdata,8);		id->revisionLevel=char2short(trak->stdata,10);		id->vendor=char2int(trak->stdata,12);		id->temporalQuality=char2int(trak->stdata,16);		id->spatialQuality=char2int(trak->stdata,20);		id->width=char2short(trak->stdata,24);		id->height=char2short(trak->stdata,26);		id->hRes=char2int(trak->stdata,28);		id->vRes=char2int(trak->stdata,32);		id->dataSize=char2int(trak->stdata,36);		id->frameCount=char2short(trak->stdata,40);		memcpy(&id->name,trak->stdata+42,32);		id->depth=char2short(trak->stdata,74);		id->clutID=char2short(trak->stdata,76);		if(trak->stdata_len>78)	memcpy(((char*)&id->clutID)+2,trak->stdata+78,trak->stdata_len-78);		sh->ImageDesc=id;#if 0		{   FILE *f=fopen("ImageDescription","wb");		    fwrite(id,id->idSize,1,f);		    fclose(f);		}#endif	}		if(trak->stdata_len >= 86) { // extra atoms found		  int pos=78;		  int atom_len;		  while(pos+8<=trak->stdata_len &&		    (pos+(atom_len=char2int(trak->stdata,pos)))<=trak->stdata_len){		   switch(char2int(trak->stdata,pos+4)) { // switch atom type		    case MOV_FOURCC('g','a','m','a'):		      // intfp with gamma value at which movie was captured		      // can be used to gamma correct movie display		      mp_msg(MSGT_DEMUX, MSGL_INFO, "MOV: Found unsupported Gamma-Correction movie atom (%d)!\n",			  atom_len);		      break;		    case MOV_FOURCC('f','i','e','l'):		      // 2 char-values (8bit int) that specify field handling		      // see the Apple's QuickTime Fileformat PDF for more info		      mp_msg(MSGT_DEMUX, MSGL_INFO, "MOV: Found unsupported Field-Handling movie atom (%d)!\n",			  atom_len);		      break;		    case MOV_FOURCC('m','j','q','t'):		      // Motion-JPEG default quantization table

⌨️ 快捷键说明

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