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