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