Add Russian translation provided by Валерий Крувялис <valkru@mail.ru>
[xiph-mirror.git] / Tremor / vorbisfile.c
blobcd4814dfeb7b84a8f314af10a04f20b0e39dbcb5
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 ********************************************************************
14 function: stdio-based convenience library for opening/seeking/decoding
15 last mod: $Id$
17 ********************************************************************/
19 #include <stdlib.h>
20 #include <stdio.h>
21 #include <errno.h>
22 #include <string.h>
23 #include <math.h>
25 #include "ivorbiscodec.h"
26 #include "ivorbisfile.h"
28 #include "os.h"
29 #include "misc.h"
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) */
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. */
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. */
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. */
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 */
61 /* read a little more data from the file/pipe into the ogg_sync framer */
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);
75 /* save a tiny smidge of verbosity to make the code more readable */
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);
86 }else{
87 /* shouldn't happen unless someone writes a broken callback */
88 return OV_EFAULT;
90 return 0;
93 /* The read/seek functions track absolute position within the stream */
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.
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
103 return: <0) did not find a page (OV_FALSE, OV_EOF, OV_EREAD)
104 n) found a page at absolute offset n */
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;
112 if(boundary>0 && vf->offset>=boundary)return(OV_FALSE);
113 more=ogg_sync_pageseek(&vf->oy,og);
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);
123 long ret=_get_data(vf);
124 if(ret==0)return(OV_EOF);
125 if(ret<0)return(OV_EREAD);
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);
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 */
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;
148 while(offset==-1){
149 begin-=CHUNKSIZE;
150 if(begin<0)
151 begin=0;
153 ret=_seek_helper(vf,begin);
154 if(ret)return(ret);
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;
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);
175 ret=_get_next_page(vf,og,CHUNKSIZE);
176 if(ret<0)
177 /* this shouldn't be possible */
178 return(OV_EFAULT);
181 return(offset);
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)++;
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));
194 (*serialno_list)[(*n)-1] = s;
197 /* returns nonzero if found */
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++;
205 return 0;
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);
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. */
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;
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;
231 while(offset==-1){
232 begin-=CHUNKSIZE;
233 if(begin<0)
234 begin=0;
236 ret=_seek_helper(vf,begin);
237 if(ret)return(ret);
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;
249 if((ogg_uint32_t)ret_serialno == *serialno){
250 prefoffset=ret;
251 *granpos=ret_gran;
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;
265 /* we're not interested in the page... just the serialno and granpos. */
266 if(prefoffset>=0)return(prefoffset);
268 *serialno = ret_serialno;
269 *granpos = ret_gran;
270 return(offset);
274 /* uses the local ogg_stream storage in vf; this is important for
275 non-streaming input sources */
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;
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;
291 vorbis_info_init(vi);
292 vorbis_comment_init(vc);
293 vf->ready_state=OPENED;
295 /* extract the serialnos of all BOS pages + the first set of vorbis
296 headers we see in the link */
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;
309 _add_serialno(og_ptr,serialno_list,serialno_n);
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);
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;
329 /* get next page */
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;
336 if(llret<0){
337 ret=OV_ENOTVORBIS;
338 goto bail_header;
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;
350 if(vf->ready_state!=STREAMSET){
351 ret = OV_ENOTVORBIS;
352 goto bail_header;
355 while(1){
357 i=0;
358 while(i<2){ /* get a page loop */
360 while(i<2){ /* get a packet loop */
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;
369 if((ret=vorbis_synthesis_headerin(vi,vc,&op)))
370 goto bail_header;
372 i++;
375 while(i<2){
376 if(_get_next_page(vf,og_ptr,CHUNKSIZE)<0){
377 ret=OV_EBADHEADER;
378 goto bail_header;
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;
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;
397 /* otherwise, keep looking */
401 return 0;
404 bail_header:
405 vorbis_info_clear(vi);
406 vorbis_comment_clear(vc);
407 vf->ready_state=OPENED;
409 return ret;
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. */
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;
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 */
428 if(ogg_page_bos(&og)) break;
429 if(ogg_page_serialno(&og)!=serialno) continue;
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;
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;
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;
453 return accumulated;
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 */
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;
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)
484 /* Is the last page in our list of current serialnumbers? */
485 if(_lookup_serialno(endserial,currentno_list,currentnos)){
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);
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);
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));
509 vf->offsets[m+1]=end;
510 vf->offsets[m]=begin;
511 vf->pcmlengths[m*2+1]=(endgran<0?0:endgran);
513 }else{
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. */
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;
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;
530 if(endsearched-searched<CHUNKSIZE){
531 bisect=searched;
532 }else{
533 bisect=(searched+endsearched)/2;
536 ret=_seek_helper(vf,bisect);
537 if(ret)return(ret);
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;
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);
557 ret=_seek_helper(vf,next);
558 if(ret)return(ret);
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;
565 /* this will consume a page, however the next bisection always
566 starts with a raw seek */
567 pcmoffset = _initial_pcmoffset(vf,&vi);
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);
573 if(next_serialno_list)_ogg_free(next_serialno_list);
575 vf->offsets[m+1]=next;
576 vf->serialnos[m+1]=serialno;
577 vf->dataoffsets[m+1]=dataoffset;
579 vf->vi[m+1]=vi;
580 vf->vc[m+1]=vc;
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;
588 return(0);
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;
601 vorbis_block_init(&vf->vd,&vf->vb);
602 vf->ready_state=INITSET;
603 vf->bittrack=0;
604 vf->samptrack=0;
605 return 0;
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;
613 /* we're partially open and have a first link header state in
614 storage in vf */
616 /* fetch initial PCM offset */
617 ogg_int64_t pcmoffset = _initial_pcmoffset(vf,vf->vi);
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;
627 /* If seek_func is implemented, tell_func must also be implemented */
628 if(vf->end==-1) return(OV_EINVAL);
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);
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);
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;
647 return(ov_raw_seek(vf,dataoffset));
650 /* clear out the current logical bitstream decoder */
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;
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).
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
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;
674 /* handle one packet. Try to fetch it from current stream state */
675 /* extract packets from page */
676 while(1){
678 if(vf->ready_state==STREAMSET){
679 int ret=_make_decode_ready(vf);
680 if(ret<0)return ret;
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;
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 */
705 /* suck in the synthesis data and track bitrate */
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);
712 vorbis_synthesis_blockin(&vf->vd,&vf->vb);
713 vf->samptrack+=vorbis_synthesis_pcmout(&vf->vd,NULL);
714 vf->bittrack+=op_ptr->bytes*8;
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;
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*
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 */
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 */
742 samples=vorbis_synthesis_pcmout(&vf->vd,NULL);
744 granulepos-=samples;
745 for(i=0;i<link;i++)
746 granulepos+=vf->pcmlengths[i*2+1];
747 vf->pcm_offset=granulepos;
749 return(1);
752 else
753 break;
757 if(vf->ready_state>=OPENED){
758 ogg_int64_t ret;
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 */
767 if(!readp)return(0);
768 if((ret=_get_next_page(vf,&og,-1))<0){
769 return(OV_EOF); /* eof. leave unitialized */
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;
776 if(vf->ready_state==INITSET){
777 if(vf->current_serialno!=ogg_page_serialno(&og)){
779 /* two possibilities:
780 1) our decoding just traversed a bitstream boundary
781 2) another stream is multiplexed into this logical section */
783 if(ogg_page_bos(&og)){
784 /* boundary case */
785 if(!spanp)
786 return(OV_EOF);
788 _decode_clear(vf);
790 if(!vf->seekable){
791 vorbis_info_clear(vf->vi);
792 vorbis_comment_clear(vf->vc);
794 break;
796 }else
797 continue; /* possibility #2 */
801 break;
805 /* Do we need to load a new machine before submitting the page? */
806 /* This is different in the seekable and non-seekable cases.
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.
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
817 if(vf->ready_state!=INITSET){
818 int link;
820 if(vf->ready_state<STREAMSET){
821 if(vf->seekable){
822 ogg_uint32_t serialno = ogg_page_serialno(&og);
824 /* match the serialno to bitstream section. We use this rather than
825 offset positions to avoid problems near logical bitstream
826 boundaries */
828 for(link=0;link<vf->links;link++)
829 if(vf->serialnos[link]==serialno)break;
831 if(link==vf->links) continue; /* not the desired Vorbis
832 bitstream section; keep
833 trying */
835 vf->current_serialno=serialno;
836 vf->current_link=link;
838 ogg_stream_reset_serialno(&vf->os,vf->current_serialno);
839 vf->ready_state=STREAMSET;
841 }else{
842 /* we're streaming */
843 /* fetch the three header packets, build the info struct */
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;
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);
861 /* if, eg, 64 bit stdio is configured by default, this will build with
862 fseek64 */
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);
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;
875 memset(vf,0,sizeof(*vf));
876 vf->datasource=f;
877 vf->callbacks = callbacks;
879 /* init the framing state */
880 ogg_sync_init(&vf->oy);
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);
892 /* can we seek? Stevens suggests the seek test was portable */
893 if(offsettest!=-1)vf->seekable=1;
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 */
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));
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;
921 vf->ready_state=PARTOPEN;
923 if(serialno_list)_ogg_free(serialno_list);
924 return(ret);
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);
936 return(ret);
937 }else
938 vf->ready_state=STREAMSET;
940 return 0;
944 /* clear out the OggVorbis_File struct */
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);
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);
957 _ogg_free(vf->vi);
958 _ogg_free(vf->vc);
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));
969 #ifdef DEBUG_LEAKS
970 _VDBG_dump();
971 #endif
972 return(0);
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.
979 return: -1) error
980 0) OK
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);
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
998 return ov_open_callbacks((void *)f, vf, initial, ibytes, callbacks);
1001 int ov_fopen(const char *path,OggVorbis_File *vf){
1002 int ret;
1003 FILE *f = fopen(path,"rb");
1004 if(!f) return -1;
1006 ret = ov_open(f,vf,NULL,0);
1007 if(ret) fclose(f);
1008 return ret;
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. */
1017 int ov_test_callbacks(void *f,OggVorbis_File *vf,
1018 const char *initial,long ibytes,ov_callbacks callbacks)
1020 return _ov_open1(f,vf,initial,ibytes,callbacks);
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
1031 return ov_test_callbacks((void *)f, vf, initial, ibytes, callbacks);
1034 int ov_test_open(OggVorbis_File *vf){
1035 if(vf->ready_state!=PARTOPEN)return(OV_EINVAL);
1036 return _ov_open2(vf);
1039 /* How many logical bitstreams in this physical bitstream? */
1040 long ov_streams(OggVorbis_File *vf){
1041 return vf->links;
1044 /* Is the FILE * associated with vf seekable? */
1045 long ov_seekable(OggVorbis_File *vf){
1046 return vf->seekable;
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).
1055 If you want the actual bitrate field settings, get them from the
1056 vorbis_info structs */
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.
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;
1088 return(OV_FALSE);
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
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);
1109 /* Guess */
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]);
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
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]);
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
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]);
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
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);
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).
1182 returns zero on success, nonzero on failure */
1184 int ov_raw_seek(OggVorbis_File *vf,ogg_int64_t pos){
1185 ogg_stream_state work_os;
1186 int ret;
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 */
1192 if(pos<0 || pos>vf->end)return(OV_EINVAL);
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 */
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);
1209 ret=_seek_helper(vf,pos);
1210 if(ret)goto seek_error;
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.
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.
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.
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;
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 */
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);
1247 if(result>0){
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{
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;
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;
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;
1280 lastblock=thisblock;
1281 continue;
1282 }else
1283 ogg_stream_packetout(&vf->os,NULL);
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;
1293 }else{
1294 /* huh? Bogus stream with packets but no granulepos */
1295 vf->pcm_offset=-1;
1296 break;
1299 /* has our decoding just traversed a bitstream boundary? */
1300 if(vf->ready_state>=STREAMSET){
1301 if(vf->current_serialno!=ogg_page_serialno(&og)){
1303 /* two possibilities:
1304 1) our decoding just traversed a bitstream boundary
1305 2) another stream is multiplexed into this logical section? */
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 */
1315 if(vf->ready_state<STREAMSET){
1316 int link;
1317 ogg_uint32_t serialno = ogg_page_serialno(&og);
1319 for(link=0;link<vf->links;link++)
1320 if(vf->serialnos[link]==serialno)break;
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]);
1333 ogg_stream_pagein(&vf->os,&og);
1334 ogg_stream_pagein(&work_os,&og);
1335 lastflag=ogg_page_eos(&og);
1340 ogg_stream_clear(&work_os);
1341 vf->bittrack=0;
1342 vf->samptrack=0;
1343 return(0);
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;
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] */
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;
1363 for(i=0;i<64;i++){
1364 if(x>=from){
1365 frac|=1;
1366 x-=from;
1368 x<<=1;
1369 frac<<=1;
1372 for(i=0;i<64;i++){
1373 if(frac & 1){
1374 ret+=to;
1376 frac>>=1;
1377 ret>>=1;
1380 return ret;
1383 /* Page granularity seek (faster than sample granularity because we
1384 don't do the last bit of decode to find a specific sample).
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. */
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);
1394 if(vf->ready_state<OPENED)return(OV_EINVAL);
1395 if(!vf->seekable)return(OV_ENOSEEK);
1397 if(pos<0 || pos>total)return(OV_EINVAL);
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;
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.
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) */
1415 /* new search algorithm originally by HB (Nicholas Vinen) */
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;
1426 ogg_page og;
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;
1433 result=_get_next_page(vf,&og,1);
1434 if(result<0) goto seek_error;
1436 got_page=1;
1439 /* bisection loop */
1440 while(begin<end){
1441 ogg_int64_t bisect;
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;
1454 result=_seek_helper(vf,bisect);
1455 if(result) goto seek_error;
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;
1473 /* don't repeat/loop on a read we've already performed */
1474 if(bisect<=begin)bisect=begin+1;
1476 /* seek and continue bisection */
1477 result=_seek_helper(vf,bisect);
1478 if(result) goto seek_error;
1480 }else{
1481 ogg_int64_t granulepos;
1482 got_page=1;
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;
1489 /* only consider pages with the granulepos set */
1490 granulepos=ogg_page_granulepos(&og);
1491 if(granulepos==-1)continue;
1493 if(granulepos<target){
1494 /* this page is a successful candidate! Set state */
1496 best=result; /* raw offset of packet with granulepos */
1497 begin=vf->offset; /* raw offset of next page */
1498 begintime=granulepos;
1500 /* if we're before our target but within a short distance,
1501 don't bisect; read forward */
1502 if(target-begintime>44100)break;
1504 bisect=begin; /* *not* begin + 1 as above */
1505 }else{
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;
1538 /* Out of bisection: did it 'fail?' */
1539 if(best == -1){
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. */
1545 if(got_page &&
1546 begin == vf->dataoffsets[link] &&
1547 ogg_page_serialno(&og)==vf->serialnos[link]){
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. */
1553 vf->pcm_offset=total;
1555 if(link!=vf->current_link){
1556 /* Different link; dump entire decode machine */
1557 _decode_clear(vf);
1559 vf->current_link=link;
1560 vf->current_serialno=vf->serialnos[link];
1561 vf->ready_state=STREAMSET;
1563 }else{
1564 vorbis_synthesis_restart(&vf->vd);
1567 ogg_stream_reset_serialno(&vf->os,vf->current_serialno);
1568 ogg_stream_pagein(&vf->os,&og);
1570 }else
1571 goto seek_error;
1573 }else{
1575 /* Bisection found our page. seek to it, update pcm offset. Easier case than
1576 raw_seek, don't keep packets preceding granulepos. */
1578 ogg_page og;
1579 ogg_packet op;
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;
1588 if(link!=vf->current_link){
1589 /* Different link; dump entire decode machine */
1590 _decode_clear(vf);
1592 vf->current_link=link;
1593 vf->current_serialno=vf->serialnos[link];
1594 vf->ready_state=STREAMSET;
1596 }else{
1597 vorbis_synthesis_restart(&vf->vd);
1600 ogg_stream_reset_serialno(&vf->os,vf->current_serialno);
1601 ogg_stream_pagein(&vf->os,&og);
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);
1626 if(result<0){
1627 result = OV_EBADPACKET;
1628 goto seek_error;
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);
1641 /* verify result */
1642 if(vf->pcm_offset>pos || pos>ov_pcm_total(vf,-1)){
1643 result=OV_EFAULT;
1644 goto seek_error;
1646 vf->bittrack=0;
1647 vf->samptrack=0;
1648 return(0);
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;
1657 /* seek to a sample offset relative to the decompressed pcm stream
1658 returns zero on success, nonzero on failure */
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;
1666 /* discard leading packets we don't need for the lapping of the
1667 position we want; don't decode them */
1669 while(1){
1670 ogg_packet op;
1671 ogg_page og;
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 */
1680 if(lastblock)vf->pcm_offset+=(lastblock+thisblock)>>2;
1682 if(vf->pcm_offset+((thisblock+
1683 vorbis_info_blocksize(vf->vi,1))>>2)>=pos)break;
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);
1692 /* end of logical stream case is hard, especially with exact
1693 length positioning. */
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];
1704 lastblock=thisblock;
1706 }else{
1707 if(ret<0 && ret!=OV_HOLE)break;
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);
1713 if(vf->ready_state<STREAMSET){
1714 ogg_uint32_t serialno=ogg_page_serialno(&og);
1715 int link;
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;
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;
1730 ogg_stream_pagein(&vf->os,&og);
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);
1742 if(samples>target)samples=target;
1743 vorbis_synthesis_read(&vf->vd,samples);
1744 vf->pcm_offset+=samples;
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 */
1750 return 0;
1753 /* seek to a playback time relative to the decompressed pcm stream
1754 returns zero on success, nonzero on failure */
1755 int ov_time_seek(OggVorbis_File *vf,ogg_int64_t milliseconds){
1756 /* translate time to PCM position and call ov_pcm_seek */
1758 int link=-1;
1759 ogg_int64_t pcm_total=0;
1760 ogg_int64_t time_total=0;
1762 if(vf->ready_state<OPENED)return(OV_EINVAL);
1763 if(!vf->seekable)return(OV_ENOSEEK);
1764 if(milliseconds<0)return(OV_EINVAL);
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];
1774 if(link==vf->links)return(OV_EINVAL);
1776 /* enough information to convert time offset to pcm offset */
1778 ogg_int64_t target=pcm_total+(milliseconds-time_total)*vf->vi[link].rate/1000;
1779 return(ov_pcm_seek(vf,target));
1783 /* page-granularity version of ov_time_seek
1784 returns zero on success, nonzero on failure */
1785 int ov_time_seek_page(OggVorbis_File *vf,ogg_int64_t milliseconds){
1786 /* translate time to PCM position and call ov_pcm_seek */
1788 int link=-1;
1789 ogg_int64_t pcm_total=0;
1790 ogg_int64_t time_total=0;
1792 if(vf->ready_state<OPENED)return(OV_EINVAL);
1793 if(!vf->seekable)return(OV_ENOSEEK);
1794 if(milliseconds<0)return(OV_EINVAL);
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];
1804 if(link==vf->links)return(OV_EINVAL);
1806 /* enough information to convert time offset to pcm offset */
1808 ogg_int64_t target=pcm_total+(milliseconds-time_total)*vf->vi[link].rate/1000;
1809 return(ov_pcm_seek_page(vf,target));
1813 /* tell the current stream offset cursor. Note that seek followed by
1814 tell will likely not give the set offset due to caching */
1815 ogg_int64_t ov_raw_tell(OggVorbis_File *vf){
1816 if(vf->ready_state<OPENED)return(OV_EINVAL);
1817 return(vf->offset);
1820 /* return PCM offset (sample) of next PCM sample to be read */
1821 ogg_int64_t ov_pcm_tell(OggVorbis_File *vf){
1822 if(vf->ready_state<OPENED)return(OV_EINVAL);
1823 return(vf->pcm_offset);
1826 /* return time offset (milliseconds) of next PCM sample to be read */
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;
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);
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;
1845 return(time_total+(1000*vf->pcm_offset-pcm_total)/vf->vi[link].rate);
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
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 */
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;
1873 /* grr, strong typing, grr, no templates/inheritence, grr */
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;
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.
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).
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
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.
1916 *section) set to the logical bitstream number */
1918 long ov_read(OggVorbis_File *vf,char *buffer,int bytes_req,int *bitstream){
1919 int i,j;
1921 ogg_int32_t **pcm;
1922 long samples;
1924 if(vf->ready_state<OPENED)return(OV_EINVAL);
1926 while(1){
1927 if(vf->ready_state==INITSET){
1928 samples=vorbis_synthesis_pcmout(&vf->vd,&pcm);
1929 if(samples)break;
1932 /* suck in another packet */
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);
1943 if(samples>0){
1945 /* yay! proceed to pack data into the byte buffer */
1947 long channels=ov_info(vf,-1)->channels;
1949 if(samples>(bytes_req/(2*channels)))
1950 samples=bytes_req/(2*channels);
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;
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);