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

📄 aviheader.c

📁 自己移植的linux下的流媒体播放器原代码,支持mms协议,支持ftp和http协议.
💻 C
📖 第 1 页 / 共 2 页
字号:
      priv->idx=malloc(priv->idx_size<<4);//      printf("\nindex to %p !!!!! (priv=%p)\n",priv->idx,priv);      stream_read(demuxer->stream,(char*)priv->idx,priv->idx_size<<4);      for (i = 0; i < priv->idx_size; i++) {	// swap index to machine endian	AVIINDEXENTRY *entry=(AVIINDEXENTRY*)priv->idx + i;	le2me_AVIINDEXENTRY(entry);	/*	 * We (ab)use the upper word for bits 32-47 of the offset, so	 * we'll clear them here.	 * FIXME: AFAIK no codec uses them, but if one does it will break	 */	entry->dwFlags&=0xffff;      }      chunksize-=priv->idx_size<<4;      if(verbose>=2) print_index(priv->idx,priv->idx_size);    }    break;    /* added May 2002 */    case mmioFOURCC('R','I','F','F'): {	char riff_type[4];	mp_msg(MSGT_HEADER, MSGL_V, "additional RIFF header...\n");	stream_read(demuxer->stream, riff_type, sizeof riff_type);	if (strncmp(riff_type, "AVIX", sizeof riff_type))	    mp_msg(MSGT_HEADER, MSGL_WARN,		   "** warning: this is no extended AVI header..\n");	else {		/*		 * We got an extended AVI header, so we need to switch to		 * ODML to get seeking to work, provided we got indx chunks		 * in the header (suidx_size > 0).		 */		if (priv->suidx_size > 0)			priv->isodml = 1;	}	chunksize = 0;	list_end = 0; /* a new list will follow */	break; }    case ckidAVIPADDING:	stream_skip(demuxer->stream, chunksize);	chunksize = 0;	break;  }  if(hdr){    mp_msg(MSGT_HEADER,MSGL_V,"hdr=%s  size=%u\n",hdr,size2);    if(size2==3)      chunksize=1; // empty    else {      char buf[256];      int len=(size2<250)?size2:250;      stream_read(demuxer->stream,buf,len);      chunksize-=len;      buf[len]=0;      mp_msg(MSGT_HEADER,MSGL_V,"%-10s: %s\n",hdr,buf);      demux_info_add(demuxer, hdr, buf);    }  }  mp_msg(MSGT_HEADER,MSGL_DBG2,"list_end=0x%X  pos=0x%X  chunksize=0x%X  next=0x%X\n",      (int)list_end, (int)stream_tell(demuxer->stream),      chunksize, (int)chunksize+stream_tell(demuxer->stream));  if(list_end>0 &&     chunksize+stream_tell(demuxer->stream) == list_end) list_end=0;  if(list_end>0 && chunksize+stream_tell(demuxer->stream)>list_end){      mp_msg(MSGT_HEADER,MSGL_V,"Broken chunk?  chunksize=%d  (id=%.4s)\n",chunksize,(char *) &id);      stream_seek(demuxer->stream,list_end);      list_end=0;  } else  if(chunksize>0) stream_skip(demuxer->stream,chunksize); else  if((int)chunksize<0) mp_msg(MSGT_HEADER,MSGL_WARN,"chunksize=%u  (id=%.4s)\n",chunksize,(char *) &id);  }if (priv->suidx_size > 0 && priv->idx_size == 0) {    /*     * No NEWAVIINDEX, but we got an OpenDML index.     */    priv->isodml = 1;}if (priv->isodml && (index_mode==-1 || index_mode==0)) {    int i, j, k;    int safety=1000;    avisuperindex_chunk *cx;    AVIINDEXENTRY *idx;    if (priv->idx_size) free(priv->idx);    priv->idx_size = 0;    priv->idx_offset = 0;    priv->idx = NULL;    mp_msg(MSGT_HEADER, MSGL_INFO, 	    "AVI: ODML: Building odml index (%d superindexchunks)\n", priv->suidx_size);    // read the standard indices    for (cx = &priv->suidx[0], i=0; i<priv->suidx_size; cx++, i++) {	stream_reset(demuxer->stream);	for (j=0; j<cx->nEntriesInUse; j++) {	    int ret1, ret2;	    memset(&cx->stdidx[j], 0, 32);	    ret1 = stream_seek(demuxer->stream, (off_t)cx->aIndex[j].qwOffset);	    ret2 = stream_read(demuxer->stream, (char *)&cx->stdidx[j], 32);	    if (ret1 != 1 || ret2 != 32 || cx->stdidx[j].nEntriesInUse==0) {		// this is a broken file (probably incomplete) let the standard		// gen_index routine handle this		priv->isodml = 0;		priv->idx_size = 0;		mp_msg(MSGT_HEADER, MSGL_WARN,			"AVI: ODML: Broken (incomplete?) file detected. Will use traditional index\n");		goto freeout;	    }	    le2me_AVISTDIDXCHUNK(&cx->stdidx[j]);	    print_avistdindex_chunk(&cx->stdidx[j]);	    priv->idx_size += cx->stdidx[j].nEntriesInUse;	    cx->stdidx[j].aIndex = malloc(cx->stdidx[j].nEntriesInUse*sizeof(avistdindex_entry));	    stream_read(demuxer->stream, (char *)cx->stdidx[j].aIndex, 		    cx->stdidx[j].nEntriesInUse*sizeof(avistdindex_entry));	    for (k=0;k<cx->stdidx[j].nEntriesInUse; k++)		le2me_AVISTDIDXENTRY(&cx->stdidx[j].aIndex[k]);	    cx->stdidx[j].dwReserved3 = 0;	}    }    /*     * We convert the index by translating all entries into AVIINDEXENTRYs     * and sorting them by offset.  The result should be the same index     * we would get with -forceidx.     */    idx = priv->idx = malloc(priv->idx_size * sizeof (AVIINDEXENTRY));    for (cx = priv->suidx; cx != &priv->suidx[priv->suidx_size]; cx++) {	avistdindex_chunk *sic;	for (sic = cx->stdidx; sic != &cx->stdidx[cx->nEntriesInUse]; sic++) {	    avistdindex_entry *sie;	    for (sie = sic->aIndex; sie != &sic->aIndex[sic->nEntriesInUse]; sie++) {		uint64_t off = sic->qwBaseOffset + sie->dwOffset - 8;		memcpy(&idx->ckid, sic->dwChunkId, 4);		idx->dwChunkOffset = off;		idx->dwFlags = (off >> 32) << 16;		idx->dwChunkLength = sie->dwSize & 0x7fffffff;		idx->dwFlags |= (sie->dwSize&0x80000000)?0x0:AVIIF_KEYFRAME; // bit 31 denotes !keyframe		idx++;	    }	}    }    qsort(priv->idx, priv->idx_size, sizeof(AVIINDEXENTRY), avi_idx_cmp);    /*       Hack to work around a "wrong" index in some divx odml files       (processor_burning.avi as an example)       They have ##dc on non keyframes but the ix00 tells us they are ##db.       Read the fcc of a non-keyframe vid frame and check it.     */    {	uint32_t id;	uint32_t db = 0;	stream_reset (demuxer->stream);	// find out the video stream id. I have seen files with 01db.	for (idx = &((AVIINDEXENTRY *)priv->idx)[0], i=0; i<priv->idx_size; i++, idx++){	    unsigned char res[2];	    if (odml_get_vstream_id(idx->ckid, res)) {		db = mmioFOURCC(res[0], res[1], 'd', 'b');		break;	    }	}	// find first non keyframe	for (idx = &((AVIINDEXENTRY *)priv->idx)[0], i=0; i<priv->idx_size; i++, idx++){	    if (!(idx->dwFlags & AVIIF_KEYFRAME) && idx->ckid == db) break;	}	if (i<priv->idx_size && db) {	    stream_seek(demuxer->stream, AVI_IDX_OFFSET(idx));	    id = stream_read_dword_le(demuxer->stream);	    if (id && id != db) // index fcc and real fcc differ? fix it.		for (idx = &((AVIINDEXENTRY *)priv->idx)[0], i=0; i<priv->idx_size; i++, idx++){		    if (!(idx->dwFlags & AVIIF_KEYFRAME) && idx->ckid == db)			idx->ckid = id;	    }	}    }    if (verbose>=2) print_index(priv->idx, priv->idx_size);    demuxer->movi_end=demuxer->stream->end_pos;freeout:    // free unneeded stuff    cx = &priv->suidx[0];    do {	for (j=0;j<cx->nEntriesInUse;j++)	    if (cx->stdidx[j].nEntriesInUse) free(cx->stdidx[j].aIndex);	free(cx->stdidx);    } while (cx++ != &priv->suidx[priv->suidx_size-1]);    free(priv->suidx);}/* Read a saved index file */if (index_file_load) {  FILE *fp;  char magic[7];  unsigned int i;  if ((fp = fopen(index_file_load, "r")) == NULL) {    mp_msg(MSGT_HEADER,MSGL_ERR, "Can't read index file %s: %s\n", index_file_load, strerror(errno));    goto gen_index;  }  fread(&magic, 6, 1, fp);  if (strncmp(magic, "MPIDX1", 6)) {    mp_msg(MSGT_HEADER,MSGL_ERR, "%s is not a valid MPlayer index file\n", index_file_load);    goto gen_index;  }  fread(&priv->idx_size, sizeof(priv->idx_size), 1, fp);  priv->idx=malloc(priv->idx_size*sizeof(AVIINDEXENTRY));  if (!priv->idx) {    mp_msg(MSGT_HEADER,MSGL_ERR, "Could not allocate memory for index data from %s\n", index_file_load);    priv->idx_size = 0;    goto gen_index;  }  for (i=0; i<priv->idx_size;i++) {    AVIINDEXENTRY *idx;    idx=&((AVIINDEXENTRY *)priv->idx)[i];    fread(idx, sizeof(AVIINDEXENTRY), 1, fp);    if (feof(fp)) {      mp_msg(MSGT_HEADER,MSGL_ERR, "Premature end of index file %s\n", index_file_load);      free(priv->idx);      priv->idx_size = 0;      goto gen_index;    }  }  fclose(fp);  mp_msg(MSGT_HEADER,MSGL_INFO, "Loaded index file: %s\n", index_file_load);}gen_index:if(index_mode>=2 || (priv->idx_size==0 && index_mode==1)){  // build index for file:  stream_reset(demuxer->stream);  stream_seek(demuxer->stream,demuxer->movi_start);    priv->idx_pos=0;  priv->idx_size=0;  priv->idx=NULL;  while(1){    int id;    unsigned len;    off_t skip;    AVIINDEXENTRY* idx;    unsigned int c;    demuxer->filepos=stream_tell(demuxer->stream);    if(demuxer->filepos>=demuxer->movi_end && demuxer->movi_start<demuxer->movi_end) break;    id=stream_read_dword_le(demuxer->stream);    len=stream_read_dword_le(demuxer->stream);    if(id==mmioFOURCC('L','I','S','T') || id==mmioFOURCC('R', 'I', 'F', 'F')){      id=stream_read_dword_le(demuxer->stream); // list or RIFF type      continue;    }    if(stream_eof(demuxer->stream)) break;    if(!id || avi_stream_id(id)==100) goto skip_chunk; // bad ID (or padding?)    if(priv->idx_pos>=priv->idx_size){//      priv->idx_size+=32;      priv->idx_size+=1024; // +16kB      priv->idx=realloc(priv->idx,priv->idx_size*sizeof(AVIINDEXENTRY));      if(!priv->idx){priv->idx_pos=0; break;} // error!    }    idx=&((AVIINDEXENTRY *)priv->idx)[priv->idx_pos++];    idx->ckid=id;    idx->dwFlags=AVIIF_KEYFRAME; // FIXME    idx->dwFlags|=(demuxer->filepos>>16)&0xffff0000U;    idx->dwChunkOffset=(unsigned long)demuxer->filepos;    idx->dwChunkLength=len;        c=stream_read_dword(demuxer->stream);    // Fix keyframes for DivX files:    if(idxfix_divx)      if(avi_stream_id(id)==idxfix_videostream){        switch(idxfix_divx){    	    case 3: c=stream_read_dword(demuxer->stream)<<5; //skip 32+5 bits for m$mpeg4v1    	    case 1: if(c&0x40000000) idx->dwFlags&=~AVIIF_KEYFRAME;break; // divx 3	    case 2: if(c==0x1B6) idx->dwFlags&=~AVIIF_KEYFRAME;break; // divx 4	}      }    // update status line:    { static off_t lastpos;      off_t pos;      off_t len=demuxer->movi_end-demuxer->movi_start;      if(len){          pos=100*(demuxer->filepos-demuxer->movi_start)/len; // %      } else {          pos=(demuxer->filepos-demuxer->movi_start)>>20; // MB      }      if(pos!=lastpos){          lastpos=pos;	  mp_msg(MSGT_HEADER,MSGL_STATUS,"Generating Index: %3lu %s     \r",		 (unsigned long)pos, len?"%":"MB");      }    }    mp_dbg(MSGT_HEADER,MSGL_DBG2,"%08X %08X %.4s %08X %X\n",(unsigned int)demuxer->filepos,id,(char *) &id,(int)c,(unsigned int) idx->dwFlags);#if 0    { unsigned char tmp[64];      int i;      stream_read(demuxer->stream,tmp,64);      printf("%.4s",&id);      for(i=0;i<64;i++) printf(" %02X",tmp[i]);      printf("\n");    }#endifskip_chunk:    skip=(len+1)&(~1UL); // total bytes in this chunk    stream_seek(demuxer->stream,8+demuxer->filepos+skip);  }  priv->idx_size=priv->idx_pos;  mp_msg(MSGT_HEADER,MSGL_INFO,"AVI: Generated index table for %d chunks!\n",priv->idx_size);  if(verbose>=2) print_index(priv->idx,priv->idx_size);  /* Write generated index to a file */  if (index_file_save) {    FILE *fp;    unsigned int i;    if ((fp=fopen(index_file_save, "w")) == NULL) {      mp_msg(MSGT_HEADER,MSGL_ERR, "Couldn't write index file %s: %s\n", index_file_save, strerror(errno));      return;    }    fwrite("MPIDX1", 6, 1, fp);    fwrite(&priv->idx_size, sizeof(priv->idx_size), 1, fp);    for (i=0; i<priv->idx_size; i++) {      AVIINDEXENTRY *idx = &((AVIINDEXENTRY *)priv->idx)[i];      fwrite(idx, sizeof(AVIINDEXENTRY), 1, fp);    }    fclose(fp);    mp_msg(MSGT_HEADER,MSGL_INFO, "Saved index file: %s\n", index_file_save);  }}}#undef MIN

⌨️ 快捷键说明

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