demux_mov.c

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

C
1,854
字号
				sh->format=char2int(trak->stdata,52+8);				mp_msg(MSGT_DEMUX, MSGL_V, "MOV: Found little endian PCM data, reversed fourcc:%04x\n", sh->format);			  }		          break;		         default:			  if (len > 8 && len + 44 <= trak->stdata_len) {				sh->codecdata_len = len-8;				sh->codecdata = trak->stdata+44+8;			  }		        }		    } else {		      if (len > 8 && len + 44 <= trak->stdata_len) {		    sh->codecdata_len = len-8;		    sh->codecdata = trak->stdata+44+8;		      }		    }		  }		}		switch (version) {		  case 0:		    adjust =  0; break;		  case 1:		    adjust = 48; break;		  case 2:		    adjust = 68; break;		  default:		    mp_msg(MSGT_DEMUX, MSGL_WARN, "MOV: unknown sound atom version (%d); may not work!\n", version);		    adjust = 68;		}		if (trak->stdata_len >= 36 + adjust) {		    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_V, "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)) {			    /* 0xdd is a "user private" id, not an official allocated id (see http://www.mp4ra.org/object.html),			       so perform some extra checks to be sure that this is really vorbis audio */			    if(esds.objectTypeId==0xdd && esds.streamType==0x15 && sh->format==0x6134706D && esds.decoderConfigLen > 8)				{					//vorbis audio					unsigned char *buf[3];					unsigned short sizes[3];					int offset, len, k;					unsigned char *ptr = esds.decoderConfig;					if(ptr[0] != 0 || ptr[1] != 30) goto quit_vorbis_block; //wrong extradata layout					offset = len = 0;					for(k = 0; k < 3; k++)					{						sizes[k] = (ptr[offset]<<8) | ptr[offset+1];						len += sizes[k];						offset += 2;						if(offset + sizes[k] > esds.decoderConfigLen)						{							mp_msg(MSGT_DEMUX, MSGL_FATAL, "MOV: ERROR!, not enough vorbis extradata to read: offset = %d, k=%d, size=%d, len: %d\n", offset, k, sizes[k], esds.decoderConfigLen);							goto quit_vorbis_block;						}						buf[k] = malloc(sizes[k]);						if(!buf[k]) goto quit_vorbis_block;						memcpy(buf[k], &ptr[offset], sizes[k]);						offset += sizes[k];					}					sh->codecdata_len = len + len/255 + 64;					sh->codecdata = malloc(sh->codecdata_len);					sh->codecdatatype = 1;					ptr = sh->codecdata;										ptr[0] = 2;					offset = 1;					offset += store_ughvlc(&ptr[offset], sizes[0]);					offset += store_ughvlc(&ptr[offset], sizes[1]);					for(k = 0; k < 3; k++) 					{						memcpy(&ptr[offset], buf[k], sizes[k]);						offset += sizes[k];					}					sh->codecdata_len = offset;					sh->codecdata = realloc(sh->codecdata, offset);					mp_msg(MSGT_DEMUX,MSGL_V, "demux_mov, vorbis extradata size: %d\n", offset);					is_vorbis = 1;quit_vorbis_block:					sh->format = mmioFOURCC('v', 'r', 'b', 's');				}			    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			    if(esds.objectTypeId==MP4OTI_13kVoice) { // 13K Voice, defined by 3GPP2				sh->format=mmioFOURCC('Q', 'c', 'l', 'p');				trak->nchannels=sh->channels=1;				trak->samplebytes=sh->samplesize=1;			    }			    // 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			    if(!is_vorbis)			    {			    sh->codecdata_len = esds.decoderConfigLen;			    sh->codecdata = malloc(sh->codecdata_len);			    sh->codecdatatype = 1;			    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_V, "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 = malloc(sh->codecdata_len);			    sh->codecdatatype = 1;			    memcpy(sh->codecdata, &trak->stdata[28], sh->codecdata_len);			}		      } break;                      case MOV_FOURCC('d','a','m','r'):                        mp_msg(MSGT_DEMUX, MSGL_V, "MOV: Found AMR 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);                        if (atom_len>14) {                          mp_msg(MSGT_DEMUX, MSGL_V, "mov: vendor: %c%c%c%c Version: %d\n",trak->stdata[36+adjust],trak->stdata[37+adjust],trak->stdata[38+adjust], trak->stdata[39+adjust],trak->stdata[40+adjust]);                          mp_msg(MSGT_DEMUX, MSGL_V, "MOV: Modes set: %02x%02x\n",trak->stdata[41+adjust],trak->stdata[42+adjust]);                          mp_msg(MSGT_DEMUX, MSGL_V, "MOV: Mode change period: %d Frames per sample: %d\n",trak->stdata[43+adjust],trak->stdata[44+adjust]);                        }                        break;		      default:			mp_msg(MSGT_DEMUX, MSGL_V, "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_V, "Fourcc: %.4s\n",(char *)&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) + (is_vorbis ? sh->codecdata_len : 0));		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=sh->samplerate;		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);		}		if(is_vorbis && sh->codecdata_len)		{			memcpy(sh->wf+1, sh->codecdata, sh->codecdata_len);			sh->wf->cbSize = sh->codecdata_len;		}		// 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;//		}    return 1;}static int gen_sh_video(sh_video_t* sh, mov_track_t* trak, int timescale) {		int depth, 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->format=trak->fourcc;		// crude video 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 Video-Delay: %.3f sec\n", sh->stream_delay);		    }		}		if (trak->stdata_len < 78) {		  mp_msg(MSGT_DEMUXER, MSGL_WARN,		  "MOV: Invalid (%d bytes instead of >= 78) video trak desc\n",		  trak->stdata_len);		  return 0;		}		depth = trak->stdata[75] | (trak->stdata[74] << 8);//  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);  // safe		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_V, "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_V, "MOV: Found unsupported Field-Handling movie atom (%d)!\n",			  atom_len);		      break;		    case MOV_FOURCC('m','j','q','t'):		      // Motion-JPEG default quantization table		      mp_msg(MSGT_DEMUX, MSGL_V, "MOV: Found unsupported MJPEG-Quantization movie atom (%d)!\n",			  atom_len);		      break;		    case MOV_FOURCC('m','j','h','t'):		      // Motion-JPEG default huffman table		      mp_msg(MSGT_DEMUX, MSGL_V, "MOV: Found unsupported MJPEG-Huffman movie atom (%d)!\n",			  atom_len);		      break;		    case MOV_FOURCC('e','s','d','s'):		      // MPEG4 Elementary Stream Descriptor header		      mp_msg(MSGT_DEMUX, MSGL_V, "MOV: Found MPEG4 movie Elementary Stream Descriptor atom (%d)!\n", atom_len);		      // add code here to save esds header of length atom_len-8		      // beginning at stdata[86] to some variable to pass it		      // on to the decoder ::atmos		      if(atom_len > 8) {      			esds_t esds; 				  			if(!mp4_parse_esds(trak->stdata+pos+8, atom_len-8, &esds)) {    			  if(esds.objectTypeId==MP4OTI_MPEG2VisualSimple || esds.objectTypeId==MP4OTI_MPEG2VisualMain ||			     esds.objectTypeId==MP4OTI_MPEG2VisualSNR || esds.objectTypeId==MP4OTI_MPEG2VisualSpatial ||			     esds.objectTypeId==MP4OTI_MPEG2VisualHigh || esds.objectTypeId==MP4OTI_MPEG2Visual422)			    sh->format=mmioFOURCC('m', 'p', 'g', '2');			  else if(esds.objectTypeId==MP4OTI_MPEG1Visual)			    sh->format=mmioFOURCC('m', 'p', 'g', '1');			  // dump away the codec specific configuration for the AAC decoder			  trak->stream_header_len = esds.decoderConfigLen;			  trak->stream_header = malloc(trak->stream_header_len);			  memcpy(trak->stream_header, esds.decoderConfig, trak->stream_header_len);			}			mp4_free_esds(&esds); // freeup esds mem		      }	      		      break;		    case MOV_FOURCC('a','v','c','C'):		      // AVC decoder configuration record		      mp_msg(MSGT_DEMUX, MSGL_V, "MOV: AVC decoder configuration record atom (%d)!\n", atom_len);		      if(atom_len > 8) {		        int i, poffs, cnt;		        // Parse some parts of avcC, just for fun :)		        // real parsing is done by avc1 decoder		        mp_msg(MSGT_DEMUX, MSGL_V, "MOV: avcC version: %d\n", *(trak->stdata+pos+8));		        if (*(trak->stdata+pos+8) != 1)		          mp_msg(MSGT_DEMUX, MSGL_ERR, "MOV: unknown avcC version (%d). Expexct problems.\n", *(trak->stdata+pos+9));		        mp_msg(MSGT_DEMUX, MSGL_V, "MOV: avcC profile: %d\n", *(trak->stdata+pos+9));		        mp_msg(MSGT_DEMUX, MSGL_V, "MOV: avcC profile compatibility: %d\n", *(trak->stdata+pos+10));		        mp_msg(MSGT_DEMUX, MSGL_V, "MOV: avcC level: %d\n", *(trak->stdata+pos+11));		        mp_msg(MSGT_DEMUX, MSGL_V, "MOV: avcC nal length size: %d\n", ((*(trak->stdata+pos+12))&0x03)+1);		        mp_msg(MSGT_DEMUX, MSGL_V, "MOV: avcC number of sequence param sets: %d\n", cnt = (*(trak->stdata+pos+13) & 0x1f));		        poffs = pos + 14;		        for (i = 0; i < cnt; i++) {		          mp_msg(MSGT_DEMUX, MSGL_V, "MOV: avcC sps %d have length %d\n", i, BE_16(trak->stdata+poffs));		          poffs += BE_16(trak->stdata+poffs) + 2;		        }		        mp_msg(MSGT_DEMUX, MSGL_V, "MOV: avcC number of picture param sets: %d\n", *(trak->stdata+poffs));		        poffs++;		        for (i = 0; i < cnt; i++) {		          mp_msg(MSGT_DEMUX, MSGL_V, "MOV: avcC pps %d have length %d\n", i, BE_16(trak->stdata+poffs));		          poffs += BE_16(trak->stdata+poffs) + 2;		        }		        // Copy avcC for the AVC decoder		        // This data will be put in extradata below, where BITMAPINFOHEADER is created		        trak->stream_header_len = atom_len-8;		        trak->stream_header = malloc(trak->stream_header_len);		        memcpy(trak->stream_header, trak->stdata+pos+8, trak->stream_header_len);		      }	      		      break;                    case MOV_FOURCC('d','2','6','3'):                      mp_msg(MSGT_DEMUX, MSGL_V, "MOV: Found H.263 decoder atom %c%c%c%c (%d)!\n", trak->stdata[pos+4],trak->stdata[pos+5],trak->stdata[pos+6],trak->stdata[pos+7],atom_len);              	      if (atom_len>10)                        mp_msg(MSGT_DEMUX, MSGL_V, "MOV: Vendor: %c%c%c%c H.263 level: %d H.263 profile: %d \n", trak->stdata[pos+8],trak->stdata[pos+9],trak->stdata[pos+10],trak->stdata[pos+11],trak->stdata[pos+12],trak->stdata[pos+13]);                      break;		    case 0:		      break;		    default:	      	      mp_msg(MSGT_DEMUX, MSGL_V, "MOV: Found unknown movie atom %c%c%c%c (%d)!\n",	      		  trak->stdata[pos+4],trak->stdata[pos+5],trak->stdata[pos+6],trak->stdata[pos+7],	      		  atom_len);		   }		   if(atom_len<8) break;		   pos+=atom_len;//		   printf("pos=%d max=%d\n",pos,trak->stdata_len);		  }		}		sh->fps=trak->timescale/		    ((trak->durmap_size>=1)?(float)trak->durmap[0].dur:1);		sh->frametime=1.0f/sh->fps;		sh->disp_w=trak->stdata[25]|(trak->stdata[24]<<8);		sh->disp_h=trak->stdata[27]|(trak->stdata[26]<<8);

⌨️ 快捷键说明

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