1 /********************************************************************
3 * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. *
4 * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS *
5 * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
6 * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
8 * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2001 *
9 * by the XIPHOPHORUS Company http://www.xiph.org/ *
11 ********************************************************************
13 function: stdio-based convenience library for opening/seeking/decoding
14 last mod: $Id: vorbisfile.c,v 1.51 2001/11/12 13:41:10 msmith Exp $
16 ********************************************************************/
24 #include "vorbis/codec.h"
25 #include "vorbis/vorbisfile.h"
28 #include "codec_internal.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 */
60 /* read a little more data from the file/pipe into the ogg_sync framer
62 #define CHUNKSIZE 8500 /* a shade over 8k; anyone using pages well
63 over 8k gets what they deserve */
64 static long _get_data(OggVorbis_File *vf){
67 char *buffer=ogg_sync_buffer(&vf->oy,CHUNKSIZE);
68 long bytes=(vf->callbacks.read_func)(buffer,1,CHUNKSIZE,vf->datasource);
69 if(bytes>0)ogg_sync_wrote(&vf->oy,bytes);
70 if(bytes==0 && errno)return(-1);
76 /* save a tiny smidge of verbosity to make the code more readable */
77 static void _seek_helper(OggVorbis_File *vf,long offset){
79 (vf->callbacks.seek_func)(vf->datasource, offset, SEEK_SET);
81 ogg_sync_reset(&vf->oy);
83 /* shouldn't happen unless someone writes a broken callback */
88 /* The read/seek functions track absolute position within the stream */
90 /* from the head of the stream, get the next page. boundary specifies
91 if the function is allowed to fetch more data from the stream (and
92 how much) or only use internally buffered data.
94 boundary: -1) unbounded search
95 0) read no additional data; use cached only
96 n) search for a new page beginning for n bytes
98 return: <0) did not find a page (OV_FALSE, OV_EOF, OV_EREAD)
99 n) found a page at absolute offset n */
101 static long _get_next_page(OggVorbis_File *vf,ogg_page *og,int boundary){
102 if(boundary>0)boundary+=vf->offset;
106 if(boundary>0 && vf->offset>=boundary)return(OV_FALSE);
107 more=ogg_sync_pageseek(&vf->oy,og);
110 /* skipped n bytes */
114 /* send more paramedics */
115 if(!boundary)return(OV_FALSE);
117 long ret=_get_data(vf);
118 if(ret==0)return(OV_EOF);
119 if(ret<0)return(OV_EREAD);
122 /* got a page. Return the offset at the page beginning,
123 advance the internal offset past the page end */
133 /* find the latest page beginning before the current stream cursor
134 position. Much dirtier than the above as Ogg doesn't have any
135 backward search linkage. no 'readp' as it will certainly have to
137 /* returns offset or OV_EREAD, OV_FAULT */
138 static long _get_prev_page(OggVorbis_File *vf,ogg_page *og){
139 long begin=vf->offset;
147 _seek_helper(vf,begin);
148 while(vf->offset<begin+CHUNKSIZE){
149 ret=_get_next_page(vf,og,begin+CHUNKSIZE-vf->offset);
150 if(ret==OV_EREAD)return(OV_EREAD);
159 /* we have the offset. Actually snork and hold the page now */
160 _seek_helper(vf,offset);
161 ret=_get_next_page(vf,og,CHUNKSIZE);
163 /* this shouldn't be possible */
169 /* finds each bitstream link one at a time using a bisection search
170 (has to begin by knowing the offset of the lb's initial page).
171 Recurses for each link so it can alloc the link storage after
172 finding them all, then unroll and fill the cache at the same time */
173 static int _bisect_forward_serialno(OggVorbis_File *vf,
179 long endsearched=end;
184 /* the below guards against garbage seperating the last and
185 first pages of two links. */
186 while(searched<endsearched){
189 if(endsearched-searched<CHUNKSIZE){
192 bisect=(searched+endsearched)/2;
195 _seek_helper(vf,bisect);
196 ret=_get_next_page(vf,&og,-1);
197 if(ret==OV_EREAD)return(OV_EREAD);
198 if(ret<0 || ogg_page_serialno(&og)!=currentno){
202 searched=ret+og.header_len+og.body_len;
206 _seek_helper(vf,next);
207 ret=_get_next_page(vf,&og,-1);
208 if(ret==OV_EREAD)return(OV_EREAD);
210 if(searched>=end || ret<0){
212 vf->offsets=_ogg_malloc((m+2)*sizeof(*vf->offsets));
213 vf->offsets[m+1]=searched;
215 ret=_bisect_forward_serialno(vf,next,vf->offset,
216 end,ogg_page_serialno(&og),m+1);
217 if(ret==OV_EREAD)return(OV_EREAD);
220 vf->offsets[m]=begin;
224 /* uses the local ogg_stream storage in vf; this is important for
225 non-streaming input sources */
226 static int _fetch_headers(OggVorbis_File *vf,vorbis_info *vi,vorbis_comment *vc,
227 long *serialno,ogg_page *og_ptr){
233 ret=_get_next_page(vf,&og,CHUNKSIZE);
234 if(ret==OV_EREAD)return(OV_EREAD);
235 if(ret<0)return OV_ENOTVORBIS;
239 if(serialno)*serialno=ogg_page_serialno(og_ptr);
240 ogg_stream_init(&vf->os,ogg_page_serialno(og_ptr));
241 vf->ready_state=STREAMSET;
243 /* extract the initial header from the first page and verify that the
244 Ogg bitstream is in fact Vorbis data */
246 vorbis_info_init(vi);
247 vorbis_comment_init(vc);
251 ogg_stream_pagein(&vf->os,og_ptr);
253 int result=ogg_stream_packetout(&vf->os,&op);
259 if((ret=vorbis_synthesis_headerin(vi,vc,&op))){
265 if(_get_next_page(vf,og_ptr,CHUNKSIZE)<0){
273 vorbis_info_clear(vi);
274 vorbis_comment_clear(vc);
275 ogg_stream_clear(&vf->os);
276 vf->ready_state=OPENED;
281 /* last step of the OggVorbis_File initialization; get all the
282 vorbis_info structs and PCM positions. Only called by the seekable
283 initialization (local stream storage is hacked slightly; pay
284 attention to how that's done) */
286 /* this is void and does not propogate errors up because we want to be
287 able to open and use damaged bitstreams as well as we can. Just
288 watch out for missing information for links in the OggVorbis_File
290 static void _prefetch_all_headers(OggVorbis_File *vf, long dataoffset){
294 vf->vi=_ogg_realloc(vf->vi,vf->links*sizeof(*vf->vi));
295 vf->vc=_ogg_realloc(vf->vc,vf->links*sizeof(*vf->vc));
296 vf->dataoffsets=_ogg_malloc(vf->links*sizeof(*vf->dataoffsets));
297 vf->pcmlengths=_ogg_malloc(vf->links*sizeof(*vf->pcmlengths));
298 vf->serialnos=_ogg_malloc(vf->links*sizeof(*vf->serialnos));
300 for(i=0;i<vf->links;i++){
302 /* we already grabbed the initial header earlier. Just set the offset */
303 vf->dataoffsets[i]=dataoffset;
306 /* seek to the location of the initial header */
308 _seek_helper(vf,vf->offsets[i]);
309 if(_fetch_headers(vf,vf->vi+i,vf->vc+i,NULL,NULL)<0){
310 vf->dataoffsets[i]=-1;
312 vf->dataoffsets[i]=vf->offset;
313 ogg_stream_clear(&vf->os);
317 /* get the serial number and PCM length of this link. To do this,
318 get the last page of the stream */
320 long end=vf->offsets[i+1];
321 _seek_helper(vf,end);
324 ret=_get_prev_page(vf,&og);
326 /* this should not be possible */
327 vorbis_info_clear(vf->vi+i);
328 vorbis_comment_clear(vf->vc+i);
331 if(ogg_page_granulepos(&og)!=-1){
332 vf->serialnos[i]=ogg_page_serialno(&og);
333 vf->pcmlengths[i]=ogg_page_granulepos(&og);
342 static void _make_decode_ready(OggVorbis_File *vf){
343 if(vf->ready_state!=STREAMSET)return;
345 vorbis_synthesis_init(&vf->vd,vf->vi+vf->current_link);
347 vorbis_synthesis_init(&vf->vd,vf->vi);
349 vorbis_block_init(&vf->vd,&vf->vb);
350 vf->ready_state=INITSET;
354 static int _open_seekable2(OggVorbis_File *vf){
355 long serialno=vf->current_serialno,end;
356 long dataoffset=vf->offset;
359 /* we're partially open and have a first link header state in
361 /* we can seek, so set out learning all about this file */
362 (vf->callbacks.seek_func)(vf->datasource,0,SEEK_END);
363 vf->offset=vf->end=(vf->callbacks.tell_func)(vf->datasource);
365 /* We get the offset for the last page of the physical bitstream.
366 Most OggVorbis files will contain a single logical bitstream */
367 end=_get_prev_page(vf,&og);
373 /* more than one logical bitstream? */
374 if(ogg_page_serialno(&og)!=serialno){
376 /* Chained bitstream. Bisect-search each logical bitstream
377 section. Do so based on serial number only */
378 if(_bisect_forward_serialno(vf,0,0,end+1,serialno,0)<0){
385 /* Only one logical bitstream */
386 if(_bisect_forward_serialno(vf,0,end,end+1,serialno,0)){
393 /* the initial header memory is referenced by vf after; don't free it */
394 _prefetch_all_headers(vf,dataoffset);
395 return(ov_raw_seek(vf,0));
398 /* clear out the current logical bitstream decoder */
399 static void _decode_clear(OggVorbis_File *vf){
400 ogg_stream_clear(&vf->os);
401 vorbis_dsp_clear(&vf->vd);
402 vorbis_block_clear(&vf->vb);
403 vf->ready_state=OPENED;
409 /* fetch and process a packet. Handles the case where we're at a
410 bitstream boundary and dumps the decoding machine. If the decoding
411 machine is unloaded, it loads it. It also keeps pcm_offset up to
412 date (seek and read both use this. seek uses a special hack with
415 return: <0) error, OV_HOLE (lost packet) or OV_EOF
416 0) need more data (only if readp==0)
420 static int _process_packet(OggVorbis_File *vf,int readp){
423 /* handle one packet. Try to fetch it from current stream state */
424 /* extract packets from page */
427 /* process a packet if we can. If the machine isn't loaded,
429 if(vf->ready_state==INITSET){
432 int result=ogg_stream_packetout(&vf->os,&op);
433 ogg_int64_t granulepos;
435 if(result==-1)return(OV_HOLE); /* hole in the data. */
437 /* got a packet. process it */
438 granulepos=op.granulepos;
439 if(!vorbis_synthesis(&vf->vb,&op)){ /* lazy check for lazy
441 header packets aren't
444 vorbis_synthesis will
447 /* suck in the synthesis data and track bitrate */
449 int oldsamples=vorbis_synthesis_pcmout(&vf->vd,NULL);
450 vorbis_synthesis_blockin(&vf->vd,&vf->vb);
451 vf->samptrack+=vorbis_synthesis_pcmout(&vf->vd,NULL)-oldsamples;
452 vf->bittrack+=op.bytes*8;
455 /* update the pcm offset. */
456 if(granulepos!=-1 && !op.e_o_s){
457 int link=(vf->seekable?vf->current_link:0);
460 /* this packet has a pcm_offset on it (the last packet
461 completed on a page carries the offset) After processing
462 (above), we know the pcm position of the *last* sample
463 ready to be returned. Find the offset of the *first*
465 As an aside, this trick is inaccurate if we begin
466 reading anew right at the last page; the end-of-stream
467 granulepos declares the last frame in the stream, and the
468 last packet of the last page may be a partial frame.
469 So, we need a previous granulepos from an in-sequence page
470 to have a reference point. Thus the !op.e_o_s clause
473 samples=vorbis_synthesis_pcmout(&vf->vd,NULL);
477 granulepos+=vf->pcmlengths[i];
478 vf->pcm_offset=granulepos;
488 if(vf->ready_state>=OPENED){
490 if(_get_next_page(vf,&og,-1)<0)return(OV_EOF); /* eof.
492 /* bitrate tracking; add the header's bytes here, the body bytes
493 are done by packet above */
494 vf->bittrack+=og.header_len*8;
496 /* has our decoding just traversed a bitstream boundary? */
497 if(vf->ready_state==INITSET){
498 if(vf->current_serialno!=ogg_page_serialno(&og)){
502 vorbis_info_clear(vf->vi);
503 vorbis_comment_clear(vf->vc);
509 /* Do we need to load a new machine before submitting the page? */
510 /* This is different in the seekable and non-seekable cases.
512 In the seekable case, we already have all the header
513 information loaded and cached; we just initialize the machine
514 with it and continue on our merry way.
516 In the non-seekable (streaming) case, we'll only be at a
517 boundary if we just left the previous logical bitstream and
518 we're now nominally at the header of the next bitstream
521 if(vf->ready_state!=INITSET){
524 if(vf->ready_state<STREAMSET){
526 vf->current_serialno=ogg_page_serialno(&og);
528 /* match the serialno to bitstream section. We use this rather than
529 offset positions to avoid problems near logical bitstream
531 for(link=0;link<vf->links;link++)
532 if(vf->serialnos[link]==vf->current_serialno)break;
533 if(link==vf->links)return(OV_EBADLINK); /* sign of a bogus
538 vf->current_link=link;
540 ogg_stream_init(&vf->os,vf->current_serialno);
541 ogg_stream_reset(&vf->os);
542 vf->ready_state=STREAMSET;
545 /* we're streaming */
546 /* fetch the three header packets, build the info struct */
548 int ret=_fetch_headers(vf,vf->vi,vf->vc,&vf->current_serialno,&og);
555 _make_decode_ready(vf);
557 ogg_stream_pagein(&vf->os,&og);
561 static int _fseek64_wrap(FILE *f,ogg_int64_t off,int whence){
562 if(f==NULL)return(-1);
563 return fseek(f,(int)off,whence);
566 static int _ov_open1(void *f,OggVorbis_File *vf,char *initial,
567 long ibytes, ov_callbacks callbacks){
568 long offset=(f?callbacks.seek_func(f,0,SEEK_CUR):-1);
571 memset(vf,0,sizeof(*vf));
573 vf->callbacks = callbacks;
575 /* init the framing state */
576 ogg_sync_init(&vf->oy);
578 /* perhaps some data was previously read into a buffer for testing
579 against other stream types. Allow initialization from this
580 previously read data (as we may be reading from a non-seekable
583 char *buffer=ogg_sync_buffer(&vf->oy,ibytes);
584 memcpy(buffer,initial,ibytes);
585 ogg_sync_wrote(&vf->oy,ibytes);
588 /* can we seek? Stevens suggests the seek test was portable */
589 if(offset!=-1)vf->seekable=1;
591 /* No seeking yet; Set up a 'single' (current) logical bitstream
592 entry for partial open */
594 vf->vi=_ogg_calloc(vf->links,sizeof(*vf->vi));
595 vf->vc=_ogg_calloc(vf->links,sizeof(*vf->vc));
597 /* Try to fetch the headers, maintaining all the storage */
598 if((ret=_fetch_headers(vf,vf->vi,vf->vc,&vf->current_serialno,NULL))<0){
601 }else if(vf->ready_state < PARTOPEN)
602 vf->ready_state=PARTOPEN;
606 static int _ov_open2(OggVorbis_File *vf){
607 if(vf->ready_state < OPENED)
608 vf->ready_state=OPENED;
610 int ret=_open_seekable2(vf);
621 /* clear out the OggVorbis_File struct */
622 int ov_clear(OggVorbis_File *vf){
624 vorbis_block_clear(&vf->vb);
625 vorbis_dsp_clear(&vf->vd);
626 ogg_stream_clear(&vf->os);
628 if(vf->vi && vf->links){
630 for(i=0;i<vf->links;i++){
631 vorbis_info_clear(vf->vi+i);
632 vorbis_comment_clear(vf->vc+i);
637 if(vf->dataoffsets)_ogg_free(vf->dataoffsets);
638 if(vf->pcmlengths)_ogg_free(vf->pcmlengths);
639 if(vf->serialnos)_ogg_free(vf->serialnos);
640 if(vf->offsets)_ogg_free(vf->offsets);
641 ogg_sync_clear(&vf->oy);
642 if(vf->datasource)(vf->callbacks.close_func)(vf->datasource);
643 memset(vf,0,sizeof(*vf));
651 /* inspects the OggVorbis file and finds/documents all the logical
652 bitstreams contained in it. Tries to be tolerant of logical
653 bitstream sections that are truncated/woogie.
659 int ov_open_callbacks(void *f,OggVorbis_File *vf,char *initial,long ibytes,
660 ov_callbacks callbacks){
661 int ret=_ov_open1(f,vf,initial,ibytes,callbacks);
663 return _ov_open2(vf);
666 int ov_open(FILE *f,OggVorbis_File *vf,char *initial,long ibytes){
667 ov_callbacks callbacks = {
668 (size_t (*)(void *, size_t, size_t, void *)) fread,
669 (int (*)(void *, ogg_int64_t, int)) _fseek64_wrap,
670 (int (*)(void *)) fclose,
671 (long (*)(void *)) ftell
674 return ov_open_callbacks((void *)f, vf, initial, ibytes, callbacks);
677 /* Only partially open the vorbis file; test for Vorbisness, and load
678 the headers for the first chain. Do not seek (although test for
679 seekability). Use ov_test_open to finish opening the file, else
680 ov_clear to close/free it. Same return codes as open. */
682 int ov_test_callbacks(void *f,OggVorbis_File *vf,char *initial,long ibytes,
683 ov_callbacks callbacks)
685 return _ov_open1(f,vf,initial,ibytes,callbacks);
688 int ov_test(FILE *f,OggVorbis_File *vf,char *initial,long ibytes){
689 ov_callbacks callbacks = {
690 (size_t (*)(void *, size_t, size_t, void *)) fread,
691 (int (*)(void *, ogg_int64_t, int)) _fseek64_wrap,
692 (int (*)(void *)) fclose,
693 (long (*)(void *)) ftell
696 return ov_test_callbacks((void *)f, vf, initial, ibytes, callbacks);
699 int ov_test_open(OggVorbis_File *vf){
700 if(vf->ready_state!=PARTOPEN)return(OV_EINVAL);
701 return _ov_open2(vf);
704 /* How many logical bitstreams in this physical bitstream? */
705 long ov_streams(OggVorbis_File *vf){
709 /* Is the FILE * associated with vf seekable? */
710 long ov_seekable(OggVorbis_File *vf){
714 /* returns the bitrate for a given logical bitstream or the entire
715 physical bitstream. If the file is open for random access, it will
716 find the *actual* average bitrate. If the file is streaming, it
717 returns the nominal bitrate (if set) else the average of the
718 upper/lower bounds (if set) else -1 (unset).
720 If you want the actual bitrate field settings, get them from the
721 vorbis_info structs */
723 long ov_bitrate(OggVorbis_File *vf,int i){
724 if(vf->ready_state<OPENED)return(OV_EINVAL);
725 if(i>=vf->links)return(OV_EINVAL);
726 if(!vf->seekable && i!=0)return(ov_bitrate(vf,0));
730 for(i=0;i<vf->links;i++)
731 bits+=(vf->offsets[i+1]-vf->dataoffsets[i])*8;
732 return(rint(bits/ov_time_total(vf,-1)));
735 /* return the actual bitrate */
736 return(rint((vf->offsets[i+1]-vf->dataoffsets[i])*8/ov_time_total(vf,i)));
738 /* return nominal if set */
739 if(vf->vi[i].bitrate_nominal>0){
740 return vf->vi[i].bitrate_nominal;
742 if(vf->vi[i].bitrate_upper>0){
743 if(vf->vi[i].bitrate_lower>0){
744 return (vf->vi[i].bitrate_upper+vf->vi[i].bitrate_lower)/2;
746 return vf->vi[i].bitrate_upper;
755 /* returns the actual bitrate since last call. returns -1 if no
756 additional data to offer since last call (or at beginning of stream),
757 EINVAL if stream is only partially open
759 long ov_bitrate_instant(OggVorbis_File *vf){
760 int link=(vf->seekable?vf->current_link:0);
762 if(vf->ready_state<OPENED)return(OV_EINVAL);
763 if(vf->samptrack==0)return(OV_FALSE);
764 ret=vf->bittrack/vf->samptrack*vf->vi[link].rate+.5;
771 long ov_serialnumber(OggVorbis_File *vf,int i){
772 if(i>=vf->links)return(ov_serialnumber(vf,vf->links-1));
773 if(!vf->seekable && i>=0)return(ov_serialnumber(vf,-1));
775 return(vf->current_serialno);
777 return(vf->serialnos[i]);
781 /* returns: total raw (compressed) length of content if i==-1
782 raw (compressed) length of that logical bitstream for i==0 to n
783 OV_EINVAL if the stream is not seekable (we can't know the length)
784 or if stream is only partially open
786 ogg_int64_t ov_raw_total(OggVorbis_File *vf,int i){
787 if(vf->ready_state<OPENED)return(OV_EINVAL);
788 if(!vf->seekable || i>=vf->links)return(OV_EINVAL);
792 for(i=0;i<vf->links;i++)
793 acc+=ov_raw_total(vf,i);
796 return(vf->offsets[i+1]-vf->offsets[i]);
800 /* returns: total PCM length (samples) of content if i==-1 PCM length
801 (samples) of that logical bitstream for i==0 to n
802 OV_EINVAL if the stream is not seekable (we can't know the
803 length) or only partially open
805 ogg_int64_t ov_pcm_total(OggVorbis_File *vf,int i){
806 if(vf->ready_state<OPENED)return(OV_EINVAL);
807 if(!vf->seekable || i>=vf->links)return(OV_EINVAL);
811 for(i=0;i<vf->links;i++)
812 acc+=ov_pcm_total(vf,i);
815 return(vf->pcmlengths[i]);
819 /* returns: total seconds of content if i==-1
820 seconds in that logical bitstream for i==0 to n
821 OV_EINVAL if the stream is not seekable (we can't know the
822 length) or only partially open
824 double ov_time_total(OggVorbis_File *vf,int i){
825 if(vf->ready_state<OPENED)return(OV_EINVAL);
826 if(!vf->seekable || i>=vf->links)return(OV_EINVAL);
830 for(i=0;i<vf->links;i++)
831 acc+=ov_time_total(vf,i);
834 return((float)(vf->pcmlengths[i])/vf->vi[i].rate);
838 /* seek to an offset relative to the *compressed* data. This also
839 scans packets to update the PCM cursor. It will cross a logical
840 bitstream boundary, but only if it can't get any packets out of the
841 tail of the bitstream we seek to (so no surprises).
843 returns zero on success, nonzero on failure */
845 int ov_raw_seek(OggVorbis_File *vf,long pos){
846 ogg_stream_state work_os;
848 if(vf->ready_state<OPENED)return(OV_EINVAL);
850 return(OV_ENOSEEK); /* don't dump machine if we can't seek */
852 if(pos<0 || pos>vf->offsets[vf->links])return(OV_EINVAL);
854 /* clear out decoding machine state */
858 _seek_helper(vf,pos);
860 /* we need to make sure the pcm_offset is set, but we don't want to
861 advance the raw cursor past good packets just to get to the first
862 with a granulepos. That's not equivalent behavior to beginning
863 decoding as immediately after the seek position as possible.
865 So, a hack. We use two stream states; a local scratch state and
866 a the shared vf->os stream state. We use the local state to
867 scan, and the shared state as a buffer for later decode.
869 Unfortuantely, on the last page we still advance to last packet
870 because the granulepos on the last page is not necessarily on a
871 packet boundary, and we need to make sure the granpos is
883 memset(&work_os,0,sizeof(work_os));/* so that it's safe to clear
884 it later even if we don't
888 if(vf->ready_state==STREAMSET){
889 /* snarf/scan a packet if we can */
890 int result=ogg_stream_packetout(&work_os,&op);
894 if(vf->vi[vf->current_link].codec_setup)
895 thisblock=vorbis_packet_blocksize(vf->vi+vf->current_link,&op);
897 ogg_stream_packetout(&vf->os,NULL);
899 if(lastblock)accblock+=(lastblock+thisblock)>>2;
901 if(op.granulepos!=-1){
902 int i,link=vf->current_link;
903 ogg_int64_t granulepos=op.granulepos;
906 granulepos+=vf->pcmlengths[i];
907 vf->pcm_offset=granulepos-accblock;
916 if(_get_next_page(vf,&og,-1)<0){
917 vf->pcm_offset=ov_pcm_total(vf,-1);
921 /* huh? Bogus stream with packets but no granulepos */
926 /* has our decoding just traversed a bitstream boundary? */
927 if(vf->ready_state==STREAMSET)
928 if(vf->current_serialno!=ogg_page_serialno(&og)){
929 _decode_clear(vf); /* clear out stream state */
930 ogg_stream_clear(&work_os);
933 if(vf->ready_state<STREAMSET){
936 vf->current_serialno=ogg_page_serialno(&og);
937 for(link=0;link<vf->links;link++)
938 if(vf->serialnos[link]==vf->current_serialno)break;
939 if(link==vf->links)goto seek_error; /* sign of a bogus stream.
941 machine uninitialized */
942 vf->current_link=link;
944 ogg_stream_init(&vf->os,vf->current_serialno);
945 ogg_stream_reset(&vf->os);
946 ogg_stream_init(&work_os,vf->current_serialno);
947 ogg_stream_reset(&work_os);
948 vf->ready_state=STREAMSET;
952 ogg_stream_pagein(&vf->os,&og);
953 ogg_stream_pagein(&work_os,&og);
954 eosflag=ogg_page_eos(&og);
958 ogg_stream_clear(&work_os);
962 /* dump the machine so we're in a known state */
964 ogg_stream_clear(&work_os);
969 /* Page granularity seek (faster than sample granularity because we
970 don't do the last bit of decode to find a specific sample).
972 Seek to the last [granule marked] page preceeding the specified pos
973 location, such that decoding past the returned point will quickly
974 arrive at the requested position. */
975 int ov_pcm_seek_page(OggVorbis_File *vf,ogg_int64_t pos){
978 ogg_int64_t total=ov_pcm_total(vf,-1);
980 if(vf->ready_state<OPENED)return(OV_EINVAL);
981 if(!vf->seekable)return(OV_ENOSEEK);
982 if(pos<0 || pos>total)return(OV_EINVAL);
984 /* which bitstream section does this pcm offset occur in? */
985 for(link=vf->links-1;link>=0;link--){
986 total-=vf->pcmlengths[link];
990 /* search within the logical bitstream for the page with the highest
991 pcm_pos preceeding (or equal to) pos. There is a danger here;
992 missing pages or incorrect frame number information in the
993 bitstream could make our task impossible. Account for that (it
994 would be an error condition) */
996 /* new search algorithm by HB (Nicholas Vinen) */
998 ogg_int64_t target=pos-total;
999 long end=vf->offsets[link+1];
1000 long begin=vf->offsets[link];
1001 ogg_int64_t endtime = vf->pcmlengths[link];
1002 ogg_int64_t begintime = 0;
1009 if(end-begin<CHUNKSIZE){
1012 /* take a (pretty decent) guess. */
1014 (target-begintime)*(end-begin)/(endtime-begintime) - CHUNKSIZE;
1018 _seek_helper(vf,bisect);
1021 ret=_get_next_page(vf,&og,end-bisect);
1022 if(ret==OV_EREAD) goto seek_error;
1025 end=begin; /* found it */
1027 if(bisect==0)goto seek_error;
1029 if(bisect<=begin)bisect=begin+1;
1030 _seek_helper(vf,bisect);
1033 ogg_int64_t granulepos=ogg_page_granulepos(&og);
1034 if(granulepos<target){
1035 best=ret; /* raw offset of packet with granulepos */
1036 begin=vf->offset; /* raw offset of next page */
1037 begintime=granulepos;
1039 if(target-begin>44100)break;
1040 bisect=begin; /* *not* begin + 1 */
1043 end=begin; /* found it */
1045 if(end==vf->offset){ /* we're pretty close - we'd be stuck in */
1047 bisect-=CHUNKSIZE; /* an endless loop otherwise. */
1048 if(bisect<=begin)bisect=begin+1;
1049 _seek_helper(vf,bisect);
1061 /* found our page. seek to it, update pcm offset. Easier case than
1062 raw_seek, don't keep packets preceeding granulepos. */
1066 /* clear out decoding machine state */
1069 _seek_helper(vf,best);
1071 if(_get_next_page(vf,&og,-1)<0)return(OV_EOF); /* shouldn't happen */
1072 vf->current_serialno=ogg_page_serialno(&og);
1073 vf->current_link=link;
1075 ogg_stream_init(&vf->os,vf->current_serialno);
1076 ogg_stream_reset(&vf->os);
1077 vf->ready_state=STREAMSET;
1078 ogg_stream_pagein(&vf->os,&og);
1080 /* pull out all but last packet; the one with granulepos */
1082 ret=ogg_stream_packetpeek(&vf->os,&op);
1084 /* !!! the packet finishing this page originated on a
1085 preceeding page. Keep fetching previous pages until we
1086 get one with a granulepos or without the 'continued' flag
1087 set. Then just use raw_seek for simplicity. */
1089 ret=_get_prev_page(vf,&og);
1090 if(ret<0)goto seek_error;
1091 if(ogg_page_granulepos(&og)>-1 ||
1092 !ogg_page_continued(&og)){
1093 return ov_raw_seek(vf,ret);
1098 if(ret<0)goto seek_error;
1099 if(op.granulepos!=-1){
1100 vf->pcm_offset=op.granulepos+total;
1103 ret=ogg_stream_packetout(&vf->os,NULL);
1109 if(vf->pcm_offset>pos || pos>ov_pcm_total(vf,-1)){
1116 /* dump machine so we're in a known state */
1122 /* seek to a sample offset relative to the decompressed pcm stream
1123 returns zero on success, nonzero on failure */
1125 int ov_pcm_seek(OggVorbis_File *vf,ogg_int64_t pos){
1126 int thisblock,lastblock=0;
1127 int ret=ov_pcm_seek_page(vf,pos);
1128 codec_setup_info *ci=vf->vi->codec_setup;
1129 if(ret<0)return(ret);
1131 /* discard leading packets we don't need for the lapping of the
1132 position we want; don't decode them */
1138 int ret=ogg_stream_packetpeek(&vf->os,&op);
1140 thisblock=vorbis_packet_blocksize(vf->vi+vf->current_link,&op);
1141 if(lastblock)vf->pcm_offset+=(lastblock+thisblock)>>2;
1143 if(vf->pcm_offset+((thisblock+ci->blocksizes[1])>>2)>=pos)break;
1145 ogg_stream_packetout(&vf->os,NULL);
1148 /* end of logical stream case is hard, especially with exact
1149 length positioning. */
1151 if(op.granulepos>-1){
1153 /* always believe the stream markers */
1154 vf->pcm_offset=op.granulepos;
1155 for(i=0;i<vf->current_link;i++)
1156 vf->pcm_offset+=vf->pcmlengths[i];
1159 lastblock=thisblock;
1162 if(ret<0 && ret!=OV_HOLE)break;
1164 /* suck in a new page */
1165 if(_get_next_page(vf,&og,-1)<0)break;
1166 if(vf->current_serialno!=ogg_page_serialno(&og))_decode_clear(vf);
1168 if(vf->ready_state<STREAMSET){
1171 vf->current_serialno=ogg_page_serialno(&og);
1172 for(link=0;link<vf->links;link++)
1173 if(vf->serialnos[link]==vf->current_serialno)break;
1174 if(link==vf->links)return(OV_EBADLINK);
1175 vf->current_link=link;
1177 ogg_stream_init(&vf->os,vf->current_serialno);
1178 ogg_stream_reset(&vf->os);
1179 vf->ready_state=STREAMSET;
1182 ogg_stream_pagein(&vf->os,&og);
1186 /* discard samples until we reach the desired position. Crossing a
1187 logical bitstream boundary with abandon is OK. */
1188 _make_decode_ready(vf);
1189 while(vf->pcm_offset<pos){
1191 long target=pos-vf->pcm_offset;
1192 long samples=vorbis_synthesis_pcmout(&vf->vd,&pcm);
1194 if(samples>target)samples=target;
1195 vorbis_synthesis_read(&vf->vd,samples);
1196 vf->pcm_offset+=samples;
1199 if(_process_packet(vf,1)<=0)
1200 vf->pcm_offset=ov_pcm_total(vf,-1); /* eof */
1205 /* seek to a playback time relative to the decompressed pcm stream
1206 returns zero on success, nonzero on failure */
1207 int ov_time_seek(OggVorbis_File *vf,double seconds){
1208 /* translate time to PCM position and call ov_pcm_seek */
1211 ogg_int64_t pcm_total=ov_pcm_total(vf,-1);
1212 double time_total=ov_time_total(vf,-1);
1214 if(vf->ready_state<OPENED)return(OV_EINVAL);
1215 if(!vf->seekable)return(OV_ENOSEEK);
1216 if(seconds<0 || seconds>time_total)return(OV_EINVAL);
1218 /* which bitstream section does this time offset occur in? */
1219 for(link=vf->links-1;link>=0;link--){
1220 pcm_total-=vf->pcmlengths[link];
1221 time_total-=ov_time_total(vf,link);
1222 if(seconds>=time_total)break;
1225 /* enough information to convert time offset to pcm offset */
1227 ogg_int64_t target=pcm_total+(seconds-time_total)*vf->vi[link].rate;
1228 return(ov_pcm_seek(vf,target));
1232 /* page-granularity version of ov_time_seek
1233 returns zero on success, nonzero on failure */
1234 int ov_time_seek_page(OggVorbis_File *vf,double seconds){
1235 /* translate time to PCM position and call ov_pcm_seek */
1238 ogg_int64_t pcm_total=ov_pcm_total(vf,-1);
1239 double time_total=ov_time_total(vf,-1);
1241 if(vf->ready_state<OPENED)return(OV_EINVAL);
1242 if(!vf->seekable)return(OV_ENOSEEK);
1243 if(seconds<0 || seconds>time_total)return(OV_EINVAL);
1245 /* which bitstream section does this time offset occur in? */
1246 for(link=vf->links-1;link>=0;link--){
1247 pcm_total-=vf->pcmlengths[link];
1248 time_total-=ov_time_total(vf,link);
1249 if(seconds>=time_total)break;
1252 /* enough information to convert time offset to pcm offset */
1254 ogg_int64_t target=pcm_total+(seconds-time_total)*vf->vi[link].rate;
1255 return(ov_pcm_seek_page(vf,target));
1259 /* tell the current stream offset cursor. Note that seek followed by
1260 tell will likely not give the set offset due to caching */
1261 ogg_int64_t ov_raw_tell(OggVorbis_File *vf){
1262 if(vf->ready_state<OPENED)return(OV_EINVAL);
1266 /* return PCM offset (sample) of next PCM sample to be read */
1267 ogg_int64_t ov_pcm_tell(OggVorbis_File *vf){
1268 if(vf->ready_state<OPENED)return(OV_EINVAL);
1269 return(vf->pcm_offset);
1272 /* return time offset (seconds) of next PCM sample to be read */
1273 double ov_time_tell(OggVorbis_File *vf){
1274 /* translate time to PCM position and call ov_pcm_seek */
1277 ogg_int64_t pcm_total=0;
1278 double time_total=0.f;
1280 if(vf->ready_state<OPENED)return(OV_EINVAL);
1282 pcm_total=ov_pcm_total(vf,-1);
1283 time_total=ov_time_total(vf,-1);
1285 /* which bitstream section does this time offset occur in? */
1286 for(link=vf->links-1;link>=0;link--){
1287 pcm_total-=vf->pcmlengths[link];
1288 time_total-=ov_time_total(vf,link);
1289 if(vf->pcm_offset>=pcm_total)break;
1293 return((double)time_total+(double)(vf->pcm_offset-pcm_total)/vf->vi[link].rate);
1296 /* link: -1) return the vorbis_info struct for the bitstream section
1297 currently being decoded
1298 0-n) to request information for a specific bitstream section
1300 In the case of a non-seekable bitstream, any call returns the
1301 current bitstream. NULL in the case that the machine is not
1304 vorbis_info *ov_info(OggVorbis_File *vf,int link){
1307 if(vf->ready_state>=STREAMSET)
1308 return vf->vi+vf->current_link;
1321 /* grr, strong typing, grr, no templates/inheritence, grr */
1322 vorbis_comment *ov_comment(OggVorbis_File *vf,int link){
1325 if(vf->ready_state>=STREAMSET)
1326 return vf->vc+vf->current_link;
1339 int host_is_big_endian() {
1340 ogg_int32_t pattern = 0xfeedface; /* deadbeef */
1341 unsigned char *bytewise = (unsigned char *)&pattern;
1342 if (bytewise[0] == 0xfe) return 1;
1346 /* up to this point, everything could more or less hide the multiple
1347 logical bitstream nature of chaining from the toplevel application
1348 if the toplevel application didn't particularly care. However, at
1349 the point that we actually read audio back, the multiple-section
1350 nature must surface: Multiple bitstream sections do not necessarily
1351 have to have the same number of channels or sampling rate.
1353 ov_read returns the sequential logical bitstream number currently
1354 being decoded along with the PCM data in order that the toplevel
1355 application can take action on channel/sample rate changes. This
1356 number will be incremented even for streamed (non-seekable) streams
1357 (for seekable streams, it represents the actual logical bitstream
1358 index within the physical bitstream. Note that the accessor
1359 functions above are aware of this dichotomy).
1361 input values: buffer) a buffer to hold packed PCM data for return
1362 length) the byte length requested to be placed into buffer
1363 bigendianp) should the data be packed LSB first (0) or
1365 word) word size for output. currently 1 (byte) or
1368 return values: <0) error/hole in data (OV_HOLE), partial open (OV_EINVAL)
1370 n) number of bytes of PCM actually returned. The
1371 below works on a packet-by-packet basis, so the
1372 return length is not related to the 'length' passed
1373 in, just guaranteed to fit.
1375 *section) set to the logical bitstream number */
1377 long ov_read(OggVorbis_File *vf,char *buffer,int length,
1378 int bigendianp,int word,int sgned,int *bitstream){
1380 int host_endian = host_is_big_endian();
1382 if(vf->ready_state<OPENED)return(OV_EINVAL);
1385 if(vf->ready_state>=STREAMSET){
1387 long samples=vorbis_synthesis_pcmout(&vf->vd,&pcm);
1389 /* yay! proceed to pack data into the byte buffer */
1391 long channels=ov_info(vf,-1)->channels;
1392 long bytespersample=word * channels;
1393 vorbis_fpu_control fpu;
1394 if(samples>length/bytespersample)samples=length/bytespersample;
1396 /* a tight loop to pack each size */
1400 int off=(sgned?0:128);
1401 vorbis_fpu_setround(&fpu);
1402 for(j=0;j<samples;j++)
1403 for(i=0;i<channels;i++){
1404 val=vorbis_ftoi(pcm[i][j]*128.f);
1406 else if(val<-128)val=-128;
1409 vorbis_fpu_restore(fpu);
1411 int off=(sgned?0:32768);
1413 if(host_endian==bigendianp){
1416 vorbis_fpu_setround(&fpu);
1417 for(i=0;i<channels;i++) { /* It's faster in this order */
1419 short *dest=((short *)buffer)+i;
1420 for(j=0;j<samples;j++) {
1421 val=vorbis_ftoi(src[j]*32768.f);
1422 if(val>32767)val=32767;
1423 else if(val<-32768)val=-32768;
1428 vorbis_fpu_restore(fpu);
1432 vorbis_fpu_setround(&fpu);
1433 for(i=0;i<channels;i++) {
1435 short *dest=((short *)buffer)+i;
1436 for(j=0;j<samples;j++) {
1437 val=vorbis_ftoi(src[j]*32768.f);
1438 if(val>32767)val=32767;
1439 else if(val<-32768)val=-32768;
1444 vorbis_fpu_restore(fpu);
1447 }else if(bigendianp){
1449 vorbis_fpu_setround(&fpu);
1450 for(j=0;j<samples;j++)
1451 for(i=0;i<channels;i++){
1452 val=vorbis_ftoi(pcm[i][j]*32768.f);
1453 if(val>32767)val=32767;
1454 else if(val<-32768)val=-32768;
1457 *buffer++=(val&0xff);
1459 vorbis_fpu_restore(fpu);
1463 vorbis_fpu_setround(&fpu);
1464 for(j=0;j<samples;j++)
1465 for(i=0;i<channels;i++){
1466 val=vorbis_ftoi(pcm[i][j]*32768.f);
1467 if(val>32767)val=32767;
1468 else if(val<-32768)val=-32768;
1470 *buffer++=(val&0xff);
1473 vorbis_fpu_restore(fpu);
1479 vorbis_synthesis_read(&vf->vd,samples);
1480 vf->pcm_offset+=samples;
1481 if(bitstream)*bitstream=vf->current_link;
1482 return(samples*bytespersample);
1486 /* suck in another packet */
1488 int ret=_process_packet(vf,1);
1489 if(ret==OV_EOF)return(0);
1490 if(ret<=0)return(ret);