1 /********************************************************************
2  *                                                                  *
3  * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE.   *
4  * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     *
5  * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
6  * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING.       *
7  *                                                                  *
8  * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2015             *
9  * by the Xiph.Org Foundation http://www.xiph.org/                  *
10  *                                                                  *
11  ********************************************************************
12 
13  function: stdio-based convenience library for opening/seeking/decoding
14  last mod: $Id: vorbisfile.c 19457 2015-03-03 00:15:29Z giles $
15 
16  ********************************************************************/
17 
18 #include <stdlib.h>
19 #include <stdio.h>
20 #include <errno.h>
21 #include <string.h>
22 #include <math.h>
23 
24 #include "vorbis/codec.h"
25 
26 /* we don't need or want the static callback symbols here */
27 #define OV_EXCLUDE_STATIC_CALLBACKS
28 #include "vorbis/vorbisfile.h"
29 
30 #include "os.h"
31 #include "misc.h"
32 
33 /* A 'chained bitstream' is a Vorbis bitstream that contains more than
34    one logical bitstream arranged end to end (the only form of Ogg
35    multiplexing allowed in a Vorbis bitstream; grouping [parallel
36    multiplexing] is not allowed in Vorbis) */
37 
38 /* A Vorbis file can be played beginning to end (streamed) without
39    worrying ahead of time about chaining (see decoder_example.c).  If
40    we have the whole file, however, and want random access
41    (seeking/scrubbing) or desire to know the total length/time of a
42    file, we need to account for the possibility of chaining. */
43 
44 /* We can handle things a number of ways; we can determine the entire
45    bitstream structure right off the bat, or find pieces on demand.
46    This example determines and caches structure for the entire
47    bitstream, but builds a virtual decoder on the fly when moving
48    between links in the chain. */
49 
50 /* There are also different ways to implement seeking.  Enough
51    information exists in an Ogg bitstream to seek to
52    sample-granularity positions in the output.  Or, one can seek by
53    picking some portion of the stream roughly in the desired area if
54    we only want coarse navigation through the stream. */
55 
56 /*************************************************************************
57  * Many, many internal helpers.  The intention is not to be confusing;
58  * rampant duplication and monolithic function implementation would be
59  * harder to understand anyway.  The high level functions are last.  Begin
60  * grokking near the end of the file */
61 
62 /* read a little more data from the file/pipe into the ogg_sync framer
63 */
64 #define CHUNKSIZE 65536 /* greater-than-page-size granularity seeking */
65 #define READSIZE 2048 /* a smaller read size is needed for low-rate streaming. */
66 
_get_data(OggVorbis_File * vf)67 static long _get_data(OggVorbis_File *vf){
68   errno=0;
69   if(!(vf->callbacks.read_func))return(-1);
70   if(vf->datasource){
71     char *buffer=ogg_sync_buffer(&vf->oy,READSIZE);
72     long bytes=(vf->callbacks.read_func)(buffer,1,READSIZE,vf->datasource);
73     if(bytes>0)ogg_sync_wrote(&vf->oy,bytes);
74     if(bytes==0 && errno)return(-1);
75     return(bytes);
76   }else
77     return(0);
78 }
79 
80 /* save a tiny smidge of verbosity to make the code more readable */
_seek_helper(OggVorbis_File * vf,ogg_int64_t offset)81 static int _seek_helper(OggVorbis_File *vf,ogg_int64_t offset){
82   if(vf->datasource){
83     /* only seek if the file position isn't already there */
84     if(vf->offset != offset){
85       if(!(vf->callbacks.seek_func)||
86          (vf->callbacks.seek_func)(vf->datasource, offset, SEEK_SET) == -1)
87         return OV_EREAD;
88       vf->offset=offset;
89       ogg_sync_reset(&vf->oy);
90     }
91   }else{
92     /* shouldn't happen unless someone writes a broken callback */
93     return OV_EFAULT;
94   }
95   return 0;
96 }
97 
98 /* The read/seek functions track absolute position within the stream */
99 
100 /* from the head of the stream, get the next page.  boundary specifies
101    if the function is allowed to fetch more data from the stream (and
102    how much) or only use internally buffered data.
103 
104    boundary: -1) unbounded search
105               0) read no additional data; use cached only
106               n) search for a new page beginning for n bytes
107 
108    return:   <0) did not find a page (OV_FALSE, OV_EOF, OV_EREAD)
109               n) found a page at absolute offset n */
110 
_get_next_page(OggVorbis_File * vf,ogg_page * og,ogg_int64_t boundary)111 static ogg_int64_t _get_next_page(OggVorbis_File *vf,ogg_page *og,
112                                   ogg_int64_t boundary){
113   if(boundary>0)boundary+=vf->offset;
114   while(1){
115     long more;
116 
117     if(boundary>0 && vf->offset>=boundary)return(OV_FALSE);
118     more=ogg_sync_pageseek(&vf->oy,og);
119 
120     if(more<0){
121       /* skipped n bytes */
122       vf->offset-=more;
123     }else{
124       if(more==0){
125         /* send more paramedics */
126         if(!boundary)return(OV_FALSE);
127         {
128           long ret=_get_data(vf);
129           if(ret==0)return(OV_EOF);
130           if(ret<0)return(OV_EREAD);
131         }
132       }else{
133         /* got a page.  Return the offset at the page beginning,
134            advance the internal offset past the page end */
135         ogg_int64_t ret=vf->offset;
136         vf->offset+=more;
137         return(ret);
138 
139       }
140     }
141   }
142 }
143 
144 /* find the latest page beginning before the passed in position. Much
145    dirtier than the above as Ogg doesn't have any backward search
146    linkage.  no 'readp' as it will certainly have to read. */
147 /* returns offset or OV_EREAD, OV_FAULT */
_get_prev_page(OggVorbis_File * vf,ogg_int64_t begin,ogg_page * og)148 static ogg_int64_t _get_prev_page(OggVorbis_File *vf,ogg_int64_t begin,ogg_page *og){
149   ogg_int64_t end = begin;
150   ogg_int64_t ret;
151   ogg_int64_t offset=-1;
152 
153   while(offset==-1){
154     begin-=CHUNKSIZE;
155     if(begin<0)
156       begin=0;
157 
158     ret=_seek_helper(vf,begin);
159     if(ret)return(ret);
160 
161     while(vf->offset<end){
162       memset(og,0,sizeof(*og));
163       ret=_get_next_page(vf,og,end-vf->offset);
164       if(ret==OV_EREAD)return(OV_EREAD);
165       if(ret<0){
166         break;
167       }else{
168         offset=ret;
169       }
170     }
171   }
172 
173   /* In a fully compliant, non-multiplexed stream, we'll still be
174      holding the last page.  In multiplexed (or noncompliant streams),
175      we will probably have to re-read the last page we saw */
176   if(og->header_len==0){
177     ret=_seek_helper(vf,offset);
178     if(ret)return(ret);
179 
180     ret=_get_next_page(vf,og,CHUNKSIZE);
181     if(ret<0)
182       /* this shouldn't be possible */
183       return(OV_EFAULT);
184   }
185 
186   return(offset);
187 }
188 
_add_serialno(ogg_page * og,long ** serialno_list,int * n)189 static void _add_serialno(ogg_page *og,long **serialno_list, int *n){
190   long s = ogg_page_serialno(og);
191   (*n)++;
192 
193   if(*serialno_list){
194     *serialno_list = _ogg_realloc(*serialno_list, sizeof(**serialno_list)*(*n));
195   }else{
196     *serialno_list = _ogg_malloc(sizeof(**serialno_list));
197   }
198 
199   (*serialno_list)[(*n)-1] = s;
200 }
201 
202 /* returns nonzero if found */
_lookup_serialno(long s,long * serialno_list,int n)203 static int _lookup_serialno(long s, long *serialno_list, int n){
204   if(serialno_list){
205     while(n--){
206       if(*serialno_list == s) return 1;
207       serialno_list++;
208     }
209   }
210   return 0;
211 }
212 
_lookup_page_serialno(ogg_page * og,long * serialno_list,int n)213 static int _lookup_page_serialno(ogg_page *og, long *serialno_list, int n){
214   long s = ogg_page_serialno(og);
215   return _lookup_serialno(s,serialno_list,n);
216 }
217 
218 /* performs the same search as _get_prev_page, but prefers pages of
219    the specified serial number. If a page of the specified serialno is
220    spotted during the seek-back-and-read-forward, it will return the
221    info of last page of the matching serial number instead of the very
222    last page.  If no page of the specified serialno is seen, it will
223    return the info of last page and alter *serialno.  */
_get_prev_page_serial(OggVorbis_File * vf,ogg_int64_t begin,long * serial_list,int serial_n,int * serialno,ogg_int64_t * granpos)224 static ogg_int64_t _get_prev_page_serial(OggVorbis_File *vf, ogg_int64_t begin,
225                                          long *serial_list, int serial_n,
226                                          int *serialno, ogg_int64_t *granpos){
227   ogg_page og;
228   ogg_int64_t end=begin;
229   ogg_int64_t ret;
230 
231   ogg_int64_t prefoffset=-1;
232   ogg_int64_t offset=-1;
233   ogg_int64_t ret_serialno=-1;
234   ogg_int64_t ret_gran=-1;
235 
236   while(offset==-1){
237     begin-=CHUNKSIZE;
238     if(begin<0)
239       begin=0;
240 
241     ret=_seek_helper(vf,begin);
242     if(ret)return(ret);
243 
244     while(vf->offset<end){
245       ret=_get_next_page(vf,&og,end-vf->offset);
246       if(ret==OV_EREAD)return(OV_EREAD);
247       if(ret<0){
248         break;
249       }else{
250         ret_serialno=ogg_page_serialno(&og);
251         ret_gran=ogg_page_granulepos(&og);
252         offset=ret;
253 
254         if(ret_serialno == *serialno){
255           prefoffset=ret;
256           *granpos=ret_gran;
257         }
258 
259         if(!_lookup_serialno(ret_serialno,serial_list,serial_n)){
260           /* we fell off the end of the link, which means we seeked
261              back too far and shouldn't have been looking in that link
262              to begin with.  If we found the preferred serial number,
263              forget that we saw it. */
264           prefoffset=-1;
265         }
266       }
267     }
268   }
269 
270   /* we're not interested in the page... just the serialno and granpos. */
271   if(prefoffset>=0)return(prefoffset);
272 
273   *serialno = ret_serialno;
274   *granpos = ret_gran;
275   return(offset);
276 
277 }
278 
279 /* uses the local ogg_stream storage in vf; this is important for
280    non-streaming input sources */
_fetch_headers(OggVorbis_File * vf,vorbis_info * vi,vorbis_comment * vc,long ** serialno_list,int * serialno_n,ogg_page * og_ptr)281 static int _fetch_headers(OggVorbis_File *vf,vorbis_info *vi,vorbis_comment *vc,
282                           long **serialno_list, int *serialno_n,
283                           ogg_page *og_ptr){
284   ogg_page og;
285   ogg_packet op;
286   int i,ret;
287   int allbos=0;
288 
289   if(!og_ptr){
290     ogg_int64_t llret=_get_next_page(vf,&og,CHUNKSIZE);
291     if(llret==OV_EREAD)return(OV_EREAD);
292     if(llret<0)return(OV_ENOTVORBIS);
293     og_ptr=&og;
294   }
295 
296   vorbis_info_init(vi);
297   vorbis_comment_init(vc);
298   vf->ready_state=OPENED;
299 
300   /* extract the serialnos of all BOS pages + the first set of vorbis
301      headers we see in the link */
302 
303   while(ogg_page_bos(og_ptr)){
304     if(serialno_list){
305       if(_lookup_page_serialno(og_ptr,*serialno_list,*serialno_n)){
306         /* a dupe serialnumber in an initial header packet set == invalid stream */
307         if(*serialno_list)_ogg_free(*serialno_list);
308         *serialno_list=0;
309         *serialno_n=0;
310         ret=OV_EBADHEADER;
311         goto bail_header;
312       }
313 
314       _add_serialno(og_ptr,serialno_list,serialno_n);
315     }
316 
317     if(vf->ready_state<STREAMSET){
318       /* we don't have a vorbis stream in this link yet, so begin
319          prospective stream setup. We need a stream to get packets */
320       ogg_stream_reset_serialno(&vf->os,ogg_page_serialno(og_ptr));
321       ogg_stream_pagein(&vf->os,og_ptr);
322 
323       if(ogg_stream_packetout(&vf->os,&op) > 0 &&
324          vorbis_synthesis_idheader(&op)){
325         /* vorbis header; continue setup */
326         vf->ready_state=STREAMSET;
327         if((ret=vorbis_synthesis_headerin(vi,vc,&op))){
328           ret=OV_EBADHEADER;
329           goto bail_header;
330         }
331       }
332     }
333 
334     /* get next page */
335     {
336       ogg_int64_t llret=_get_next_page(vf,og_ptr,CHUNKSIZE);
337       if(llret==OV_EREAD){
338         ret=OV_EREAD;
339         goto bail_header;
340       }
341       if(llret<0){
342         ret=OV_ENOTVORBIS;
343         goto bail_header;
344       }
345 
346       /* if this page also belongs to our vorbis stream, submit it and break */
347       if(vf->ready_state==STREAMSET &&
348          vf->os.serialno == ogg_page_serialno(og_ptr)){
349         ogg_stream_pagein(&vf->os,og_ptr);
350         break;
351       }
352     }
353   }
354 
355   if(vf->ready_state!=STREAMSET){
356     ret = OV_ENOTVORBIS;
357     goto bail_header;
358   }
359 
360   while(1){
361 
362     i=0;
363     while(i<2){ /* get a page loop */
364 
365       while(i<2){ /* get a packet loop */
366 
367         int result=ogg_stream_packetout(&vf->os,&op);
368         if(result==0)break;
369         if(result==-1){
370           ret=OV_EBADHEADER;
371           goto bail_header;
372         }
373 
374         if((ret=vorbis_synthesis_headerin(vi,vc,&op)))
375           goto bail_header;
376 
377         i++;
378       }
379 
380       while(i<2){
381         if(_get_next_page(vf,og_ptr,CHUNKSIZE)<0){
382           ret=OV_EBADHEADER;
383           goto bail_header;
384         }
385 
386         /* if this page belongs to the correct stream, go parse it */
387         if(vf->os.serialno == ogg_page_serialno(og_ptr)){
388           ogg_stream_pagein(&vf->os,og_ptr);
389           break;
390         }
391 
392         /* if we never see the final vorbis headers before the link
393            ends, abort */
394         if(ogg_page_bos(og_ptr)){
395           if(allbos){
396             ret = OV_EBADHEADER;
397             goto bail_header;
398           }else
399             allbos=1;
400         }
401 
402         /* otherwise, keep looking */
403       }
404     }
405 
406     return 0;
407   }
408 
409  bail_header:
410   vorbis_info_clear(vi);
411   vorbis_comment_clear(vc);
412   vf->ready_state=OPENED;
413 
414   return ret;
415 }
416 
417 /* Starting from current cursor position, get initial PCM offset of
418    next page.  Consumes the page in the process without decoding
419    audio, however this is only called during stream parsing upon
420    seekable open. */
_initial_pcmoffset(OggVorbis_File * vf,vorbis_info * vi)421 static ogg_int64_t _initial_pcmoffset(OggVorbis_File *vf, vorbis_info *vi){
422   ogg_page    og;
423   ogg_int64_t accumulated=0;
424   long        lastblock=-1;
425   int         result;
426   int         serialno = vf->os.serialno;
427 
428   while(1){
429     ogg_packet op;
430     if(_get_next_page(vf,&og,-1)<0)
431       break; /* should not be possible unless the file is truncated/mangled */
432 
433     if(ogg_page_bos(&og)) break;
434     if(ogg_page_serialno(&og)!=serialno) continue;
435 
436     /* count blocksizes of all frames in the page */
437     ogg_stream_pagein(&vf->os,&og);
438     while((result=ogg_stream_packetout(&vf->os,&op))){
439       if(result>0){ /* ignore holes */
440         long thisblock=vorbis_packet_blocksize(vi,&op);
441         if(thisblock>=0){
442           if(lastblock!=-1)
443             accumulated+=(lastblock+thisblock)>>2;
444           lastblock=thisblock;
445         }
446       }
447     }
448 
449     if(ogg_page_granulepos(&og)!=-1){
450       /* pcm offset of last packet on the first audio page */
451       accumulated= ogg_page_granulepos(&og)-accumulated;
452       break;
453     }
454   }
455 
456   /* less than zero?  Either a corrupt file or a stream with samples
457      trimmed off the beginning, a normal occurrence; in both cases set
458      the offset to zero */
459   if(accumulated<0)accumulated=0;
460 
461   return accumulated;
462 }
463 
464 /* finds each bitstream link one at a time using a bisection search
465    (has to begin by knowing the offset of the lb's initial page).
466    Recurses for each link so it can alloc the link storage after
467    finding them all, then unroll and fill the cache at the same time */
_bisect_forward_serialno(OggVorbis_File * vf,ogg_int64_t begin,ogg_int64_t searched,ogg_int64_t end,ogg_int64_t endgran,int endserial,long * currentno_list,int currentnos,long m)468 static int _bisect_forward_serialno(OggVorbis_File *vf,
469                                     ogg_int64_t begin,
470                                     ogg_int64_t searched,
471                                     ogg_int64_t end,
472                                     ogg_int64_t endgran,
473                                     int endserial,
474                                     long *currentno_list,
475                                     int  currentnos,
476                                     long m){
477   ogg_int64_t pcmoffset;
478   ogg_int64_t dataoffset=searched;
479   ogg_int64_t endsearched=end;
480   ogg_int64_t next=end;
481   ogg_int64_t searchgran=-1;
482   ogg_page og;
483   ogg_int64_t ret,last;
484   int serialno = vf->os.serialno;
485 
486   /* invariants:
487      we have the headers and serialnos for the link beginning at 'begin'
488      we have the offset and granpos of the last page in the file (potentially
489        not a page we care about)
490   */
491 
492   /* Is the last page in our list of current serialnumbers? */
493   if(_lookup_serialno(endserial,currentno_list,currentnos)){
494 
495     /* last page is in the starting serialno list, so we've bisected
496        down to (or just started with) a single link.  Now we need to
497        find the last vorbis page belonging to the first vorbis stream
498        for this link. */
499     searched = end;
500     while(endserial != serialno){
501       endserial = serialno;
502       searched=_get_prev_page_serial(vf,searched,currentno_list,currentnos,&endserial,&endgran);
503     }
504 
505     vf->links=m+1;
506     if(vf->offsets)_ogg_free(vf->offsets);
507     if(vf->serialnos)_ogg_free(vf->serialnos);
508     if(vf->dataoffsets)_ogg_free(vf->dataoffsets);
509 
510     vf->offsets=_ogg_malloc((vf->links+1)*sizeof(*vf->offsets));
511     vf->vi=_ogg_realloc(vf->vi,vf->links*sizeof(*vf->vi));
512     vf->vc=_ogg_realloc(vf->vc,vf->links*sizeof(*vf->vc));
513     vf->serialnos=_ogg_malloc(vf->links*sizeof(*vf->serialnos));
514     vf->dataoffsets=_ogg_malloc(vf->links*sizeof(*vf->dataoffsets));
515     vf->pcmlengths=_ogg_malloc(vf->links*2*sizeof(*vf->pcmlengths));
516 
517     vf->offsets[m+1]=end;
518     vf->offsets[m]=begin;
519     vf->pcmlengths[m*2+1]=(endgran<0?0:endgran);
520 
521   }else{
522 
523     /* last page is not in the starting stream's serial number list,
524        so we have multiple links.  Find where the stream that begins
525        our bisection ends. */
526 
527     long *next_serialno_list=NULL;
528     int next_serialnos=0;
529     vorbis_info vi;
530     vorbis_comment vc;
531     int testserial = serialno+1;
532 
533     /* the below guards against garbage seperating the last and
534        first pages of two links. */
535     while(searched<endsearched){
536       ogg_int64_t bisect;
537 
538       if(endsearched-searched<CHUNKSIZE){
539         bisect=searched;
540       }else{
541         bisect=(searched+endsearched)/2;
542       }
543 
544       ret=_seek_helper(vf,bisect);
545       if(ret)return(ret);
546 
547       last=_get_next_page(vf,&og,-1);
548       if(last==OV_EREAD)return(OV_EREAD);
549       if(last<0 || !_lookup_page_serialno(&og,currentno_list,currentnos)){
550         endsearched=bisect;
551         if(last>=0)next=last;
552       }else{
553         searched=vf->offset;
554       }
555     }
556 
557     /* Bisection point found */
558     /* for the time being, fetch end PCM offset the simple way */
559     searched = next;
560     while(testserial != serialno){
561       testserial = serialno;
562       searched = _get_prev_page_serial(vf,searched,currentno_list,currentnos,&testserial,&searchgran);
563     }
564 
565     ret=_seek_helper(vf,next);
566     if(ret)return(ret);
567 
568     ret=_fetch_headers(vf,&vi,&vc,&next_serialno_list,&next_serialnos,NULL);
569     if(ret)return(ret);
570     serialno = vf->os.serialno;
571     dataoffset = vf->offset;
572 
573     /* this will consume a page, however the next bisection always
574        starts with a raw seek */
575     pcmoffset = _initial_pcmoffset(vf,&vi);
576 
577     ret=_bisect_forward_serialno(vf,next,vf->offset,end,endgran,endserial,
578                                  next_serialno_list,next_serialnos,m+1);
579     if(ret)return(ret);
580 
581     if(next_serialno_list)_ogg_free(next_serialno_list);
582 
583     vf->offsets[m+1]=next;
584     vf->serialnos[m+1]=serialno;
585     vf->dataoffsets[m+1]=dataoffset;
586 
587     vf->vi[m+1]=vi;
588     vf->vc[m+1]=vc;
589 
590     vf->pcmlengths[m*2+1]=searchgran;
591     vf->pcmlengths[m*2+2]=pcmoffset;
592     vf->pcmlengths[m*2+3]-=pcmoffset;
593     if(vf->pcmlengths[m*2+3]<0)vf->pcmlengths[m*2+3]=0;
594   }
595   return(0);
596 }
597 
_make_decode_ready(OggVorbis_File * vf)598 static int _make_decode_ready(OggVorbis_File *vf){
599   if(vf->ready_state>STREAMSET)return 0;
600   if(vf->ready_state<STREAMSET)return OV_EFAULT;
601   if(vf->seekable){
602     if(vorbis_synthesis_init(&vf->vd,vf->vi+vf->current_link))
603       return OV_EBADLINK;
604   }else{
605     if(vorbis_synthesis_init(&vf->vd,vf->vi))
606       return OV_EBADLINK;
607   }
608   vorbis_block_init(&vf->vd,&vf->vb);
609   vf->ready_state=INITSET;
610   vf->bittrack=0.f;
611   vf->samptrack=0.f;
612   return 0;
613 }
614 
_open_seekable2(OggVorbis_File * vf)615 static int _open_seekable2(OggVorbis_File *vf){
616   ogg_int64_t dataoffset=vf->dataoffsets[0],end,endgran=-1;
617   int endserial=vf->os.serialno;
618   int serialno=vf->os.serialno;
619 
620   /* we're partially open and have a first link header state in
621      storage in vf */
622 
623   /* fetch initial PCM offset */
624   ogg_int64_t pcmoffset = _initial_pcmoffset(vf,vf->vi);
625 
626   /* we can seek, so set out learning all about this file */
627   if(vf->callbacks.seek_func && vf->callbacks.tell_func){
628     (vf->callbacks.seek_func)(vf->datasource,0,SEEK_END);
629     vf->offset=vf->end=(vf->callbacks.tell_func)(vf->datasource);
630   }else{
631     vf->offset=vf->end=-1;
632   }
633 
634   /* If seek_func is implemented, tell_func must also be implemented */
635   if(vf->end==-1) return(OV_EINVAL);
636 
637   /* Get the offset of the last page of the physical bitstream, or, if
638      we're lucky the last vorbis page of this link as most OggVorbis
639      files will contain a single logical bitstream */
640   end=_get_prev_page_serial(vf,vf->end,vf->serialnos+2,vf->serialnos[1],&endserial,&endgran);
641   if(end<0)return(end);
642 
643   /* now determine bitstream structure recursively */
644   if(_bisect_forward_serialno(vf,0,dataoffset,end,endgran,endserial,
645                               vf->serialnos+2,vf->serialnos[1],0)<0)return(OV_EREAD);
646 
647   vf->offsets[0]=0;
648   vf->serialnos[0]=serialno;
649   vf->dataoffsets[0]=dataoffset;
650   vf->pcmlengths[0]=pcmoffset;
651   vf->pcmlengths[1]-=pcmoffset;
652   if(vf->pcmlengths[1]<0)vf->pcmlengths[1]=0;
653 
654   return(ov_raw_seek(vf,dataoffset));
655 }
656 
657 /* clear out the current logical bitstream decoder */
_decode_clear(OggVorbis_File * vf)658 static void _decode_clear(OggVorbis_File *vf){
659   vorbis_dsp_clear(&vf->vd);
660   vorbis_block_clear(&vf->vb);
661   vf->ready_state=OPENED;
662 }
663 
664 /* fetch and process a packet.  Handles the case where we're at a
665    bitstream boundary and dumps the decoding machine.  If the decoding
666    machine is unloaded, it loads it.  It also keeps pcm_offset up to
667    date (seek and read both use this.  seek uses a special hack with
668    readp).
669 
670    return: <0) error, OV_HOLE (lost packet) or OV_EOF
671             0) need more data (only if readp==0)
672             1) got a packet
673 */
674 
_fetch_and_process_packet(OggVorbis_File * vf,ogg_packet * op_in,int readp,int spanp)675 static int _fetch_and_process_packet(OggVorbis_File *vf,
676                                      ogg_packet *op_in,
677                                      int readp,
678                                      int spanp){
679   ogg_page og;
680 
681   /* handle one packet.  Try to fetch it from current stream state */
682   /* extract packets from page */
683   while(1){
684 
685     if(vf->ready_state==STREAMSET){
686       int ret=_make_decode_ready(vf);
687       if(ret<0)return ret;
688     }
689 
690     /* process a packet if we can. */
691 
692     if(vf->ready_state==INITSET){
693       int hs=vorbis_synthesis_halfrate_p(vf->vi);
694 
695       while(1) {
696               ogg_packet op;
697               ogg_packet *op_ptr=(op_in?op_in:&op);
698         int result=ogg_stream_packetout(&vf->os,op_ptr);
699         ogg_int64_t granulepos;
700 
701         op_in=NULL;
702         if(result==-1)return(OV_HOLE); /* hole in the data. */
703         if(result>0){
704           /* got a packet.  process it */
705           granulepos=op_ptr->granulepos;
706           if(!vorbis_synthesis(&vf->vb,op_ptr)){ /* lazy check for lazy
707                                                     header handling.  The
708                                                     header packets aren't
709                                                     audio, so if/when we
710                                                     submit them,
711                                                     vorbis_synthesis will
712                                                     reject them */
713 
714             /* suck in the synthesis data and track bitrate */
715             {
716               int oldsamples=vorbis_synthesis_pcmout(&vf->vd,NULL);
717               /* for proper use of libvorbis within libvorbisfile,
718                  oldsamples will always be zero. */
719               if(oldsamples)return(OV_EFAULT);
720 
721               vorbis_synthesis_blockin(&vf->vd,&vf->vb);
722               vf->samptrack+=(vorbis_synthesis_pcmout(&vf->vd,NULL)<<hs);
723               vf->bittrack+=op_ptr->bytes*8;
724             }
725 
726             /* update the pcm offset. */
727             if(granulepos!=-1 && !op_ptr->e_o_s){
728               int link=(vf->seekable?vf->current_link:0);
729               int i,samples;
730 
731               /* this packet has a pcm_offset on it (the last packet
732                  completed on a page carries the offset) After processing
733                  (above), we know the pcm position of the *last* sample
734                  ready to be returned. Find the offset of the *first*
735 
736                  As an aside, this trick is inaccurate if we begin
737                  reading anew right at the last page; the end-of-stream
738                  granulepos declares the last frame in the stream, and the
739                  last packet of the last page may be a partial frame.
740                  So, we need a previous granulepos from an in-sequence page
741                  to have a reference point.  Thus the !op_ptr->e_o_s clause
742                  above */
743 
744               if(vf->seekable && link>0)
745                 granulepos-=vf->pcmlengths[link*2];
746               if(granulepos<0)granulepos=0; /* actually, this
747                                                shouldn't be possible
748                                                here unless the stream
749                                                is very broken */
750 
751               samples=(vorbis_synthesis_pcmout(&vf->vd,NULL)<<hs);
752 
753               granulepos-=samples;
754               for(i=0;i<link;i++)
755                 granulepos+=vf->pcmlengths[i*2+1];
756               vf->pcm_offset=granulepos;
757             }
758             return(1);
759           }
760         }
761         else
762           break;
763       }
764     }
765 
766     if(vf->ready_state>=OPENED){
767       ogg_int64_t ret;
768 
769       while(1){
770         /* the loop is not strictly necessary, but there's no sense in
771            doing the extra checks of the larger loop for the common
772            case in a multiplexed bistream where the page is simply
773            part of a different logical bitstream; keep reading until
774            we get one with the correct serialno */
775 
776         if(!readp)return(0);
777         if((ret=_get_next_page(vf,&og,-1))<0){
778           return(OV_EOF); /* eof. leave unitialized */
779         }
780 
781         /* bitrate tracking; add the header's bytes here, the body bytes
782            are done by packet above */
783         vf->bittrack+=og.header_len*8;
784 
785         if(vf->ready_state==INITSET){
786           if(vf->current_serialno!=ogg_page_serialno(&og)){
787 
788             /* two possibilities:
789                1) our decoding just traversed a bitstream boundary
790                2) another stream is multiplexed into this logical section */
791 
792             if(ogg_page_bos(&og)){
793               /* boundary case */
794               if(!spanp)
795                 return(OV_EOF);
796 
797               _decode_clear(vf);
798 
799               if(!vf->seekable){
800                 vorbis_info_clear(vf->vi);
801                 vorbis_comment_clear(vf->vc);
802               }
803               break;
804 
805             }else
806               continue; /* possibility #2 */
807           }
808         }
809 
810         break;
811       }
812     }
813 
814     /* Do we need to load a new machine before submitting the page? */
815     /* This is different in the seekable and non-seekable cases.
816 
817        In the seekable case, we already have all the header
818        information loaded and cached; we just initialize the machine
819        with it and continue on our merry way.
820 
821        In the non-seekable (streaming) case, we'll only be at a
822        boundary if we just left the previous logical bitstream and
823        we're now nominally at the header of the next bitstream
824     */
825 
826     if(vf->ready_state!=INITSET){
827       int link;
828 
829       if(vf->ready_state<STREAMSET){
830         if(vf->seekable){
831           long serialno = ogg_page_serialno(&og);
832 
833           /* match the serialno to bitstream section.  We use this rather than
834              offset positions to avoid problems near logical bitstream
835              boundaries */
836 
837           for(link=0;link<vf->links;link++)
838             if(vf->serialnos[link]==serialno)break;
839 
840           if(link==vf->links) continue; /* not the desired Vorbis
841                                            bitstream section; keep
842                                            trying */
843 
844           vf->current_serialno=serialno;
845           vf->current_link=link;
846 
847           ogg_stream_reset_serialno(&vf->os,vf->current_serialno);
848           vf->ready_state=STREAMSET;
849 
850         }else{
851           /* we're streaming */
852           /* fetch the three header packets, build the info struct */
853 
854           int ret=_fetch_headers(vf,vf->vi,vf->vc,NULL,NULL,&og);
855           if(ret)return(ret);
856           vf->current_serialno=vf->os.serialno;
857           vf->current_link++;
858           link=0;
859         }
860       }
861     }
862 
863     /* the buffered page is the data we want, and we're ready for it;
864        add it to the stream state */
865     ogg_stream_pagein(&vf->os,&og);
866 
867   }
868 }
869 
870 /* if, eg, 64 bit stdio is configured by default, this will build with
871    fseek64 */
_fseek64_wrap(FILE * f,ogg_int64_t off,int whence)872 static int _fseek64_wrap(FILE *f,ogg_int64_t off,int whence){
873   if(f==NULL)return(-1);
874   return fseek(f,off,whence);
875 }
876 
_ov_open1(void * f,OggVorbis_File * vf,const char * initial,long ibytes,ov_callbacks callbacks)877 static int _ov_open1(void *f,OggVorbis_File *vf,const char *initial,
878                      long ibytes, ov_callbacks callbacks){
879   int offsettest=((f && callbacks.seek_func)?callbacks.seek_func(f,0,SEEK_CUR):-1);
880   long *serialno_list=NULL;
881   int serialno_list_size=0;
882   int ret;
883 
884   memset(vf,0,sizeof(*vf));
885   vf->datasource=f;
886   vf->callbacks = callbacks;
887 
888   /* init the framing state */
889   ogg_sync_init(&vf->oy);
890 
891   /* perhaps some data was previously read into a buffer for testing
892      against other stream types.  Allow initialization from this
893      previously read data (especially as we may be reading from a
894      non-seekable stream) */
895   if(initial){
896     char *buffer=ogg_sync_buffer(&vf->oy,ibytes);
897     memcpy(buffer,initial,ibytes);
898     ogg_sync_wrote(&vf->oy,ibytes);
899   }
900 
901   /* can we seek? Stevens suggests the seek test was portable */
902   if(offsettest!=-1)vf->seekable=1;
903 
904   /* No seeking yet; Set up a 'single' (current) logical bitstream
905      entry for partial open */
906   vf->links=1;
907   vf->vi=_ogg_calloc(vf->links,sizeof(*vf->vi));
908   vf->vc=_ogg_calloc(vf->links,sizeof(*vf->vc));
909   ogg_stream_init(&vf->os,-1); /* fill in the serialno later */
910 
911   /* Fetch all BOS pages, store the vorbis header and all seen serial
912      numbers, load subsequent vorbis setup headers */
913   if((ret=_fetch_headers(vf,vf->vi,vf->vc,&serialno_list,&serialno_list_size,NULL))<0){
914     vf->datasource=NULL;
915     ov_clear(vf);
916   }else{
917     /* serial number list for first link needs to be held somewhere
918        for second stage of seekable stream open; this saves having to
919        seek/reread first link's serialnumber data then. */
920     vf->serialnos=_ogg_calloc(serialno_list_size+2,sizeof(*vf->serialnos));
921     vf->serialnos[0]=vf->current_serialno=vf->os.serialno;
922     vf->serialnos[1]=serialno_list_size;
923     memcpy(vf->serialnos+2,serialno_list,serialno_list_size*sizeof(*vf->serialnos));
924 
925     vf->offsets=_ogg_calloc(1,sizeof(*vf->offsets));
926     vf->dataoffsets=_ogg_calloc(1,sizeof(*vf->dataoffsets));
927     vf->offsets[0]=0;
928     vf->dataoffsets[0]=vf->offset;
929 
930     vf->ready_state=PARTOPEN;
931   }
932   if(serialno_list)_ogg_free(serialno_list);
933   return(ret);
934 }
935 
_ov_open2(OggVorbis_File * vf)936 static int _ov_open2(OggVorbis_File *vf){
937   if(vf->ready_state != PARTOPEN) return OV_EINVAL;
938   vf->ready_state=OPENED;
939   if(vf->seekable){
940     int ret=_open_seekable2(vf);
941     if(ret){
942       vf->datasource=NULL;
943       ov_clear(vf);
944     }
945     return(ret);
946   }else
947     vf->ready_state=STREAMSET;
948 
949   return 0;
950 }
951 
952 
953 /* clear out the OggVorbis_File struct */
ov_clear(OggVorbis_File * vf)954 int ov_clear(OggVorbis_File *vf){
955   if(vf){
956     vorbis_block_clear(&vf->vb);
957     vorbis_dsp_clear(&vf->vd);
958     ogg_stream_clear(&vf->os);
959 
960     if(vf->vi && vf->links){
961       int i;
962       for(i=0;i<vf->links;i++){
963         vorbis_info_clear(vf->vi+i);
964         vorbis_comment_clear(vf->vc+i);
965       }
966       _ogg_free(vf->vi);
967       _ogg_free(vf->vc);
968     }
969     if(vf->dataoffsets)_ogg_free(vf->dataoffsets);
970     if(vf->pcmlengths)_ogg_free(vf->pcmlengths);
971     if(vf->serialnos)_ogg_free(vf->serialnos);
972     if(vf->offsets)_ogg_free(vf->offsets);
973     ogg_sync_clear(&vf->oy);
974     if(vf->datasource && vf->callbacks.close_func)
975       (vf->callbacks.close_func)(vf->datasource);
976     memset(vf,0,sizeof(*vf));
977   }
978 #ifdef DEBUG_LEAKS
979   _VDBG_dump();
980 #endif
981   return(0);
982 }
983 
984 /* inspects the OggVorbis file and finds/documents all the logical
985    bitstreams contained in it.  Tries to be tolerant of logical
986    bitstream sections that are truncated/woogie.
987 
988    return: -1) error
989             0) OK
990 */
991 
ov_open_callbacks(void * f,OggVorbis_File * vf,const char * initial,long ibytes,ov_callbacks callbacks)992 int ov_open_callbacks(void *f,OggVorbis_File *vf,
993     const char *initial,long ibytes,ov_callbacks callbacks){
994   int ret=_ov_open1(f,vf,initial,ibytes,callbacks);
995   if(ret)return ret;
996   return _ov_open2(vf);
997 }
998 
ov_open(FILE * f,OggVorbis_File * vf,const char * initial,long ibytes)999 int ov_open(FILE *f,OggVorbis_File *vf,const char *initial,long ibytes){
1000   ov_callbacks callbacks = {
1001     (size_t (*)(void *, size_t, size_t, void *))  fread,
1002     (int (*)(void *, ogg_int64_t, int))              _fseek64_wrap,
1003     (int (*)(void *))                             fclose,
1004     (long (*)(void *))                            ftell
1005   };
1006 
1007   return ov_open_callbacks((void *)f, vf, initial, ibytes, callbacks);
1008 }
1009 
ov_fopen(const char * path,OggVorbis_File * vf)1010 int ov_fopen(const char *path,OggVorbis_File *vf){
1011   int ret;
1012   FILE *f = fopen(path,"rb");
1013   if(!f) return -1;
1014 
1015   ret = ov_open(f,vf,NULL,0);
1016   if(ret) fclose(f);
1017   return ret;
1018 }
1019 
1020 
1021 /* cheap hack for game usage where downsampling is desirable; there's
1022    no need for SRC as we can just do it cheaply in libvorbis. */
1023 
ov_halfrate(OggVorbis_File * vf,int flag)1024 int ov_halfrate(OggVorbis_File *vf,int flag){
1025   int i;
1026   if(vf->vi==NULL)return OV_EINVAL;
1027   if(vf->ready_state>STREAMSET){
1028     /* clear out stream state; dumping the decode machine is needed to
1029        reinit the MDCT lookups. */
1030     vorbis_dsp_clear(&vf->vd);
1031     vorbis_block_clear(&vf->vb);
1032     vf->ready_state=STREAMSET;
1033     if(vf->pcm_offset>=0){
1034       ogg_int64_t pos=vf->pcm_offset;
1035       vf->pcm_offset=-1; /* make sure the pos is dumped if unseekable */
1036       ov_pcm_seek(vf,pos);
1037     }
1038   }
1039 
1040   for(i=0;i<vf->links;i++){
1041     if(vorbis_synthesis_halfrate(vf->vi+i,flag)){
1042       if(flag) ov_halfrate(vf,0);
1043       return OV_EINVAL;
1044     }
1045   }
1046   return 0;
1047 }
1048 
ov_halfrate_p(OggVorbis_File * vf)1049 int ov_halfrate_p(OggVorbis_File *vf){
1050   if(vf->vi==NULL)return OV_EINVAL;
1051   return vorbis_synthesis_halfrate_p(vf->vi);
1052 }
1053 
1054 /* Only partially open the vorbis file; test for Vorbisness, and load
1055    the headers for the first chain.  Do not seek (although test for
1056    seekability).  Use ov_test_open to finish opening the file, else
1057    ov_clear to close/free it. Same return codes as open.
1058 
1059    Note that vorbisfile does _not_ take ownership of the file if the
1060    call fails; the calling applicaiton is responsible for closing the file
1061    if this call returns an error. */
1062 
ov_test_callbacks(void * f,OggVorbis_File * vf,const char * initial,long ibytes,ov_callbacks callbacks)1063 int ov_test_callbacks(void *f,OggVorbis_File *vf,
1064     const char *initial,long ibytes,ov_callbacks callbacks)
1065 {
1066   return _ov_open1(f,vf,initial,ibytes,callbacks);
1067 }
1068 
ov_test(FILE * f,OggVorbis_File * vf,const char * initial,long ibytes)1069 int ov_test(FILE *f,OggVorbis_File *vf,const char *initial,long ibytes){
1070   ov_callbacks callbacks = {
1071     (size_t (*)(void *, size_t, size_t, void *))  fread,
1072     (int (*)(void *, ogg_int64_t, int))              _fseek64_wrap,
1073     (int (*)(void *))                             fclose,
1074     (long (*)(void *))                            ftell
1075   };
1076 
1077   return ov_test_callbacks((void *)f, vf, initial, ibytes, callbacks);
1078 }
1079 
ov_test_open(OggVorbis_File * vf)1080 int ov_test_open(OggVorbis_File *vf){
1081   if(vf->ready_state!=PARTOPEN)return(OV_EINVAL);
1082   return _ov_open2(vf);
1083 }
1084 
1085 /* How many logical bitstreams in this physical bitstream? */
ov_streams(OggVorbis_File * vf)1086 long ov_streams(OggVorbis_File *vf){
1087   return vf->links;
1088 }
1089 
1090 /* Is the FILE * associated with vf seekable? */
ov_seekable(OggVorbis_File * vf)1091 long ov_seekable(OggVorbis_File *vf){
1092   return vf->seekable;
1093 }
1094 
1095 /* returns the bitrate for a given logical bitstream or the entire
1096    physical bitstream.  If the file is open for random access, it will
1097    find the *actual* average bitrate.  If the file is streaming, it
1098    returns the nominal bitrate (if set) else the average of the
1099    upper/lower bounds (if set) else -1 (unset).
1100 
1101    If you want the actual bitrate field settings, get them from the
1102    vorbis_info structs */
1103 
ov_bitrate(OggVorbis_File * vf,int i)1104 long ov_bitrate(OggVorbis_File *vf,int i){
1105   if(vf->ready_state<OPENED)return(OV_EINVAL);
1106   if(i>=vf->links)return(OV_EINVAL);
1107   if(!vf->seekable && i!=0)return(ov_bitrate(vf,0));
1108   if(i<0){
1109     ogg_int64_t bits=0;
1110     int i;
1111     float br;
1112     for(i=0;i<vf->links;i++)
1113       bits+=(vf->offsets[i+1]-vf->dataoffsets[i])*8;
1114     /* This once read: return(rint(bits/ov_time_total(vf,-1)));
1115      * gcc 3.x on x86 miscompiled this at optimisation level 2 and above,
1116      * so this is slightly transformed to make it work.
1117      */
1118     br = bits/ov_time_total(vf,-1);
1119     return(rint(br));
1120   }else{
1121     if(vf->seekable){
1122       /* return the actual bitrate */
1123       return(rint((vf->offsets[i+1]-vf->dataoffsets[i])*8/ov_time_total(vf,i)));
1124     }else{
1125       /* return nominal if set */
1126       if(vf->vi[i].bitrate_nominal>0){
1127         return vf->vi[i].bitrate_nominal;
1128       }else{
1129         if(vf->vi[i].bitrate_upper>0){
1130           if(vf->vi[i].bitrate_lower>0){
1131             return (vf->vi[i].bitrate_upper+vf->vi[i].bitrate_lower)/2;
1132           }else{
1133             return vf->vi[i].bitrate_upper;
1134           }
1135         }
1136         return(OV_FALSE);
1137       }
1138     }
1139   }
1140 }
1141 
1142 /* returns the actual bitrate since last call.  returns -1 if no
1143    additional data to offer since last call (or at beginning of stream),
1144    EINVAL if stream is only partially open
1145 */
ov_bitrate_instant(OggVorbis_File * vf)1146 long ov_bitrate_instant(OggVorbis_File *vf){
1147   int link=(vf->seekable?vf->current_link:0);
1148   long ret;
1149   if(vf->ready_state<OPENED)return(OV_EINVAL);
1150   if(vf->samptrack==0)return(OV_FALSE);
1151   ret=vf->bittrack/vf->samptrack*vf->vi[link].rate+.5;
1152   vf->bittrack=0.f;
1153   vf->samptrack=0.f;
1154   return(ret);
1155 }
1156 
1157 /* Guess */
ov_serialnumber(OggVorbis_File * vf,int i)1158 long ov_serialnumber(OggVorbis_File *vf,int i){
1159   if(i>=vf->links)return(ov_serialnumber(vf,vf->links-1));
1160   if(!vf->seekable && i>=0)return(ov_serialnumber(vf,-1));
1161   if(i<0){
1162     return(vf->current_serialno);
1163   }else{
1164     return(vf->serialnos[i]);
1165   }
1166 }
1167 
1168 /* returns: total raw (compressed) length of content if i==-1
1169             raw (compressed) length of that logical bitstream for i==0 to n
1170             OV_EINVAL if the stream is not seekable (we can't know the length)
1171             or if stream is only partially open
1172 */
ov_raw_total(OggVorbis_File * vf,int i)1173 ogg_int64_t ov_raw_total(OggVorbis_File *vf,int i){
1174   if(vf->ready_state<OPENED)return(OV_EINVAL);
1175   if(!vf->seekable || i>=vf->links)return(OV_EINVAL);
1176   if(i<0){
1177     ogg_int64_t acc=0;
1178     int i;
1179     for(i=0;i<vf->links;i++)
1180       acc+=ov_raw_total(vf,i);
1181     return(acc);
1182   }else{
1183     return(vf->offsets[i+1]-vf->offsets[i]);
1184   }
1185 }
1186 
1187 /* returns: total PCM length (samples) of content if i==-1 PCM length
1188             (samples) of that logical bitstream for i==0 to n
1189             OV_EINVAL if the stream is not seekable (we can't know the
1190             length) or only partially open
1191 */
ov_pcm_total(OggVorbis_File * vf,int i)1192 ogg_int64_t ov_pcm_total(OggVorbis_File *vf,int i){
1193   if(vf->ready_state<OPENED)return(OV_EINVAL);
1194   if(!vf->seekable || i>=vf->links)return(OV_EINVAL);
1195   if(i<0){
1196     ogg_int64_t acc=0;
1197     int i;
1198     for(i=0;i<vf->links;i++)
1199       acc+=ov_pcm_total(vf,i);
1200     return(acc);
1201   }else{
1202     return(vf->pcmlengths[i*2+1]);
1203   }
1204 }
1205 
1206 /* returns: total seconds of content if i==-1
1207             seconds in that logical bitstream for i==0 to n
1208             OV_EINVAL if the stream is not seekable (we can't know the
1209             length) or only partially open
1210 */
ov_time_total(OggVorbis_File * vf,int i)1211 double ov_time_total(OggVorbis_File *vf,int i){
1212   if(vf->ready_state<OPENED)return(OV_EINVAL);
1213   if(!vf->seekable || i>=vf->links)return(OV_EINVAL);
1214   if(i<0){
1215     double acc=0;
1216     int i;
1217     for(i=0;i<vf->links;i++)
1218       acc+=ov_time_total(vf,i);
1219     return(acc);
1220   }else{
1221     return((double)(vf->pcmlengths[i*2+1])/vf->vi[i].rate);
1222   }
1223 }
1224 
1225 /* seek to an offset relative to the *compressed* data. This also
1226    scans packets to update the PCM cursor. It will cross a logical
1227    bitstream boundary, but only if it can't get any packets out of the
1228    tail of the bitstream we seek to (so no surprises).
1229 
1230    returns zero on success, nonzero on failure */
1231 
ov_raw_seek(OggVorbis_File * vf,ogg_int64_t pos)1232 int ov_raw_seek(OggVorbis_File *vf,ogg_int64_t pos){
1233   ogg_stream_state work_os;
1234   int ret;
1235 
1236   if(vf->ready_state<OPENED)return(OV_EINVAL);
1237   if(!vf->seekable)
1238     return(OV_ENOSEEK); /* don't dump machine if we can't seek */
1239 
1240   if(pos<0 || pos>vf->end)return(OV_EINVAL);
1241 
1242   /* is the seek position outside our current link [if any]? */
1243   if(vf->ready_state>=STREAMSET){
1244     if(pos<vf->offsets[vf->current_link] || pos>=vf->offsets[vf->current_link+1])
1245       _decode_clear(vf); /* clear out stream state */
1246   }
1247 
1248   /* don't yet clear out decoding machine (if it's initialized), in
1249      the case we're in the same link.  Restart the decode lapping, and
1250      let _fetch_and_process_packet deal with a potential bitstream
1251      boundary */
1252   vf->pcm_offset=-1;
1253   ogg_stream_reset_serialno(&vf->os,
1254                             vf->current_serialno); /* must set serialno */
1255   vorbis_synthesis_restart(&vf->vd);
1256 
1257   ret=_seek_helper(vf,pos);
1258   if(ret)goto seek_error;
1259 
1260   /* we need to make sure the pcm_offset is set, but we don't want to
1261      advance the raw cursor past good packets just to get to the first
1262      with a granulepos.  That's not equivalent behavior to beginning
1263      decoding as immediately after the seek position as possible.
1264 
1265      So, a hack.  We use two stream states; a local scratch state and
1266      the shared vf->os stream state.  We use the local state to
1267      scan, and the shared state as a buffer for later decode.
1268 
1269      Unfortuantely, on the last page we still advance to last packet
1270      because the granulepos on the last page is not necessarily on a
1271      packet boundary, and we need to make sure the granpos is
1272      correct.
1273   */
1274 
1275   {
1276     ogg_page og;
1277     ogg_packet op;
1278     int lastblock=0;
1279     int accblock=0;
1280     int thisblock=0;
1281     int lastflag=0;
1282     int firstflag=0;
1283     ogg_int64_t pagepos=-1;
1284 
1285     ogg_stream_init(&work_os,vf->current_serialno); /* get the memory ready */
1286     ogg_stream_reset(&work_os); /* eliminate the spurious OV_HOLE
1287                                    return from not necessarily
1288                                    starting from the beginning */
1289 
1290     while(1){
1291       if(vf->ready_state>=STREAMSET){
1292         /* snarf/scan a packet if we can */
1293         int result=ogg_stream_packetout(&work_os,&op);
1294 
1295         if(result>0){
1296 
1297           if(vf->vi[vf->current_link].codec_setup){
1298             thisblock=vorbis_packet_blocksize(vf->vi+vf->current_link,&op);
1299             if(thisblock<0){
1300               ogg_stream_packetout(&vf->os,NULL);
1301               thisblock=0;
1302             }else{
1303 
1304               /* We can't get a guaranteed correct pcm position out of the
1305                  last page in a stream because it might have a 'short'
1306                  granpos, which can only be detected in the presence of a
1307                  preceding page.  However, if the last page is also the first
1308                  page, the granpos rules of a first page take precedence.  Not
1309                  only that, but for first==last, the EOS page must be treated
1310                  as if its a normal first page for the stream to open/play. */
1311               if(lastflag && !firstflag)
1312                 ogg_stream_packetout(&vf->os,NULL);
1313               else
1314                 if(lastblock)accblock+=(lastblock+thisblock)>>2;
1315             }
1316 
1317             if(op.granulepos!=-1){
1318               int i,link=vf->current_link;
1319               ogg_int64_t granulepos=op.granulepos-vf->pcmlengths[link*2];
1320               if(granulepos<0)granulepos=0;
1321 
1322               for(i=0;i<link;i++)
1323                 granulepos+=vf->pcmlengths[i*2+1];
1324               vf->pcm_offset=granulepos-accblock;
1325               if(vf->pcm_offset<0)vf->pcm_offset=0;
1326               break;
1327             }
1328             lastblock=thisblock;
1329             continue;
1330           }else
1331             ogg_stream_packetout(&vf->os,NULL);
1332         }
1333       }
1334 
1335       if(!lastblock){
1336         pagepos=_get_next_page(vf,&og,-1);
1337         if(pagepos<0){
1338           vf->pcm_offset=ov_pcm_total(vf,-1);
1339           break;
1340         }
1341       }else{
1342         /* huh?  Bogus stream with packets but no granulepos */
1343         vf->pcm_offset=-1;
1344         break;
1345       }
1346 
1347       /* has our decoding just traversed a bitstream boundary? */
1348       if(vf->ready_state>=STREAMSET){
1349         if(vf->current_serialno!=ogg_page_serialno(&og)){
1350 
1351           /* two possibilities:
1352              1) our decoding just traversed a bitstream boundary
1353              2) another stream is multiplexed into this logical section? */
1354 
1355           if(ogg_page_bos(&og)){
1356             /* we traversed */
1357             _decode_clear(vf); /* clear out stream state */
1358             ogg_stream_clear(&work_os);
1359           } /* else, do nothing; next loop will scoop another page */
1360         }
1361       }
1362 
1363       if(vf->ready_state<STREAMSET){
1364         int link;
1365         long serialno = ogg_page_serialno(&og);
1366 
1367         for(link=0;link<vf->links;link++)
1368           if(vf->serialnos[link]==serialno)break;
1369 
1370         if(link==vf->links) continue; /* not the desired Vorbis
1371                                          bitstream section; keep
1372                                          trying */
1373         vf->current_link=link;
1374         vf->current_serialno=serialno;
1375         ogg_stream_reset_serialno(&vf->os,serialno);
1376         ogg_stream_reset_serialno(&work_os,serialno);
1377         vf->ready_state=STREAMSET;
1378         firstflag=(pagepos<=vf->dataoffsets[link]);
1379       }
1380 
1381       ogg_stream_pagein(&vf->os,&og);
1382       ogg_stream_pagein(&work_os,&og);
1383       lastflag=ogg_page_eos(&og);
1384 
1385     }
1386   }
1387 
1388   ogg_stream_clear(&work_os);
1389   vf->bittrack=0.f;
1390   vf->samptrack=0.f;
1391   return(0);
1392 
1393  seek_error:
1394   /* dump the machine so we're in a known state */
1395   vf->pcm_offset=-1;
1396   ogg_stream_clear(&work_os);
1397   _decode_clear(vf);
1398   return OV_EBADLINK;
1399 }
1400 
1401 /* Page granularity seek (faster than sample granularity because we
1402    don't do the last bit of decode to find a specific sample).
1403 
1404    Seek to the last [granule marked] page preceding the specified pos
1405    location, such that decoding past the returned point will quickly
1406    arrive at the requested position. */
ov_pcm_seek_page(OggVorbis_File * vf,ogg_int64_t pos)1407 int ov_pcm_seek_page(OggVorbis_File *vf,ogg_int64_t pos){
1408   int link=-1;
1409   ogg_int64_t result=0;
1410   ogg_int64_t total=ov_pcm_total(vf,-1);
1411 
1412   if(vf->ready_state<OPENED)return(OV_EINVAL);
1413   if(!vf->seekable)return(OV_ENOSEEK);
1414 
1415   if(pos<0 || pos>total)return(OV_EINVAL);
1416 
1417   /* which bitstream section does this pcm offset occur in? */
1418   for(link=vf->links-1;link>=0;link--){
1419     total-=vf->pcmlengths[link*2+1];
1420     if(pos>=total)break;
1421   }
1422 
1423   /* Search within the logical bitstream for the page with the highest
1424      pcm_pos preceding pos.  If we're looking for a position on the
1425      first page, bisection will halt without finding our position as
1426      it's before the first explicit granulepos fencepost. That case is
1427      handled separately below.
1428 
1429      There is a danger here; missing pages or incorrect frame number
1430      information in the bitstream could make our task impossible.
1431      Account for that (it would be an error condition) */
1432 
1433   /* new search algorithm originally by HB (Nicholas Vinen) */
1434 
1435   {
1436     ogg_int64_t end=vf->offsets[link+1];
1437     ogg_int64_t begin=vf->dataoffsets[link];
1438     ogg_int64_t begintime = vf->pcmlengths[link*2];
1439     ogg_int64_t endtime = vf->pcmlengths[link*2+1]+begintime;
1440     ogg_int64_t target=pos-total+begintime;
1441     ogg_int64_t best=-1;
1442     int         got_page=0;
1443 
1444     ogg_page og;
1445 
1446     /* if we have only one page, there will be no bisection.  Grab the page here */
1447     if(begin==end){
1448       result=_seek_helper(vf,begin);
1449       if(result) goto seek_error;
1450 
1451       result=_get_next_page(vf,&og,1);
1452       if(result<0) goto seek_error;
1453 
1454       got_page=1;
1455     }
1456 
1457     /* bisection loop */
1458     while(begin<end){
1459       ogg_int64_t bisect;
1460 
1461       if(end-begin<CHUNKSIZE){
1462         bisect=begin;
1463       }else{
1464         /* take a (pretty decent) guess. */
1465         bisect=begin +
1466           (ogg_int64_t)((double)(target-begintime)*(end-begin)/(endtime-begintime))
1467           - CHUNKSIZE;
1468         if(bisect<begin+CHUNKSIZE)
1469           bisect=begin;
1470       }
1471 
1472       result=_seek_helper(vf,bisect);
1473       if(result) goto seek_error;
1474 
1475       /* read loop within the bisection loop */
1476       while(begin<end){
1477         result=_get_next_page(vf,&og,end-vf->offset);
1478         if(result==OV_EREAD) goto seek_error;
1479         if(result<0){
1480           /* there is no next page! */
1481           if(bisect<=begin+1)
1482               /* No bisection left to perform.  We've either found the
1483                  best candidate already or failed. Exit loop. */
1484             end=begin;
1485           else{
1486             /* We tried to load a fraction of the last page; back up a
1487                bit and try to get the whole last page */
1488             if(bisect==0) goto seek_error;
1489             bisect-=CHUNKSIZE;
1490 
1491             /* don't repeat/loop on a read we've already performed */
1492             if(bisect<=begin)bisect=begin+1;
1493 
1494             /* seek and cntinue bisection */
1495             result=_seek_helper(vf,bisect);
1496             if(result) goto seek_error;
1497           }
1498         }else{
1499           ogg_int64_t granulepos;
1500           got_page=1;
1501 
1502           /* got a page. analyze it */
1503           /* only consider pages from primary vorbis stream */
1504           if(ogg_page_serialno(&og)!=vf->serialnos[link])
1505             continue;
1506 
1507           /* only consider pages with the granulepos set */
1508           granulepos=ogg_page_granulepos(&og);
1509           if(granulepos==-1)continue;
1510 
1511           if(granulepos<target){
1512             /* this page is a successful candidate! Set state */
1513 
1514             best=result;  /* raw offset of packet with granulepos */
1515             begin=vf->offset; /* raw offset of next page */
1516             begintime=granulepos;
1517 
1518             /* if we're before our target but within a short distance,
1519                don't bisect; read forward */
1520             if(target-begintime>44100)break;
1521 
1522             bisect=begin; /* *not* begin + 1 as above */
1523           }else{
1524 
1525             /* This is one of our pages, but the granpos is
1526                post-target; it is not a bisection return
1527                candidate. (The only way we'd use it is if it's the
1528                first page in the stream; we handle that case later
1529                outside the bisection) */
1530             if(bisect<=begin+1){
1531               /* No bisection left to perform.  We've either found the
1532                  best candidate already or failed. Exit loop. */
1533               end=begin;
1534             }else{
1535               if(end==vf->offset){
1536                 /* bisection read to the end; use the known page
1537                    boundary (result) to update bisection, back up a
1538                    little bit, and try again */
1539                 end=result;
1540                 bisect-=CHUNKSIZE;
1541                 if(bisect<=begin)bisect=begin+1;
1542                 result=_seek_helper(vf,bisect);
1543                 if(result) goto seek_error;
1544               }else{
1545                 /* Normal bisection */
1546                 end=bisect;
1547                 endtime=granulepos;
1548                 break;
1549               }
1550             }
1551           }
1552         }
1553       }
1554     }
1555 
1556     /* Out of bisection: did it 'fail?' */
1557     if(best == -1){
1558 
1559       /* Check the 'looking for data in first page' special case;
1560          bisection would 'fail' because our search target was before the
1561          first PCM granule position fencepost. */
1562 
1563       if(got_page &&
1564          begin == vf->dataoffsets[link] &&
1565          ogg_page_serialno(&og)==vf->serialnos[link]){
1566 
1567         /* Yes, this is the beginning-of-stream case. We already have
1568            our page, right at the beginning of PCM data.  Set state
1569            and return. */
1570 
1571         vf->pcm_offset=total;
1572 
1573         if(link!=vf->current_link){
1574           /* Different link; dump entire decode machine */
1575           _decode_clear(vf);
1576 
1577           vf->current_link=link;
1578           vf->current_serialno=vf->serialnos[link];
1579           vf->ready_state=STREAMSET;
1580 
1581         }else{
1582           vorbis_synthesis_restart(&vf->vd);
1583         }
1584 
1585         ogg_stream_reset_serialno(&vf->os,vf->current_serialno);
1586         ogg_stream_pagein(&vf->os,&og);
1587 
1588       }else
1589         goto seek_error;
1590 
1591     }else{
1592 
1593       /* Bisection found our page. seek to it, update pcm offset. Easier case than
1594          raw_seek, don't keep packets preceding granulepos. */
1595 
1596       ogg_page og;
1597       ogg_packet op;
1598 
1599       /* seek */
1600       result=_seek_helper(vf,best);
1601       vf->pcm_offset=-1;
1602       if(result) goto seek_error;
1603       result=_get_next_page(vf,&og,-1);
1604       if(result<0) goto seek_error;
1605 
1606       if(link!=vf->current_link){
1607         /* Different link; dump entire decode machine */
1608         _decode_clear(vf);
1609 
1610         vf->current_link=link;
1611         vf->current_serialno=vf->serialnos[link];
1612         vf->ready_state=STREAMSET;
1613 
1614       }else{
1615         vorbis_synthesis_restart(&vf->vd);
1616       }
1617 
1618       ogg_stream_reset_serialno(&vf->os,vf->current_serialno);
1619       ogg_stream_pagein(&vf->os,&og);
1620 
1621       /* pull out all but last packet; the one with granulepos */
1622       while(1){
1623         result=ogg_stream_packetpeek(&vf->os,&op);
1624         if(result==0){
1625           /* No packet returned; we exited the bisection with 'best'
1626              pointing to a page with a granule position, so the packet
1627              finishing this page ('best') originated on a preceding
1628              page. Keep fetching previous pages until we get one with
1629              a granulepos or without the 'continued' flag set.  Then
1630              just use raw_seek for simplicity. */
1631           /* Do not rewind past the beginning of link data; if we do,
1632              it's either a bug or a broken stream */
1633           result=best;
1634           while(result>vf->dataoffsets[link]){
1635             result=_get_prev_page(vf,result,&og);
1636             if(result<0) goto seek_error;
1637             if(ogg_page_serialno(&og)==vf->current_serialno &&
1638                (ogg_page_granulepos(&og)>-1 ||
1639                 !ogg_page_continued(&og))){
1640               return ov_raw_seek(vf,result);
1641             }
1642           }
1643         }
1644         if(result<0){
1645           result = OV_EBADPACKET;
1646           goto seek_error;
1647         }
1648         if(op.granulepos!=-1){
1649           vf->pcm_offset=op.granulepos-vf->pcmlengths[vf->current_link*2];
1650           if(vf->pcm_offset<0)vf->pcm_offset=0;
1651           vf->pcm_offset+=total;
1652           break;
1653         }else
1654           result=ogg_stream_packetout(&vf->os,NULL);
1655       }
1656     }
1657   }
1658 
1659   /* verify result */
1660   if(vf->pcm_offset>pos || pos>ov_pcm_total(vf,-1)){
1661     result=OV_EFAULT;
1662     goto seek_error;
1663   }
1664   vf->bittrack=0.f;
1665   vf->samptrack=0.f;
1666   return(0);
1667 
1668  seek_error:
1669   /* dump machine so we're in a known state */
1670   vf->pcm_offset=-1;
1671   _decode_clear(vf);
1672   return (int)result;
1673 }
1674 
1675 /* seek to a sample offset relative to the decompressed pcm stream
1676    returns zero on success, nonzero on failure */
1677 
ov_pcm_seek(OggVorbis_File * vf,ogg_int64_t pos)1678 int ov_pcm_seek(OggVorbis_File *vf,ogg_int64_t pos){
1679   int thisblock,lastblock=0;
1680   int ret=ov_pcm_seek_page(vf,pos);
1681   if(ret<0)return(ret);
1682   if((ret=_make_decode_ready(vf)))return ret;
1683 
1684   /* discard leading packets we don't need for the lapping of the
1685      position we want; don't decode them */
1686 
1687   while(1){
1688     ogg_packet op;
1689     ogg_page og;
1690 
1691     int ret=ogg_stream_packetpeek(&vf->os,&op);
1692     if(ret>0){
1693       thisblock=vorbis_packet_blocksize(vf->vi+vf->current_link,&op);
1694       if(thisblock<0){
1695         ogg_stream_packetout(&vf->os,NULL);
1696         continue; /* non audio packet */
1697       }
1698       if(lastblock)vf->pcm_offset+=(lastblock+thisblock)>>2;
1699 
1700       if(vf->pcm_offset+((thisblock+
1701                           vorbis_info_blocksize(vf->vi,1))>>2)>=pos)break;
1702 
1703       /* remove the packet from packet queue and track its granulepos */
1704       ogg_stream_packetout(&vf->os,NULL);
1705       vorbis_synthesis_trackonly(&vf->vb,&op);  /* set up a vb with
1706                                                    only tracking, no
1707                                                    pcm_decode */
1708       vorbis_synthesis_blockin(&vf->vd,&vf->vb);
1709 
1710       /* end of logical stream case is hard, especially with exact
1711          length positioning. */
1712 
1713       if(op.granulepos>-1){
1714         int i;
1715         /* always believe the stream markers */
1716         vf->pcm_offset=op.granulepos-vf->pcmlengths[vf->current_link*2];
1717         if(vf->pcm_offset<0)vf->pcm_offset=0;
1718         for(i=0;i<vf->current_link;i++)
1719           vf->pcm_offset+=vf->pcmlengths[i*2+1];
1720       }
1721 
1722       lastblock=thisblock;
1723 
1724     }else{
1725       if(ret<0 && ret!=OV_HOLE)break;
1726 
1727       /* suck in a new page */
1728       if(_get_next_page(vf,&og,-1)<0)break;
1729       if(ogg_page_bos(&og))_decode_clear(vf);
1730 
1731       if(vf->ready_state<STREAMSET){
1732         long serialno=ogg_page_serialno(&og);
1733         int link;
1734 
1735         for(link=0;link<vf->links;link++)
1736           if(vf->serialnos[link]==serialno)break;
1737         if(link==vf->links) continue;
1738         vf->current_link=link;
1739 
1740         vf->ready_state=STREAMSET;
1741         vf->current_serialno=ogg_page_serialno(&og);
1742         ogg_stream_reset_serialno(&vf->os,serialno);
1743         ret=_make_decode_ready(vf);
1744         if(ret)return ret;
1745         lastblock=0;
1746       }
1747 
1748       ogg_stream_pagein(&vf->os,&og);
1749     }
1750   }
1751 
1752   vf->bittrack=0.f;
1753   vf->samptrack=0.f;
1754   /* discard samples until we reach the desired position. Crossing a
1755      logical bitstream boundary with abandon is OK. */
1756   {
1757     /* note that halfrate could be set differently in each link, but
1758        vorbisfile encoforces all links are set or unset */
1759     int hs=vorbis_synthesis_halfrate_p(vf->vi);
1760     while(vf->pcm_offset<((pos>>hs)<<hs)){
1761       ogg_int64_t target=(pos-vf->pcm_offset)>>hs;
1762       long samples=vorbis_synthesis_pcmout(&vf->vd,NULL);
1763 
1764       if(samples>target)samples=target;
1765       vorbis_synthesis_read(&vf->vd,samples);
1766       vf->pcm_offset+=samples<<hs;
1767 
1768       if(samples<target)
1769         if(_fetch_and_process_packet(vf,NULL,1,1)<=0)
1770           vf->pcm_offset=ov_pcm_total(vf,-1); /* eof */
1771     }
1772   }
1773   return 0;
1774 }
1775 
1776 /* seek to a playback time relative to the decompressed pcm stream
1777    returns zero on success, nonzero on failure */
ov_time_seek(OggVorbis_File * vf,double seconds)1778 int ov_time_seek(OggVorbis_File *vf,double seconds){
1779   /* translate time to PCM position and call ov_pcm_seek */
1780 
1781   int link=-1;
1782   ogg_int64_t pcm_total=0;
1783   double time_total=0.;
1784 
1785   if(vf->ready_state<OPENED)return(OV_EINVAL);
1786   if(!vf->seekable)return(OV_ENOSEEK);
1787   if(seconds<0)return(OV_EINVAL);
1788 
1789   /* which bitstream section does this time offset occur in? */
1790   for(link=0;link<vf->links;link++){
1791     double addsec = ov_time_total(vf,link);
1792     if(seconds<time_total+addsec)break;
1793     time_total+=addsec;
1794     pcm_total+=vf->pcmlengths[link*2+1];
1795   }
1796 
1797   if(link==vf->links)return(OV_EINVAL);
1798 
1799   /* enough information to convert time offset to pcm offset */
1800   {
1801     ogg_int64_t target=pcm_total+(seconds-time_total)*vf->vi[link].rate;
1802     return(ov_pcm_seek(vf,target));
1803   }
1804 }
1805 
1806 /* page-granularity version of ov_time_seek
1807    returns zero on success, nonzero on failure */
ov_time_seek_page(OggVorbis_File * vf,double seconds)1808 int ov_time_seek_page(OggVorbis_File *vf,double seconds){
1809   /* translate time to PCM position and call ov_pcm_seek */
1810 
1811   int link=-1;
1812   ogg_int64_t pcm_total=0;
1813   double time_total=0.;
1814 
1815   if(vf->ready_state<OPENED)return(OV_EINVAL);
1816   if(!vf->seekable)return(OV_ENOSEEK);
1817   if(seconds<0)return(OV_EINVAL);
1818 
1819   /* which bitstream section does this time offset occur in? */
1820   for(link=0;link<vf->links;link++){
1821     double addsec = ov_time_total(vf,link);
1822     if(seconds<time_total+addsec)break;
1823     time_total+=addsec;
1824     pcm_total+=vf->pcmlengths[link*2+1];
1825   }
1826 
1827   if(link==vf->links)return(OV_EINVAL);
1828 
1829   /* enough information to convert time offset to pcm offset */
1830   {
1831     ogg_int64_t target=pcm_total+(seconds-time_total)*vf->vi[link].rate;
1832     return(ov_pcm_seek_page(vf,target));
1833   }
1834 }
1835 
1836 /* tell the current stream offset cursor.  Note that seek followed by
1837    tell will likely not give the set offset due to caching */
ov_raw_tell(OggVorbis_File * vf)1838 ogg_int64_t ov_raw_tell(OggVorbis_File *vf){
1839   if(vf->ready_state<OPENED)return(OV_EINVAL);
1840   return(vf->offset);
1841 }
1842 
1843 /* return PCM offset (sample) of next PCM sample to be read */
ov_pcm_tell(OggVorbis_File * vf)1844 ogg_int64_t ov_pcm_tell(OggVorbis_File *vf){
1845   if(vf->ready_state<OPENED)return(OV_EINVAL);
1846   return(vf->pcm_offset);
1847 }
1848 
1849 /* return time offset (seconds) of next PCM sample to be read */
ov_time_tell(OggVorbis_File * vf)1850 double ov_time_tell(OggVorbis_File *vf){
1851   int link=0;
1852   ogg_int64_t pcm_total=0;
1853   double time_total=0.f;
1854 
1855   if(vf->ready_state<OPENED)return(OV_EINVAL);
1856   if(vf->seekable){
1857     pcm_total=ov_pcm_total(vf,-1);
1858     time_total=ov_time_total(vf,-1);
1859 
1860     /* which bitstream section does this time offset occur in? */
1861     for(link=vf->links-1;link>=0;link--){
1862       pcm_total-=vf->pcmlengths[link*2+1];
1863       time_total-=ov_time_total(vf,link);
1864       if(vf->pcm_offset>=pcm_total)break;
1865     }
1866   }
1867 
1868   return((double)time_total+(double)(vf->pcm_offset-pcm_total)/vf->vi[link].rate);
1869 }
1870 
1871 /*  link:   -1) return the vorbis_info struct for the bitstream section
1872                 currently being decoded
1873            0-n) to request information for a specific bitstream section
1874 
1875     In the case of a non-seekable bitstream, any call returns the
1876     current bitstream.  NULL in the case that the machine is not
1877     initialized */
1878 
ov_info(OggVorbis_File * vf,int link)1879 vorbis_info *ov_info(OggVorbis_File *vf,int link){
1880   if(vf->seekable){
1881     if(link<0)
1882       if(vf->ready_state>=STREAMSET)
1883         return vf->vi+vf->current_link;
1884       else
1885       return vf->vi;
1886     else
1887       if(link>=vf->links)
1888         return NULL;
1889       else
1890         return vf->vi+link;
1891   }else{
1892     return vf->vi;
1893   }
1894 }
1895 
1896 /* grr, strong typing, grr, no templates/inheritence, grr */
ov_comment(OggVorbis_File * vf,int link)1897 vorbis_comment *ov_comment(OggVorbis_File *vf,int link){
1898   if(vf->seekable){
1899     if(link<0)
1900       if(vf->ready_state>=STREAMSET)
1901         return vf->vc+vf->current_link;
1902       else
1903         return vf->vc;
1904     else
1905       if(link>=vf->links)
1906         return NULL;
1907       else
1908         return vf->vc+link;
1909   }else{
1910     return vf->vc;
1911   }
1912 }
1913 
host_is_big_endian()1914 static int host_is_big_endian() {
1915   ogg_int32_t pattern = 0xfeedface; /* deadbeef */
1916   unsigned char *bytewise = (unsigned char *)&pattern;
1917   if (bytewise[0] == 0xfe) return 1;
1918   return 0;
1919 }
1920 
1921 /* up to this point, everything could more or less hide the multiple
1922    logical bitstream nature of chaining from the toplevel application
1923    if the toplevel application didn't particularly care.  However, at
1924    the point that we actually read audio back, the multiple-section
1925    nature must surface: Multiple bitstream sections do not necessarily
1926    have to have the same number of channels or sampling rate.
1927 
1928    ov_read returns the sequential logical bitstream number currently
1929    being decoded along with the PCM data in order that the toplevel
1930    application can take action on channel/sample rate changes.  This
1931    number will be incremented even for streamed (non-seekable) streams
1932    (for seekable streams, it represents the actual logical bitstream
1933    index within the physical bitstream.  Note that the accessor
1934    functions above are aware of this dichotomy).
1935 
1936    ov_read_filter is exactly the same as ov_read except that it processes
1937    the decoded audio data through a filter before packing it into the
1938    requested format. This gives greater accuracy than applying a filter
1939    after the audio has been converted into integral PCM.
1940 
1941    input values: buffer) a buffer to hold packed PCM data for return
1942                  length) the byte length requested to be placed into buffer
1943                  bigendianp) should the data be packed LSB first (0) or
1944                              MSB first (1)
1945                  word) word size for output.  currently 1 (byte) or
1946                        2 (16 bit short)
1947 
1948    return values: <0) error/hole in data (OV_HOLE), partial open (OV_EINVAL)
1949                    0) EOF
1950                    n) number of bytes of PCM actually returned.  The
1951                    below works on a packet-by-packet basis, so the
1952                    return length is not related to the 'length' passed
1953                    in, just guaranteed to fit.
1954 
1955             *section) set to the logical bitstream number */
1956 
ov_read_filter(OggVorbis_File * vf,char * buffer,int length,int bigendianp,int word,int sgned,int * bitstream,void (* filter)(float ** pcm,long channels,long samples,void * filter_param),void * filter_param)1957 long ov_read_filter(OggVorbis_File *vf,char *buffer,int length,
1958                     int bigendianp,int word,int sgned,int *bitstream,
1959                     void (*filter)(float **pcm,long channels,long samples,void *filter_param),void *filter_param){
1960   int i,j;
1961   int host_endian = host_is_big_endian();
1962   int hs;
1963 
1964   float **pcm;
1965   long samples;
1966 
1967   if(vf->ready_state<OPENED)return(OV_EINVAL);
1968 
1969   while(1){
1970     if(vf->ready_state==INITSET){
1971       samples=vorbis_synthesis_pcmout(&vf->vd,&pcm);
1972       if(samples)break;
1973     }
1974 
1975     /* suck in another packet */
1976     {
1977       int ret=_fetch_and_process_packet(vf,NULL,1,1);
1978       if(ret==OV_EOF)
1979         return(0);
1980       if(ret<=0)
1981         return(ret);
1982     }
1983 
1984   }
1985 
1986   if(samples>0){
1987 
1988     /* yay! proceed to pack data into the byte buffer */
1989 
1990     long channels=ov_info(vf,-1)->channels;
1991     long bytespersample=word * channels;
1992     vorbis_fpu_control fpu;
1993     if(samples>length/bytespersample)samples=length/bytespersample;
1994 
1995     if(samples <= 0)
1996       return OV_EINVAL;
1997 
1998     /* Here. */
1999     if(filter)
2000       filter(pcm,channels,samples,filter_param);
2001 
2002     /* a tight loop to pack each size */
2003     {
2004       int val;
2005       if(word==1){
2006         int off=(sgned?0:128);
2007         vorbis_fpu_setround(&fpu);
2008         for(j=0;j<samples;j++)
2009           for(i=0;i<channels;i++){
2010             val=vorbis_ftoi(pcm[i][j]*128.f);
2011             if(val>127)val=127;
2012             else if(val<-128)val=-128;
2013             *buffer++=val+off;
2014           }
2015         vorbis_fpu_restore(fpu);
2016       }else{
2017         int off=(sgned?0:32768);
2018 
2019         if(host_endian==bigendianp){
2020           if(sgned){
2021 
2022             vorbis_fpu_setround(&fpu);
2023             for(i=0;i<channels;i++) { /* It's faster in this order */
2024               float *src=pcm[i];
2025               short *dest=((short *)buffer)+i;
2026               for(j=0;j<samples;j++) {
2027                 val=vorbis_ftoi(src[j]*32768.f);
2028                 if(val>32767)val=32767;
2029                 else if(val<-32768)val=-32768;
2030                 *dest=val;
2031                 dest+=channels;
2032               }
2033             }
2034             vorbis_fpu_restore(fpu);
2035 
2036           }else{
2037 
2038             vorbis_fpu_setround(&fpu);
2039             for(i=0;i<channels;i++) {
2040               float *src=pcm[i];
2041               short *dest=((short *)buffer)+i;
2042               for(j=0;j<samples;j++) {
2043                 val=vorbis_ftoi(src[j]*32768.f);
2044                 if(val>32767)val=32767;
2045                 else if(val<-32768)val=-32768;
2046                 *dest=val+off;
2047                 dest+=channels;
2048               }
2049             }
2050             vorbis_fpu_restore(fpu);
2051 
2052           }
2053         }else if(bigendianp){
2054 
2055           vorbis_fpu_setround(&fpu);
2056           for(j=0;j<samples;j++)
2057             for(i=0;i<channels;i++){
2058               val=vorbis_ftoi(pcm[i][j]*32768.f);
2059               if(val>32767)val=32767;
2060               else if(val<-32768)val=-32768;
2061               val+=off;
2062               *buffer++=(val>>8);
2063               *buffer++=(val&0xff);
2064             }
2065           vorbis_fpu_restore(fpu);
2066 
2067         }else{
2068           int val;
2069           vorbis_fpu_setround(&fpu);
2070           for(j=0;j<samples;j++)
2071             for(i=0;i<channels;i++){
2072               val=vorbis_ftoi(pcm[i][j]*32768.f);
2073               if(val>32767)val=32767;
2074               else if(val<-32768)val=-32768;
2075               val+=off;
2076               *buffer++=(val&0xff);
2077               *buffer++=(val>>8);
2078                   }
2079           vorbis_fpu_restore(fpu);
2080 
2081         }
2082       }
2083     }
2084 
2085     vorbis_synthesis_read(&vf->vd,samples);
2086     hs=vorbis_synthesis_halfrate_p(vf->vi);
2087     vf->pcm_offset+=(samples<<hs);
2088     if(bitstream)*bitstream=vf->current_link;
2089     return(samples*bytespersample);
2090   }else{
2091     return(samples);
2092   }
2093 }
2094 
ov_read(OggVorbis_File * vf,char * buffer,int length,int bigendianp,int word,int sgned,int * bitstream)2095 long ov_read(OggVorbis_File *vf,char *buffer,int length,
2096              int bigendianp,int word,int sgned,int *bitstream){
2097   return ov_read_filter(vf, buffer, length, bigendianp, word, sgned, bitstream, NULL, NULL);
2098 }
2099 
2100 /* input values: pcm_channels) a float vector per channel of output
2101                  length) the sample length being read by the app
2102 
2103    return values: <0) error/hole in data (OV_HOLE), partial open (OV_EINVAL)
2104                    0) EOF
2105                    n) number of samples of PCM actually returned.  The
2106                    below works on a packet-by-packet basis, so the
2107                    return length is not related to the 'length' passed
2108                    in, just guaranteed to fit.
2109 
2110             *section) set to the logical bitstream number */
2111 
2112 
2113 
ov_read_float(OggVorbis_File * vf,float *** pcm_channels,int length,int * bitstream)2114 long ov_read_float(OggVorbis_File *vf,float ***pcm_channels,int length,
2115                    int *bitstream){
2116 
2117   if(vf->ready_state<OPENED)return(OV_EINVAL);
2118 
2119   while(1){
2120     if(vf->ready_state==INITSET){
2121       float **pcm;
2122       long samples=vorbis_synthesis_pcmout(&vf->vd,&pcm);
2123       if(samples){
2124         int hs=vorbis_synthesis_halfrate_p(vf->vi);
2125         if(pcm_channels)*pcm_channels=pcm;
2126         if(samples>length)samples=length;
2127         vorbis_synthesis_read(&vf->vd,samples);
2128         vf->pcm_offset+=samples<<hs;
2129         if(bitstream)*bitstream=vf->current_link;
2130         return samples;
2131 
2132       }
2133     }
2134 
2135     /* suck in another packet */
2136     {
2137       int ret=_fetch_and_process_packet(vf,NULL,1,1);
2138       if(ret==OV_EOF)return(0);
2139       if(ret<=0)return(ret);
2140     }
2141 
2142   }
2143 }
2144 
2145 extern const float *vorbis_window(vorbis_dsp_state *v,int W);
2146 
_ov_splice(float ** pcm,float ** lappcm,int n1,int n2,int ch1,int ch2,const float * w1,const float * w2)2147 static void _ov_splice(float **pcm,float **lappcm,
2148                        int n1, int n2,
2149                        int ch1, int ch2,
2150                        const float *w1, const float *w2){
2151   int i,j;
2152   const float *w=w1;
2153   int n=n1;
2154 
2155   if(n1>n2){
2156     n=n2;
2157     w=w2;
2158   }
2159 
2160   /* splice */
2161   for(j=0;j<ch1 && j<ch2;j++){
2162     float *s=lappcm[j];
2163     float *d=pcm[j];
2164 
2165     for(i=0;i<n;i++){
2166       float wd=w[i]*w[i];
2167       float ws=1.-wd;
2168       d[i]=d[i]*wd + s[i]*ws;
2169     }
2170   }
2171   /* window from zero */
2172   for(;j<ch2;j++){
2173     float *d=pcm[j];
2174     for(i=0;i<n;i++){
2175       float wd=w[i]*w[i];
2176       d[i]=d[i]*wd;
2177     }
2178   }
2179 
2180 }
2181 
2182 /* make sure vf is INITSET */
_ov_initset(OggVorbis_File * vf)2183 static int _ov_initset(OggVorbis_File *vf){
2184   while(1){
2185     if(vf->ready_state==INITSET)break;
2186     /* suck in another packet */
2187     {
2188       int ret=_fetch_and_process_packet(vf,NULL,1,0);
2189       if(ret<0 && ret!=OV_HOLE)return(ret);
2190     }
2191   }
2192   return 0;
2193 }
2194 
2195 /* make sure vf is INITSET and that we have a primed buffer; if
2196    we're crosslapping at a stream section boundary, this also makes
2197    sure we're sanity checking against the right stream information */
_ov_initprime(OggVorbis_File * vf)2198 static int _ov_initprime(OggVorbis_File *vf){
2199   vorbis_dsp_state *vd=&vf->vd;
2200   while(1){
2201     if(vf->ready_state==INITSET)
2202       if(vorbis_synthesis_pcmout(vd,NULL))break;
2203 
2204     /* suck in another packet */
2205     {
2206       int ret=_fetch_and_process_packet(vf,NULL,1,0);
2207       if(ret<0 && ret!=OV_HOLE)return(ret);
2208     }
2209   }
2210   return 0;
2211 }
2212 
2213 /* grab enough data for lapping from vf; this may be in the form of
2214    unreturned, already-decoded pcm, remaining PCM we will need to
2215    decode, or synthetic postextrapolation from last packets. */
_ov_getlap(OggVorbis_File * vf,vorbis_info * vi,vorbis_dsp_state * vd,float ** lappcm,int lapsize)2216 static void _ov_getlap(OggVorbis_File *vf,vorbis_info *vi,vorbis_dsp_state *vd,
2217                        float **lappcm,int lapsize){
2218   int lapcount=0,i;
2219   float **pcm;
2220 
2221   /* try first to decode the lapping data */
2222   while(lapcount<lapsize){
2223     int samples=vorbis_synthesis_pcmout(vd,&pcm);
2224     if(samples){
2225       if(samples>lapsize-lapcount)samples=lapsize-lapcount;
2226       for(i=0;i<vi->channels;i++)
2227         memcpy(lappcm[i]+lapcount,pcm[i],sizeof(**pcm)*samples);
2228       lapcount+=samples;
2229       vorbis_synthesis_read(vd,samples);
2230     }else{
2231     /* suck in another packet */
2232       int ret=_fetch_and_process_packet(vf,NULL,1,0); /* do *not* span */
2233       if(ret==OV_EOF)break;
2234     }
2235   }
2236   if(lapcount<lapsize){
2237     /* failed to get lapping data from normal decode; pry it from the
2238        postextrapolation buffering, or the second half of the MDCT
2239        from the last packet */
2240     int samples=vorbis_synthesis_lapout(&vf->vd,&pcm);
2241     if(samples==0){
2242       for(i=0;i<vi->channels;i++)
2243         memset(lappcm[i]+lapcount,0,sizeof(**pcm)*lapsize-lapcount);
2244       lapcount=lapsize;
2245     }else{
2246       if(samples>lapsize-lapcount)samples=lapsize-lapcount;
2247       for(i=0;i<vi->channels;i++)
2248         memcpy(lappcm[i]+lapcount,pcm[i],sizeof(**pcm)*samples);
2249       lapcount+=samples;
2250     }
2251   }
2252 }
2253 
2254 /* this sets up crosslapping of a sample by using trailing data from
2255    sample 1 and lapping it into the windowing buffer of sample 2 */
ov_crosslap(OggVorbis_File * vf1,OggVorbis_File * vf2)2256 int ov_crosslap(OggVorbis_File *vf1, OggVorbis_File *vf2){
2257   vorbis_info *vi1,*vi2;
2258   float **lappcm;
2259   float **pcm;
2260   const float *w1,*w2;
2261   int n1,n2,i,ret,hs1,hs2;
2262 
2263   if(vf1==vf2)return(0); /* degenerate case */
2264   if(vf1->ready_state<OPENED)return(OV_EINVAL);
2265   if(vf2->ready_state<OPENED)return(OV_EINVAL);
2266 
2267   /* the relevant overlap buffers must be pre-checked and pre-primed
2268      before looking at settings in the event that priming would cross
2269      a bitstream boundary.  So, do it now */
2270 
2271   ret=_ov_initset(vf1);
2272   if(ret)return(ret);
2273   ret=_ov_initprime(vf2);
2274   if(ret)return(ret);
2275 
2276   vi1=ov_info(vf1,-1);
2277   vi2=ov_info(vf2,-1);
2278   hs1=ov_halfrate_p(vf1);
2279   hs2=ov_halfrate_p(vf2);
2280 
2281   lappcm=alloca(sizeof(*lappcm)*vi1->channels);
2282   n1=vorbis_info_blocksize(vi1,0)>>(1+hs1);
2283   n2=vorbis_info_blocksize(vi2,0)>>(1+hs2);
2284   w1=vorbis_window(&vf1->vd,0);
2285   w2=vorbis_window(&vf2->vd,0);
2286 
2287   for(i=0;i<vi1->channels;i++)
2288     lappcm[i]=alloca(sizeof(**lappcm)*n1);
2289 
2290   _ov_getlap(vf1,vi1,&vf1->vd,lappcm,n1);
2291 
2292   /* have a lapping buffer from vf1; now to splice it into the lapping
2293      buffer of vf2 */
2294   /* consolidate and expose the buffer. */
2295   vorbis_synthesis_lapout(&vf2->vd,&pcm);
2296 
2297 #if 0
2298   _analysis_output_always("pcmL",0,pcm[0],n1*2,0,0,0);
2299   _analysis_output_always("pcmR",0,pcm[1],n1*2,0,0,0);
2300 #endif
2301 
2302   /* splice */
2303   _ov_splice(pcm,lappcm,n1,n2,vi1->channels,vi2->channels,w1,w2);
2304 
2305   /* done */
2306   return(0);
2307 }
2308 
_ov_64_seek_lap(OggVorbis_File * vf,ogg_int64_t pos,int (* localseek)(OggVorbis_File *,ogg_int64_t))2309 static int _ov_64_seek_lap(OggVorbis_File *vf,ogg_int64_t pos,
2310                            int (*localseek)(OggVorbis_File *,ogg_int64_t)){
2311   vorbis_info *vi;
2312   float **lappcm;
2313   float **pcm;
2314   const float *w1,*w2;
2315   int n1,n2,ch1,ch2,hs;
2316   int i,ret;
2317 
2318   if(vf->ready_state<OPENED)return(OV_EINVAL);
2319   ret=_ov_initset(vf);
2320   if(ret)return(ret);
2321   vi=ov_info(vf,-1);
2322   hs=ov_halfrate_p(vf);
2323 
2324   ch1=vi->channels;
2325   n1=vorbis_info_blocksize(vi,0)>>(1+hs);
2326   w1=vorbis_window(&vf->vd,0);  /* window arrays from libvorbis are
2327                                    persistent; even if the decode state
2328                                    from this link gets dumped, this
2329                                    window array continues to exist */
2330 
2331   lappcm=alloca(sizeof(*lappcm)*ch1);
2332   for(i=0;i<ch1;i++)
2333     lappcm[i]=alloca(sizeof(**lappcm)*n1);
2334   _ov_getlap(vf,vi,&vf->vd,lappcm,n1);
2335 
2336   /* have lapping data; seek and prime the buffer */
2337   ret=localseek(vf,pos);
2338   if(ret)return ret;
2339   ret=_ov_initprime(vf);
2340   if(ret)return(ret);
2341 
2342  /* Guard against cross-link changes; they're perfectly legal */
2343   vi=ov_info(vf,-1);
2344   ch2=vi->channels;
2345   n2=vorbis_info_blocksize(vi,0)>>(1+hs);
2346   w2=vorbis_window(&vf->vd,0);
2347 
2348   /* consolidate and expose the buffer. */
2349   vorbis_synthesis_lapout(&vf->vd,&pcm);
2350 
2351   /* splice */
2352   _ov_splice(pcm,lappcm,n1,n2,ch1,ch2,w1,w2);
2353 
2354   /* done */
2355   return(0);
2356 }
2357 
ov_raw_seek_lap(OggVorbis_File * vf,ogg_int64_t pos)2358 int ov_raw_seek_lap(OggVorbis_File *vf,ogg_int64_t pos){
2359   return _ov_64_seek_lap(vf,pos,ov_raw_seek);
2360 }
2361 
ov_pcm_seek_lap(OggVorbis_File * vf,ogg_int64_t pos)2362 int ov_pcm_seek_lap(OggVorbis_File *vf,ogg_int64_t pos){
2363   return _ov_64_seek_lap(vf,pos,ov_pcm_seek);
2364 }
2365 
ov_pcm_seek_page_lap(OggVorbis_File * vf,ogg_int64_t pos)2366 int ov_pcm_seek_page_lap(OggVorbis_File *vf,ogg_int64_t pos){
2367   return _ov_64_seek_lap(vf,pos,ov_pcm_seek_page);
2368 }
2369 
_ov_d_seek_lap(OggVorbis_File * vf,double pos,int (* localseek)(OggVorbis_File *,double))2370 static int _ov_d_seek_lap(OggVorbis_File *vf,double pos,
2371                            int (*localseek)(OggVorbis_File *,double)){
2372   vorbis_info *vi;
2373   float **lappcm;
2374   float **pcm;
2375   const float *w1,*w2;
2376   int n1,n2,ch1,ch2,hs;
2377   int i,ret;
2378 
2379   if(vf->ready_state<OPENED)return(OV_EINVAL);
2380   ret=_ov_initset(vf);
2381   if(ret)return(ret);
2382   vi=ov_info(vf,-1);
2383   hs=ov_halfrate_p(vf);
2384 
2385   ch1=vi->channels;
2386   n1=vorbis_info_blocksize(vi,0)>>(1+hs);
2387   w1=vorbis_window(&vf->vd,0);  /* window arrays from libvorbis are
2388                                    persistent; even if the decode state
2389                                    from this link gets dumped, this
2390                                    window array continues to exist */
2391 
2392   lappcm=alloca(sizeof(*lappcm)*ch1);
2393   for(i=0;i<ch1;i++)
2394     lappcm[i]=alloca(sizeof(**lappcm)*n1);
2395   _ov_getlap(vf,vi,&vf->vd,lappcm,n1);
2396 
2397   /* have lapping data; seek and prime the buffer */
2398   ret=localseek(vf,pos);
2399   if(ret)return ret;
2400   ret=_ov_initprime(vf);
2401   if(ret)return(ret);
2402 
2403  /* Guard against cross-link changes; they're perfectly legal */
2404   vi=ov_info(vf,-1);
2405   ch2=vi->channels;
2406   n2=vorbis_info_blocksize(vi,0)>>(1+hs);
2407   w2=vorbis_window(&vf->vd,0);
2408 
2409   /* consolidate and expose the buffer. */
2410   vorbis_synthesis_lapout(&vf->vd,&pcm);
2411 
2412   /* splice */
2413   _ov_splice(pcm,lappcm,n1,n2,ch1,ch2,w1,w2);
2414 
2415   /* done */
2416   return(0);
2417 }
2418 
ov_time_seek_lap(OggVorbis_File * vf,double pos)2419 int ov_time_seek_lap(OggVorbis_File *vf,double pos){
2420   return _ov_d_seek_lap(vf,pos,ov_time_seek);
2421 }
2422 
ov_time_seek_page_lap(OggVorbis_File * vf,double pos)2423 int ov_time_seek_page_lap(OggVorbis_File *vf,double pos){
2424   return _ov_d_seek_lap(vf,pos,ov_time_seek_page);
2425 }
2426