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

📄 vorbisfile.c

📁 betaplayer_0.096源码 tcpmp老版本
💻 C
📖 第 1 页 / 共 4 页
字号:
	  break;	}	vf->offset=ret;      }    }  }  ogg_page_release(&og);}static void _make_decode_ready(OggVorbis_File *vf){  if(vf->ready_state!=STREAMSET)return;  if(vf->seekable){    vorbis_synthesis_init(&vf->vd,vf->vi+vf->current_link);  }else{    vorbis_synthesis_init(&vf->vd,vf->vi);  }      vorbis_block_init(&vf->vd,&vf->vb);  vf->ready_state=INITSET;  vf->bittrack=0;  vf->samptrack=0;  return;}static int _open_seekable2(OggVorbis_File *vf){  ogg_uint32_t serialno=vf->current_serialno;  ogg_uint32_t tempserialno;  ogg_int64_t dataoffset=vf->offset, end;  ogg_page og={0,0,0,0};  /* we're partially open and have a first link header state in     storage in vf */  /* we can seek, so set out learning all about this file */  (vf->callbacks.seek_func)(vf->datasource,0,SEEK_END);  vf->offset=vf->end=(vf->callbacks.tell_func)(vf->datasource);    /* We get the offset for the last page of the physical bitstream.     Most OggVorbis files will contain a single logical bitstream */  end=_get_prev_page(vf,&og);  if(end<0)return(end);  /* more than one logical bitstream? */  tempserialno=ogg_page_serialno(&og);  ogg_page_release(&og);  if(tempserialno!=serialno){    /* Chained bitstream. Bisect-search each logical bitstream       section.  Do so based on serial number only */    if(_bisect_forward_serialno(vf,0,0,end+1,serialno,0)<0)return(OV_EREAD);  }else{    /* Only one logical bitstream */    if(_bisect_forward_serialno(vf,0,end,end+1,serialno,0))return(OV_EREAD);  }  /* the initial header memory is referenced by vf after; don't free it */  _prefetch_all_headers(vf,dataoffset);  return(ov_raw_seek(vf,0));}/* clear out the current logical bitstream decoder */ static void _decode_clear(OggVorbis_File *vf){  vorbis_dsp_clear(&vf->vd);  vorbis_block_clear(&vf->vb);  vf->ready_state=OPENED;}/* fetch and process a packet.  Handles the case where we're at a   bitstream boundary and dumps the decoding machine.  If the decoding   machine is unloaded, it loads it.  It also keeps pcm_offset up to   date (seek and read both use this.  seek uses a special hack with   readp).    return: <0) error, OV_HOLE (lost packet) or OV_EOF            0) need more data (only if readp==0)	    1) got a packet */static int _fetch_and_process_packet(OggVorbis_File *vf,				     int readp,				     int spanp){  ogg_page og={0,0,0,0};  ogg_packet op={0,0,0,0,0,0};  int ret=0;  /* handle one packet.  Try to fetch it from current stream state */  /* extract packets from page */  while(1){        /* process a packet if we can.  If the machine isn't loaded,       neither is a page */    if(vf->ready_state==INITSET){      while(1) {	int result=ogg_stream_packetout(vf->os,&op);	ogg_int64_t granulepos;	if(result<0){	  ret=OV_HOLE; /* hole in the data. */	  goto cleanup;	}	if(result>0){	  /* got a packet.  process it */	  granulepos=op.granulepos;	  if(!vorbis_synthesis(&vf->vb,&op,1)){ /* lazy check for lazy						      header handling.  The						      header packets aren't						      audio, so if/when we						      submit them,						      vorbis_synthesis will						      reject them */	    /* suck in the synthesis data and track bitrate */	    {	      int oldsamples=vorbis_synthesis_pcmout(&vf->vd,NULL);	      /* for proper use of libvorbis within libvorbisfile,                 oldsamples will always be zero. */	      if(oldsamples){		ret=OV_EFAULT;		goto cleanup;	      }	      vorbis_synthesis_blockin(&vf->vd,&vf->vb);	      vf->samptrack+=vorbis_synthesis_pcmout(&vf->vd,NULL)-oldsamples;	      vf->bittrack+=op.bytes*8;	    }	  	    /* update the pcm offset. */	    if(granulepos!=-1 && !op.e_o_s){	      int link=(vf->seekable?vf->current_link:0);	      int i,samples;	    	      /* this packet has a pcm_offset on it (the last packet	         completed on a page carries the offset) After processing	         (above), we know the pcm position of the *last* sample	         ready to be returned. Find the offset of the *first*	         As an aside, this trick is inaccurate if we begin	         reading anew right at the last page; the end-of-stream	         granulepos declares the last frame in the stream, and the	         last packet of the last page may be a partial frame.	         So, we need a previous granulepos from an in-sequence page	         to have a reference point.  Thus the !op.e_o_s clause	         above */	      if(vf->seekable && link>0)		granulepos-=vf->pcmlengths[link*2];	      if(granulepos<0)granulepos=0; /* actually, this					       shouldn't be possible					       here unless the stream					       is very broken */	      samples=vorbis_synthesis_pcmout(&vf->vd,NULL);	    	      granulepos-=samples;	      for(i=0;i<link;i++)	        granulepos+=vf->pcmlengths[i*2+1];	      vf->pcm_offset=granulepos;	    }	    ret=1;	    goto cleanup;	  }	}	else 	  break;      }    }    if(vf->ready_state>=OPENED){      int ret;      if(!readp){	ret=0;	goto cleanup;      }      if((ret=_get_next_page(vf,&og,-1))<0){	ret=OV_EOF; /* eof. leave unitialized */	goto cleanup;      }	/* bitrate tracking; add the header's bytes here, the body bytes	   are done by packet above */      vf->bittrack+=og.header_len*8;            /* has our decoding just traversed a bitstream boundary? */      if(vf->ready_state==INITSET){	if(vf->current_serialno!=ogg_page_serialno(&og)){	  if(!spanp){	    ret=OV_EOF;	    goto cleanup;	  }	  _decode_clear(vf);	  	  if(!vf->seekable){	    vorbis_info_clear(vf->vi);	    vorbis_comment_clear(vf->vc);	  }	}      }    }    /* Do we need to load a new machine before submitting the page? */    /* This is different in the seekable and non-seekable cases.         In the seekable case, we already have all the header       information loaded and cached; we just initialize the machine       with it and continue on our merry way.       In the non-seekable (streaming) case, we'll only be at a       boundary if we just left the previous logical bitstream and       we're now nominally at the header of the next bitstream    */    if(vf->ready_state!=INITSET){       int link;      if(vf->ready_state<STREAMSET){	if(vf->seekable){	  vf->current_serialno=ogg_page_serialno(&og);	  	  /* match the serialno to bitstream section.  We use this rather than	     offset positions to avoid problems near logical bitstream	     boundaries */	  for(link=0;link<vf->links;link++)	    if(vf->serialnos[link]==vf->current_serialno)break;	  if(link==vf->links){	    ret=OV_EBADLINK; /* sign of a bogus stream.  error out,				leave machine uninitialized */	    goto cleanup;	  }	  	  vf->current_link=link;	  	  ogg_stream_reset_serialno(vf->os,vf->current_serialno);	  vf->ready_state=STREAMSET;	  	}else{	  /* we're streaming */	  /* fetch the three header packets, build the info struct */	  	  int ret=_fetch_headers(vf,vf->vi,vf->vc,&vf->current_serialno,&og);	  if(ret) goto cleanup;	  vf->current_link++;	  link=0;	}      }            _make_decode_ready(vf);    }    ogg_stream_pagein(vf->os,&og);  } cleanup:  ogg_packet_release(&op);  ogg_page_release(&og);  return ret;}/* if, eg, 64 bit stdio is configured by default, this will build with   fseek64 */static int _fseek64_wrap(FILE *f,ogg_int64_t off,int whence){  if(f==NULL)return(-1);  return fseek(f,off,whence);}static int _ov_open1(void *f,OggVorbis_File *vf,char *initial,		     long ibytes, ov_callbacks callbacks){  int offsettest=(f?callbacks.seek_func(f,0,SEEK_CUR):-1);  int ret;  memset(vf,0,sizeof(*vf));  vf->datasource=f;  vf->callbacks = callbacks;  /* init the framing state */  vf->oy=ogg_sync_create();  /* perhaps some data was previously read into a buffer for testing     against other stream types.  Allow initialization from this     previously read data (as we may be reading from a non-seekable     stream) */  if(initial){    char *buffer=ogg_sync_bufferin(vf->oy,ibytes);    memcpy(buffer,initial,ibytes);    ogg_sync_wrote(vf->oy,ibytes);  }  /* can we seek? Stevens suggests the seek test was portable */  if(offsettest!=-1)vf->seekable=1;  /* No seeking yet; Set up a 'single' (current) logical bitstream     entry for partial open */  vf->links=1;  vf->vi=_ogg_calloc(vf->links,sizeof(*vf->vi));  vf->vc=_ogg_calloc(vf->links,sizeof(*vf->vc));  vf->os=ogg_stream_create(-1); /* fill in the serialno later */  /* Try to fetch the headers, maintaining all the storage */  if((ret=_fetch_headers(vf,vf->vi,vf->vc,&vf->current_serialno,NULL))<0){    vf->datasource=NULL;    ov_clear(vf);  }else if(vf->ready_state < PARTOPEN)    vf->ready_state=PARTOPEN;  return(ret);}static int _ov_open2(OggVorbis_File *vf){  if(vf->ready_state < OPENED)    vf->ready_state=OPENED;  if(vf->seekable){    int ret=_open_seekable2(vf);    if(ret){      vf->datasource=NULL;      ov_clear(vf);    }    return(ret);  }  return 0;}/* clear out the OggVorbis_File struct */int ov_clear(OggVorbis_File *vf){  if(vf){    vorbis_block_clear(&vf->vb);    vorbis_dsp_clear(&vf->vd);    ogg_stream_destroy(vf->os);        if(vf->vi && vf->links){      int i;      for(i=0;i<vf->links;i++){	vorbis_info_clear(vf->vi+i);	vorbis_comment_clear(vf->vc+i);      }      _ogg_free(vf->vi);      _ogg_free(vf->vc);    }    if(vf->dataoffsets)_ogg_free(vf->dataoffsets);    if(vf->pcmlengths)_ogg_free(vf->pcmlengths);    if(vf->serialnos)_ogg_free(vf->serialnos);    if(vf->offsets)_ogg_free(vf->offsets);    ogg_sync_destroy(vf->oy);    if(vf->datasource)(vf->callbacks.close_func)(vf->datasource);    memset(vf,0,sizeof(*vf));  }#ifdef DEBUG_LEAKS  _VDBG_dump();#endif  return(0);}/* inspects the OggVorbis file and finds/documents all the logical   bitstreams contained in it.  Tries to be tolerant of logical   bitstream sections that are truncated/woogie.    return: -1) error            0) OK*/int ov_open_callbacks(void *f,OggVorbis_File *vf,char *initial,long ibytes,    ov_callbacks callbacks){  int ret=_ov_open1(f,vf,initial,ibytes,callbacks);  if(ret)return ret;  return _ov_open2(vf);}int ov_open(FILE *f,OggVorbis_File *vf,char *initial,long ibytes){  ov_callbacks callbacks = {    (size_t (*)(void *, size_t, size_t, void *))  fread,    (int (*)(void *, ogg_int64_t, int))              _fseek64_wrap,    (int (*)(void *))                             fclose,    (long (*)(void *))                            ftell  };  return ov_open_callbacks((void *)f, vf, initial, ibytes, callbacks);}  /* Only partially open the vorbis file; test for Vorbisness, and load   the headers for the first chain.  Do not seek (although test for   seekability).  Use ov_test_open to finish opening the file, else   ov_clear to close/free it. Same return codes as open. */int ov_test_callbacks(void *f,OggVorbis_File *vf,char *initial,long ibytes,    ov_callbacks callbacks){  return _ov_open1(f,vf,initial,ibytes,callbacks);}int ov_test(FILE *f,OggVorbis_File *vf,char *initial,long ibytes){  ov_callbacks callbacks = {    (size_t (*)(void *, size_t, size_t, void *))  fread,    (int (*)(void *, ogg_int64_t, int))              _fseek64_wrap,    (int (*)(void *))                             fclose,    (long (*)(void *))                            ftell  };  return ov_test_callbacks((void *)f, vf, initial, ibytes, callbacks);}

⌨️ 快捷键说明

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