1 /********************************************************************
2  *                                                                  *
3  * THIS FILE IS PART OF THE OggVorbis 'TREMOR' CODEC SOURCE CODE.   *
4  *                                                                  *
5  * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     *
6  * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
7  * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING.       *
8  *                                                                  *
9  * THE OggVorbis 'TREMOR' SOURCE CODE IS (C) COPYRIGHT 1994-2009    *
10  * BY THE Xiph.Org FOUNDATION http://www.xiph.org/                  *
11  *                                                                  *
12  ********************************************************************
13 
14  function: stdio-based convenience library for opening/seeking/decoding
15  last mod: $Id: vorbisfile.c,v 1.6 2003/03/30 23:40:56 xiphmont Exp $
16 
17  ********************************************************************/
18 
19 #include <stdlib.h>
20 #include <stdio.h>
21 #include <errno.h>
22 #include <string.h>
23 #include <math.h>
24 
25 #include "ivorbiscodec.h"
26 #include "ivorbisfile.h"
27 
28 #include "os.h"
29 #include "misc.h"
30 
31 /* A 'chained bitstream' is a Vorbis bitstream that contains more than
32    one logical bitstream arranged end to end (the only form of Ogg
33    multiplexing allowed in a Vorbis bitstream; grouping [parallel
34    multiplexing] is not allowed in Vorbis) */
35 
36 /* A Vorbis file can be played beginning to end (streamed) without
37    worrying ahead of time about chaining (see decoder_example.c).  If
38    we have the whole file, however, and want random access
39    (seeking/scrubbing) or desire to know the total length/time of a
40    file, we need to account for the possibility of chaining. */
41 
42 /* We can handle things a number of ways; we can determine the entire
43    bitstream structure right off the bat, or find pieces on demand.
44    This example determines and caches structure for the entire
45    bitstream, but builds a virtual decoder on the fly when moving
46    between links in the chain. */
47 
48 /* There are also different ways to implement seeking.  Enough
49    information exists in an Ogg bitstream to seek to
50    sample-granularity positions in the output.  Or, one can seek by
51    picking some portion of the stream roughly in the desired area if
52    we only want coarse navigation through the stream. */
53 
54 /*************************************************************************
55  * Many, many internal helpers.  The intention is not to be confusing;
56  * rampant duplication and monolithic function implementation would be
57  * harder to understand anyway.  The high level functions are last.  Begin
58  * grokking near the end of the file */
59 
60 
61 /* read a little more data from the file/pipe into the ogg_sync framer */
_get_data(OggVorbis_File * vf)62 static long _get_data(OggVorbis_File *vf){
63   errno=0;
64   if(!(vf->callbacks.read_func))return(-1);
65   if(vf->datasource){
66     char *buffer=ogg_sync_buffer(&vf->oy,CHUNKSIZE);
67     long bytes=(vf->callbacks.read_func)(buffer,1,CHUNKSIZE,vf->datasource);
68     if(bytes>0)ogg_sync_wrote(&vf->oy,bytes);
69 #ifdef GEKKO
70     // It seems that EOVERFLOW is set whenever
71     // we read to the end of the file on WII...
72 	// Fix copied from WiiMednafen code.
73     if(bytes==0 && errno && errno != EOVERFLOW)
74 #else
75     if(bytes==0 && errno)
76 #endif
77 	{
78 	  return(-1);
79 	}
80     return(bytes);
81   }else
82     return(0);
83 }
84 
85 /* save a tiny smidge of verbosity to make the code more readable */
_seek_helper(OggVorbis_File * vf,int64_t offset)86 static int _seek_helper(OggVorbis_File *vf,int64_t offset){
87   if(vf->datasource){
88     if(!(vf->callbacks.seek_func)||
89        (vf->callbacks.seek_func)(vf->datasource, offset, SEEK_SET) == -1)
90       return OV_EREAD;
91     vf->offset=offset;
92     ogg_sync_reset(&vf->oy);
93   }else{
94     /* shouldn't happen unless someone writes a broken callback */
95     return OV_EFAULT;
96   }
97   return 0;
98 }
99 
100 /* The read/seek functions track absolute position within the stream */
101 
102 /* from the head of the stream, get the next page.  boundary specifies
103    if the function is allowed to fetch more data from the stream (and
104    how much) or only use internally buffered data.
105 
106    boundary: -1) unbounded search
107               0) read no additional data; use cached only
108               n) search for a new page beginning for n bytes
109 
110    return:   <0) did not find a page (OV_FALSE, OV_EOF, OV_EREAD)
111               n) found a page at absolute offset n */
112 
_get_next_page(OggVorbis_File * vf,ogg_page * og,int64_t boundary)113 static int64_t _get_next_page(OggVorbis_File *vf,ogg_page *og,
114                                   int64_t boundary){
115   if(boundary>0)boundary+=vf->offset;
116   while(1){
117     long more;
118 
119     if(boundary>0 && vf->offset>=boundary)return(OV_FALSE);
120     more=ogg_sync_pageseek(&vf->oy,og);
121 
122     if(more<0){
123       /* skipped n bytes */
124       vf->offset-=more;
125     }else{
126       if(more==0){
127         /* send more paramedics */
128         if(!boundary)return(OV_FALSE);
129         {
130           long ret=_get_data(vf);
131           if(ret==0)return(OV_EOF);
132           if(ret<0)return(OV_EREAD);
133         }
134       }else{
135         /* got a page.  Return the offset at the page beginning,
136            advance the internal offset past the page end */
137         int64_t ret=vf->offset;
138         vf->offset+=more;
139         return(ret);
140 
141       }
142     }
143   }
144 }
145 
146 /* find the latest page beginning before the current stream cursor
147    position. Much dirtier than the above as Ogg doesn't have any
148    backward search linkage.  no 'readp' as it will certainly have to
149    read. */
150 /* returns offset or OV_EREAD, OV_FAULT */
_get_prev_page(OggVorbis_File * vf,ogg_page * og)151 static int64_t _get_prev_page(OggVorbis_File *vf,ogg_page *og){
152   int64_t begin=vf->offset;
153   int64_t end=begin;
154   int64_t ret;
155   int64_t offset=-1;
156 
157   while(offset==-1){
158     begin-=CHUNKSIZE;
159     if(begin<0)
160       begin=0;
161 
162     ret=_seek_helper(vf,begin);
163     if(ret)return(ret);
164 
165     while(vf->offset<end){
166       memset(og,0,sizeof(*og));
167       ret=_get_next_page(vf,og,end-vf->offset);
168       if(ret==OV_EREAD)return(OV_EREAD);
169       if(ret<0){
170         break;
171       }else{
172         offset=ret;
173       }
174     }
175   }
176 
177   /* In a fully compliant, non-multiplexed stream, we'll still be
178      holding the last page.  In multiplexed (or noncompliant streams),
179      we will probably have to re-read the last page we saw */
180   if(og->header_len==0){
181     ret=_seek_helper(vf,offset);
182     if(ret)return(ret);
183 
184     ret=_get_next_page(vf,og,CHUNKSIZE);
185     if(ret<0)
186       /* this shouldn't be possible */
187       return(OV_EFAULT);
188   }
189 
190   return(offset);
191 }
192 
_add_serialno(ogg_page * og,uint32_t ** serialno_list,int * n)193 static void _add_serialno(ogg_page *og,uint32_t **serialno_list, int *n){
194   uint32_t s = ogg_page_serialno(og);
195   (*n)++;
196 
197   if(*serialno_list){
198     *serialno_list = realloc(*serialno_list, sizeof(**serialno_list)*(*n));
199   }else{
200     *serialno_list = malloc(sizeof(**serialno_list));
201   }
202 
203   (*serialno_list)[(*n)-1] = s;
204 }
205 
206 /* returns nonzero if found */
_lookup_serialno(uint32_t s,uint32_t * serialno_list,int n)207 static int _lookup_serialno(uint32_t s, uint32_t *serialno_list, int n){
208   if(serialno_list){
209     while(n--){
210       if(*serialno_list == s) return 1;
211       serialno_list++;
212     }
213   }
214   return 0;
215 }
216 
_lookup_page_serialno(ogg_page * og,uint32_t * serialno_list,int n)217 static int _lookup_page_serialno(ogg_page *og, uint32_t *serialno_list, int n){
218   uint32_t s = ogg_page_serialno(og);
219   return _lookup_serialno(s,serialno_list,n);
220 }
221 
222 /* performs the same search as _get_prev_page, but prefers pages of
223    the specified serial number. If a page of the specified serialno is
224    spotted during the seek-back-and-read-forward, it will return the
225    info of last page of the matching serial number instead of the very
226    last page.  If no page of the specified serialno is seen, it will
227    return the info of last page and alter *serialno.  */
_get_prev_page_serial(OggVorbis_File * vf,uint32_t * serial_list,int serial_n,int * serialno,int64_t * granpos)228 static int64_t _get_prev_page_serial(OggVorbis_File *vf,
229                                          uint32_t *serial_list, int serial_n,
230                                          int *serialno, int64_t *granpos){
231   ogg_page og;
232   int64_t begin=vf->offset;
233   int64_t end=begin;
234   int64_t ret;
235 
236   int64_t prefoffset=-1;
237   int64_t offset=-1;
238   int64_t ret_serialno=-1;
239   int64_t ret_gran=-1;
240 
241   while(offset==-1){
242     begin-=CHUNKSIZE;
243     if(begin<0)
244       begin=0;
245 
246     ret=_seek_helper(vf,begin);
247     if(ret)return(ret);
248 
249     while(vf->offset<end){
250       ret=_get_next_page(vf,&og,end-vf->offset);
251       if(ret==OV_EREAD)return(OV_EREAD);
252       if(ret<0){
253         break;
254       }else{
255         ret_serialno=ogg_page_serialno(&og);
256         ret_gran=ogg_page_granulepos(&og);
257         offset=ret;
258 
259         if((uint32_t)ret_serialno == *serialno){
260           prefoffset=ret;
261           *granpos=ret_gran;
262         }
263 
264         if(!_lookup_serialno((uint32_t)ret_serialno,serial_list,serial_n)){
265           /* we fell off the end of the link, which means we seeked
266              back too far and shouldn't have been looking in that link
267              to begin with.  If we found the preferred serial number,
268              forget that we saw it. */
269           prefoffset=-1;
270         }
271       }
272     }
273   }
274 
275   /* we're not interested in the page... just the serialno and granpos. */
276   if(prefoffset>=0)return(prefoffset);
277 
278   *serialno = ret_serialno;
279   *granpos = ret_gran;
280   return(offset);
281 
282 }
283 
284 /* uses the local ogg_stream storage in vf; this is important for
285    non-streaming input sources */
_fetch_headers(OggVorbis_File * vf,vorbis_info * vi,vorbis_comment * vc,uint32_t ** serialno_list,int * serialno_n,ogg_page * og_ptr)286 static int _fetch_headers(OggVorbis_File *vf,vorbis_info *vi,vorbis_comment *vc,
287                           uint32_t **serialno_list, int *serialno_n,
288                           ogg_page *og_ptr){
289   ogg_page og;
290   ogg_packet op;
291   int i,ret;
292   int allbos=0;
293 
294   if(!og_ptr){
295     int64_t llret=_get_next_page(vf,&og,CHUNKSIZE);
296     if(llret==OV_EREAD)return(OV_EREAD);
297     if(llret<0)return(OV_ENOTVORBIS);
298     og_ptr=&og;
299   }
300 
301   vorbis_info_init(vi);
302   vorbis_comment_init(vc);
303   vf->ready_state=OPENED;
304 
305   /* extract the serialnos of all BOS pages + the first set of vorbis
306      headers we see in the link */
307 
308   while(ogg_page_bos(og_ptr)){
309     if(serialno_list){
310       if(_lookup_page_serialno(og_ptr,*serialno_list,*serialno_n)){
311         /* a dupe serialnumber in an initial header packet set == invalid stream */
312         if(*serialno_list)
313            free(*serialno_list);
314         *serialno_list=0;
315         *serialno_n=0;
316         ret=OV_EBADHEADER;
317         goto bail_header;
318       }
319 
320       _add_serialno(og_ptr,serialno_list,serialno_n);
321     }
322 
323     if(vf->ready_state<STREAMSET){
324       /* we don't have a vorbis stream in this link yet, so begin
325          prospective stream setup. We need a stream to get packets */
326       ogg_stream_reset_serialno(&vf->os,ogg_page_serialno(og_ptr));
327       ogg_stream_pagein(&vf->os,og_ptr);
328 
329       if(ogg_stream_packetout(&vf->os,&op) > 0 &&
330          vorbis_synthesis_idheader(&op)){
331         /* vorbis header; continue setup */
332         vf->ready_state=STREAMSET;
333         if((ret=vorbis_synthesis_headerin(vi,vc,&op))){
334           ret=OV_EBADHEADER;
335           goto bail_header;
336         }
337       }
338     }
339 
340     /* get next page */
341     {
342       int64_t llret=_get_next_page(vf,og_ptr,CHUNKSIZE);
343       if(llret==OV_EREAD){
344         ret=OV_EREAD;
345         goto bail_header;
346       }
347       if(llret<0){
348         ret=OV_ENOTVORBIS;
349         goto bail_header;
350       }
351 
352       /* if this page also belongs to our vorbis stream, submit it and break */
353       if(vf->ready_state==STREAMSET &&
354          vf->os.serialno == ogg_page_serialno(og_ptr)){
355         ogg_stream_pagein(&vf->os,og_ptr);
356         break;
357       }
358     }
359   }
360 
361   if(vf->ready_state!=STREAMSET){
362     ret = OV_ENOTVORBIS;
363     goto bail_header;
364   }
365 
366   while(1){
367 
368     i=0;
369     while(i<2){ /* get a page loop */
370 
371       while(i<2){ /* get a packet loop */
372 
373         int result=ogg_stream_packetout(&vf->os,&op);
374         if(result==0)break;
375         if(result==-1){
376           ret=OV_EBADHEADER;
377           goto bail_header;
378         }
379 
380         if((ret=vorbis_synthesis_headerin(vi,vc,&op)))
381           goto bail_header;
382 
383         i++;
384       }
385 
386       while(i<2){
387         if(_get_next_page(vf,og_ptr,CHUNKSIZE)<0){
388           ret=OV_EBADHEADER;
389           goto bail_header;
390         }
391 
392         /* if this page belongs to the correct stream, go parse it */
393         if(vf->os.serialno == ogg_page_serialno(og_ptr)){
394           ogg_stream_pagein(&vf->os,og_ptr);
395           break;
396         }
397 
398         /* if we never see the final vorbis headers before the link
399            ends, abort */
400         if(ogg_page_bos(og_ptr)){
401           if(allbos){
402             ret = OV_EBADHEADER;
403             goto bail_header;
404           }else
405             allbos=1;
406         }
407 
408         /* otherwise, keep looking */
409       }
410     }
411 
412     return 0;
413   }
414 
415  bail_header:
416   vorbis_info_clear(vi);
417   vorbis_comment_clear(vc);
418   vf->ready_state=OPENED;
419 
420   return ret;
421 }
422 
423 /* Starting from current cursor position, get initial PCM offset of
424    next page.  Consumes the page in the process without decoding
425    audio, however this is only called during stream parsing upon
426    seekable open. */
_initial_pcmoffset(OggVorbis_File * vf,vorbis_info * vi)427 static int64_t _initial_pcmoffset(OggVorbis_File *vf, vorbis_info *vi){
428   ogg_page    og;
429   int64_t accumulated=0;
430   long        lastblock=-1;
431   int         result;
432   int         serialno = vf->os.serialno;
433 
434   while(1){
435     ogg_packet op;
436     if(_get_next_page(vf,&og,-1)<0)
437       break; /* should not be possible unless the file is truncated/mangled */
438 
439     if(ogg_page_bos(&og)) break;
440     if(ogg_page_serialno(&og)!=serialno) continue;
441 
442     /* count blocksizes of all frames in the page */
443     ogg_stream_pagein(&vf->os,&og);
444     while((result=ogg_stream_packetout(&vf->os,&op))){
445       if(result>0){ /* ignore holes */
446         long thisblock=vorbis_packet_blocksize(vi,&op);
447         if(lastblock!=-1)
448           accumulated+=(lastblock+thisblock)>>2;
449         lastblock=thisblock;
450       }
451     }
452 
453     if(ogg_page_granulepos(&og)!=-1){
454       /* pcm offset of last packet on the first audio page */
455       accumulated= ogg_page_granulepos(&og)-accumulated;
456       break;
457     }
458   }
459 
460   /* less than zero?  This is a stream with samples trimmed off
461      the beginning, a normal occurrence; set the offset to zero */
462   if(accumulated<0)accumulated=0;
463 
464   return accumulated;
465 }
466 
467 /* finds each bitstream link one at a time using a bisection search
468    (has to begin by knowing the offset of the lb's initial page).
469    Recurses for each link so it can alloc the link storage after
470    finding them all, then unroll and fill the cache at the same time */
_bisect_forward_serialno(OggVorbis_File * vf,int64_t begin,int64_t searched,int64_t end,int64_t endgran,int endserial,uint32_t * currentno_list,int currentnos,long m)471 static int _bisect_forward_serialno(OggVorbis_File *vf,
472                                     int64_t begin,
473                                     int64_t searched,
474                                     int64_t end,
475                                     int64_t endgran,
476                                     int endserial,
477                                     uint32_t *currentno_list,
478                                     int  currentnos,
479                                     long m){
480   int64_t pcmoffset;
481   int64_t dataoffset=searched;
482   int64_t endsearched=end;
483   int64_t next=end;
484   int64_t searchgran=-1;
485   ogg_page og;
486   int64_t ret,last;
487   int serialno = vf->os.serialno;
488 
489   /* invariants:
490      we have the headers and serialnos for the link beginning at 'begin'
491      we have the offset and granpos of the last page in the file (potentially
492        not a page we care about)
493   */
494 
495   /* Is the last page in our list of current serialnumbers? */
496   if(_lookup_serialno(endserial,currentno_list,currentnos)){
497 
498     /* last page is in the starting serialno list, so we've bisected
499        down to (or just started with) a single link.  Now we need to
500        find the last vorbis page belonging to the first vorbis stream
501        for this link. */
502 
503     while(endserial != serialno){
504       endserial = serialno;
505       vf->offset=_get_prev_page_serial(vf,currentno_list,currentnos,&endserial,&endgran);
506     }
507 
508     vf->links=m+1;
509     if(vf->offsets)
510        free(vf->offsets);
511     if(vf->serialnos)
512        free(vf->serialnos);
513     if(vf->dataoffsets)
514        free(vf->dataoffsets);
515 
516     vf->offsets=malloc((vf->links+1)*sizeof(*vf->offsets));
517     vf->vi=realloc(vf->vi,vf->links*sizeof(*vf->vi));
518     vf->vc=realloc(vf->vc,vf->links*sizeof(*vf->vc));
519     vf->serialnos=malloc(vf->links*sizeof(*vf->serialnos));
520     vf->dataoffsets=malloc(vf->links*sizeof(*vf->dataoffsets));
521     vf->pcmlengths=malloc(vf->links*2*sizeof(*vf->pcmlengths));
522 
523     vf->offsets[m+1]=end;
524     vf->offsets[m]=begin;
525     vf->pcmlengths[m*2+1]=endgran;
526 
527   }else{
528 
529     uint32_t *next_serialno_list=NULL;
530     int next_serialnos=0;
531     vorbis_info vi;
532     vorbis_comment vc;
533 
534     /* the below guards against garbage seperating the last and
535        first pages of two links. */
536     while(searched<endsearched){
537       int64_t bisect;
538 
539       if(endsearched-searched<CHUNKSIZE){
540         bisect=searched;
541       }else{
542         bisect=(searched+endsearched)/2;
543       }
544 
545       if(bisect != vf->offset){
546         ret=_seek_helper(vf,bisect);
547         if(ret)return(ret);
548       }
549 
550       last=_get_next_page(vf,&og,-1);
551       if(last==OV_EREAD)return(OV_EREAD);
552       if(last<0 || !_lookup_page_serialno(&og,currentno_list,currentnos)){
553         endsearched=bisect;
554         if(last>=0)next=last;
555       }else{
556         searched=vf->offset;
557       }
558     }
559 
560     /* Bisection point found */
561 
562     /* for the time being, fetch end PCM offset the simple way */
563     {
564       int testserial = serialno+1;
565       vf->offset = next;
566       while(testserial != serialno){
567         testserial = serialno;
568         vf->offset=_get_prev_page_serial(vf,currentno_list,currentnos,&testserial,&searchgran);
569       }
570     }
571 
572     if(vf->offset!=next){
573       ret=_seek_helper(vf,next);
574       if(ret)return(ret);
575     }
576 
577     ret=_fetch_headers(vf,&vi,&vc,&next_serialno_list,&next_serialnos,NULL);
578     if(ret)return(ret);
579     serialno = vf->os.serialno;
580     dataoffset = vf->offset;
581 
582     /* this will consume a page, however the next bistection always
583        starts with a raw seek */
584     pcmoffset = _initial_pcmoffset(vf,&vi);
585 
586     ret=_bisect_forward_serialno(vf,next,vf->offset,end,endgran,endserial,
587                                  next_serialno_list,next_serialnos,m+1);
588     if(ret)return(ret);
589 
590     if(next_serialno_list)
591        free(next_serialno_list);
592 
593     vf->offsets[m+1]=next;
594     vf->serialnos[m+1]=serialno;
595     vf->dataoffsets[m+1]=dataoffset;
596 
597     vf->vi[m+1]=vi;
598     vf->vc[m+1]=vc;
599 
600     vf->pcmlengths[m*2+1]=searchgran;
601     vf->pcmlengths[m*2+2]=pcmoffset;
602     vf->pcmlengths[m*2+3]-=pcmoffset;
603 
604   }
605   return(0);
606 }
607 
_make_decode_ready(OggVorbis_File * vf)608 static int _make_decode_ready(OggVorbis_File *vf){
609   if(vf->ready_state>STREAMSET)return 0;
610   if(vf->ready_state<STREAMSET)return OV_EFAULT;
611   if(vf->seekable){
612     if(vorbis_synthesis_init(&vf->vd,vf->vi+vf->current_link))
613       return OV_EBADLINK;
614   }else{
615     if(vorbis_synthesis_init(&vf->vd,vf->vi))
616       return OV_EBADLINK;
617   }
618   vorbis_block_init(&vf->vd,&vf->vb);
619   vf->ready_state=INITSET;
620   vf->bittrack=0;
621   vf->samptrack=0;
622   return 0;
623 }
624 
_open_seekable2(OggVorbis_File * vf)625 static int _open_seekable2(OggVorbis_File *vf){
626   int64_t dataoffset=vf->dataoffsets[0],end,endgran=-1;
627   int endserial=vf->os.serialno;
628   int serialno=vf->os.serialno;
629 
630   /* we're partially open and have a first link header state in
631      storage in vf */
632 
633   /* fetch initial PCM offset */
634   int64_t pcmoffset = _initial_pcmoffset(vf,vf->vi);
635 
636   /* we can seek, so set out learning all about this file */
637   if(vf->callbacks.seek_func && vf->callbacks.tell_func){
638     (vf->callbacks.seek_func)(vf->datasource,0,SEEK_END);
639     vf->offset=vf->end=(vf->callbacks.tell_func)(vf->datasource);
640   }else{
641     vf->offset=vf->end=-1;
642   }
643 
644   /* If seek_func is implemented, tell_func must also be implemented */
645   if(vf->end==-1) return(OV_EINVAL);
646 
647   /* Get the offset of the last page of the physical bitstream, or, if
648      we're lucky the last vorbis page of this link as most OggVorbis
649      files will contain a single logical bitstream */
650   end=_get_prev_page_serial(vf,vf->serialnos+2,vf->serialnos[1],&endserial,&endgran);
651   if(end<0)return(end);
652 
653   /* now determine bitstream structure recursively */
654   if(_bisect_forward_serialno(vf,0,dataoffset,vf->offset,endgran,endserial,
655                               vf->serialnos+2,vf->serialnos[1],0)<0)return(OV_EREAD);
656 
657   vf->offsets[0]=0;
658   vf->serialnos[0]=serialno;
659   vf->dataoffsets[0]=dataoffset;
660   vf->pcmlengths[0]=pcmoffset;
661   vf->pcmlengths[1]-=pcmoffset;
662 
663   return(ov_raw_seek(vf,dataoffset));
664 }
665 
666 /* clear out the current logical bitstream decoder */
_decode_clear(OggVorbis_File * vf)667 static void _decode_clear(OggVorbis_File *vf){
668   vorbis_dsp_clear(&vf->vd);
669   vorbis_block_clear(&vf->vb);
670   vf->ready_state=OPENED;
671 }
672 
673 /* fetch and process a packet.  Handles the case where we're at a
674    bitstream boundary and dumps the decoding machine.  If the decoding
675    machine is unloaded, it loads it.  It also keeps pcm_offset up to
676    date (seek and read both use this.  seek uses a special hack with
677    readp).
678 
679    return: <0) error, OV_HOLE (lost packet) or OV_EOF
680             0) need more data (only if readp==0)
681             1) got a packet
682 */
683 
_fetch_and_process_packet(OggVorbis_File * vf,ogg_packet * op_in,int readp,int spanp)684 static int _fetch_and_process_packet(OggVorbis_File *vf,
685                                      ogg_packet *op_in,
686                                      int readp,
687                                      int spanp){
688   ogg_page og;
689 
690   /* handle one packet.  Try to fetch it from current stream state */
691   /* extract packets from page */
692   while(1){
693 
694     if(vf->ready_state==STREAMSET){
695       int ret=_make_decode_ready(vf);
696       if(ret<0)return ret;
697     }
698 
699     /* process a packet if we can.  If the machine isn't loaded,
700        neither is a page */
701     if(vf->ready_state==INITSET){
702       while(1) {
703               ogg_packet op;
704               ogg_packet *op_ptr=(op_in?op_in:&op);
705         int result=ogg_stream_packetout(&vf->os,op_ptr);
706         int64_t granulepos;
707 
708         op_in=NULL;
709         if(result==-1)return(OV_HOLE); /* hole in the data. */
710         if(result>0){
711           /* got a packet.  process it */
712           granulepos=op_ptr->granulepos;
713           if(!vorbis_synthesis(&vf->vb,op_ptr)){ /* lazy check for lazy
714                                                     header handling.  The
715                                                     header packets aren't
716                                                     audio, so if/when we
717                                                     submit them,
718                                                     vorbis_synthesis will
719                                                     reject them */
720 
721             /* suck in the synthesis data and track bitrate */
722             {
723               int oldsamples=vorbis_synthesis_pcmout(&vf->vd,NULL);
724               /* for proper use of libvorbis within libvorbisfile,
725                  oldsamples will always be zero. */
726               if(oldsamples)return(OV_EFAULT);
727 
728               vorbis_synthesis_blockin(&vf->vd,&vf->vb);
729               vf->samptrack+=vorbis_synthesis_pcmout(&vf->vd,NULL)-oldsamples;
730               vf->bittrack+=op_ptr->bytes*8;
731             }
732 
733             /* update the pcm offset. */
734             if(granulepos!=-1 && !op_ptr->e_o_s){
735               int link=(vf->seekable?vf->current_link:0);
736               int i,samples;
737 
738               /* this packet has a pcm_offset on it (the last packet
739                  completed on a page carries the offset) After processing
740                  (above), we know the pcm position of the *last* sample
741                  ready to be returned. Find the offset of the *first*
742 
743                  As an aside, this trick is inaccurate if we begin
744                  reading anew right at the last page; the end-of-stream
745                  granulepos declares the last frame in the stream, and the
746                  last packet of the last page may be a partial frame.
747                  So, we need a previous granulepos from an in-sequence page
748                  to have a reference point.  Thus the !op_ptr->e_o_s clause
749                  above */
750 
751               if(vf->seekable && link>0)
752                 granulepos-=vf->pcmlengths[link*2];
753               if(granulepos<0)granulepos=0; /* actually, this
754                                                shouldn't be possible
755                                                here unless the stream
756                                                is very broken */
757 
758               samples=vorbis_synthesis_pcmout(&vf->vd,NULL);
759 
760               granulepos-=samples;
761               for(i=0;i<link;i++)
762                 granulepos+=vf->pcmlengths[i*2+1];
763               vf->pcm_offset=granulepos;
764             }
765             return(1);
766           }
767         }
768         else
769           break;
770       }
771     }
772 
773     if(vf->ready_state>=OPENED){
774       int64_t ret;
775 
776       while(1){
777         /* the loop is not strictly necessary, but there's no sense in
778            doing the extra checks of the larger loop for the common
779            case in a multiplexed bistream where the page is simply
780            part of a different logical bitstream; keep reading until
781            we get one with the correct serialno */
782 
783         if(!readp)return(0);
784         if((ret=_get_next_page(vf,&og,-1))<0){
785           return(OV_EOF); /* eof. leave unitialized */
786         }
787 
788         /* bitrate tracking; add the header's bytes here, the body bytes
789            are done by packet above */
790         vf->bittrack+=og.header_len*8;
791 
792         if(vf->ready_state==INITSET){
793           if(vf->current_serialno!=ogg_page_serialno(&og)){
794 
795             /* two possibilities:
796                1) our decoding just traversed a bitstream boundary
797                2) another stream is multiplexed into this logical section */
798 
799             if(ogg_page_bos(&og)){
800               /* boundary case */
801               if(!spanp)
802                 return(OV_EOF);
803 
804               _decode_clear(vf);
805 
806               if(!vf->seekable){
807                 vorbis_info_clear(vf->vi);
808                 vorbis_comment_clear(vf->vc);
809               }
810               break;
811 
812             }else
813               continue; /* possibility #2 */
814           }
815         }
816 
817         break;
818       }
819     }
820 
821     /* Do we need to load a new machine before submitting the page? */
822     /* This is different in the seekable and non-seekable cases.
823 
824        In the seekable case, we already have all the header
825        information loaded and cached; we just initialize the machine
826        with it and continue on our merry way.
827 
828        In the non-seekable (streaming) case, we'll only be at a
829        boundary if we just left the previous logical bitstream and
830        we're now nominally at the header of the next bitstream
831     */
832 
833     if(vf->ready_state!=INITSET){
834       int link;
835 
836       if(vf->ready_state<STREAMSET){
837         if(vf->seekable){
838           uint32_t serialno = ogg_page_serialno(&og);
839 
840           /* match the serialno to bitstream section.  We use this rather than
841              offset positions to avoid problems near logical bitstream
842              boundaries */
843 
844           for(link=0;link<vf->links;link++)
845             if(vf->serialnos[link]==serialno)break;
846 
847           if(link==vf->links) continue; /* not the desired Vorbis
848                                            bitstream section; keep
849                                            trying */
850 
851           vf->current_serialno=serialno;
852           vf->current_link=link;
853 
854           ogg_stream_reset_serialno(&vf->os,vf->current_serialno);
855           vf->ready_state=STREAMSET;
856 
857         }else{
858           /* we're streaming */
859           /* fetch the three header packets, build the info struct */
860 
861           int ret=_fetch_headers(vf,vf->vi,vf->vc,NULL,NULL,&og);
862           if(ret)return(ret);
863           vf->current_serialno=vf->os.serialno;
864           vf->current_link++;
865           link=0;
866         }
867       }
868     }
869 
870     /* the buffered page is the data we want, and we're ready for it;
871        add it to the stream state */
872     ogg_stream_pagein(&vf->os,&og);
873 
874   }
875 }
876 
877 /* if, eg, 64 bit stdio is configured by default, this will build with
878    fseek64 */
_fseek64_wrap(FILE * f,int64_t off,int whence)879 static int _fseek64_wrap(FILE *f,int64_t off,int whence){
880   if(f==NULL)return(-1);
881   return fseek(f,off,whence);
882 }
883 
_ov_open1(void * f,OggVorbis_File * vf,const char * initial,long ibytes,ov_callbacks callbacks)884 static int _ov_open1(void *f,OggVorbis_File *vf,const char *initial,
885                      long ibytes, ov_callbacks callbacks){
886   int offsettest=((f && callbacks.seek_func)?callbacks.seek_func(f,0,SEEK_CUR):-1);
887   uint32_t *serialno_list=NULL;
888   int serialno_list_size=0;
889   int ret;
890 
891   memset(vf,0,sizeof(*vf));
892   vf->datasource=f;
893   vf->callbacks = callbacks;
894 
895   /* init the framing state */
896   ogg_sync_init(&vf->oy);
897 
898   /* perhaps some data was previously read into a buffer for testing
899      against other stream types.  Allow initialization from this
900      previously read data (especially as we may be reading from a
901      non-seekable stream) */
902   if(initial){
903     char *buffer=ogg_sync_buffer(&vf->oy,ibytes);
904     memcpy(buffer,initial,ibytes);
905     ogg_sync_wrote(&vf->oy,ibytes);
906   }
907 
908   /* can we seek? Stevens suggests the seek test was portable */
909   if(offsettest!=-1)vf->seekable=1;
910 
911   /* No seeking yet; Set up a 'single' (current) logical bitstream
912      entry for partial open */
913   vf->links=1;
914   vf->vi=calloc(vf->links,sizeof(*vf->vi));
915   vf->vc=calloc(vf->links,sizeof(*vf->vc));
916   ogg_stream_init(&vf->os,-1); /* fill in the serialno later */
917 
918   /* Fetch all BOS pages, store the vorbis header and all seen serial
919      numbers, load subsequent vorbis setup headers */
920   if((ret=_fetch_headers(vf,vf->vi,vf->vc,&serialno_list,&serialno_list_size,NULL))<0){
921     vf->datasource=NULL;
922     ov_clear(vf);
923   }else{
924     /* serial number list for first link needs to be held somewhere
925        for second stage of seekable stream open; this saves having to
926        seek/reread first link's serialnumber data then. */
927     vf->serialnos=calloc(serialno_list_size+2,sizeof(*vf->serialnos));
928     vf->serialnos[0]=vf->current_serialno=vf->os.serialno;
929     vf->serialnos[1]=serialno_list_size;
930     memcpy(vf->serialnos+2,serialno_list,serialno_list_size*sizeof(*vf->serialnos));
931 
932     vf->offsets=calloc(1,sizeof(*vf->offsets));
933     vf->dataoffsets=calloc(1,sizeof(*vf->dataoffsets));
934     vf->offsets[0]=0;
935     vf->dataoffsets[0]=vf->offset;
936 
937     vf->ready_state=PARTOPEN;
938   }
939   if(serialno_list)
940      free(serialno_list);
941   return(ret);
942 }
943 
_ov_open2(OggVorbis_File * vf)944 static int _ov_open2(OggVorbis_File *vf){
945   if(vf->ready_state != PARTOPEN) return OV_EINVAL;
946   vf->ready_state=OPENED;
947   if(vf->seekable){
948     int ret=_open_seekable2(vf);
949     if(ret){
950       vf->datasource=NULL;
951       ov_clear(vf);
952     }
953     return(ret);
954   }else
955     vf->ready_state=STREAMSET;
956 
957   return 0;
958 }
959 
960 
961 /* clear out the OggVorbis_File struct */
ov_clear(OggVorbis_File * vf)962 int ov_clear(OggVorbis_File *vf){
963   if(vf){
964     vorbis_block_clear(&vf->vb);
965     vorbis_dsp_clear(&vf->vd);
966     ogg_stream_clear(&vf->os);
967 
968     if(vf->vi && vf->links){
969       int i;
970       for(i=0;i<vf->links;i++){
971         vorbis_info_clear(vf->vi+i);
972         vorbis_comment_clear(vf->vc+i);
973       }
974       free(vf->vi);
975       free(vf->vc);
976     }
977     if(vf->dataoffsets)
978        free(vf->dataoffsets);
979     if(vf->pcmlengths)
980        free(vf->pcmlengths);
981     if(vf->serialnos)
982        free(vf->serialnos);
983     if(vf->offsets)
984        free(vf->offsets);
985     ogg_sync_clear(&vf->oy);
986     if(vf->datasource && vf->callbacks.close_func)
987       (vf->callbacks.close_func)(vf->datasource);
988     memset(vf,0,sizeof(*vf));
989   }
990 #ifdef DEBUG_LEAKS
991   _VDBG_dump();
992 #endif
993   return(0);
994 }
995 
996 /* inspects the OggVorbis file and finds/documents all the logical
997    bitstreams contained in it.  Tries to be tolerant of logical
998    bitstream sections that are truncated/woogie.
999 
1000    return: -1) error
1001             0) OK
1002 */
1003 
ov_open_callbacks(void * f,OggVorbis_File * vf,const char * initial,long ibytes,ov_callbacks callbacks)1004 int ov_open_callbacks(void *f,OggVorbis_File *vf,
1005     const char *initial,long ibytes,ov_callbacks callbacks){
1006   int ret=_ov_open1(f,vf,initial,ibytes,callbacks);
1007   if(ret)return ret;
1008   return _ov_open2(vf);
1009 }
1010 
ov_open(FILE * f,OggVorbis_File * vf,const char * initial,long ibytes)1011 int ov_open(FILE *f,OggVorbis_File *vf,const char *initial,long ibytes){
1012   ov_callbacks callbacks = {
1013     (size_t (*)(void *, size_t, size_t, void *))  fread,
1014     (int (*)(void *, int64_t, int))              _fseek64_wrap,
1015     (int (*)(void *))                             fclose,
1016     (long (*)(void *))                            ftell
1017   };
1018 
1019   return ov_open_callbacks((void *)f, vf, initial, ibytes, callbacks);
1020 }
1021 
ov_fopen(const char * path,OggVorbis_File * vf)1022 int ov_fopen(const char *path,OggVorbis_File *vf){
1023   int ret;
1024   FILE *f = fopen(path,"rb");
1025   if(!f) return -1;
1026 
1027   ret = ov_open(f,vf,NULL,0);
1028   if(ret) fclose(f);
1029   return ret;
1030 }
1031 
1032 
1033 /* Only partially open the vorbis file; test for Vorbisness, and load
1034    the headers for the first chain.  Do not seek (although test for
1035    seekability).  Use ov_test_open to finish opening the file, else
1036    ov_clear to close/free it. Same return codes as open. */
1037 
ov_test_callbacks(void * f,OggVorbis_File * vf,const char * initial,long ibytes,ov_callbacks callbacks)1038 int ov_test_callbacks(void *f,OggVorbis_File *vf,
1039     const char *initial,long ibytes,ov_callbacks callbacks)
1040 {
1041   return _ov_open1(f,vf,initial,ibytes,callbacks);
1042 }
1043 
ov_test(FILE * f,OggVorbis_File * vf,const char * initial,long ibytes)1044 int ov_test(FILE *f,OggVorbis_File *vf,const char *initial,long ibytes){
1045   ov_callbacks callbacks = {
1046     (size_t (*)(void *, size_t, size_t, void *))  fread,
1047     (int (*)(void *, int64_t, int))              _fseek64_wrap,
1048     (int (*)(void *))                             fclose,
1049     (long (*)(void *))                            ftell
1050   };
1051 
1052   return ov_test_callbacks((void *)f, vf, initial, ibytes, callbacks);
1053 }
1054 
ov_test_open(OggVorbis_File * vf)1055 int ov_test_open(OggVorbis_File *vf){
1056   if(vf->ready_state!=PARTOPEN)return(OV_EINVAL);
1057   return _ov_open2(vf);
1058 }
1059 
1060 /* How many logical bitstreams in this physical bitstream? */
ov_streams(OggVorbis_File * vf)1061 long ov_streams(OggVorbis_File *vf){
1062   return vf->links;
1063 }
1064 
1065 /* Is the FILE * associated with vf seekable? */
ov_seekable(OggVorbis_File * vf)1066 long ov_seekable(OggVorbis_File *vf){
1067   return vf->seekable;
1068 }
1069 
1070 /* returns the bitrate for a given logical bitstream or the entire
1071    physical bitstream.  If the file is open for random access, it will
1072    find the *actual* average bitrate.  If the file is streaming, it
1073    returns the nominal bitrate (if set) else the average of the
1074    upper/lower bounds (if set) else -1 (unset).
1075 
1076    If you want the actual bitrate field settings, get them from the
1077    vorbis_info structs */
1078 
ov_bitrate(OggVorbis_File * vf,int i)1079 long ov_bitrate(OggVorbis_File *vf,int i){
1080   if(vf->ready_state<OPENED)return(OV_EINVAL);
1081   if(i>=vf->links)return(OV_EINVAL);
1082   if(!vf->seekable && i!=0)return(ov_bitrate(vf,0));
1083   if(i<0){
1084     int64_t bits=0;
1085     int i;
1086     for(i=0;i<vf->links;i++)
1087       bits+=(vf->offsets[i+1]-vf->dataoffsets[i])*8;
1088     /* This once read: return(rint(bits/ov_time_total(vf,-1)));
1089      * gcc 3.x on x86 miscompiled this at optimisation level 2 and above,
1090      * so this is slightly transformed to make it work.
1091      */
1092     return(bits*1000/ov_time_total(vf,-1));
1093   }else{
1094     if(vf->seekable){
1095       /* return the actual bitrate */
1096       return((vf->offsets[i+1]-vf->dataoffsets[i])*8000/ov_time_total(vf,i));
1097     }else{
1098       /* return nominal if set */
1099       if(vf->vi[i].bitrate_nominal>0){
1100         return vf->vi[i].bitrate_nominal;
1101       }else{
1102         if(vf->vi[i].bitrate_upper>0){
1103           if(vf->vi[i].bitrate_lower>0){
1104             return (vf->vi[i].bitrate_upper+vf->vi[i].bitrate_lower)/2;
1105           }else{
1106             return vf->vi[i].bitrate_upper;
1107           }
1108         }
1109         return(OV_FALSE);
1110       }
1111     }
1112   }
1113 }
1114 
1115 /* returns the actual bitrate since last call.  returns -1 if no
1116    additional data to offer since last call (or at beginning of stream),
1117    EINVAL if stream is only partially open
1118 */
ov_bitrate_instant(OggVorbis_File * vf)1119 long ov_bitrate_instant(OggVorbis_File *vf){
1120   int link=(vf->seekable?vf->current_link:0);
1121   long ret;
1122   if(vf->ready_state<OPENED)return(OV_EINVAL);
1123   if(vf->samptrack==0)return(OV_FALSE);
1124   ret=vf->bittrack/vf->samptrack*vf->vi[link].rate;
1125   vf->bittrack=0;
1126   vf->samptrack=0;
1127   return(ret);
1128 }
1129 
1130 /* Guess */
ov_serialnumber(OggVorbis_File * vf,int i)1131 long ov_serialnumber(OggVorbis_File *vf,int i){
1132   if(i>=vf->links)return(ov_serialnumber(vf,vf->links-1));
1133   if(!vf->seekable && i>=0)return(ov_serialnumber(vf,-1));
1134   if(i<0){
1135     return(vf->current_serialno);
1136   }else{
1137     return(vf->serialnos[i]);
1138   }
1139 }
1140 
1141 /* returns: total raw (compressed) length of content if i==-1
1142             raw (compressed) length of that logical bitstream for i==0 to n
1143             OV_EINVAL if the stream is not seekable (we can't know the length)
1144             or if stream is only partially open
1145 */
ov_raw_total(OggVorbis_File * vf,int i)1146 int64_t ov_raw_total(OggVorbis_File *vf,int i){
1147   if(vf->ready_state<OPENED)return(OV_EINVAL);
1148   if(!vf->seekable || i>=vf->links)return(OV_EINVAL);
1149   if(i<0){
1150     int64_t acc=0;
1151     int i;
1152     for(i=0;i<vf->links;i++)
1153       acc+=ov_raw_total(vf,i);
1154     return(acc);
1155   }else{
1156     return(vf->offsets[i+1]-vf->offsets[i]);
1157   }
1158 }
1159 
1160 /* returns: total PCM length (samples) of content if i==-1 PCM length
1161             (samples) of that logical bitstream for i==0 to n
1162             OV_EINVAL if the stream is not seekable (we can't know the
1163             length) or only partially open
1164 */
ov_pcm_total(OggVorbis_File * vf,int i)1165 int64_t ov_pcm_total(OggVorbis_File *vf,int i){
1166   if(vf->ready_state<OPENED)return(OV_EINVAL);
1167   if(!vf->seekable || i>=vf->links)return(OV_EINVAL);
1168   if(i<0){
1169     int64_t acc=0;
1170     int i;
1171     for(i=0;i<vf->links;i++)
1172       acc+=ov_pcm_total(vf,i);
1173     return(acc);
1174   }else{
1175     return(vf->pcmlengths[i*2+1]);
1176   }
1177 }
1178 
1179 /* returns: total milliseconds of content if i==-1
1180             milliseconds in that logical bitstream for i==0 to n
1181             OV_EINVAL if the stream is not seekable (we can't know the
1182             length) or only partially open
1183 */
ov_time_total(OggVorbis_File * vf,int i)1184 int64_t ov_time_total(OggVorbis_File *vf,int i){
1185   if(vf->ready_state<OPENED)return(OV_EINVAL);
1186   if(!vf->seekable || i>=vf->links)return(OV_EINVAL);
1187   if(i<0){
1188     int64_t acc=0;
1189     int i;
1190     for(i=0;i<vf->links;i++)
1191       acc+=ov_time_total(vf,i);
1192     return(acc);
1193   }else{
1194     return(((int64_t)vf->pcmlengths[i*2+1])*1000/vf->vi[i].rate);
1195   }
1196 }
1197 
1198 /* seek to an offset relative to the *compressed* data. This also
1199    scans packets to update the PCM cursor. It will cross a logical
1200    bitstream boundary, but only if it can't get any packets out of the
1201    tail of the bitstream we seek to (so no surprises).
1202 
1203    returns zero on success, nonzero on failure */
1204 
ov_raw_seek(OggVorbis_File * vf,int64_t pos)1205 int ov_raw_seek(OggVorbis_File *vf,int64_t pos){
1206   ogg_stream_state work_os;
1207   int ret;
1208 
1209   if(vf->ready_state<OPENED)return(OV_EINVAL);
1210   if(!vf->seekable)
1211     return(OV_ENOSEEK); /* don't dump machine if we can't seek */
1212 
1213   if(pos<0 || pos>vf->end)return(OV_EINVAL);
1214 
1215   /* is the seek position outside our current link [if any]? */
1216   if(vf->ready_state>=STREAMSET){
1217     if(pos<vf->offsets[vf->current_link] || pos>=vf->offsets[vf->current_link+1])
1218       _decode_clear(vf); /* clear out stream state */
1219   }
1220 
1221   /* don't yet clear out decoding machine (if it's initialized), in
1222      the case we're in the same link.  Restart the decode lapping, and
1223      let _fetch_and_process_packet deal with a potential bitstream
1224      boundary */
1225   vf->pcm_offset=-1;
1226   ogg_stream_reset_serialno(&vf->os,
1227                             vf->current_serialno); /* must set serialno */
1228   vorbis_synthesis_restart(&vf->vd);
1229 
1230   ret=_seek_helper(vf,pos);
1231   if(ret)goto seek_error;
1232 
1233   /* we need to make sure the pcm_offset is set, but we don't want to
1234      advance the raw cursor past good packets just to get to the first
1235      with a granulepos.  That's not equivalent behavior to beginning
1236      decoding as immediately after the seek position as possible.
1237 
1238      So, a hack.  We use two stream states; a local scratch state and
1239      the shared vf->os stream state.  We use the local state to
1240      scan, and the shared state as a buffer for later decode.
1241 
1242      Unfortuantely, on the last page we still advance to last packet
1243      because the granulepos on the last page is not necessarily on a
1244      packet boundary, and we need to make sure the granpos is
1245      correct.
1246   */
1247 
1248   {
1249     ogg_page og;
1250     ogg_packet op;
1251     int lastblock=0;
1252     int accblock=0;
1253     int thisblock=0;
1254     int lastflag=0;
1255     int firstflag=0;
1256     int64_t pagepos=-1;
1257 
1258     ogg_stream_init(&work_os,vf->current_serialno); /* get the memory ready */
1259     ogg_stream_reset(&work_os); /* eliminate the spurious OV_HOLE
1260                                    return from not necessarily
1261                                    starting from the beginning */
1262 
1263     while(1){
1264       if(vf->ready_state>=STREAMSET){
1265         /* snarf/scan a packet if we can */
1266         int result=ogg_stream_packetout(&work_os,&op);
1267 
1268         if(result>0){
1269 
1270           if(vf->vi[vf->current_link].codec_setup){
1271             thisblock=vorbis_packet_blocksize(vf->vi+vf->current_link,&op);
1272             if(thisblock<0){
1273               ogg_stream_packetout(&vf->os,NULL);
1274               thisblock=0;
1275             }else{
1276 
1277               /* We can't get a guaranteed correct pcm position out of the
1278                  last page in a stream because it might have a 'short'
1279                  granpos, which can only be detected in the presence of a
1280                  preceding page.  However, if the last page is also the first
1281                  page, the granpos rules of a first page take precedence.  Not
1282                  only that, but for first==last, the EOS page must be treated
1283                  as if its a normal first page for the stream to open/play. */
1284               if(lastflag && !firstflag)
1285                 ogg_stream_packetout(&vf->os,NULL);
1286               else
1287                 if(lastblock)accblock+=(lastblock+thisblock)>>2;
1288             }
1289 
1290             if(op.granulepos!=-1){
1291               int i,link=vf->current_link;
1292               int64_t granulepos=op.granulepos-vf->pcmlengths[link*2];
1293               if(granulepos<0)granulepos=0;
1294 
1295               for(i=0;i<link;i++)
1296                 granulepos+=vf->pcmlengths[i*2+1];
1297               vf->pcm_offset=granulepos-accblock;
1298               if(vf->pcm_offset<0)vf->pcm_offset=0;
1299               break;
1300             }
1301             lastblock=thisblock;
1302             continue;
1303           }else
1304             ogg_stream_packetout(&vf->os,NULL);
1305         }
1306       }
1307 
1308       if(!lastblock){
1309         pagepos=_get_next_page(vf,&og,-1);
1310         if(pagepos<0){
1311           vf->pcm_offset=ov_pcm_total(vf,-1);
1312           break;
1313         }
1314       }else{
1315         /* huh?  Bogus stream with packets but no granulepos */
1316         vf->pcm_offset=-1;
1317         break;
1318       }
1319 
1320       /* has our decoding just traversed a bitstream boundary? */
1321       if(vf->ready_state>=STREAMSET){
1322         if(vf->current_serialno!=ogg_page_serialno(&og)){
1323 
1324           /* two possibilities:
1325              1) our decoding just traversed a bitstream boundary
1326              2) another stream is multiplexed into this logical section? */
1327 
1328           if(ogg_page_bos(&og)){
1329             /* we traversed */
1330             _decode_clear(vf); /* clear out stream state */
1331             ogg_stream_clear(&work_os);
1332           } /* else, do nothing; next loop will scoop another page */
1333         }
1334       }
1335 
1336       if(vf->ready_state<STREAMSET){
1337         int link;
1338         uint32_t serialno = ogg_page_serialno(&og);
1339 
1340         for(link=0;link<vf->links;link++)
1341           if(vf->serialnos[link]==serialno)break;
1342 
1343         if(link==vf->links) continue; /* not the desired Vorbis
1344                                          bitstream section; keep
1345                                          trying */
1346         vf->current_link=link;
1347         vf->current_serialno=serialno;
1348         ogg_stream_reset_serialno(&vf->os,serialno);
1349         ogg_stream_reset_serialno(&work_os,serialno);
1350         vf->ready_state=STREAMSET;
1351         firstflag=(pagepos<=vf->dataoffsets[link]);
1352       }
1353 
1354       ogg_stream_pagein(&vf->os,&og);
1355       ogg_stream_pagein(&work_os,&og);
1356       lastflag=ogg_page_eos(&og);
1357 
1358     }
1359   }
1360 
1361   ogg_stream_clear(&work_os);
1362   vf->bittrack=0;
1363   vf->samptrack=0;
1364   return(0);
1365 
1366  seek_error:
1367   /* dump the machine so we're in a known state */
1368   vf->pcm_offset=-1;
1369   ogg_stream_clear(&work_os);
1370   _decode_clear(vf);
1371   return OV_EBADLINK;
1372 }
1373 
1374 /* rescales the number x from the range of [0,from] to [0,to]
1375    x is in the range [0,from]
1376    from, to are in the range [1, 1<<62-1] */
rescale64(int64_t x,int64_t from,int64_t to)1377 int64_t rescale64(int64_t x, int64_t from, int64_t to){
1378   int64_t frac=0;
1379   int64_t ret=0;
1380   int i;
1381   if(x >= from) return to;
1382   if(x <= 0) return 0;
1383 
1384   for(i=0;i<64;i++){
1385     if(x>=from){
1386       frac|=1;
1387       x-=from;
1388     }
1389     x<<=1;
1390     frac<<=1;
1391   }
1392 
1393   for(i=0;i<64;i++){
1394     if(frac & 1){
1395       ret+=to;
1396     }
1397     frac>>=1;
1398     ret>>=1;
1399   }
1400 
1401   return ret;
1402 }
1403 
1404 /* Page granularity seek (faster than sample granularity because we
1405    don't do the last bit of decode to find a specific sample).
1406 
1407    Seek to the last [granule marked] page preceding the specified pos
1408    location, such that decoding past the returned point will quickly
1409    arrive at the requested position. */
ov_pcm_seek_page(OggVorbis_File * vf,int64_t pos)1410 int ov_pcm_seek_page(OggVorbis_File *vf,int64_t pos){
1411   int link=-1;
1412   int64_t result=0;
1413   int64_t total=ov_pcm_total(vf,-1);
1414 
1415   if(vf->ready_state<OPENED)return(OV_EINVAL);
1416   if(!vf->seekable)return(OV_ENOSEEK);
1417 
1418   if(pos<0 || pos>total)return(OV_EINVAL);
1419 
1420   /* which bitstream section does this pcm offset occur in? */
1421   for(link=vf->links-1;link>=0;link--){
1422     total-=vf->pcmlengths[link*2+1];
1423     if(pos>=total)break;
1424   }
1425 
1426   /* search within the logical bitstream for the page with the highest
1427      pcm_pos preceding (or equal to) pos.  There is a danger here;
1428      missing pages or incorrect frame number information in the
1429      bitstream could make our task impossible.  Account for that (it
1430      would be an error condition) */
1431 
1432   /* new search algorithm by HB (Nicholas Vinen) */
1433   {
1434     int64_t end=vf->offsets[link+1];
1435     int64_t begin=vf->offsets[link];
1436     int64_t begintime = vf->pcmlengths[link*2];
1437     int64_t endtime = vf->pcmlengths[link*2+1]+begintime;
1438     int64_t target=pos-total+begintime;
1439     int64_t best=begin;
1440 
1441     ogg_page og;
1442     while(begin<end){
1443       int64_t bisect;
1444 
1445       if(end-begin<CHUNKSIZE){
1446         bisect=begin;
1447       }else{
1448         /* take a (pretty decent) guess. */
1449         bisect=begin + rescale64(target-begintime,
1450 				 endtime-begintime,
1451 				 end-begin) - CHUNKSIZE;
1452         if(bisect<begin+CHUNKSIZE)
1453           bisect=begin;
1454       }
1455 
1456       if(bisect!=vf->offset){
1457         result=_seek_helper(vf,bisect);
1458         if(result) goto seek_error;
1459       }
1460 
1461       while(begin<end){
1462         result=_get_next_page(vf,&og,end-vf->offset);
1463         if(result==OV_EREAD) goto seek_error;
1464         if(result<0){
1465           if(bisect<=begin+1)
1466             end=begin; /* found it */
1467           else{
1468             if(bisect==0) goto seek_error;
1469             bisect-=CHUNKSIZE;
1470             if(bisect<=begin)bisect=begin+1;
1471             result=_seek_helper(vf,bisect);
1472             if(result) goto seek_error;
1473           }
1474         }else{
1475           int64_t granulepos;
1476 
1477           if(ogg_page_serialno(&og)!=vf->serialnos[link])
1478             continue;
1479 
1480           granulepos=ogg_page_granulepos(&og);
1481           if(granulepos==-1)continue;
1482 
1483           if(granulepos<target){
1484             best=result;  /* raw offset of packet with granulepos */
1485             begin=vf->offset; /* raw offset of next page */
1486             begintime=granulepos;
1487 
1488             if(target-begintime>44100)break;
1489             bisect=begin; /* *not* begin + 1 */
1490           }else{
1491             if(bisect<=begin+1)
1492               end=begin;  /* found it */
1493             else{
1494               if(end==vf->offset){ /* we're pretty close - we'd be stuck in */
1495                 end=result;
1496                 bisect-=CHUNKSIZE; /* an endless loop otherwise. */
1497                 if(bisect<=begin)bisect=begin+1;
1498                 result=_seek_helper(vf,bisect);
1499                 if(result) goto seek_error;
1500               }else{
1501                 end=bisect;
1502                 endtime=granulepos;
1503                 break;
1504               }
1505             }
1506           }
1507         }
1508       }
1509     }
1510 
1511     /* found our page. seek to it, update pcm offset. Easier case than
1512        raw_seek, don't keep packets preceding granulepos. */
1513     {
1514       ogg_page og;
1515       ogg_packet op;
1516 
1517       /* seek */
1518       result=_seek_helper(vf,best);
1519       vf->pcm_offset=-1;
1520       if(result) goto seek_error;
1521       result=_get_next_page(vf,&og,-1);
1522       if(result<0) goto seek_error;
1523 
1524       if(link!=vf->current_link){
1525         /* Different link; dump entire decode machine */
1526         _decode_clear(vf);
1527 
1528         vf->current_link=link;
1529         vf->current_serialno=vf->serialnos[link];
1530         vf->ready_state=STREAMSET;
1531 
1532       }else{
1533         vorbis_synthesis_restart(&vf->vd);
1534       }
1535 
1536       ogg_stream_reset_serialno(&vf->os,vf->current_serialno);
1537       ogg_stream_pagein(&vf->os,&og);
1538 
1539       /* pull out all but last packet; the one with granulepos */
1540       while(1){
1541         result=ogg_stream_packetpeek(&vf->os,&op);
1542         if(result==0){
1543           /* !!! the packet finishing this page originated on a
1544              preceding page. Keep fetching previous pages until we
1545              get one with a granulepos or without the 'continued' flag
1546              set.  Then just use raw_seek for simplicity. */
1547 
1548           result=_seek_helper(vf,best);
1549           if(result<0) goto seek_error;
1550 
1551           while(1){
1552             result=_get_prev_page(vf,&og);
1553             if(result<0) goto seek_error;
1554             if(ogg_page_serialno(&og)==vf->current_serialno &&
1555                (ogg_page_granulepos(&og)>-1 ||
1556                 !ogg_page_continued(&og))){
1557               return ov_raw_seek(vf,result);
1558             }
1559             vf->offset=result;
1560           }
1561         }
1562         if(result<0){
1563           result = OV_EBADPACKET;
1564           goto seek_error;
1565         }
1566         if(op.granulepos!=-1){
1567           vf->pcm_offset=op.granulepos-vf->pcmlengths[vf->current_link*2];
1568           if(vf->pcm_offset<0)vf->pcm_offset=0;
1569           vf->pcm_offset+=total;
1570           break;
1571         }else
1572           result=ogg_stream_packetout(&vf->os,NULL);
1573       }
1574     }
1575   }
1576 
1577   /* verify result */
1578   if(vf->pcm_offset>pos || pos>ov_pcm_total(vf,-1)){
1579     result=OV_EFAULT;
1580     goto seek_error;
1581   }
1582   vf->bittrack=0;
1583   vf->samptrack=0;
1584   return(0);
1585 
1586  seek_error:
1587   /* dump machine so we're in a known state */
1588   vf->pcm_offset=-1;
1589   _decode_clear(vf);
1590   return (int)result;
1591 }
1592 
1593 /* seek to a sample offset relative to the decompressed pcm stream
1594    returns zero on success, nonzero on failure */
1595 
ov_pcm_seek(OggVorbis_File * vf,int64_t pos)1596 int ov_pcm_seek(OggVorbis_File *vf,int64_t pos){
1597   int thisblock,lastblock=0;
1598   int ret=ov_pcm_seek_page(vf,pos);
1599   if(ret<0)return(ret);
1600   if((ret=_make_decode_ready(vf)))return ret;
1601 
1602   /* discard leading packets we don't need for the lapping of the
1603      position we want; don't decode them */
1604 
1605   while(1){
1606     ogg_packet op;
1607     ogg_page og;
1608 
1609     int ret=ogg_stream_packetpeek(&vf->os,&op);
1610     if(ret>0){
1611       thisblock=vorbis_packet_blocksize(vf->vi+vf->current_link,&op);
1612       if(thisblock<0){
1613         ogg_stream_packetout(&vf->os,NULL);
1614         continue; /* non audio packet */
1615       }
1616       if(lastblock)vf->pcm_offset+=(lastblock+thisblock)>>2;
1617 
1618       if(vf->pcm_offset+((thisblock+
1619                           vorbis_info_blocksize(vf->vi,1))>>2)>=pos)break;
1620 
1621       /* remove the packet from packet queue and track its granulepos */
1622       ogg_stream_packetout(&vf->os,NULL);
1623       vorbis_synthesis_trackonly(&vf->vb,&op);  /* set up a vb with
1624                                                    only tracking, no
1625                                                    pcm_decode */
1626       vorbis_synthesis_blockin(&vf->vd,&vf->vb);
1627 
1628       /* end of logical stream case is hard, especially with exact
1629          length positioning. */
1630 
1631       if(op.granulepos>-1){
1632         int i;
1633         /* always believe the stream markers */
1634         vf->pcm_offset=op.granulepos-vf->pcmlengths[vf->current_link*2];
1635         if(vf->pcm_offset<0)vf->pcm_offset=0;
1636         for(i=0;i<vf->current_link;i++)
1637           vf->pcm_offset+=vf->pcmlengths[i*2+1];
1638       }
1639 
1640       lastblock=thisblock;
1641 
1642     }else{
1643       if(ret<0 && ret!=OV_HOLE)break;
1644 
1645       /* suck in a new page */
1646       if(_get_next_page(vf,&og,-1)<0)break;
1647       if(ogg_page_bos(&og))_decode_clear(vf);
1648 
1649       if(vf->ready_state<STREAMSET){
1650         uint32_t serialno=ogg_page_serialno(&og);
1651         int link;
1652 
1653         for(link=0;link<vf->links;link++)
1654           if(vf->serialnos[link]==serialno)break;
1655         if(link==vf->links) continue;
1656         vf->current_link=link;
1657 
1658         vf->ready_state=STREAMSET;
1659         vf->current_serialno=ogg_page_serialno(&og);
1660         ogg_stream_reset_serialno(&vf->os,serialno);
1661         ret=_make_decode_ready(vf);
1662         if(ret)return ret;
1663         lastblock=0;
1664       }
1665 
1666       ogg_stream_pagein(&vf->os,&og);
1667     }
1668   }
1669 
1670   vf->bittrack=0;
1671   vf->samptrack=0;
1672   /* discard samples until we reach the desired position. Crossing a
1673      logical bitstream boundary with abandon is OK. */
1674   while(vf->pcm_offset<pos){
1675     int64_t target=pos-vf->pcm_offset;
1676     long samples=vorbis_synthesis_pcmout(&vf->vd,NULL);
1677 
1678     if(samples>target)samples=target;
1679     vorbis_synthesis_read(&vf->vd,samples);
1680     vf->pcm_offset+=samples;
1681 
1682     if(samples<target)
1683       if(_fetch_and_process_packet(vf,NULL,1,1)<=0)
1684         vf->pcm_offset=ov_pcm_total(vf,-1); /* eof */
1685   }
1686   return 0;
1687 }
1688 
1689 /* seek to a playback time relative to the decompressed pcm stream
1690    returns zero on success, nonzero on failure */
ov_time_seek(OggVorbis_File * vf,int64_t milliseconds)1691 int ov_time_seek(OggVorbis_File *vf,int64_t milliseconds){
1692   /* translate time to PCM position and call ov_pcm_seek */
1693 
1694   int link=-1;
1695   int64_t pcm_total=0;
1696   int64_t time_total=0;
1697 
1698   if(vf->ready_state<OPENED)return(OV_EINVAL);
1699   if(!vf->seekable)return(OV_ENOSEEK);
1700   if(milliseconds<0)return(OV_EINVAL);
1701 
1702   /* which bitstream section does this time offset occur in? */
1703   for(link=0;link<vf->links;link++){
1704     int64_t addsec = ov_time_total(vf,link);
1705     if(milliseconds<time_total+addsec)break;
1706     time_total+=addsec;
1707     pcm_total+=vf->pcmlengths[link*2+1];
1708   }
1709 
1710   if(link==vf->links)return(OV_EINVAL);
1711 
1712   /* enough information to convert time offset to pcm offset */
1713   {
1714     int64_t target=pcm_total+(milliseconds-time_total)*vf->vi[link].rate/1000;
1715     return(ov_pcm_seek(vf,target));
1716   }
1717 }
1718 
1719 /* page-granularity version of ov_time_seek
1720    returns zero on success, nonzero on failure */
ov_time_seek_page(OggVorbis_File * vf,int64_t milliseconds)1721 int ov_time_seek_page(OggVorbis_File *vf,int64_t milliseconds){
1722   /* translate time to PCM position and call ov_pcm_seek */
1723 
1724   int link=-1;
1725   int64_t pcm_total=0;
1726   int64_t time_total=0;
1727 
1728   if(vf->ready_state<OPENED)return(OV_EINVAL);
1729   if(!vf->seekable)return(OV_ENOSEEK);
1730   if(milliseconds<0)return(OV_EINVAL);
1731 
1732   /* which bitstream section does this time offset occur in? */
1733   for(link=0;link<vf->links;link++){
1734     int64_t addsec = ov_time_total(vf,link);
1735     if(milliseconds<time_total+addsec)break;
1736     time_total+=addsec;
1737     pcm_total+=vf->pcmlengths[link*2+1];
1738   }
1739 
1740   if(link==vf->links)return(OV_EINVAL);
1741 
1742   /* enough information to convert time offset to pcm offset */
1743   {
1744     int64_t target=pcm_total+(milliseconds-time_total)*vf->vi[link].rate/1000;
1745     return(ov_pcm_seek_page(vf,target));
1746   }
1747 }
1748 
1749 /* tell the current stream offset cursor.  Note that seek followed by
1750    tell will likely not give the set offset due to caching */
ov_raw_tell(OggVorbis_File * vf)1751 int64_t ov_raw_tell(OggVorbis_File *vf){
1752   if(vf->ready_state<OPENED)return(OV_EINVAL);
1753   return(vf->offset);
1754 }
1755 
1756 /* return PCM offset (sample) of next PCM sample to be read */
ov_pcm_tell(OggVorbis_File * vf)1757 int64_t ov_pcm_tell(OggVorbis_File *vf){
1758   if(vf->ready_state<OPENED)return(OV_EINVAL);
1759   return(vf->pcm_offset);
1760 }
1761 
1762 /* return time offset (milliseconds) of next PCM sample to be read */
ov_time_tell(OggVorbis_File * vf)1763 int64_t ov_time_tell(OggVorbis_File *vf){
1764   int link=0;
1765   int64_t pcm_total=0;
1766   int64_t time_total=0;
1767 
1768   if(vf->ready_state<OPENED)return(OV_EINVAL);
1769   if(vf->seekable){
1770     pcm_total=ov_pcm_total(vf,-1);
1771     time_total=ov_time_total(vf,-1);
1772 
1773     /* which bitstream section does this time offset occur in? */
1774     for(link=vf->links-1;link>=0;link--){
1775       pcm_total-=vf->pcmlengths[link*2+1];
1776       time_total-=ov_time_total(vf,link);
1777       if(vf->pcm_offset>=pcm_total)break;
1778     }
1779   }
1780 
1781   return(time_total+(1000*vf->pcm_offset-pcm_total)/vf->vi[link].rate);
1782 }
1783 
1784 /*  link:   -1) return the vorbis_info struct for the bitstream section
1785                 currently being decoded
1786            0-n) to request information for a specific bitstream section
1787 
1788     In the case of a non-seekable bitstream, any call returns the
1789     current bitstream.  NULL in the case that the machine is not
1790     initialized */
1791 
ov_info(OggVorbis_File * vf,int link)1792 vorbis_info *ov_info(OggVorbis_File *vf,int link){
1793   if(vf->seekable){
1794     if(link<0)
1795       if(vf->ready_state>=STREAMSET)
1796         return vf->vi+vf->current_link;
1797       else
1798       return vf->vi;
1799     else
1800       if(link>=vf->links)
1801         return NULL;
1802       else
1803         return vf->vi+link;
1804   }else{
1805     return vf->vi;
1806   }
1807 }
1808 
1809 /* grr, strong typing, grr, no templates/inheritence, grr */
ov_comment(OggVorbis_File * vf,int link)1810 vorbis_comment *ov_comment(OggVorbis_File *vf,int link){
1811   if(vf->seekable){
1812     if(link<0)
1813       if(vf->ready_state>=STREAMSET)
1814         return vf->vc+vf->current_link;
1815       else
1816         return vf->vc;
1817     else
1818       if(link>=vf->links)
1819         return NULL;
1820       else
1821         return vf->vc+link;
1822   }else{
1823     return vf->vc;
1824   }
1825 }
1826 
1827 /* up to this point, everything could more or less hide the multiple
1828    logical bitstream nature of chaining from the toplevel application
1829    if the toplevel application didn't particularly care.  However, at
1830    the point that we actually read audio back, the multiple-section
1831    nature must surface: Multiple bitstream sections do not necessarily
1832    have to have the same number of channels or sampling rate.
1833 
1834    ov_read returns the sequential logical bitstream number currently
1835    being decoded along with the PCM data in order that the toplevel
1836    application can take action on channel/sample rate changes.  This
1837    number will be incremented even for streamed (non-seekable) streams
1838    (for seekable streams, it represents the actual logical bitstream
1839    index within the physical bitstream.  Note that the accessor
1840    functions above are aware of this dichotomy).
1841 
1842    input values: buffer) a buffer to hold packed PCM data for return
1843                  bytes_req) the byte length requested to be placed into buffer
1844 
1845    return values: <0) error/hole in data (OV_HOLE), partial open (OV_EINVAL)
1846                    0) EOF
1847                    n) number of bytes of PCM actually returned.  The
1848                    below works on a packet-by-packet basis, so the
1849                    return length is not related to the 'length' passed
1850                    in, just guaranteed to fit.
1851 
1852             *section) set to the logical bitstream number */
1853 
ov_read(OggVorbis_File * vf,char * buffer,int bytes_req,int * bitstream)1854 long ov_read(OggVorbis_File *vf,char *buffer,int bytes_req,int *bitstream){
1855   int i,j;
1856 
1857   int32_t **pcm;
1858   long samples;
1859 
1860   if(vf->ready_state<OPENED)return(OV_EINVAL);
1861 
1862   while(1){
1863     if(vf->ready_state==INITSET){
1864       samples=vorbis_synthesis_pcmout(&vf->vd,&pcm);
1865       if(samples)break;
1866     }
1867 
1868     /* suck in another packet */
1869     {
1870       int ret=_fetch_and_process_packet(vf,NULL,1,1);
1871       if(ret==OV_EOF)
1872         return(0);
1873       if(ret<=0)
1874         return(ret);
1875     }
1876 
1877   }
1878 
1879   if(samples>0){
1880 
1881     /* yay! proceed to pack data into the byte buffer */
1882 
1883     long channels=ov_info(vf,-1)->channels;
1884 
1885     if(samples>(bytes_req/(2*channels)))
1886       samples=bytes_req/(2*channels);
1887 
1888     for(i=0;i<channels;i++) { /* It's faster in this order */
1889       int32_t *src=pcm[i];
1890       short *dest=((short *)buffer)+i;
1891       for(j=0;j<samples;j++) {
1892         *dest=CLIP_TO_15(src[j]>>9);
1893         dest+=channels;
1894       }
1895     }
1896 
1897     vorbis_synthesis_read(&vf->vd,samples);
1898     vf->pcm_offset+=samples;
1899     if(bitstream)*bitstream=vf->current_link;
1900     return(samples*2*channels);
1901   }else{
1902     return(samples);
1903   }
1904 }
1905