Home | History | Annotate | Download | only in Tremolo
      1 /************************************************************************
      2  * Copyright (C) 2002-2009, Xiph.org Foundation
      3  * Copyright (C) 2010, Robin Watts for Pinknoise Productions Ltd
      4  * All rights reserved.
      5  *
      6  * Redistribution and use in source and binary forms, with or without
      7  * modification, are permitted provided that the following conditions
      8  * are met:
      9  *
     10  *     * Redistributions of source code must retain the above copyright
     11  * notice, this list of conditions and the following disclaimer.
     12  *     * Redistributions in binary form must reproduce the above
     13  * copyright notice, this list of conditions and the following disclaimer
     14  * in the documentation and/or other materials provided with the
     15  * distribution.
     16  *     * Neither the names of the Xiph.org Foundation nor Pinknoise
     17  * Productions Ltd nor the names of its contributors may be used to
     18  * endorse or promote products derived from this software without
     19  * specific prior written permission.
     20  *
     21  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     22  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     23  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
     24  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
     25  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
     26  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
     27  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     28  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     29  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     30  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
     31  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     32  ************************************************************************
     33 
     34  function: stdio-based convenience library for opening/seeking/decoding
     35  last mod: $Id: vorbisfile.c,v 1.6.2.5 2003/11/20 06:16:17 xiphmont Exp $
     36 
     37  ************************************************************************/
     38 
     39 #include <stdlib.h>
     40 #include <stdio.h>
     41 //#include <gerrno.h>
     42 #include <string.h>
     43 #include <math.h>
     44 
     45 #include "codec_internal.h"
     46 #include "ivorbisfile.h"
     47 
     48 #include "os.h"
     49 #include "misc.h"
     50 
     51 int gerrno;
     52 
     53 #define  NOTOPEN   0
     54 #define  PARTOPEN  1
     55 #define  OPENED    2
     56 #define  STREAMSET 3 /* serialno and link set, but not to current link */
     57 #define  LINKSET   4 /* serialno and link set to current link */
     58 #define  INITSET   5
     59 
     60 /* A 'chained bitstream' is a Vorbis bitstream that contains more than
     61    one logical bitstream arranged end to end (the only form of Ogg
     62    multiplexing allowed in a Vorbis bitstream; grouping [parallel
     63    multiplexing] is not allowed in Vorbis) */
     64 
     65 /* A Vorbis file can be played beginning to end (streamed) without
     66    worrying ahead of time about chaining (see decoder_example.c).  If
     67    we have the whole file, however, and want random access
     68    (seeking/scrubbing) or desire to know the total length/time of a
     69    file, we need to account for the possibility of chaining. */
     70 
     71 /* We can handle things a number of ways; we can determine the entire
     72    bitstream structure right off the bat, or find pieces on demand.
     73    This example determines and caches structure for the entire
     74    bitstream, but builds a virtual decoder on the fly when moving
     75    between links in the chain. */
     76 
     77 /* There are also different ways to implement seeking.  Enough
     78    information exists in an Ogg bitstream to seek to
     79    sample-granularity positions in the output.  Or, one can seek by
     80    picking some portion of the stream roughly in the desired area if
     81    we only want coarse navigation through the stream. */
     82 
     83 /*************************************************************************
     84  * Many, many internal helpers.  The intention is not to be confusing;
     85  * rampant duplication and monolithic function implementation would be
     86  * harder to understand anyway.  The high level functions are last.  Begin
     87  * grokking near the end of the file */
     88 
     89 
     90 /* read a little more data from the file/pipe into the ogg_sync framer */
     91 static long _get_data(OggVorbis_File *vf){
     92   gerrno=0;
     93   if(vf->datasource){
     94     unsigned char *buffer=ogg_sync_bufferin(vf->oy,CHUNKSIZE);
     95     long bytes=(vf->callbacks.read_func)(buffer,1,CHUNKSIZE,vf->datasource);
     96     if(bytes>0)ogg_sync_wrote(vf->oy,bytes);
     97     if(bytes==0 && gerrno)return -1;
     98     return bytes;
     99   }else
    100     return 0;
    101 }
    102 
    103 /* save a tiny smidge of verbosity to make the code more readable */
    104 static void _seek_helper(OggVorbis_File *vf,ogg_int64_t offset){
    105   if(vf->datasource){
    106     (vf->callbacks.seek_func)(vf->datasource, offset, SEEK_SET);
    107     vf->offset=offset;
    108     ogg_sync_reset(vf->oy);
    109   }else{
    110     /* shouldn't happen unless someone writes a broken callback */
    111     return;
    112   }
    113 }
    114 
    115 /* The read/seek functions track absolute position within the stream */
    116 
    117 /* from the head of the stream, get the next page.  boundary specifies
    118    if the function is allowed to fetch more data from the stream (and
    119    how much) or only use internally buffered data.
    120 
    121    boundary: -1) unbounded search
    122               0) read no additional data; use cached only
    123 	      n) search for a new page beginning for n bytes
    124 
    125    return:   <0) did not find a page (OV_FALSE, OV_EOF, OV_EREAD)
    126               n) found a page at absolute offset n
    127 
    128               produces a refcounted page */
    129 
    130 static ogg_int64_t _get_next_page(OggVorbis_File *vf,ogg_page *og,
    131 				  ogg_int64_t boundary){
    132   if(boundary>0)boundary+=vf->offset;
    133   while(1){
    134     long more;
    135 
    136     if(boundary>0 && vf->offset>=boundary)return OV_FALSE;
    137     more=ogg_sync_pageseek(vf->oy,og);
    138 
    139     if(more<0){
    140       /* skipped n bytes */
    141       vf->offset-=more;
    142     }else{
    143       if(more==0){
    144 	/* send more paramedics */
    145 	if(!boundary)return OV_FALSE;
    146 	{
    147 	  long ret=_get_data(vf);
    148 	  if(ret==0)return OV_EOF;
    149 	  if(ret<0)return OV_EREAD;
    150 	}
    151       }else{
    152 	/* got a page.  Return the offset at the page beginning,
    153            advance the internal offset past the page end */
    154 	ogg_int64_t ret=vf->offset;
    155 	vf->offset+=more;
    156 	return ret;
    157 
    158       }
    159     }
    160   }
    161 }
    162 
    163 /* find the latest page beginning before the current stream cursor
    164    position. Much dirtier than the above as Ogg doesn't have any
    165    backward search linkage.  no 'readp' as it will certainly have to
    166    read. */
    167 /* returns offset or OV_EREAD, OV_FAULT and produces a refcounted page */
    168 
    169 static ogg_int64_t _get_prev_page(OggVorbis_File *vf,ogg_page *og){
    170   ogg_int64_t begin=vf->offset;
    171   ogg_int64_t end=begin;
    172   ogg_int64_t ret;
    173   ogg_int64_t offset=-1;
    174 
    175   while(offset==-1){
    176     begin-=CHUNKSIZE;
    177     if(begin<0)
    178       begin=0;
    179     _seek_helper(vf,begin);
    180     while(vf->offset<end){
    181       ret=_get_next_page(vf,og,end-vf->offset);
    182       if(ret==OV_EREAD)return OV_EREAD;
    183       if(ret<0){
    184 	break;
    185       }else{
    186 	offset=ret;
    187       }
    188     }
    189   }
    190 
    191   /* we have the offset.  Actually snork and hold the page now */
    192   _seek_helper(vf,offset);
    193   ret=_get_next_page(vf,og,CHUNKSIZE);
    194   if(ret<0)
    195     /* this shouldn't be possible */
    196     return OV_EFAULT;
    197 
    198   return offset;
    199 }
    200 
    201 /* finds each bitstream link one at a time using a bisection search
    202    (has to begin by knowing the offset of the lb's initial page).
    203    Recurses for each link so it can alloc the link storage after
    204    finding them all, then unroll and fill the cache at the same time */
    205 static int _bisect_forward_serialno(OggVorbis_File *vf,
    206 				    ogg_int64_t begin,
    207 				    ogg_int64_t searched,
    208 				    ogg_int64_t end,
    209 				    ogg_uint32_t currentno,
    210 				    long m){
    211   ogg_int64_t endsearched=end;
    212   ogg_int64_t next=end;
    213   ogg_page og={0,0,0,0};
    214   ogg_int64_t ret;
    215 
    216   /* the below guards against garbage seperating the last and
    217      first pages of two links. */
    218   while(searched<endsearched){
    219     ogg_int64_t bisect;
    220 
    221     if(endsearched-searched<CHUNKSIZE){
    222       bisect=searched;
    223     }else{
    224       bisect=(searched+endsearched)/2;
    225     }
    226 
    227     _seek_helper(vf,bisect);
    228     ret=_get_next_page(vf,&og,-1);
    229     if(ret==OV_EREAD)return OV_EREAD;
    230     if(ret<0 || ogg_page_serialno(&og)!=currentno){
    231       endsearched=bisect;
    232       if(ret>=0)next=ret;
    233     }else{
    234       searched=ret+og.header_len+og.body_len;
    235     }
    236     ogg_page_release(&og);
    237   }
    238 
    239   _seek_helper(vf,next);
    240   ret=_get_next_page(vf,&og,-1);
    241   if(ret==OV_EREAD)return OV_EREAD;
    242 
    243   if(searched>=end || ret<0){
    244     ogg_page_release(&og);
    245     vf->links=m+1;
    246     vf->offsets=_ogg_malloc((vf->links+1)*sizeof(*vf->offsets));
    247     vf->serialnos=_ogg_malloc(vf->links*sizeof(*vf->serialnos));
    248     vf->offsets[m+1]=searched;
    249   }else{
    250     ret=_bisect_forward_serialno(vf,next,vf->offset,
    251 				 end,ogg_page_serialno(&og),m+1);
    252     ogg_page_release(&og);
    253     if(ret==OV_EREAD)return OV_EREAD;
    254   }
    255 
    256   vf->offsets[m]=begin;
    257   vf->serialnos[m]=currentno;
    258   return 0;
    259 }
    260 
    261 static int _decode_clear(OggVorbis_File *vf){
    262   if(vf->ready_state==INITSET){
    263     vorbis_dsp_destroy(vf->vd);
    264     vf->vd=0;
    265     vf->ready_state=STREAMSET;
    266   }
    267 
    268   if(vf->ready_state>=STREAMSET){
    269     vorbis_info_clear(&vf->vi);
    270     vorbis_comment_clear(&vf->vc);
    271     vf->ready_state=OPENED;
    272   }
    273   return 0;
    274 }
    275 
    276 /* uses the local ogg_stream storage in vf; this is important for
    277    non-streaming input sources */
    278 /* consumes the page that's passed in (if any) */
    279 /* state is LINKSET upon successful return */
    280 
    281 static int _fetch_headers(OggVorbis_File *vf,
    282 			  vorbis_info *vi,
    283 			  vorbis_comment *vc,
    284 			  ogg_uint32_t *serialno,
    285 			  ogg_page *og_ptr){
    286   ogg_page og={0,0,0,0};
    287   ogg_packet op={0,0,0,0,0,0};
    288   int i,ret;
    289 
    290   if(vf->ready_state>OPENED)_decode_clear(vf);
    291 
    292   if(!og_ptr){
    293     ogg_int64_t llret=_get_next_page(vf,&og,CHUNKSIZE);
    294     if(llret==OV_EREAD)return OV_EREAD;
    295     if(llret<0)return OV_ENOTVORBIS;
    296     og_ptr=&og;
    297   }
    298 
    299   ogg_stream_reset_serialno(vf->os,ogg_page_serialno(og_ptr));
    300   if(serialno)*serialno=vf->os->serialno;
    301 
    302   /* extract the initial header from the first page and verify that the
    303      Ogg bitstream is in fact Vorbis data */
    304 
    305   vorbis_info_init(vi);
    306   vorbis_comment_init(vc);
    307 
    308   i=0;
    309   while(i<3){
    310     ogg_stream_pagein(vf->os,og_ptr);
    311     while(i<3){
    312       int result=ogg_stream_packetout(vf->os,&op);
    313       if(result==0)break;
    314       if(result==-1){
    315 	ret=OV_EBADHEADER;
    316 	goto bail_header;
    317       }
    318       if((ret=vorbis_dsp_headerin(vi,vc,&op))){
    319 	goto bail_header;
    320       }
    321       i++;
    322     }
    323     if(i<3)
    324       if(_get_next_page(vf,og_ptr,CHUNKSIZE)<0){
    325 	ret=OV_EBADHEADER;
    326 	goto bail_header;
    327       }
    328   }
    329 
    330   ogg_packet_release(&op);
    331   ogg_page_release(&og);
    332   vf->ready_state=LINKSET;
    333   return 0;
    334 
    335  bail_header:
    336   ogg_packet_release(&op);
    337   ogg_page_release(&og);
    338   vorbis_info_clear(vi);
    339   vorbis_comment_clear(vc);
    340   vf->ready_state=OPENED;
    341 
    342   return ret;
    343 }
    344 
    345 /* we no longer preload all vorbis_info (and the associated
    346    codec_setup) structs.  Call this to seek and fetch the info from
    347    the bitstream, if needed */
    348 static int _set_link_number(OggVorbis_File *vf,int link){
    349   if(link != vf->current_link) _decode_clear(vf);
    350   if(vf->ready_state<STREAMSET){
    351     _seek_helper(vf,vf->offsets[link]);
    352     ogg_stream_reset_serialno(vf->os,vf->serialnos[link]);
    353     vf->current_serialno=vf->serialnos[link];
    354     vf->current_link=link;
    355     return _fetch_headers(vf,&vf->vi,&vf->vc,&vf->current_serialno,NULL);
    356   }
    357   return 0;
    358 }
    359 
    360 static int _set_link_number_preserve_pos(OggVorbis_File *vf,int link){
    361   ogg_int64_t pos=vf->offset;
    362   int ret=_set_link_number(vf,link);
    363   if(ret)return ret;
    364   _seek_helper(vf,pos);
    365   if(pos<vf->offsets[link] || pos>=vf->offsets[link+1])
    366     vf->ready_state=STREAMSET;
    367   return 0;
    368 }
    369 
    370 /* last step of the OggVorbis_File initialization; get all the offset
    371    positions.  Only called by the seekable initialization (local
    372    stream storage is hacked slightly; pay attention to how that's
    373    done) */
    374 
    375 /* this is void and does not propogate errors up because we want to be
    376    able to open and use damaged bitstreams as well as we can.  Just
    377    watch out for missing information for links in the OggVorbis_File
    378    struct */
    379 static void _prefetch_all_offsets(OggVorbis_File *vf, ogg_int64_t dataoffset){
    380   ogg_page og={0,0,0,0};
    381   int i;
    382   ogg_int64_t ret;
    383 
    384   vf->dataoffsets=_ogg_malloc(vf->links*sizeof(*vf->dataoffsets));
    385   vf->pcmlengths=_ogg_malloc(vf->links*2*sizeof(*vf->pcmlengths));
    386 
    387   for(i=0;i<vf->links;i++){
    388     if(i==0){
    389       /* we already grabbed the initial header earlier.  Just set the offset */
    390       vf->dataoffsets[i]=dataoffset;
    391       _seek_helper(vf,dataoffset);
    392 
    393     }else{
    394 
    395       /* seek to the location of the initial header */
    396 
    397       _seek_helper(vf,vf->offsets[i]);
    398       if(_fetch_headers(vf,&vf->vi,&vf->vc,NULL,NULL)<0){
    399     	vf->dataoffsets[i]=-1;
    400       }else{
    401 	vf->dataoffsets[i]=vf->offset;
    402       }
    403     }
    404 
    405     /* fetch beginning PCM offset */
    406 
    407     if(vf->dataoffsets[i]!=-1){
    408       ogg_int64_t accumulated=0,pos;
    409       long        lastblock=-1;
    410       int         result;
    411 
    412       ogg_stream_reset_serialno(vf->os,vf->serialnos[i]);
    413 
    414       while(1){
    415 	ogg_packet op={0,0,0,0,0,0};
    416 
    417 	ret=_get_next_page(vf,&og,-1);
    418 	if(ret<0)
    419 	  /* this should not be possible unless the file is
    420              truncated/mangled */
    421 	  break;
    422 
    423 	if(ogg_page_serialno(&og)!=vf->serialnos[i])
    424 	  break;
    425 
    426 	pos=ogg_page_granulepos(&og);
    427 
    428 	/* count blocksizes of all frames in the page */
    429 	ogg_stream_pagein(vf->os,&og);
    430 	while((result=ogg_stream_packetout(vf->os,&op))){
    431 	  if(result>0){ /* ignore holes */
    432 	    long thisblock=vorbis_packet_blocksize(&vf->vi,&op);
    433 	    if(lastblock!=-1)
    434 	      accumulated+=(lastblock+thisblock)>>2;
    435 	    lastblock=thisblock;
    436 	  }
    437 	}
    438 	ogg_packet_release(&op);
    439 
    440 	if(pos!=-1){
    441 	  /* pcm offset of last packet on the first audio page */
    442 	  accumulated= pos-accumulated;
    443 	  break;
    444 	}
    445       }
    446 
    447       /* less than zero?  This is a stream with samples trimmed off
    448          the beginning, a normal occurrence; set the offset to zero */
    449       if(accumulated<0)accumulated=0;
    450 
    451       vf->pcmlengths[i*2]=accumulated;
    452     }
    453 
    454     /* get the PCM length of this link. To do this,
    455        get the last page of the stream */
    456     {
    457       ogg_int64_t end=vf->offsets[i+1];
    458       _seek_helper(vf,end);
    459 
    460       while(1){
    461 	ret=_get_prev_page(vf,&og);
    462 	if(ret<0){
    463 	  /* this should not be possible */
    464 	  vorbis_info_clear(&vf->vi);
    465 	  vorbis_comment_clear(&vf->vc);
    466 	  break;
    467 	}
    468 	if(ogg_page_granulepos(&og)!=-1){
    469 	  vf->pcmlengths[i*2+1]=ogg_page_granulepos(&og)-vf->pcmlengths[i*2];
    470 	  break;
    471 	}
    472 	vf->offset=ret;
    473       }
    474     }
    475   }
    476   ogg_page_release(&og);
    477 }
    478 
    479 static int _make_decode_ready(OggVorbis_File *vf){
    480   int i;
    481   switch(vf->ready_state){
    482   case OPENED:
    483   case STREAMSET:
    484     for(i=0;i<vf->links;i++)
    485       if(vf->offsets[i+1]>=vf->offset)break;
    486     if(i==vf->links)return -1;
    487     i=_set_link_number_preserve_pos(vf,i);
    488     if(i)return i;
    489     /* fall through */
    490   case LINKSET:
    491     vf->vd=vorbis_dsp_create(&vf->vi);
    492     vf->ready_state=INITSET;
    493     vf->bittrack=0;
    494     vf->samptrack=0;
    495   case INITSET:
    496     return 0;
    497   default:
    498     return -1;
    499   }
    500 
    501 }
    502 
    503 static int _open_seekable2(OggVorbis_File *vf){
    504   ogg_uint32_t serialno=vf->current_serialno;
    505   ogg_uint32_t tempserialno;
    506   ogg_int64_t dataoffset=vf->offset, end;
    507   ogg_page og={0,0,0,0};
    508 
    509   /* we're partially open and have a first link header state in
    510      storage in vf */
    511   /* we can seek, so set out learning all about this file */
    512   (vf->callbacks.seek_func)(vf->datasource,0,SEEK_END);
    513   vf->offset=vf->end=(vf->callbacks.tell_func)(vf->datasource);
    514 
    515   /* We get the offset for the last page of the physical bitstream.
    516      Most OggVorbis files will contain a single logical bitstream */
    517   end=_get_prev_page(vf,&og);
    518   if(end<0)return (int)end;
    519 
    520   /* more than one logical bitstream? */
    521   tempserialno=ogg_page_serialno(&og);
    522   ogg_page_release(&og);
    523 
    524   if(tempserialno!=serialno){
    525 
    526     /* Chained bitstream. Bisect-search each logical bitstream
    527        section.  Do so based on serial number only */
    528     if(_bisect_forward_serialno(vf,0,0,end+1,serialno,0)<0)return OV_EREAD;
    529 
    530   }else{
    531 
    532     /* Only one logical bitstream */
    533     if(_bisect_forward_serialno(vf,0,end,end+1,serialno,0))return OV_EREAD;
    534 
    535   }
    536 
    537   /* the initial header memory is referenced by vf after; don't free it */
    538   _prefetch_all_offsets(vf,dataoffset);
    539   return ov_raw_seek(vf,0);
    540 }
    541 
    542 /* fetch and process a packet.  Handles the case where we're at a
    543    bitstream boundary and dumps the decoding machine.  If the decoding
    544    machine is unloaded, it loads it.  It also keeps pcm_offset up to
    545    date (seek and read both use this.  seek uses a special hack with
    546    readp).
    547 
    548    return: <0) error, OV_HOLE (lost packet) or OV_EOF
    549             0) need more data (only if readp==0)
    550 	    1) got a packet
    551 */
    552 
    553 static int _fetch_and_process_packet(OggVorbis_File *vf,
    554 				     int readp,
    555 				     int spanp){
    556   ogg_page og={0,0,0,0};
    557   ogg_packet op={0,0,0,0,0,0};
    558   int ret=0;
    559 
    560   /* handle one packet.  Try to fetch it from current stream state */
    561   /* extract packets from page */
    562   while(1){
    563 
    564     /* process a packet if we can.  If the machine isn't loaded,
    565        neither is a page */
    566     if(vf->ready_state==INITSET){
    567       while(1) {
    568 	int result=ogg_stream_packetout(vf->os,&op);
    569 	ogg_int64_t granulepos;
    570 
    571 	if(result<0){
    572 	  ret=OV_HOLE; /* hole in the data. */
    573 	  goto cleanup;
    574 	}
    575 	if(result>0){
    576 	  /* got a packet.  process it */
    577 	  granulepos=op.granulepos;
    578 	  if(!vorbis_dsp_synthesis(vf->vd,&op,1)){ /* lazy check for lazy
    579 						      header handling.  The
    580 						      header packets aren't
    581 						      audio, so if/when we
    582 						      submit them,
    583 						      vorbis_synthesis will
    584 						      reject them */
    585 
    586 	    vf->samptrack+=vorbis_dsp_pcmout(vf->vd,NULL,0);
    587 	    vf->bittrack+=op.bytes*8;
    588 
    589 	    /* update the pcm offset. */
    590 	    if(granulepos!=-1 && !op.e_o_s){
    591 	      int link=(vf->seekable?vf->current_link:0);
    592 	      int i,samples;
    593 
    594 	      /* this packet has a pcm_offset on it (the last packet
    595 	         completed on a page carries the offset) After processing
    596 	         (above), we know the pcm position of the *last* sample
    597 	         ready to be returned. Find the offset of the *first*
    598 
    599 	         As an aside, this trick is inaccurate if we begin
    600 	         reading anew right at the last page; the end-of-stream
    601 	         granulepos declares the last frame in the stream, and the
    602 	         last packet of the last page may be a partial frame.
    603 	         So, we need a previous granulepos from an in-sequence page
    604 	         to have a reference point.  Thus the !op.e_o_s clause
    605 	         above */
    606 
    607 	      if(vf->seekable && link>0)
    608 		granulepos-=vf->pcmlengths[link*2];
    609 	      if(granulepos<0)granulepos=0; /* actually, this
    610 					       shouldn't be possible
    611 					       here unless the stream
    612 					       is very broken */
    613 
    614 	      samples=vorbis_dsp_pcmout(vf->vd,NULL,0);
    615 
    616 	      granulepos-=samples;
    617 	      for(i=0;i<link;i++)
    618 	        granulepos+=vf->pcmlengths[i*2+1];
    619 	      vf->pcm_offset=granulepos;
    620 	    }
    621 	    ret=1;
    622 	    goto cleanup;
    623 	  }
    624 	}
    625 	else
    626 	  break;
    627       }
    628     }
    629 
    630     if(vf->ready_state>=OPENED){
    631       int ret;
    632       if(!readp){
    633 	ret=0;
    634 	goto cleanup;
    635       }
    636       ret=(int)_get_next_page(vf,&og,-1);
    637       if(ret<0){
    638 	ret=OV_EOF; /* eof. leave unitialized */
    639 	goto cleanup;
    640       }
    641 
    642 	/* bitrate tracking; add the header's bytes here, the body bytes
    643 	   are done by packet above */
    644       vf->bittrack+=og.header_len*8;
    645 
    646       /* has our decoding just traversed a bitstream boundary? */
    647       if(vf->ready_state==INITSET){
    648 	if(vf->current_serialno!=ogg_page_serialno(&og)){
    649 	  if(!spanp){
    650 	    ret=OV_EOF;
    651 	    goto cleanup;
    652 	  }
    653 
    654 	  _decode_clear(vf);
    655 	}
    656       }
    657     }
    658 
    659     /* Do we need to load a new machine before submitting the page? */
    660     /* This is different in the seekable and non-seekable cases.
    661 
    662        In the seekable case, we already have all the header
    663        information loaded and cached; we just initialize the machine
    664        with it and continue on our merry way.
    665 
    666        In the non-seekable (streaming) case, we'll only be at a
    667        boundary if we just left the previous logical bitstream and
    668        we're now nominally at the header of the next bitstream
    669     */
    670 
    671     if(vf->ready_state!=INITSET){
    672       int link,ret;
    673 
    674       if(vf->ready_state<STREAMSET){
    675 	if(vf->seekable){
    676 	  vf->current_serialno=ogg_page_serialno(&og);
    677 
    678 	  /* match the serialno to bitstream section.  We use this rather than
    679 	     offset positions to avoid problems near logical bitstream
    680 	     boundaries */
    681 	  for(link=0;link<vf->links;link++)
    682 	    if(vf->serialnos[link]==vf->current_serialno)break;
    683 	  if(link==vf->links){
    684 	    ret=OV_EBADLINK; /* sign of a bogus stream.  error out,
    685 				leave machine uninitialized */
    686 	    goto cleanup;
    687 	  }
    688 
    689 	  vf->current_link=link;
    690 	  ret=_fetch_headers(vf,&vf->vi,&vf->vc,&vf->current_serialno,&og);
    691 	  if(ret) goto cleanup;
    692 
    693 	}else{
    694 	  /* we're streaming */
    695 	  /* fetch the three header packets, build the info struct */
    696 
    697 	  int ret=_fetch_headers(vf,&vf->vi,&vf->vc,&vf->current_serialno,&og);
    698 	  if(ret) goto cleanup;
    699 	  vf->current_link++;
    700 	}
    701       }
    702 
    703       if(_make_decode_ready(vf)) return OV_EBADLINK;
    704     }
    705     ogg_stream_pagein(vf->os,&og);
    706   }
    707  cleanup:
    708   ogg_packet_release(&op);
    709   ogg_page_release(&og);
    710   return ret;
    711 }
    712 
    713 /* if, eg, 64 bit stdio is configured by default, this will build with
    714    fseek64 */
    715 static int _fseek64_wrap(FILE *f,ogg_int64_t off,int whence){
    716   if(f==NULL)return -1;
    717   return fseek(f,(long)off,whence);
    718 }
    719 
    720 static int _ov_open1(void *f,OggVorbis_File *vf,char *initial,
    721 		     long ibytes, ov_callbacks callbacks){
    722   int offsettest=(f?callbacks.seek_func(f,0,SEEK_CUR):-1);
    723   int ret;
    724 
    725   memset(vf,0,sizeof(*vf));
    726 
    727   /* Tremor assumes in multiple places that right shift of a signed
    728      integer is an arithmetic shift */
    729   if( (-1>>1) != -1) return OV_EIMPL;
    730 
    731   vf->datasource=f;
    732   vf->callbacks = callbacks;
    733 
    734   /* init the framing state */
    735   vf->oy=ogg_sync_create();
    736 
    737   /* perhaps some data was previously read into a buffer for testing
    738      against other stream types.  Allow initialization from this
    739      previously read data (as we may be reading from a non-seekable
    740      stream) */
    741   if(initial){
    742     unsigned char *buffer=ogg_sync_bufferin(vf->oy,ibytes);
    743     memcpy(buffer,initial,ibytes);
    744     ogg_sync_wrote(vf->oy,ibytes);
    745   }
    746 
    747   /* can we seek? Stevens suggests the seek test was portable */
    748   if(offsettest!=-1)vf->seekable=1;
    749 
    750   /* No seeking yet; Set up a 'single' (current) logical bitstream
    751      entry for partial open */
    752   vf->links=1;
    753   vf->os=ogg_stream_create(-1); /* fill in the serialno later */
    754 
    755   /* Try to fetch the headers, maintaining all the storage */
    756   if((ret=_fetch_headers(vf,&vf->vi,&vf->vc,&vf->current_serialno,NULL))<0){
    757     vf->datasource=NULL;
    758     ov_clear(vf);
    759   }else if(vf->ready_state < PARTOPEN)
    760     vf->ready_state=PARTOPEN;
    761   return ret;
    762 }
    763 
    764 static int _ov_open2(OggVorbis_File *vf){
    765   if(vf->ready_state < OPENED)
    766     vf->ready_state=OPENED;
    767   if(vf->seekable){
    768     int ret=_open_seekable2(vf);
    769     if(ret){
    770       vf->datasource=NULL;
    771       ov_clear(vf);
    772     }
    773     return ret;
    774   }
    775   return 0;
    776 }
    777 
    778 
    779 /* clear out the OggVorbis_File struct */
    780 int ov_clear(OggVorbis_File *vf){
    781   if(vf){
    782     vorbis_dsp_destroy(vf->vd);
    783     vf->vd=0;
    784     ogg_stream_destroy(vf->os);
    785     vorbis_info_clear(&vf->vi);
    786     vorbis_comment_clear(&vf->vc);
    787     if(vf->dataoffsets)_ogg_free(vf->dataoffsets);
    788     if(vf->pcmlengths)_ogg_free(vf->pcmlengths);
    789     if(vf->serialnos)_ogg_free(vf->serialnos);
    790     if(vf->offsets)_ogg_free(vf->offsets);
    791     ogg_sync_destroy(vf->oy);
    792 
    793     if(vf->datasource)(vf->callbacks.close_func)(vf->datasource);
    794     memset(vf,0,sizeof(*vf));
    795   }
    796 #ifdef DEBUG_LEAKS
    797   _VDBG_dump();
    798 #endif
    799   return 0;
    800 }
    801 
    802 /* inspects the OggVorbis file and finds/documents all the logical
    803    bitstreams contained in it.  Tries to be tolerant of logical
    804    bitstream sections that are truncated/woogie.
    805 
    806    return: -1) error
    807             0) OK
    808 */
    809 
    810 int ov_open_callbacks(void *f,OggVorbis_File *vf,char *initial,long ibytes,
    811     ov_callbacks callbacks){
    812   int ret=_ov_open1(f,vf,initial,ibytes,callbacks);
    813   if(ret)return ret;
    814   return _ov_open2(vf);
    815 }
    816 
    817 int ov_open(FILE *f,OggVorbis_File *vf,char *initial,long ibytes){
    818   ov_callbacks callbacks = {
    819     (size_t (*)(void *, size_t, size_t, void *))  fread,
    820     (int (*)(void *, ogg_int64_t, int))              _fseek64_wrap,
    821     (int (*)(void *))                             fclose,
    822     (long (*)(void *))                            ftell
    823   };
    824 
    825   return ov_open_callbacks((void *)f, vf, initial, ibytes, callbacks);
    826 }
    827 
    828 /* Only partially open the vorbis file; test for Vorbisness, and load
    829    the headers for the first chain.  Do not seek (although test for
    830    seekability).  Use ov_test_open to finish opening the file, else
    831    ov_clear to close/free it. Same return codes as open. */
    832 
    833 int ov_test_callbacks(void *f,OggVorbis_File *vf,char *initial,long ibytes,
    834     ov_callbacks callbacks)
    835 {
    836   return _ov_open1(f,vf,initial,ibytes,callbacks);
    837 }
    838 
    839 int ov_test(FILE *f,OggVorbis_File *vf,char *initial,long ibytes){
    840   ov_callbacks callbacks = {
    841     (size_t (*)(void *, size_t, size_t, void *))  fread,
    842     (int (*)(void *, ogg_int64_t, int))              _fseek64_wrap,
    843     (int (*)(void *))                             fclose,
    844     (long (*)(void *))                            ftell
    845   };
    846 
    847   return ov_test_callbacks((void *)f, vf, initial, ibytes, callbacks);
    848 }
    849 
    850 int ov_test_open(OggVorbis_File *vf){
    851   if(vf->ready_state!=PARTOPEN)return OV_EINVAL;
    852   return _ov_open2(vf);
    853 }
    854 
    855 /* How many logical bitstreams in this physical bitstream? */
    856 long ov_streams(OggVorbis_File *vf){
    857   return vf->links;
    858 }
    859 
    860 /* Is the FILE * associated with vf seekable? */
    861 long ov_seekable(OggVorbis_File *vf){
    862   return vf->seekable;
    863 }
    864 
    865 /* returns the bitrate for a given logical bitstream or the entire
    866    physical bitstream.  If the file is open for random access, it will
    867    find the *actual* average bitrate.  If the file is streaming, it
    868    returns the nominal bitrate (if set) else the average of the
    869    upper/lower bounds (if set) else -1 (unset).
    870 
    871    If you want the actual bitrate field settings, get them from the
    872    vorbis_info structs */
    873 
    874 long ov_bitrate(OggVorbis_File *vf,int i){
    875   if(vf->ready_state<OPENED)return OV_EINVAL;
    876   if(i>=vf->links)return OV_EINVAL;
    877   if(!vf->seekable && i!=0)return ov_bitrate(vf,0);
    878   if(i<0){
    879     ogg_int64_t bits=0;
    880     int i;
    881     for(i=0;i<vf->links;i++)
    882       bits+=(vf->offsets[i+1]-vf->dataoffsets[i])*8;
    883     /* This once read: return(rint(bits/ov_time_total(vf,-1)));
    884      * gcc 3.x on x86 miscompiled this at optimisation level 2 and above,
    885      * so this is slightly transformed to make it work.
    886      */
    887     return (long)(bits*1000/ov_time_total(vf,-1));
    888   }else{
    889     if(vf->seekable){
    890       /* return the actual bitrate */
    891       return (long)((vf->offsets[i+1]-vf->dataoffsets[i])*8000/ov_time_total(vf,i));
    892     }else{
    893       /* return nominal if set */
    894       if(vf->vi.bitrate_nominal>0){
    895 	return vf->vi.bitrate_nominal;
    896       }else{
    897 	if(vf->vi.bitrate_upper>0){
    898 	  if(vf->vi.bitrate_lower>0){
    899 	    return (vf->vi.bitrate_upper+vf->vi.bitrate_lower)/2;
    900 	  }else{
    901 	    return vf->vi.bitrate_upper;
    902 	  }
    903 	}
    904 	return OV_FALSE;
    905       }
    906     }
    907   }
    908 }
    909 
    910 /* returns the actual bitrate since last call.  returns -1 if no
    911    additional data to offer since last call (or at beginning of stream),
    912    EINVAL if stream is only partially open
    913 */
    914 long ov_bitrate_instant(OggVorbis_File *vf){
    915   long ret;
    916   if(vf->ready_state<OPENED)return OV_EINVAL;
    917   if(vf->samptrack==0)return OV_FALSE;
    918   ret=(long)(vf->bittrack/vf->samptrack*vf->vi.rate);
    919   vf->bittrack=0;
    920   vf->samptrack=0;
    921   return ret;
    922 }
    923 
    924 /* Guess */
    925 long ov_serialnumber(OggVorbis_File *vf,int i){
    926   if(i>=vf->links)return ov_serialnumber(vf,vf->links-1);
    927   if(!vf->seekable && i>=0)return ov_serialnumber(vf,-1);
    928   if(i<0){
    929     return vf->current_serialno;
    930   }else{
    931     return vf->serialnos[i];
    932   }
    933 }
    934 
    935 /* returns: total raw (compressed) length of content if i==-1
    936             raw (compressed) length of that logical bitstream for i==0 to n
    937 	    OV_EINVAL if the stream is not seekable (we can't know the length)
    938 	    or if stream is only partially open
    939 */
    940 ogg_int64_t ov_raw_total(OggVorbis_File *vf,int i){
    941   if(vf->ready_state<OPENED)return OV_EINVAL;
    942   if(!vf->seekable || i>=vf->links)return OV_EINVAL;
    943   if(i<0){
    944     ogg_int64_t acc=0;
    945     int i;
    946     for(i=0;i<vf->links;i++)
    947       acc+=ov_raw_total(vf,i);
    948     return acc;
    949   }else{
    950     return vf->offsets[i+1]-vf->offsets[i];
    951   }
    952 }
    953 
    954 /* returns: total PCM length (samples) of content if i==-1 PCM length
    955 	    (samples) of that logical bitstream for i==0 to n
    956 	    OV_EINVAL if the stream is not seekable (we can't know the
    957 	    length) or only partially open
    958 */
    959 ogg_int64_t ov_pcm_total(OggVorbis_File *vf,int i){
    960   if(vf->ready_state<OPENED)return OV_EINVAL;
    961   if(!vf->seekable || i>=vf->links)return OV_EINVAL;
    962   if(i<0){
    963     ogg_int64_t acc=0;
    964     int i;
    965     for(i=0;i<vf->links;i++)
    966       acc+=ov_pcm_total(vf,i);
    967     return acc;
    968   }else{
    969     return vf->pcmlengths[i*2+1];
    970   }
    971 }
    972 
    973 /* returns: total milliseconds of content if i==-1
    974             milliseconds in that logical bitstream for i==0 to n
    975 	    OV_EINVAL if the stream is not seekable (we can't know the
    976 	    length) or only partially open
    977 */
    978 ogg_int64_t ov_time_total(OggVorbis_File *vf,int i){
    979   if(vf->ready_state<OPENED)return OV_EINVAL;
    980   if(!vf->seekable || i>=vf->links)return OV_EINVAL;
    981   if(i<0){
    982     ogg_int64_t acc=0;
    983     int i;
    984     for(i=0;i<vf->links;i++)
    985       acc+=ov_time_total(vf,i);
    986     return acc;
    987   }else{
    988     return ((ogg_int64_t)vf->pcmlengths[i*2+1])*1000/vf->vi.rate;
    989   }
    990 }
    991 
    992 /* seek to an offset relative to the *compressed* data. This also
    993    scans packets to update the PCM cursor. It will cross a logical
    994    bitstream boundary, but only if it can't get any packets out of the
    995    tail of the bitstream we seek to (so no surprises).
    996 
    997    returns zero on success, nonzero on failure */
    998 
    999 int ov_raw_seek(OggVorbis_File *vf,ogg_int64_t pos){
   1000   ogg_stream_state *work_os=NULL;
   1001   ogg_page og={0,0,0,0};
   1002   ogg_packet op={0,0,0,0,0,0};
   1003 
   1004   if(vf->ready_state<OPENED)return OV_EINVAL;
   1005   if(!vf->seekable)
   1006     return OV_ENOSEEK; /* don't dump machine if we can't seek */
   1007 
   1008   if(pos<0 || pos>vf->end)return OV_EINVAL;
   1009 
   1010   /* don't yet clear out decoding machine (if it's initialized), in
   1011      the case we're in the same link.  Restart the decode lapping, and
   1012      let _fetch_and_process_packet deal with a potential bitstream
   1013      boundary */
   1014   vf->pcm_offset=-1;
   1015   ogg_stream_reset_serialno(vf->os,
   1016 			    vf->current_serialno); /* must set serialno */
   1017   vorbis_dsp_restart(vf->vd);
   1018 
   1019   _seek_helper(vf,pos);
   1020 
   1021   /* we need to make sure the pcm_offset is set, but we don't want to
   1022      advance the raw cursor past good packets just to get to the first
   1023      with a granulepos.  That's not equivalent behavior to beginning
   1024      decoding as immediately after the seek position as possible.
   1025 
   1026      So, a hack.  We use two stream states; a local scratch state and
   1027      the shared vf->os stream state.  We use the local state to
   1028      scan, and the shared state as a buffer for later decode.
   1029 
   1030      Unfortuantely, on the last page we still advance to last packet
   1031      because the granulepos on the last page is not necessarily on a
   1032      packet boundary, and we need to make sure the granpos is
   1033      correct.
   1034   */
   1035 
   1036   {
   1037     int lastblock=0;
   1038     int accblock=0;
   1039     int thisblock;
   1040     int eosflag;
   1041 
   1042     work_os=ogg_stream_create(vf->current_serialno); /* get the memory ready */
   1043     while(1){
   1044       if(vf->ready_state>=STREAMSET){
   1045 	/* snarf/scan a packet if we can */
   1046 	int result=ogg_stream_packetout(work_os,&op);
   1047 
   1048 	if(result>0){
   1049 
   1050 	  if(vf->vi.codec_setup){
   1051 	    thisblock=vorbis_packet_blocksize(&vf->vi,&op);
   1052 	    if(thisblock<0){
   1053 	      ogg_stream_packetout(vf->os,NULL);
   1054 	      thisblock=0;
   1055 	    }else{
   1056 
   1057 	      if(eosflag)
   1058 		ogg_stream_packetout(vf->os,NULL);
   1059 	      else
   1060 		if(lastblock)accblock+=(lastblock+thisblock)>>2;
   1061 	    }
   1062 
   1063 	    if(op.granulepos!=-1){
   1064 	      int i,link=vf->current_link;
   1065 	      ogg_int64_t granulepos=op.granulepos-vf->pcmlengths[link*2];
   1066 	      if(granulepos<0)granulepos=0;
   1067 
   1068 	      for(i=0;i<link;i++)
   1069 		granulepos+=vf->pcmlengths[i*2+1];
   1070 	      vf->pcm_offset=granulepos-accblock;
   1071 	      break;
   1072 	    }
   1073 	    lastblock=thisblock;
   1074 	    continue;
   1075 	  }else
   1076 	    ogg_stream_packetout(vf->os,NULL);
   1077 	}
   1078       }
   1079 
   1080       if(!lastblock){
   1081 	if(_get_next_page(vf,&og,-1)<0){
   1082 	  vf->pcm_offset=ov_pcm_total(vf,-1);
   1083 	  break;
   1084 	}
   1085       }else{
   1086 	/* huh?  Bogus stream with packets but no granulepos */
   1087 	vf->pcm_offset=-1;
   1088 	break;
   1089       }
   1090 
   1091       /* did we just grab a page from other than current link? */
   1092       if(vf->ready_state>=STREAMSET)
   1093 	if(vf->current_serialno!=ogg_page_serialno(&og)){
   1094 	  _decode_clear(vf); /* clear out stream state */
   1095 	  ogg_stream_destroy(work_os);
   1096 	}
   1097 
   1098       if(vf->ready_state<STREAMSET){
   1099 	int link;
   1100 
   1101 	vf->current_serialno=ogg_page_serialno(&og);
   1102 	for(link=0;link<vf->links;link++)
   1103 	  if(vf->serialnos[link]==vf->current_serialno)break;
   1104 	if(link==vf->links)
   1105 	  goto seek_error; /* sign of a bogus stream.  error out,
   1106 			      leave machine uninitialized */
   1107 
   1108 	/* need to initialize machine to this link */
   1109 	{
   1110 	  int ret=_set_link_number_preserve_pos(vf,link);
   1111 	  if(ret) goto seek_error;
   1112 	}
   1113 	ogg_stream_reset_serialno(vf->os,vf->current_serialno);
   1114 	ogg_stream_reset_serialno(work_os,vf->current_serialno);
   1115 
   1116 
   1117       }
   1118 
   1119       {
   1120 	ogg_page dup;
   1121 	ogg_page_dup(&dup,&og);
   1122 	eosflag=ogg_page_eos(&og);
   1123 	ogg_stream_pagein(vf->os,&og);
   1124 	ogg_stream_pagein(work_os,&dup);
   1125       }
   1126     }
   1127   }
   1128 
   1129   ogg_packet_release(&op);
   1130   ogg_page_release(&og);
   1131   ogg_stream_destroy(work_os);
   1132   vf->bittrack=0;
   1133   vf->samptrack=0;
   1134   return 0;
   1135 
   1136  seek_error:
   1137   ogg_packet_release(&op);
   1138   ogg_page_release(&og);
   1139 
   1140   /* dump the machine so we're in a known state */
   1141   vf->pcm_offset=-1;
   1142   ogg_stream_destroy(work_os);
   1143   _decode_clear(vf);
   1144   return OV_EBADLINK;
   1145 }
   1146 
   1147 /* Page granularity seek (faster than sample granularity because we
   1148    don't do the last bit of decode to find a specific sample).
   1149 
   1150    Seek to the last [granule marked] page preceeding the specified pos
   1151    location, such that decoding past the returned point will quickly
   1152    arrive at the requested position. */
   1153 int ov_pcm_seek_page(OggVorbis_File *vf,ogg_int64_t pos){
   1154   int link=-1;
   1155   ogg_int64_t result=0;
   1156   ogg_int64_t total=ov_pcm_total(vf,-1);
   1157   ogg_page og={0,0,0,0};
   1158   ogg_packet op={0,0,0,0,0,0};
   1159 
   1160   if(vf->ready_state<OPENED)return OV_EINVAL;
   1161   if(!vf->seekable)return OV_ENOSEEK;
   1162   if(pos<0 || pos>total)return OV_EINVAL;
   1163 
   1164   /* which bitstream section does this pcm offset occur in? */
   1165   for(link=vf->links-1;link>=0;link--){
   1166     total-=vf->pcmlengths[link*2+1];
   1167     if(pos>=total)break;
   1168   }
   1169 
   1170 
   1171   if(link!=vf->current_link){
   1172     int ret=_set_link_number(vf,link);
   1173     if(ret) goto seek_error;
   1174   }else{
   1175     vorbis_dsp_restart(vf->vd);
   1176   }
   1177 
   1178   ogg_stream_reset_serialno(vf->os,vf->serialnos[link]);
   1179 
   1180   /* search within the logical bitstream for the page with the highest
   1181      pcm_pos preceeding (or equal to) pos.  There is a danger here;
   1182      missing pages or incorrect frame number information in the
   1183      bitstream could make our task impossible.  Account for that (it
   1184      would be an error condition) */
   1185 
   1186   /* new search algorithm by HB (Nicholas Vinen) */
   1187   {
   1188     ogg_int64_t end=vf->offsets[link+1];
   1189     ogg_int64_t begin=vf->offsets[link];
   1190     ogg_int64_t begintime = vf->pcmlengths[link*2];
   1191     ogg_int64_t endtime = vf->pcmlengths[link*2+1]+begintime;
   1192     ogg_int64_t target=pos-total+begintime;
   1193     ogg_int64_t best=begin;
   1194 
   1195     while(begin<end){
   1196       ogg_int64_t bisect;
   1197 
   1198       if(end-begin<CHUNKSIZE){
   1199 	bisect=begin;
   1200       }else{
   1201 	/* take a (pretty decent) guess. */
   1202 	bisect=begin +
   1203 	  (target-begintime)*(end-begin)/(endtime-begintime) - CHUNKSIZE;
   1204 	if(bisect<=begin)
   1205 	  bisect=begin+1;
   1206       }
   1207 
   1208       _seek_helper(vf,bisect);
   1209 
   1210       while(begin<end){
   1211 	result=_get_next_page(vf,&og,end-vf->offset);
   1212 	if(result==OV_EREAD) goto seek_error;
   1213 	if(result<0){
   1214 	  if(bisect<=begin+1)
   1215 	    end=begin; /* found it */
   1216 	  else{
   1217 	    if(bisect==0) goto seek_error;
   1218 	    bisect-=CHUNKSIZE;
   1219 	    if(bisect<=begin)bisect=begin+1;
   1220 	    _seek_helper(vf,bisect);
   1221 	  }
   1222 	}else{
   1223 	  ogg_int64_t granulepos=ogg_page_granulepos(&og);
   1224 	  if(granulepos==-1)continue;
   1225 	  if(granulepos<target){
   1226 	    best=result;  /* raw offset of packet with granulepos */
   1227 	    begin=vf->offset; /* raw offset of next page */
   1228 	    begintime=granulepos;
   1229 
   1230 	    if(target-begintime>44100)break;
   1231 	    bisect=begin; /* *not* begin + 1 */
   1232 	  }else{
   1233 	    if(bisect<=begin+1)
   1234 	      end=begin;  /* found it */
   1235 	    else{
   1236 	      if(end==vf->offset){ /* we're pretty close - we'd be stuck in */
   1237 		end=result;
   1238 		bisect-=CHUNKSIZE; /* an endless loop otherwise. */
   1239 		if(bisect<=begin)bisect=begin+1;
   1240 		_seek_helper(vf,bisect);
   1241 	      }else{
   1242 		end=result;
   1243 		endtime=granulepos;
   1244 		break;
   1245 	      }
   1246 	    }
   1247 	  }
   1248 	}
   1249       }
   1250     }
   1251 
   1252     /* found our page. seek to it, update pcm offset. Easier case than
   1253        raw_seek, don't keep packets preceeding granulepos. */
   1254     {
   1255 
   1256       /* seek */
   1257       _seek_helper(vf,best);
   1258       vf->pcm_offset=-1;
   1259 
   1260       if(_get_next_page(vf,&og,-1)<0){
   1261 	ogg_page_release(&og);
   1262 	return OV_EOF; /* shouldn't happen */
   1263       }
   1264 
   1265       ogg_stream_pagein(vf->os,&og);
   1266 
   1267       /* pull out all but last packet; the one with granulepos */
   1268       while(1){
   1269 	result=ogg_stream_packetpeek(vf->os,&op);
   1270 	if(result==0){
   1271 	  /* !!! the packet finishing this page originated on a
   1272              preceeding page. Keep fetching previous pages until we
   1273              get one with a granulepos or without the 'continued' flag
   1274              set.  Then just use raw_seek for simplicity. */
   1275 
   1276 	  _seek_helper(vf,best);
   1277 
   1278 	  while(1){
   1279 	    result=_get_prev_page(vf,&og);
   1280 	    if(result<0) goto seek_error;
   1281 	    if(ogg_page_granulepos(&og)>-1 ||
   1282 	       !ogg_page_continued(&og)){
   1283 	      return ov_raw_seek(vf,result);
   1284 	    }
   1285 	    vf->offset=result;
   1286 	  }
   1287 	}
   1288 	if(result<0){
   1289 	  result = OV_EBADPACKET;
   1290 	  goto seek_error;
   1291 	}
   1292 	if(op.granulepos!=-1){
   1293 	  vf->pcm_offset=op.granulepos-vf->pcmlengths[vf->current_link*2];
   1294 	  if(vf->pcm_offset<0)vf->pcm_offset=0;
   1295 	  vf->pcm_offset+=total;
   1296 	  break;
   1297 	}else
   1298 	  result=ogg_stream_packetout(vf->os,NULL);
   1299       }
   1300     }
   1301   }
   1302 
   1303   /* verify result */
   1304   if(vf->pcm_offset>pos || pos>ov_pcm_total(vf,-1)){
   1305     result=OV_EFAULT;
   1306     goto seek_error;
   1307   }
   1308   vf->bittrack=0;
   1309   vf->samptrack=0;
   1310 
   1311   ogg_page_release(&og);
   1312   ogg_packet_release(&op);
   1313   return 0;
   1314 
   1315  seek_error:
   1316 
   1317   ogg_page_release(&og);
   1318   ogg_packet_release(&op);
   1319 
   1320   /* dump machine so we're in a known state */
   1321   vf->pcm_offset=-1;
   1322   _decode_clear(vf);
   1323   return (int)result;
   1324 }
   1325 
   1326 /* seek to a sample offset relative to the decompressed pcm stream
   1327    returns zero on success, nonzero on failure */
   1328 
   1329 int ov_pcm_seek(OggVorbis_File *vf,ogg_int64_t pos){
   1330   ogg_packet op={0,0,0,0,0,0};
   1331   ogg_page og={0,0,0,0};
   1332   int thisblock,lastblock=0;
   1333   int ret=ov_pcm_seek_page(vf,pos);
   1334   if(ret<0)return ret;
   1335   if(_make_decode_ready(vf))return OV_EBADLINK;
   1336 
   1337   /* discard leading packets we don't need for the lapping of the
   1338      position we want; don't decode them */
   1339 
   1340   while(1){
   1341 
   1342     int ret=ogg_stream_packetpeek(vf->os,&op);
   1343     if(ret>0){
   1344       thisblock=vorbis_packet_blocksize(&vf->vi,&op);
   1345       if(thisblock<0){
   1346 	ogg_stream_packetout(vf->os,NULL);
   1347 	continue; /* non audio packet */
   1348       }
   1349       if(lastblock)vf->pcm_offset+=(lastblock+thisblock)>>2;
   1350 
   1351       if(vf->pcm_offset+((thisblock+
   1352 			  vorbis_info_blocksize(&vf->vi,1))>>2)>=pos)break;
   1353 
   1354       /* remove the packet from packet queue and track its granulepos */
   1355       ogg_stream_packetout(vf->os,NULL);
   1356       vorbis_dsp_synthesis(vf->vd,&op,0);  /* set up a vb with
   1357 					      only tracking, no
   1358 					      pcm_decode */
   1359 
   1360       /* end of logical stream case is hard, especially with exact
   1361 	 length positioning. */
   1362 
   1363       if(op.granulepos>-1){
   1364 	int i;
   1365 	/* always believe the stream markers */
   1366 	vf->pcm_offset=op.granulepos-vf->pcmlengths[vf->current_link*2];
   1367 	if(vf->pcm_offset<0)vf->pcm_offset=0;
   1368 	for(i=0;i<vf->current_link;i++)
   1369 	  vf->pcm_offset+=vf->pcmlengths[i*2+1];
   1370       }
   1371 
   1372       lastblock=thisblock;
   1373 
   1374     }else{
   1375       if(ret<0 && ret!=OV_HOLE)break;
   1376 
   1377       /* suck in a new page */
   1378       if(_get_next_page(vf,&og,-1)<0)break;
   1379       if(vf->current_serialno!=ogg_page_serialno(&og))_decode_clear(vf);
   1380 
   1381       if(vf->ready_state<STREAMSET){
   1382 	int link,ret;
   1383 
   1384 	vf->current_serialno=ogg_page_serialno(&og);
   1385 	for(link=0;link<vf->links;link++)
   1386 	  if(vf->serialnos[link]==vf->current_serialno)break;
   1387 	if(link==vf->links){
   1388 	  ogg_page_release(&og);
   1389 	  ogg_packet_release(&op);
   1390 	  return OV_EBADLINK;
   1391 	}
   1392 
   1393 
   1394 	vf->current_link=link;
   1395 	ret=_fetch_headers(vf,&vf->vi,&vf->vc,&vf->current_serialno,&og);
   1396 	if(ret) return ret;
   1397 	if(_make_decode_ready(vf))return OV_EBADLINK;
   1398 	lastblock=0;
   1399       }
   1400 
   1401       ogg_stream_pagein(vf->os,&og);
   1402     }
   1403   }
   1404 
   1405   vf->bittrack=0;
   1406   vf->samptrack=0;
   1407   /* discard samples until we reach the desired position. Crossing a
   1408      logical bitstream boundary with abandon is OK. */
   1409   while(vf->pcm_offset<pos){
   1410     ogg_int64_t target=pos-vf->pcm_offset;
   1411     long samples=vorbis_dsp_pcmout(vf->vd,NULL,0);
   1412 
   1413     if(samples>target)samples=(long)target;
   1414     vorbis_dsp_read(vf->vd,samples);
   1415     vf->pcm_offset+=samples;
   1416 
   1417     if(samples<target)
   1418       if(_fetch_and_process_packet(vf,1,1)<=0)
   1419 	vf->pcm_offset=ov_pcm_total(vf,-1); /* eof */
   1420   }
   1421 
   1422   ogg_page_release(&og);
   1423   ogg_packet_release(&op);
   1424   return 0;
   1425 }
   1426 
   1427 /* seek to a playback time relative to the decompressed pcm stream
   1428    returns zero on success, nonzero on failure */
   1429 int ov_time_seek(OggVorbis_File *vf,ogg_int64_t milliseconds){
   1430   /* translate time to PCM position and call ov_pcm_seek */
   1431 
   1432   int link=-1;
   1433   ogg_int64_t pcm_total=ov_pcm_total(vf,-1);
   1434   ogg_int64_t time_total=ov_time_total(vf,-1);
   1435 
   1436   if(vf->ready_state<OPENED)return OV_EINVAL;
   1437   if(!vf->seekable)return OV_ENOSEEK;
   1438   if(milliseconds<0 || milliseconds>time_total)return OV_EINVAL;
   1439 
   1440   /* which bitstream section does this time offset occur in? */
   1441   for(link=vf->links-1;link>=0;link--){
   1442     pcm_total-=vf->pcmlengths[link*2+1];
   1443     time_total-=ov_time_total(vf,link);
   1444     if(milliseconds>=time_total)break;
   1445   }
   1446 
   1447   /* enough information to convert time offset to pcm offset */
   1448   {
   1449     int ret=_set_link_number(vf,link);
   1450     if(ret)return ret;
   1451     return
   1452       ov_pcm_seek(vf,pcm_total+(milliseconds-time_total)*
   1453 		  vf->vi.rate/1000);
   1454   }
   1455 }
   1456 
   1457 /* page-granularity version of ov_time_seek
   1458    returns zero on success, nonzero on failure */
   1459 int ov_time_seek_page(OggVorbis_File *vf,ogg_int64_t milliseconds){
   1460   /* translate time to PCM position and call ov_pcm_seek */
   1461 
   1462   int link=-1;
   1463   ogg_int64_t pcm_total=ov_pcm_total(vf,-1);
   1464   ogg_int64_t time_total=ov_time_total(vf,-1);
   1465 
   1466   if(vf->ready_state<OPENED)return OV_EINVAL;
   1467   if(!vf->seekable)return OV_ENOSEEK;
   1468   if(milliseconds<0 || milliseconds>time_total)return OV_EINVAL;
   1469 
   1470   /* which bitstream section does this time offset occur in? */
   1471   for(link=vf->links-1;link>=0;link--){
   1472     pcm_total-=vf->pcmlengths[link*2+1];
   1473     time_total-=ov_time_total(vf,link);
   1474     if(milliseconds>=time_total)break;
   1475   }
   1476 
   1477   /* enough information to convert time offset to pcm offset */
   1478   {
   1479     int ret=_set_link_number(vf,link);
   1480     if(ret)return ret;
   1481     return
   1482       ov_pcm_seek_page(vf,pcm_total+(milliseconds-time_total)*
   1483 		       vf->vi.rate/1000);
   1484   }
   1485 }
   1486 
   1487 /* tell the current stream offset cursor.  Note that seek followed by
   1488    tell will likely not give the set offset due to caching */
   1489 ogg_int64_t ov_raw_tell(OggVorbis_File *vf){
   1490   if(vf->ready_state<OPENED)return OV_EINVAL;
   1491   return vf->offset;
   1492 }
   1493 
   1494 /* return PCM offset (sample) of next PCM sample to be read */
   1495 ogg_int64_t ov_pcm_tell(OggVorbis_File *vf){
   1496   if(vf->ready_state<OPENED)return OV_EINVAL;
   1497   return vf->pcm_offset;
   1498 }
   1499 
   1500 /* return time offset (milliseconds) of next PCM sample to be read */
   1501 ogg_int64_t ov_time_tell(OggVorbis_File *vf){
   1502   int link=0;
   1503   ogg_int64_t pcm_total=0;
   1504   ogg_int64_t time_total=0;
   1505 
   1506   if(vf->ready_state<OPENED)return OV_EINVAL;
   1507   if(vf->seekable){
   1508     pcm_total=ov_pcm_total(vf,-1);
   1509     time_total=ov_time_total(vf,-1);
   1510 
   1511     /* which bitstream section does this time offset occur in? */
   1512     for(link=vf->links-1;link>=0;link--){
   1513       pcm_total-=vf->pcmlengths[link*2+1];
   1514       time_total-=ov_time_total(vf,link);
   1515       if(vf->pcm_offset>=pcm_total)break;
   1516     }
   1517   }
   1518 
   1519   return time_total+(1000*vf->pcm_offset-pcm_total)/vf->vi.rate;
   1520 }
   1521 
   1522 /*  link:   -1) return the vorbis_info struct for the bitstream section
   1523                 currently being decoded
   1524            0-n) to request information for a specific bitstream section
   1525 
   1526     In the case of a non-seekable bitstream, any call returns the
   1527     current bitstream.  NULL in the case that the machine is not
   1528     initialized */
   1529 
   1530 vorbis_info *ov_info(OggVorbis_File *vf,int link){
   1531   if(vf->seekable){
   1532     if(link>=vf->links)return NULL;
   1533     if(link>=0){
   1534       int ret=_set_link_number_preserve_pos(vf,link);
   1535       if(ret)return NULL;
   1536     }
   1537   }
   1538   return &vf->vi;
   1539 }
   1540 
   1541 /* grr, strong typing, grr, no templates/inheritence, grr */
   1542 vorbis_comment *ov_comment(OggVorbis_File *vf,int link){
   1543   if(vf->seekable){
   1544     if(link>=vf->links)return NULL;
   1545     if(link>=0){
   1546       int ret=_set_link_number_preserve_pos(vf,link);
   1547       if(ret)return NULL;
   1548     }
   1549   }
   1550   return &vf->vc;
   1551 }
   1552 
   1553 /* up to this point, everything could more or less hide the multiple
   1554    logical bitstream nature of chaining from the toplevel application
   1555    if the toplevel application didn't particularly care.  However, at
   1556    the point that we actually read audio back, the multiple-section
   1557    nature must surface: Multiple bitstream sections do not necessarily
   1558    have to have the same number of channels or sampling rate.
   1559 
   1560    ov_read returns the sequential logical bitstream number currently
   1561    being decoded along with the PCM data in order that the toplevel
   1562    application can take action on channel/sample rate changes.  This
   1563    number will be incremented even for streamed (non-seekable) streams
   1564    (for seekable streams, it represents the actual logical bitstream
   1565    index within the physical bitstream.  Note that the accessor
   1566    functions above are aware of this dichotomy).
   1567 
   1568    input values: buffer) a buffer to hold packed PCM data for return
   1569 		 length) the byte length requested to be placed into buffer
   1570 
   1571    return values: <0) error/hole in data (OV_HOLE), partial open (OV_EINVAL)
   1572                    0) EOF
   1573 		   n) number of bytes of PCM actually returned.  The
   1574 		   below works on a packet-by-packet basis, so the
   1575 		   return length is not related to the 'length' passed
   1576 		   in, just guaranteed to fit.
   1577 
   1578 	    *section) set to the logical bitstream number */
   1579 
   1580 long ov_read(OggVorbis_File *vf,void *buffer,int bytes_req,int *bitstream){
   1581 
   1582   long samples;
   1583   long channels;
   1584 
   1585   if(vf->ready_state<OPENED)return OV_EINVAL;
   1586 
   1587   while(1){
   1588     if(vf->ready_state==INITSET){
   1589       channels=vf->vi.channels;
   1590       samples=vorbis_dsp_pcmout(vf->vd,buffer,(bytes_req>>1)/channels);
   1591       if(samples){
   1592 	if(samples>0){
   1593 	  vorbis_dsp_read(vf->vd,samples);
   1594 	  vf->pcm_offset+=samples;
   1595 	  if(bitstream)*bitstream=vf->current_link;
   1596 	  return samples*2*channels;
   1597 	}
   1598 	return samples;
   1599       }
   1600     }
   1601 
   1602     /* suck in another packet */
   1603     {
   1604       int ret=_fetch_and_process_packet(vf,1,1);
   1605       if(ret==OV_EOF)
   1606 	return 0;
   1607       if(ret<=0)
   1608 	return ret;
   1609     }
   1610 
   1611   }
   1612 }
   1613