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

📄 demux_mov.c

📁 自己移植的linux下的流媒体播放器原代码,支持mms协议,支持ftp和http协议.
💻 C
📖 第 1 页 / 共 5 页
字号:
		      mp_msg(MSGT_DEMUX, MSGL_INFO, "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_INFO, "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_INFO, "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 = (unsigned char *)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_INFO, "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 = (unsigned char *)malloc(trak->stream_header_len);		        memcpy(trak->stream_header, trak->stdata+pos+8, trak->stream_header_len);		      }	      		      break;		    case 0:		      break;		    default:	      	      mp_msg(MSGT_DEMUX, MSGL_INFO, "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);		// if image size is zero, fallback to display size		if(!sh->disp_w && !sh->disp_h) {		  sh->disp_w=trak->tkdata[77]|(trak->tkdata[76]<<8);		  sh->disp_h=trak->tkdata[81]|(trak->tkdata[80]<<8);		} else if(sh->disp_w!=(trak->tkdata[77]|(trak->tkdata[76]<<8))){		  // codec and display width differ... use display one for aspect		  sh->aspect=trak->tkdata[77]|(trak->tkdata[76]<<8);		  sh->aspect/=trak->tkdata[81]|(trak->tkdata[80]<<8);		}				if(depth>32+8) printf("*** depth = 0x%X\n",depth);		// palettized?		gray = 0;		if (depth > 32) { depth&=31; gray = 1; } // depth > 32 means grayscale		if ((depth == 2) || (depth == 4) || (depth == 8))		  palette_count = (1 << depth);		else		  palette_count = 0;		// emulate BITMAPINFOHEADER:		if (palette_count)		{		  sh->bih=malloc(sizeof(BITMAPINFOHEADER) + palette_count * 4);		  memset(sh->bih,0,sizeof(BITMAPINFOHEADER) + palette_count * 4);		  sh->bih->biSize=40 + palette_count * 4;		  // fetch the relevant fields		  flag = BE_16(&trak->stdata[hdr_ptr]);		  hdr_ptr += 2;		  start = BE_32(&trak->stdata[hdr_ptr]);		  hdr_ptr += 4;		  count_flag = BE_16(&trak->stdata[hdr_ptr]);		  hdr_ptr += 2;		  end = BE_16(&trak->stdata[hdr_ptr]);		  hdr_ptr += 2;		  palette_map = (unsigned char *)sh->bih + 40;		  mp_msg(MSGT_DEMUX, MSGL_INFO, "Allocated %d entries for palette\n",		    palette_count);		  mp_msg(MSGT_DEMUX, MSGL_DBG2, "QT palette: start: %x, end: %x, count flag: %d, flags: %x\n",		    start, end, count_flag, flag);		  /* XXX: problems with sample (statunit6.mov) with flag&0x4 set! - alex*/		  // load default palette		  if (flag & 0x08)		  {		    if (gray)		    {		      mp_msg(MSGT_DEMUX, MSGL_INFO, "Using default QT grayscale palette\n");		      if (palette_count == 16)		        memcpy(palette_map, qt_default_grayscale_palette_16, 16 * 4);		      else if (palette_count == 256) {		        memcpy(palette_map, qt_default_grayscale_palette_256, 256 * 4);		        if (trak->fourcc == mmioFOURCC('c','v','i','d')) {		          int i;		          // Hack for grayscale CVID, negative palette		          // If you have samples where this is not required contact me (rxt)		          mp_msg(MSGT_DEMUX, MSGL_INFO, "MOV: greyscale cvid with default palette,"		            " enabling negative palette hack.\n");		          for (i = 0; i < 256 * 4; i++)		            palette_map[i] = palette_map[i] ^ 0xff;		        }		      }		    }		    else		    {		      mp_msg(MSGT_DEMUX, MSGL_INFO, "Using default QT colour palette\n");		      if (palette_count == 4)		        memcpy(palette_map, qt_default_palette_4, 4 * 4);		      else if (palette_count == 16)		        memcpy(palette_map, qt_default_palette_16, 16 * 4);		      else if (palette_count == 256)		        memcpy(palette_map, qt_default_palette_256, 256 * 4);		    }		  }		  // load palette from file		  else		  {		    mp_msg(MSGT_DEMUX, MSGL_INFO, "Loading palette from file\n");		    for (i = start; i <= end; i++)		    {		      entry = BE_16(&trak->stdata[hdr_ptr]);		      hdr_ptr += 2;		      // apparently, if count_flag is set, entry is same as i		      if (count_flag & 0x8000)		        entry = i;		      // only care about top 8 bits of 16-bit R, G, or B value		      if (entry <= palette_count && entry >= 0)		      {		        palette_map[entry * 4 + 2] = trak->stdata[hdr_ptr + 0];		        palette_map[entry * 4 + 1] = trak->stdata[hdr_ptr + 2];		        palette_map[entry * 4 + 0] = trak->stdata[hdr_ptr + 4];		        mp_dbg(MSGT_DEMUX, MSGL_DBG2, "QT palette: added entry: %d of %d (colors: R:%x G:%x B:%x)\n",			    entry, palette_count,			    palette_map[entry * 4 + 2], 			    palette_map[entry * 4 + 1],			    palette_map[entry * 4 + 0]);		      }		      else		        mp_msg(MSGT_DEMUX, MSGL_V, "QT palette: skipped entry (out of count): %d of %d\n",			    entry, palette_count);		      hdr_ptr += 6;		    }		  }		}		else		{		 if (trak->fourcc == mmioFOURCC('a','v','c','1')) {		  sh->bih=malloc(sizeof(BITMAPINFOHEADER) + trak->stream_header_len);		  memset(sh->bih,0,sizeof(BITMAPINFOHEADER) + trak->stream_header_len);		  sh->bih->biSize=40  + trak->stream_header_len;		  memcpy(((unsigned char *)sh->bih)+40,  trak->stream_header, trak->stream_header_len);		  free (trak->stream_header);		  trak->stream_header_len = 0;		  trak->stream_header = NULL;		 } else {		  sh->bih=malloc(sizeof(BITMAPINFOHEADER));		  memset(sh->bih,0,sizeof(BITMAPINFOHEADER));		  sh->bih->biSize=40;		 }		}		sh->bih->biWidth=sh->disp_w;		sh->bih->biHeight=sh->disp_h;		sh->bih->biPlanes=0;		sh->bih->biBitCount=depth;		sh->bih->biCompression=trak->fourcc;		sh->bih->biSizeImage=sh->bih->biWidth*sh->bih->biHeight;		mp_msg(MSGT_DEMUX, MSGL_INFO, "Image size: %d x %d (%d bpp)\n",sh->disp_w,sh->disp_h,sh->bih->biBitCount);		if(trak->tkdata_len>81)		mp_msg(MSGT_DEMUX, MSGL_INFO, "Display size: %d x %d\n",		    trak->tkdata[77]|(trak->tkdata[76]<<8),		    trak->tkdata[81]|(trak->tkdata[80]<<8));		mp_msg(MSGT_DEMUX, MSGL_INFO, "Fourcc: %.4s  Codec: '%.*s'\n",&trak->fourcc,trak->stdata[42]&31,trak->stdata+43);		//		if(demuxer->video->id==-1 || demuxer->video->id==priv->track_db){//		    // (auto)selected video track://		    demuxer->video->id=priv->track_db;//		    demuxer->video->sh=sh; sh->ds=demuxer->video;//		}		break;	    }	    case MOV_TRAK_GENERIC:		mp_msg(MSGT_DEMUX, MSGL_INFO, "Generic track - not completely understood! (id: %d)\n",		    trak->id);		/* XXX: Also this contains the FLASH data */#if 0	    {		int pos = stream_tell(demuxer->stream);		int i;		int fd;		char name[20];			for (i=0; i<trak->samples_size; i++)		{		    char buf[trak->samples[i].size];		    stream_seek(demuxer->stream, trak->samples[i].pos);		    snprintf((char *)&name[0], 20, "samp%d", i);		    fd = open((char *)&name[0], O_CREAT|O_WRONLY);		    stream_read(demuxer->stream, &buf[0], trak->samples[i].size);		    write(fd, &buf[0], trak->samples[i].size);		    close(fd);		 }		for (i=0; i<trak->chunks_size; i++)		{		    char buf[trak->length];		    stream_seek(demuxer->stream, trak->chunks[i].pos);		    snprintf((char *)&name[0], 20, "chunk%d", i);		    fd = open((char *)&name[0], O_CREAT|O_WRONLY);		    stream_read(demuxer->stream, &buf[0], trak->length);		    write(fd, &buf[0], trak->length);		    close(fd);		 }		 if (trak->samplesize > 0)		 {		    char *buf;		    		    buf = malloc(trak->samplesize);		    stream_seek(demuxer->stream, trak->chunks[0].pos);		    snprintf((char *)&name[0], 20, "trak%d", trak->id);		    fd = open((char *)&name[0], O_CREAT|O_WRONLY);		    stream_read(demuxer->stream, buf, trak->samplesize);		    write(fd, buf, trak->samplesize);		    close(fd);		 }		 stream_seek(demuxer->stream, pos);	    }		#endif		break;	    default:		mp_msg(MSGT_DEMUX, MSGL_INFO, "Unknown track type found (type: %d)\n", trak->type);		break;	    }	    mp_msg(MSGT_DEMUX, MSGL_INFO, "--------------\n");	    priv->track_db++;	    trak=NULL;	    break;	}#ifndef HAVE_ZLIB	case MOV_FOURCC('c','m','o','v'): {	    mp_msg(MSGT_DEMUX,MSGL_ERR,MSGTR_MOVcomprhdr);	    return;	}#else	case MOV_FOURCC('m','o','o','v'):	case MOV_FOURCC('c','m','o','v'): {//	    mp_msg(MSGT_DEMUX,MSGL_ERR,MSGTR_MOVcomprhdr);	    lschunks(demuxer,level+1,pos+len,NULL);	    break;	}	case MOV_FOURCC('d','c','o','m'): {//	    int temp=stream_read_dword(demuxer->stream);	    unsigned int algo=be2me_32(stream_read_dword(demuxer->stream));	    mp_msg(MSGT_DEMUX, MSGL_INFO, "Compressed header uses %.4s algo!\n",&algo);	    break;	}	case MOV_FOURCC('c','m','v','d'): {//	    int temp=stream_read_dword(demuxer->stream);	    unsigned int moov_sz=stream_read_dword(demuxer->stream);	    unsigned int cmov_sz=len-4;	    unsigned char* cmov_buf=malloc(cmov_sz);	    unsigned char* moov_buf=malloc(moov_sz+16);	    int zret;	    z_stream zstrm;	    stream_t* backup;	    mp_msg(MSGT_DEMUX, MSGL_INFO, "Compressed header size: %d / %d\n",cmov_sz,moov_sz);	    stream_read(demuxer->stream,cmov_buf,cmov_sz);	      zstrm.zalloc          = (alloc_func)0;	      zstrm.zfree           = (free_func)0;	      zstrm.opaque          = (voidpf)0;	      zstrm.next_in         = cmov_buf;	      zstrm.avail_in        = cmov_sz;	      zstrm.next_out        = moov_buf;	      zstrm.avail_out       = moov_sz;	    	      zret = inflateInit(&zstrm);	      if (zret != Z_OK)		{ mp_msg(MSGT_DEMUX, MSGL_ERR, "QT cmov: inflateInit err %d\n",zret);		return;		}	      zret = inflate(&zstrm, Z_NO_FLUSH);	      if ((zret != Z_OK) && (zret != Z_STREAM_END))		{ mp_msg(MSGT_DEMUX, MSGL_ERR, "QT cmov inflate: ERR %d\n",zret);		return;		}#if 0	      else {		FILE *DecOut;		DecOut = fopen("Out.bin", "w");		fwrite(moov_buf, 1, moov_sz, DecOut);		fclose(DecOut);	      }#endif	      if(moov_sz != zstrm.total_out)	        mp_msg(MSGT_DEMUX, MSGL_WARN, "Warning! moov size differs cmov: %d  zlib: %d\n",moov_sz,zstrm.total_out);	      zret = inflateEnd(&zstrm);	      	      backup=demuxer->stream;	       demuxer->stream=new_memory_stream(moov_buf,moov_sz);	       stream_skip(demuxer->stream,8);	       lschunks(demuxer,level+1,moov_sz,NULL); // parse uncompr. 'moov'	       //free_stream(demuxer->stream);	      demuxer->stream=backup;	      free(cmov_buf);	      free(moov_buf);	    	      break;	}#endif	case MOV_FOURCC('u','d','t','a'):	{	    unsigned int udta_id;	    off_t udta_len;	    off_t udta_size = len;		    mp_msg(MSGT_DEMUX, MSGL_DBG2, "mov: user data record found\n");	    mp_msg(MSGT_DEMUX, MSGL_V, "Quicktime Clip Info:\n");	    while((len > 8) && (udta_size > 8))	    {		udta_len = stream_read_dword(demuxer->stream);		udta_id = stream_read_dword(demuxer->stream);		udta_size -= 8;		mp_msg(MSGT_DEMUX, MSGL_DBG2, "udta_id: %.4s (len: %d)\n", &udta_id, udta_len);		switch (udta_id)		{		    case MOV_FOURCC(0xa9,'c','p','y'):		    case MOV_FOURCC(0xa9,'d','a','y'):		    case MOV_FOURCC(0xa9,'d','i','r'):		    /* 0xa9,'e','d','1' - '9' : edit timestamps */

⌨️ 快捷键说明

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