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

📄 vorbisfile.c

📁 betaplayer_0.096源码 tcpmp老版本
💻 C
📖 第 1 页 / 共 4 页
字号:
  int ov_test_open(OggVorbis_File *vf){  if(vf->ready_state!=PARTOPEN)return(OV_EINVAL);  return _ov_open2(vf);}/* How many logical bitstreams in this physical bitstream? */long ov_streams(OggVorbis_File *vf){  return vf->links;}/* Is the FILE * associated with vf seekable? */long ov_seekable(OggVorbis_File *vf){  return vf->seekable;}/* returns the bitrate for a given logical bitstream or the entire   physical bitstream.  If the file is open for random access, it will   find the *actual* average bitrate.  If the file is streaming, it   returns the nominal bitrate (if set) else the average of the   upper/lower bounds (if set) else -1 (unset).   If you want the actual bitrate field settings, get them from the   vorbis_info structs */long ov_bitrate(OggVorbis_File *vf,int i){  if(vf->ready_state<OPENED)return(OV_EINVAL);  if(i>=vf->links)return(OV_EINVAL);  if(!vf->seekable && i!=0)return(ov_bitrate(vf,0));  if(i<0){    ogg_int64_t bits=0;    int i;    for(i=0;i<vf->links;i++)      bits+=(vf->offsets[i+1]-vf->dataoffsets[i])*8;    /* This once read: return(rint(bits/ov_time_total(vf,-1)));     * gcc 3.x on x86 miscompiled this at optimisation level 2 and above,     * so this is slightly transformed to make it work.     */    return(bits*1000/ov_time_total(vf,-1));  }else{    if(vf->seekable){      /* return the actual bitrate */      return((vf->offsets[i+1]-vf->dataoffsets[i])*8000/ov_time_total(vf,i));    }else{      /* return nominal if set */      if(vf->vi[i].bitrate_nominal>0){	return vf->vi[i].bitrate_nominal;      }else{	if(vf->vi[i].bitrate_upper>0){	  if(vf->vi[i].bitrate_lower>0){	    return (vf->vi[i].bitrate_upper+vf->vi[i].bitrate_lower)/2;	  }else{	    return vf->vi[i].bitrate_upper;	  }	}	return(OV_FALSE);      }    }  }}/* returns the actual bitrate since last call.  returns -1 if no   additional data to offer since last call (or at beginning of stream),   EINVAL if stream is only partially open */long ov_bitrate_instant(OggVorbis_File *vf){  int link=(vf->seekable?vf->current_link:0);  long ret;  if(vf->ready_state<OPENED)return(OV_EINVAL);  if(vf->samptrack==0)return(OV_FALSE);  ret=vf->bittrack/vf->samptrack*vf->vi[link].rate;  vf->bittrack=0;  vf->samptrack=0;  return(ret);}/* Guess */long ov_serialnumber(OggVorbis_File *vf,int i){  if(i>=vf->links)return(ov_serialnumber(vf,vf->links-1));  if(!vf->seekable && i>=0)return(ov_serialnumber(vf,-1));  if(i<0){    return(vf->current_serialno);  }else{    return(vf->serialnos[i]);  }}/* returns: total raw (compressed) length of content if i==-1            raw (compressed) length of that logical bitstream for i==0 to n	    OV_EINVAL if the stream is not seekable (we can't know the length)	    or if stream is only partially open*/ogg_int64_t ov_raw_total(OggVorbis_File *vf,int i){  if(vf->ready_state<OPENED)return(OV_EINVAL);  if(!vf->seekable || i>=vf->links)return(OV_EINVAL);  if(i<0){    ogg_int64_t acc=0;    int i;    for(i=0;i<vf->links;i++)      acc+=ov_raw_total(vf,i);    return(acc);  }else{    return(vf->offsets[i+1]-vf->offsets[i]);  }}/* returns: total PCM length (samples) of content if i==-1 PCM length	    (samples) of that logical bitstream for i==0 to n	    OV_EINVAL if the stream is not seekable (we can't know the	    length) or only partially open */ogg_int64_t ov_pcm_total(OggVorbis_File *vf,int i){  if(vf->ready_state<OPENED)return(OV_EINVAL);  if(!vf->seekable || i>=vf->links)return(OV_EINVAL);  if(i<0){    ogg_int64_t acc=0;    int i;    for(i=0;i<vf->links;i++)      acc+=ov_pcm_total(vf,i);    return(acc);  }else{    return(vf->pcmlengths[i*2+1]);  }}/* returns: total milliseconds of content if i==-1            milliseconds in that logical bitstream for i==0 to n	    OV_EINVAL if the stream is not seekable (we can't know the	    length) or only partially open */ogg_int64_t ov_time_total(OggVorbis_File *vf,int i){  if(vf->ready_state<OPENED)return(OV_EINVAL);  if(!vf->seekable || i>=vf->links)return(OV_EINVAL);  if(i<0){    ogg_int64_t acc=0;    int i;    for(i=0;i<vf->links;i++)      acc+=ov_time_total(vf,i);    return(acc);  }else{    return(((ogg_int64_t)vf->pcmlengths[i*2+1])*1000/vf->vi[i].rate);  }}/* seek to an offset relative to the *compressed* data. This also   scans packets to update the PCM cursor. It will cross a logical   bitstream boundary, but only if it can't get any packets out of the   tail of the bitstream we seek to (so no surprises).   returns zero on success, nonzero on failure */int ov_raw_seek(OggVorbis_File *vf,ogg_int64_t pos){  ogg_stream_state *work_os=NULL;  ogg_page og={0,0,0,0};  ogg_packet op={0,0,0,0,0,0};    if(vf->ready_state<OPENED)return(OV_EINVAL);  if(!vf->seekable)    return(OV_ENOSEEK); /* don't dump machine if we can't seek */  if(pos<0 || pos>vf->end)return(OV_EINVAL);  /* don't yet clear out decoding machine (if it's initialized), in     the case we're in the same link.  Restart the decode lapping, and     let _fetch_and_process_packet deal with a potential bitstream     boundary */  vf->pcm_offset=-1;  ogg_stream_reset_serialno(vf->os,			    vf->current_serialno); /* must set serialno */  vorbis_synthesis_restart(&vf->vd);      _seek_helper(vf,pos);  /* we need to make sure the pcm_offset is set, but we don't want to     advance the raw cursor past good packets just to get to the first     with a granulepos.  That's not equivalent behavior to beginning     decoding as immediately after the seek position as possible.     So, a hack.  We use two stream states; a local scratch state and     the shared vf->os stream state.  We use the local state to     scan, and the shared state as a buffer for later decode.      Unfortuantely, on the last page we still advance to last packet     because the granulepos on the last page is not necessarily on a     packet boundary, and we need to make sure the granpos is     correct.   */  {    int lastblock=0;    int accblock=0;    int thisblock;    int eosflag;    work_os=ogg_stream_create(vf->current_serialno); /* get the memory ready */    while(1){      if(vf->ready_state>=STREAMSET){	/* snarf/scan a packet if we can */	int result=ogg_stream_packetout(work_os,&op);      	if(result>0){	  if(vf->vi[vf->current_link].codec_setup){	    thisblock=vorbis_packet_blocksize(vf->vi+vf->current_link,&op);	    if(thisblock<0){	      ogg_stream_packetout(vf->os,NULL);	      thisblock=0;	    }else{	      	      if(eosflag)		ogg_stream_packetout(vf->os,NULL);	      else		if(lastblock)accblock+=(lastblock+thisblock)>>2;	    }	    	    if(op.granulepos!=-1){	      int i,link=vf->current_link;	      ogg_int64_t granulepos=op.granulepos-vf->pcmlengths[link*2];	      if(granulepos<0)granulepos=0;	      	      for(i=0;i<link;i++)		granulepos+=vf->pcmlengths[i*2+1];	      vf->pcm_offset=granulepos-accblock;	      break;	    }	    lastblock=thisblock;	    continue;	  }else	    ogg_stream_packetout(vf->os,NULL);	}      }            if(!lastblock){	if(_get_next_page(vf,&og,-1)<0){	  vf->pcm_offset=ov_pcm_total(vf,-1);	  break;	}      }else{	/* huh?  Bogus stream with packets but no granulepos */	vf->pcm_offset=-1;	break;      }            /* has our decoding just traversed a bitstream boundary? */      if(vf->ready_state>=STREAMSET)	if(vf->current_serialno!=ogg_page_serialno(&og)){	  _decode_clear(vf); /* clear out stream state */	  ogg_stream_destroy(work_os);	}      if(vf->ready_state<STREAMSET){	int link;		vf->current_serialno=ogg_page_serialno(&og);	for(link=0;link<vf->links;link++)	  if(vf->serialnos[link]==vf->current_serialno)break;	if(link==vf->links)	  goto seek_error; /* sign of a bogus stream.  error out,			      leave machine uninitialized */ 	vf->current_link=link;		ogg_stream_reset_serialno(vf->os,vf->current_serialno);	ogg_stream_reset_serialno(work_os,vf->current_serialno); 	vf->ready_state=STREAMSET;	      }          {	ogg_page dup;	ogg_page_dup(&dup,&og);	eosflag=ogg_page_eos(&og);	ogg_stream_pagein(vf->os,&og);	ogg_stream_pagein(work_os,&dup);      }    }  }  ogg_packet_release(&op);  ogg_page_release(&og);  ogg_stream_destroy(work_os);  vf->bittrack=0;  vf->samptrack=0;  return(0); seek_error:  ogg_packet_release(&op);  ogg_page_release(&og);  /* dump the machine so we're in a known state */  vf->pcm_offset=-1;  ogg_stream_destroy(work_os);  _decode_clear(vf);  return OV_EBADLINK;}/* Page granularity seek (faster than sample granularity because we   don't do the last bit of decode to find a specific sample).   Seek to the last [granule marked] page preceeding the specified pos   location, such that decoding past the returned point will quickly   arrive at the requested position. */int ov_pcm_seek_page(OggVorbis_File *vf,ogg_int64_t pos){  int link=-1;  ogg_int64_t result=0;  ogg_int64_t total=ov_pcm_total(vf,-1);  ogg_page og={0,0,0,0};  ogg_packet op={0,0,0,0,0,0};  if(vf->ready_state<OPENED)return(OV_EINVAL);  if(!vf->seekable)return(OV_ENOSEEK);  if(pos<0 || pos>total)return(OV_EINVAL);   /* which bitstream section does this pcm offset occur in? */  for(link=vf->links-1;link>=0;link--){    total-=vf->pcmlengths[link*2+1];    if(pos>=total)break;  }  /* search within the logical bitstream for the page with the highest     pcm_pos preceeding (or equal to) pos.  There is a danger here;     missing pages or incorrect frame number information in the     bitstream could make our task impossible.  Account for that (it     would be an error condition) */  /* new search algorithm by HB (Nicholas Vinen) */  {    ogg_int64_t end=vf->offsets[link+1];    ogg_int64_t begin=vf->offsets[link];    ogg_int64_t begintime = vf->pcmlengths[link*2];    ogg_int64_t endtime = vf->pcmlengths[link*2+1]+begintime;    ogg_int64_t target=pos-total+begintime;    ogg_int64_t best=begin;        while(begin<end){      ogg_int64_t bisect;            if(end-begin<CHUNKSIZE){	bisect=begin;      }else{	/* take a (pretty decent) guess. */	bisect=begin + 	  (target-begintime)*(end-begin)/(endtime-begintime) - CHUNKSIZE;	if(bisect<=begin)	  bisect=begin+1;      }            _seek_helper(vf,bisect);          while(begin<end){	result=_get_next_page(vf,&og,end-vf->offset);	if(result==OV_EREAD) goto seek_error;	if(result<0){	  if(bisect<=begin+1)	    end=begin; /* found it */	  else{	    if(bisect==0) goto seek_error;	    bisect-=CHUNKSIZE;	    if(bisect<=begin)bisect=begin+1;	    _seek_helper(vf,bisect);	  }	}else{	  ogg_int64_t granulepos=ogg_page_granulepos(&og);	  if(granulepos==-1)continue;	  if(granulepos<target){	    best=result;  /* raw offset of packet with granulepos */ 	    begin=vf->offset; /* raw offset of next page */	    begintime=granulepos;	    	    if(target-begintime>44100)break;	    bisect=begin; /* *not* begin + 1 */	  }else{	    if(bisect<=begin+1)	      end=begin;  /* found it */	    else{	      if(end==vf->offset){ /* we're pretty close - we'd be stuck in */		end=result;		bisect-=CHUNKSIZE; /* an endless loop otherwise. */		if(bisect<=begin)bisect=begin+1;		_seek_helper(vf,bisect);	      }else{		end=result;		endtime=granulepos;		break;	      }	    }	  }	}      }    }    /* found our page. seek to it, update pcm offset. Easier case than       raw_seek, don't keep packets preceeding granulepos. */    {            /* seek */      _seek_helper(vf,best);      vf->pcm_offset=-1;      

⌨️ 快捷键说明

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