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.48 2001/06/02 11:38:14 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;
145 _seek_helper(vf,begin);
146 while(vf->offset<begin+CHUNKSIZE){
147 ret=_get_next_page(vf,og,begin+CHUNKSIZE-vf->offset);
148 if(ret==OV_EREAD)return(OV_EREAD);
157 /* we have the offset. Actually snork and hold the page now */
158 _seek_helper(vf,offset);
159 ret=_get_next_page(vf,og,CHUNKSIZE);
161 /* this shouldn't be possible */
167 /* finds each bitstream link one at a time using a bisection search
168 (has to begin by knowing the offset of the lb's initial page).
169 Recurses for each link so it can alloc the link storage after
170 finding them all, then unroll and fill the cache at the same time */
171 static int _bisect_forward_serialno(OggVorbis_File *vf,
177 long endsearched=end;
182 /* the below guards against garbage seperating the last and
183 first pages of two links. */
184 while(searched<endsearched){
187 if(endsearched-searched<CHUNKSIZE){
190 bisect=(searched+endsearched)/2;
193 _seek_helper(vf,bisect);
194 ret=_get_next_page(vf,&og,-1);
195 if(ret==OV_EREAD)return(OV_EREAD);
196 if(ret<0 || ogg_page_serialno(&og)!=currentno){
200 searched=ret+og.header_len+og.body_len;
204 _seek_helper(vf,next);
205 ret=_get_next_page(vf,&og,-1);
206 if(ret==OV_EREAD)return(OV_EREAD);
208 if(searched>=end || ret<0){
210 vf->offsets=_ogg_malloc((m+2)*sizeof(ogg_int64_t));
211 vf->offsets[m+1]=searched;
213 ret=_bisect_forward_serialno(vf,next,vf->offset,
214 end,ogg_page_serialno(&og),m+1);
215 if(ret==OV_EREAD)return(OV_EREAD);
218 vf->offsets[m]=begin;
222 /* uses the local ogg_stream storage in vf; this is important for
223 non-streaming input sources */
224 static int _fetch_headers(OggVorbis_File *vf,vorbis_info *vi,vorbis_comment *vc,
225 long *serialno,ogg_page *og_ptr){
231 ret=_get_next_page(vf,&og,CHUNKSIZE);
232 if(ret==OV_EREAD)return(OV_EREAD);
233 if(ret<0)return OV_ENOTVORBIS;
237 if(serialno)*serialno=ogg_page_serialno(og_ptr);
238 ogg_stream_init(&vf->os,ogg_page_serialno(og_ptr));
239 vf->ready_state=STREAMSET;
241 /* extract the initial header from the first page and verify that the
242 Ogg bitstream is in fact Vorbis data */
244 vorbis_info_init(vi);
245 vorbis_comment_init(vc);
249 ogg_stream_pagein(&vf->os,og_ptr);
251 int result=ogg_stream_packetout(&vf->os,&op);
257 if((ret=vorbis_synthesis_headerin(vi,vc,&op))){
263 if(_get_next_page(vf,og_ptr,1)<0){
271 vorbis_info_clear(vi);
272 vorbis_comment_clear(vc);
273 ogg_stream_clear(&vf->os);
277 /* last step of the OggVorbis_File initialization; get all the
278 vorbis_info structs and PCM positions. Only called by the seekable
279 initialization (local stream storage is hacked slightly; pay
280 attention to how that's done) */
282 /* this is void and does not propogate errors up because we want to be
283 able to open and use damaged bitstreams as well as we can. Just
284 watch out for missing information for links in the OggVorbis_File
286 static void _prefetch_all_headers(OggVorbis_File *vf, long dataoffset){
290 vf->vi=_ogg_realloc(vf->vi,vf->links*sizeof(vorbis_info));
291 vf->vc=_ogg_realloc(vf->vc,vf->links*sizeof(vorbis_info));
292 vf->dataoffsets=_ogg_malloc(vf->links*sizeof(ogg_int64_t));
293 vf->pcmlengths=_ogg_malloc(vf->links*sizeof(ogg_int64_t));
294 vf->serialnos=_ogg_malloc(vf->links*sizeof(long));
296 for(i=0;i<vf->links;i++){
298 /* we already grabbed the initial header earlier. Just set the offset */
299 vf->dataoffsets[i]=dataoffset;
302 /* seek to the location of the initial header */
304 _seek_helper(vf,vf->offsets[i]);
305 if(_fetch_headers(vf,vf->vi+i,vf->vc+i,NULL,NULL)<0){
306 vf->dataoffsets[i]=-1;
308 vf->dataoffsets[i]=vf->offset;
309 ogg_stream_clear(&vf->os);
313 /* get the serial number and PCM length of this link. To do this,
314 get the last page of the stream */
316 long end=vf->offsets[i+1];
317 _seek_helper(vf,end);
320 ret=_get_prev_page(vf,&og);
322 /* this should not be possible */
323 vorbis_info_clear(vf->vi+i);
324 vorbis_comment_clear(vf->vc+i);
327 if(ogg_page_granulepos(&og)!=-1){
328 vf->serialnos[i]=ogg_page_serialno(&og);
329 vf->pcmlengths[i]=ogg_page_granulepos(&og);
338 static void _make_decode_ready(OggVorbis_File *vf){
339 if(vf->ready_state!=STREAMSET)return;
341 vorbis_synthesis_init(&vf->vd,vf->vi+vf->current_link);
343 vorbis_synthesis_init(&vf->vd,vf->vi);
345 vorbis_block_init(&vf->vd,&vf->vb);
346 vf->ready_state=INITSET;
350 static int _open_seekable2(OggVorbis_File *vf){
351 long serialno=vf->current_serialno,end;
352 long dataoffset=vf->offset;
355 /* we're partially open and have a first link header state in
357 /* we can seek, so set out learning all about this file */
358 (vf->callbacks.seek_func)(vf->datasource,0,SEEK_END);
359 vf->offset=vf->end=(vf->callbacks.tell_func)(vf->datasource);
361 /* We get the offset for the last page of the physical bitstream.
362 Most OggVorbis files will contain a single logical bitstream */
363 end=_get_prev_page(vf,&og);
369 /* more than one logical bitstream? */
370 if(ogg_page_serialno(&og)!=serialno){
372 /* Chained bitstream. Bisect-search each logical bitstream
373 section. Do so based on serial number only */
374 if(_bisect_forward_serialno(vf,0,0,end+1,serialno,0)<0){
381 /* Only one logical bitstream */
382 if(_bisect_forward_serialno(vf,0,end,end+1,serialno,0)){
389 /* the initial header memory is referenced by vf after; don't free it */
390 _prefetch_all_headers(vf,dataoffset);
391 return(ov_raw_seek(vf,0));
394 /* clear out the current logical bitstream decoder */
395 static void _decode_clear(OggVorbis_File *vf){
396 ogg_stream_clear(&vf->os);
397 vorbis_dsp_clear(&vf->vd);
398 vorbis_block_clear(&vf->vb);
399 vf->ready_state=OPENED;
405 /* fetch and process a packet. Handles the case where we're at a
406 bitstream boundary and dumps the decoding machine. If the decoding
407 machine is unloaded, it loads it. It also keeps pcm_offset up to
408 date (seek and read both use this. seek uses a special hack with
411 return: <0) error, OV_HOLE (lost packet) or OV_EOF
412 0) need more data (only if readp==0)
416 static int _process_packet(OggVorbis_File *vf,int readp){
419 /* handle one packet. Try to fetch it from current stream state */
420 /* extract packets from page */
423 /* process a packet if we can. If the machine isn't loaded,
425 if(vf->ready_state==INITSET){
427 int result=ogg_stream_packetout(&vf->os,&op);
428 ogg_int64_t granulepos;
430 if(result==-1)return(OV_HOLE); /* hole in the data. */
432 /* got a packet. process it */
433 granulepos=op.granulepos;
434 if(!vorbis_synthesis(&vf->vb,&op)){ /* lazy check for lazy
436 header packets aren't
439 vorbis_synthesis will
442 /* suck in the synthesis data and track bitrate */
444 int oldsamples=vorbis_synthesis_pcmout(&vf->vd,NULL);
445 vorbis_synthesis_blockin(&vf->vd,&vf->vb);
446 vf->samptrack+=vorbis_synthesis_pcmout(&vf->vd,NULL)-oldsamples;
447 vf->bittrack+=op.bytes*8;
450 /* update the pcm offset. */
451 if(granulepos!=-1 && !op.e_o_s){
452 int link=(vf->seekable?vf->current_link:0);
455 /* this packet has a pcm_offset on it (the last packet
456 completed on a page carries the offset) After processing
457 (above), we know the pcm position of the *last* sample
458 ready to be returned. Find the offset of the *first*
460 As an aside, this trick is inaccurate if we begin
461 reading anew right at the last page; the end-of-stream
462 granulepos declares the last frame in the stream, and the
463 last packet of the last page may be a partial frame.
464 So, we need a previous granulepos from an in-sequence page
465 to have a reference point. Thus the !op.e_o_s clause
468 samples=vorbis_synthesis_pcmout(&vf->vd,NULL);
472 granulepos+=vf->pcmlengths[i];
473 vf->pcm_offset=granulepos;
480 if(vf->ready_state>=STREAMSET){
482 if(_get_next_page(vf,&og,-1)<0)return(OV_EOF); /* eof.
485 /* bitrate tracking; add the header's bytes here, the body bytes
486 are done by packet above */
487 vf->bittrack+=og.header_len*8;
489 /* has our decoding just traversed a bitstream boundary? */
490 if(vf->ready_state==INITSET){
491 if(vf->current_serialno!=ogg_page_serialno(&og)){
495 vorbis_info_clear(vf->vi);
496 vorbis_comment_clear(vf->vc);
502 /* Do we need to load a new machine before submitting the page? */
503 /* This is different in the seekable and non-seekable cases.
505 In the seekable case, we already have all the header
506 information loaded and cached; we just initialize the machine
507 with it and continue on our merry way.
509 In the non-seekable (streaming) case, we'll only be at a
510 boundary if we just left the previous logical bitstream and
511 we're now nominally at the header of the next bitstream
514 if(vf->ready_state!=INITSET){
517 if(vf->ready_state<STREAMSET){
519 vf->current_serialno=ogg_page_serialno(&og);
521 /* match the serialno to bitstream section. We use this rather than
522 offset positions to avoid problems near logical bitstream
524 for(link=0;link<vf->links;link++)
525 if(vf->serialnos[link]==vf->current_serialno)break;
526 if(link==vf->links)return(OV_EBADLINK); /* sign of a bogus
531 vf->current_link=link;
533 ogg_stream_init(&vf->os,vf->current_serialno);
534 ogg_stream_reset(&vf->os);
535 vf->ready_state=STREAMSET;
538 /* we're streaming */
539 /* fetch the three header packets, build the info struct */
541 _fetch_headers(vf,vf->vi,vf->vc,&vf->current_serialno,&og);
547 _make_decode_ready(vf);
549 ogg_stream_pagein(&vf->os,&og);
553 static int _fseek64_wrap(FILE *f,ogg_int64_t off,int whence){
554 if(f==NULL)return(-1);
555 return fseek(f,(int)off,whence);
558 static int _ov_open1(void *f,OggVorbis_File *vf,char *initial,
559 long ibytes, ov_callbacks callbacks){
560 long offset=(f?callbacks.seek_func(f,0,SEEK_CUR):-1);
563 memset(vf,0,sizeof(OggVorbis_File));
565 vf->callbacks = callbacks;
567 /* init the framing state */
568 ogg_sync_init(&vf->oy);
570 /* perhaps some data was previously read into a buffer for testing
571 against other stream types. Allow initialization from this
572 previously read data (as we may be reading from a non-seekable
575 char *buffer=ogg_sync_buffer(&vf->oy,ibytes);
576 memcpy(buffer,initial,ibytes);
577 ogg_sync_wrote(&vf->oy,ibytes);
580 /* can we seek? Stevens suggests the seek test was portable */
581 if(offset!=-1)vf->seekable=1;
583 /* No seeking yet; Set up a 'single' (current) logical bitstream
584 entry for partial open */
586 vf->vi=_ogg_calloc(vf->links,sizeof(vorbis_info));
587 vf->vc=_ogg_calloc(vf->links,sizeof(vorbis_info));
589 /* Try to fetch the headers, maintaining all the storage */
590 if((ret=_fetch_headers(vf,vf->vi,vf->vc,&vf->current_serialno,NULL))<0){
593 }else if(vf->ready_state < PARTOPEN)
594 vf->ready_state=PARTOPEN;
598 static int _ov_open2(OggVorbis_File *vf){
599 if(vf->ready_state < OPENED)
600 vf->ready_state=OPENED;
602 int ret=_open_seekable2(vf);
613 /* clear out the OggVorbis_File struct */
614 int ov_clear(OggVorbis_File *vf){
616 vorbis_block_clear(&vf->vb);
617 vorbis_dsp_clear(&vf->vd);
618 ogg_stream_clear(&vf->os);
620 if(vf->vi && vf->links){
622 for(i=0;i<vf->links;i++){
623 vorbis_info_clear(vf->vi+i);
624 vorbis_comment_clear(vf->vc+i);
629 if(vf->dataoffsets)_ogg_free(vf->dataoffsets);
630 if(vf->pcmlengths)_ogg_free(vf->pcmlengths);
631 if(vf->serialnos)_ogg_free(vf->serialnos);
632 if(vf->offsets)_ogg_free(vf->offsets);
633 ogg_sync_clear(&vf->oy);
634 if(vf->datasource)(vf->callbacks.close_func)(vf->datasource);
635 memset(vf,0,sizeof(OggVorbis_File));
643 /* inspects the OggVorbis file and finds/documents all the logical
644 bitstreams contained in it. Tries to be tolerant of logical
645 bitstream sections that are truncated/woogie.
651 int ov_open_callbacks(void *f,OggVorbis_File *vf,char *initial,long ibytes,
652 ov_callbacks callbacks){
653 int ret=_ov_open1(f,vf,initial,ibytes,callbacks);
655 return _ov_open2(vf);
658 int ov_open(FILE *f,OggVorbis_File *vf,char *initial,long ibytes){
659 ov_callbacks callbacks = {
660 (size_t (*)(void *, size_t, size_t, void *)) fread,
661 (int (*)(void *, ogg_int64_t, int)) _fseek64_wrap,
662 (int (*)(void *)) fclose,
663 (long (*)(void *)) ftell
666 return ov_open_callbacks((void *)f, vf, initial, ibytes, callbacks);
669 /* Only partially open the vorbis file; test for Vorbisness, and load
670 the headers for the first chain. Do not seek (although test for
671 seekability). Use ov_test_open to finish opening the file, else
672 ov_clear to close/free it. Same return codes as open. */
674 int ov_test_callbacks(void *f,OggVorbis_File *vf,char *initial,long ibytes,
675 ov_callbacks callbacks)
677 return _ov_open1(f,vf,initial,ibytes,callbacks);
680 int ov_test(FILE *f,OggVorbis_File *vf,char *initial,long ibytes){
681 ov_callbacks callbacks = {
682 (size_t (*)(void *, size_t, size_t, void *)) fread,
683 (int (*)(void *, ogg_int64_t, int)) _fseek64_wrap,
684 (int (*)(void *)) fclose,
685 (long (*)(void *)) ftell
688 return ov_test_callbacks((void *)f, vf, initial, ibytes, callbacks);
691 int ov_test_open(OggVorbis_File *vf){
692 if(vf->ready_state!=PARTOPEN)return(OV_EINVAL);
693 return _ov_open2(vf);
696 /* How many logical bitstreams in this physical bitstream? */
697 long ov_streams(OggVorbis_File *vf){
701 /* Is the FILE * associated with vf seekable? */
702 long ov_seekable(OggVorbis_File *vf){
706 /* returns the bitrate for a given logical bitstream or the entire
707 physical bitstream. If the file is open for random access, it will
708 find the *actual* average bitrate. If the file is streaming, it
709 returns the nominal bitrate (if set) else the average of the
710 upper/lower bounds (if set) else -1 (unset).
712 If you want the actual bitrate field settings, get them from the
713 vorbis_info structs */
715 long ov_bitrate(OggVorbis_File *vf,int i){
716 if(vf->ready_state<OPENED)return(OV_EINVAL);
717 if(i>=vf->links)return(OV_EINVAL);
718 if(!vf->seekable && i!=0)return(ov_bitrate(vf,0));
722 for(i=0;i<vf->links;i++)
723 bits+=(vf->offsets[i+1]-vf->dataoffsets[i])*8;
724 return(rint(bits/ov_time_total(vf,-1)));
727 /* return the actual bitrate */
728 return(rint((vf->offsets[i+1]-vf->dataoffsets[i])*8/ov_time_total(vf,i)));
730 /* return nominal if set */
731 if(vf->vi[i].bitrate_nominal>0){
732 return vf->vi[i].bitrate_nominal;
734 if(vf->vi[i].bitrate_upper>0){
735 if(vf->vi[i].bitrate_lower>0){
736 return (vf->vi[i].bitrate_upper+vf->vi[i].bitrate_lower)/2;
738 return vf->vi[i].bitrate_upper;
747 /* returns the actual bitrate since last call. returns -1 if no
748 additional data to offer since last call (or at beginning of stream),
749 EINVAL if stream is only partially open
751 long ov_bitrate_instant(OggVorbis_File *vf){
752 int link=(vf->seekable?vf->current_link:0);
754 if(vf->ready_state<OPENED)return(OV_EINVAL);
755 if(vf->samptrack==0)return(OV_FALSE);
756 ret=vf->bittrack/vf->samptrack*vf->vi[link].rate+.5;
763 long ov_serialnumber(OggVorbis_File *vf,int i){
764 if(i>=vf->links)return(ov_serialnumber(vf,vf->links-1));
765 if(!vf->seekable && i>=0)return(ov_serialnumber(vf,-1));
767 return(vf->current_serialno);
769 return(vf->serialnos[i]);
773 /* returns: total raw (compressed) length of content if i==-1
774 raw (compressed) length of that logical bitstream for i==0 to n
775 OV_EINVAL if the stream is not seekable (we can't know the length)
776 or if stream is only partially open
778 ogg_int64_t ov_raw_total(OggVorbis_File *vf,int i){
779 if(vf->ready_state<OPENED)return(OV_EINVAL);
780 if(!vf->seekable || i>=vf->links)return(OV_EINVAL);
784 for(i=0;i<vf->links;i++)
785 acc+=ov_raw_total(vf,i);
788 return(vf->offsets[i+1]-vf->offsets[i]);
792 /* returns: total PCM length (samples) of content if i==-1 PCM length
793 (samples) of that logical bitstream for i==0 to n
794 OV_EINVAL if the stream is not seekable (we can't know the
795 length) or only partially open
797 ogg_int64_t ov_pcm_total(OggVorbis_File *vf,int i){
798 if(vf->ready_state<OPENED)return(OV_EINVAL);
799 if(!vf->seekable || i>=vf->links)return(OV_EINVAL);
803 for(i=0;i<vf->links;i++)
804 acc+=ov_pcm_total(vf,i);
807 return(vf->pcmlengths[i]);
811 /* returns: total seconds of content if i==-1
812 seconds in that logical bitstream for i==0 to n
813 OV_EINVAL if the stream is not seekable (we can't know the
814 length) or only partially open
816 double ov_time_total(OggVorbis_File *vf,int i){
817 if(vf->ready_state<OPENED)return(OV_EINVAL);
818 if(!vf->seekable || i>=vf->links)return(OV_EINVAL);
822 for(i=0;i<vf->links;i++)
823 acc+=ov_time_total(vf,i);
826 return((float)(vf->pcmlengths[i])/vf->vi[i].rate);
830 /* seek to an offset relative to the *compressed* data. This also
831 scans packets to update the PCM cursor. It will cross a logical
832 bitstream boundary, but only if it can't get any packets out of the
833 tail of the bitstream we seek to (so no surprises).
835 returns zero on success, nonzero on failure */
837 int ov_raw_seek(OggVorbis_File *vf,long pos){
838 ogg_stream_state work_os;
840 if(vf->ready_state<OPENED)return(OV_EINVAL);
842 return(OV_ENOSEEK); /* don't dump machine if we can't seek */
844 if(pos<0 || pos>vf->offsets[vf->links])return(OV_EINVAL);
846 /* clear out decoding machine state */
850 _seek_helper(vf,pos);
852 /* we need to make sure the pcm_offset is set, but we don't want to
853 advance the raw cursor past good packets just to get to the first
854 with a granulepos. That's not equivalent behavior to beginning
855 decoding as immediately after the seek position as possible.
857 So, a hack. We use two stream states; a local scratch state and
858 a the shared vf->os stream state. We use the local state to
859 scan, and the shared state as a buffer for later decode.
861 Unfortuantely, on the last page we still advance to last packet
862 because the granulepos on the last page is not necessarily on a
863 packet boundary, and we need to make sure the granpos is
875 memset(&work_os,0,sizeof(work_os));/* so that it's safe to clear
876 it later even if we don't
880 if(vf->ready_state==STREAMSET){
881 /* snarf/scan a packet if we can */
882 int result=ogg_stream_packetout(&work_os,&op);
886 if(vf->vi[vf->current_link].codec_setup)
887 thisblock=vorbis_packet_blocksize(vf->vi+vf->current_link,&op);
889 ogg_stream_packetout(&vf->os,NULL);
891 if(lastblock)accblock+=(lastblock+thisblock)>>2;
893 if(op.granulepos!=-1){
894 int i,link=vf->current_link;
895 ogg_int64_t granulepos=op.granulepos;
898 granulepos+=vf->pcmlengths[i];
899 vf->pcm_offset=granulepos-accblock;
908 if(_get_next_page(vf,&og,-1)<0){
909 vf->pcm_offset=ov_pcm_total(vf,-1);
913 /* huh? Bogus stream with packets but no granulepos */
918 /* has our decoding just traversed a bitstream boundary? */
919 if(vf->ready_state==STREAMSET)
920 if(vf->current_serialno!=ogg_page_serialno(&og)){
921 _decode_clear(vf); /* clear out stream state */
922 ogg_stream_clear(&work_os);
925 if(vf->ready_state<STREAMSET){
928 vf->current_serialno=ogg_page_serialno(&og);
929 for(link=0;link<vf->links;link++)
930 if(vf->serialnos[link]==vf->current_serialno)break;
931 if(link==vf->links)goto seek_error; /* sign of a bogus stream.
933 machine uninitialized */
934 vf->current_link=link;
936 ogg_stream_init(&vf->os,vf->current_serialno);
937 ogg_stream_reset(&vf->os);
938 ogg_stream_init(&work_os,vf->current_serialno);
939 ogg_stream_reset(&work_os);
940 vf->ready_state=STREAMSET;
944 ogg_stream_pagein(&vf->os,&og);
945 ogg_stream_pagein(&work_os,&og);
946 eosflag=ogg_page_eos(&og);
950 ogg_stream_clear(&work_os);
954 /* dump the machine so we're in a known state */
956 ogg_stream_clear(&work_os);
961 /* Page granularity seek (faster than sample granularity because we
962 don't do the last bit of decode to find a specific sample).
964 Seek to the last [granule marked] page preceeding the specified pos
965 location, such that decoding past the returned point will quickly
966 arrive at the requested position. */
967 int ov_pcm_seek_page(OggVorbis_File *vf,ogg_int64_t pos){
970 ogg_int64_t total=ov_pcm_total(vf,-1);
972 if(vf->ready_state<OPENED)return(OV_EINVAL);
973 if(!vf->seekable)return(OV_ENOSEEK);
974 if(pos<0 || pos>total)return(OV_EINVAL);
976 /* which bitstream section does this pcm offset occur in? */
977 for(link=vf->links-1;link>=0;link--){
978 total-=vf->pcmlengths[link];
982 /* search within the logical bitstream for the page with the highest
983 pcm_pos preceeding (or equal to) pos. There is a danger here;
984 missing pages or incorrect frame number information in the
985 bitstream could make our task impossible. Account for that (it
986 would be an error condition) */
988 /* new search algorithm by HB (Nicholas Vinen) */
990 ogg_int64_t target=pos-total;
991 long end=vf->offsets[link+1];
992 long begin=vf->offsets[link];
993 ogg_int64_t endtime = vf->pcmlengths[link];
994 ogg_int64_t begintime = 0;
1001 if(end-begin<CHUNKSIZE){
1004 /* take a (pretty decent) guess. */
1006 (target-begintime)*(end-begin)/(endtime-begintime) - CHUNKSIZE;
1010 _seek_helper(vf,bisect);
1013 ret=_get_next_page(vf,&og,end-bisect);
1014 if(ret==OV_EREAD) goto seek_error;
1017 end=begin; /* found it */
1019 if(bisect==0)goto seek_error;
1021 if(bisect<=begin)bisect=begin+1;
1022 _seek_helper(vf,bisect);
1025 ogg_int64_t granulepos=ogg_page_granulepos(&og);
1026 if(granulepos<target){
1027 best=ret; /* raw offset of packet with granulepos */
1028 begin=vf->offset; /* raw offset of next page */
1029 begintime=granulepos;
1031 if(target-begin>44100)break;
1032 bisect=begin; /* *not* begin + 1 */
1035 end=begin; /* found it */
1037 if(end==vf->offset){ /* we're pretty close - we'd be stuck in */
1039 bisect-=CHUNKSIZE; /* an endless loop otherwise. */
1040 if(bisect<=begin)bisect=begin+1;
1041 _seek_helper(vf,bisect);
1053 /* found our page. seek to it, update pcm offset. Easier case than
1054 raw_seek, don't keep packets preceeding granulepos. */
1058 /* clear out decoding machine state */
1061 _seek_helper(vf,best);
1063 if(_get_next_page(vf,&og,-1)<0)return(OV_EOF); /* shouldn't happen */
1064 vf->current_serialno=ogg_page_serialno(&og);
1065 vf->current_link=link;
1067 ogg_stream_init(&vf->os,vf->current_serialno);
1068 ogg_stream_reset(&vf->os);
1069 vf->ready_state=STREAMSET;
1070 ogg_stream_pagein(&vf->os,&og);
1072 /* pull out all but last packet; the one with granulepos */
1074 ret=ogg_stream_packetpeek(&vf->os,&op);
1076 /* !!! the packet finishing this page originated on a
1077 preceeding page. Keep fetching previous pages until we
1078 get one with a granulepos or without the 'continued' flag
1079 set. Then just use raw_seek for simplicity. */
1081 ret=_get_prev_page(vf,&og);
1082 if(ret<0)goto seek_error;
1083 if(ogg_page_granulepos(&og)>-1 ||
1084 !ogg_page_continued(&og)){
1085 return ov_raw_seek(vf,ret);
1090 if(ret<0)goto seek_error;
1091 if(op.granulepos!=-1){
1092 vf->pcm_offset=op.granulepos+total;
1095 ret=ogg_stream_packetout(&vf->os,NULL);
1101 if(vf->pcm_offset>pos || pos>ov_pcm_total(vf,-1)){
1108 /* dump machine so we're in a known state */
1114 /* seek to a sample offset relative to the decompressed pcm stream
1115 returns zero on success, nonzero on failure */
1117 int ov_pcm_seek(OggVorbis_File *vf,ogg_int64_t pos){
1118 int thisblock,lastblock=0;
1119 int ret=ov_pcm_seek_page(vf,pos);
1120 codec_setup_info *ci=vf->vi->codec_setup;
1121 if(ret<0)return(ret);
1123 /* discard leading packets we don't need for the lapping of the
1124 position we want; don't decode them */
1130 int ret=ogg_stream_packetpeek(&vf->os,&op);
1132 thisblock=vorbis_packet_blocksize(vf->vi+vf->current_link,&op);
1133 if(lastblock)vf->pcm_offset+=(lastblock+thisblock)>>2;
1135 if(vf->pcm_offset+((thisblock+ci->blocksizes[1])>>2)>=pos)break;
1137 ogg_stream_packetout(&vf->os,NULL);
1140 /* end of logical stream case is hard, especially with exact
1141 length positioning. */
1143 if(op.granulepos>-1){
1145 /* always believe the stream markers */
1146 vf->pcm_offset=op.granulepos;
1147 for(i=0;i<vf->current_link;i++)
1148 vf->pcm_offset+=vf->pcmlengths[i];
1151 lastblock=thisblock;
1154 if(ret<0 && ret!=OV_HOLE)break;
1156 /* suck in a new page */
1157 if(_get_next_page(vf,&og,-1)<0)break;
1158 if(vf->current_serialno!=ogg_page_serialno(&og))_decode_clear(vf);
1160 if(vf->ready_state<STREAMSET){
1163 vf->current_serialno=ogg_page_serialno(&og);
1164 for(link=0;link<vf->links;link++)
1165 if(vf->serialnos[link]==vf->current_serialno)break;
1166 if(link==vf->links)return(OV_EBADLINK);
1167 vf->current_link=link;
1169 ogg_stream_init(&vf->os,vf->current_serialno);
1170 ogg_stream_reset(&vf->os);
1171 vf->ready_state=STREAMSET;
1174 ogg_stream_pagein(&vf->os,&og);
1178 /* discard samples until we reach the desired position. Crossing a
1179 logical bitstream boundary with abandon is OK. */
1180 _make_decode_ready(vf);
1181 while(vf->pcm_offset<pos){
1183 long target=pos-vf->pcm_offset;
1184 long samples=vorbis_synthesis_pcmout(&vf->vd,&pcm);
1186 if(samples>target)samples=target;
1187 vorbis_synthesis_read(&vf->vd,samples);
1188 vf->pcm_offset+=samples;
1191 if(_process_packet(vf,1)<=0)
1192 vf->pcm_offset=ov_pcm_total(vf,-1); /* eof */
1197 /* seek to a playback time relative to the decompressed pcm stream
1198 returns zero on success, nonzero on failure */
1199 int ov_time_seek(OggVorbis_File *vf,double seconds){
1200 /* translate time to PCM position and call ov_pcm_seek */
1203 ogg_int64_t pcm_total=ov_pcm_total(vf,-1);
1204 double time_total=ov_time_total(vf,-1);
1206 if(vf->ready_state<OPENED)return(OV_EINVAL);
1207 if(!vf->seekable)return(OV_ENOSEEK);
1208 if(seconds<0 || seconds>time_total)return(OV_EINVAL);
1210 /* which bitstream section does this time offset occur in? */
1211 for(link=vf->links-1;link>=0;link--){
1212 pcm_total-=vf->pcmlengths[link];
1213 time_total-=ov_time_total(vf,link);
1214 if(seconds>=time_total)break;
1217 /* enough information to convert time offset to pcm offset */
1219 ogg_int64_t target=pcm_total+(seconds-time_total)*vf->vi[link].rate;
1220 return(ov_pcm_seek(vf,target));
1224 /* page-granularity version of ov_time_seek
1225 returns zero on success, nonzero on failure */
1226 int ov_time_seek_page(OggVorbis_File *vf,double seconds){
1227 /* translate time to PCM position and call ov_pcm_seek */
1230 ogg_int64_t pcm_total=ov_pcm_total(vf,-1);
1231 double time_total=ov_time_total(vf,-1);
1233 if(vf->ready_state<OPENED)return(OV_EINVAL);
1234 if(!vf->seekable)return(OV_ENOSEEK);
1235 if(seconds<0 || seconds>time_total)return(OV_EINVAL);
1237 /* which bitstream section does this time offset occur in? */
1238 for(link=vf->links-1;link>=0;link--){
1239 pcm_total-=vf->pcmlengths[link];
1240 time_total-=ov_time_total(vf,link);
1241 if(seconds>=time_total)break;
1244 /* enough information to convert time offset to pcm offset */
1246 ogg_int64_t target=pcm_total+(seconds-time_total)*vf->vi[link].rate;
1247 return(ov_pcm_seek_page(vf,target));
1251 /* tell the current stream offset cursor. Note that seek followed by
1252 tell will likely not give the set offset due to caching */
1253 ogg_int64_t ov_raw_tell(OggVorbis_File *vf){
1254 if(vf->ready_state<OPENED)return(OV_EINVAL);
1258 /* return PCM offset (sample) of next PCM sample to be read */
1259 ogg_int64_t ov_pcm_tell(OggVorbis_File *vf){
1260 if(vf->ready_state<OPENED)return(OV_EINVAL);
1261 return(vf->pcm_offset);
1264 /* return time offset (seconds) of next PCM sample to be read */
1265 double ov_time_tell(OggVorbis_File *vf){
1266 /* translate time to PCM position and call ov_pcm_seek */
1269 ogg_int64_t pcm_total=0;
1270 double time_total=0.f;
1272 if(vf->ready_state<OPENED)return(OV_EINVAL);
1274 pcm_total=ov_pcm_total(vf,-1);
1275 time_total=ov_time_total(vf,-1);
1277 /* which bitstream section does this time offset occur in? */
1278 for(link=vf->links-1;link>=0;link--){
1279 pcm_total-=vf->pcmlengths[link];
1280 time_total-=ov_time_total(vf,link);
1281 if(vf->pcm_offset>=pcm_total)break;
1285 return((double)time_total+(double)(vf->pcm_offset-pcm_total)/vf->vi[link].rate);
1288 /* link: -1) return the vorbis_info struct for the bitstream section
1289 currently being decoded
1290 0-n) to request information for a specific bitstream section
1292 In the case of a non-seekable bitstream, any call returns the
1293 current bitstream. NULL in the case that the machine is not
1296 vorbis_info *ov_info(OggVorbis_File *vf,int link){
1299 if(vf->ready_state>=STREAMSET)
1300 return vf->vi+vf->current_link;
1313 /* grr, strong typing, grr, no templates/inheritence, grr */
1314 vorbis_comment *ov_comment(OggVorbis_File *vf,int link){
1317 if(vf->ready_state>=STREAMSET)
1318 return vf->vc+vf->current_link;
1331 int host_is_big_endian() {
1332 ogg_int32_t pattern = 0xfeedface; /* deadbeef */
1333 unsigned char *bytewise = (unsigned char *)&pattern;
1334 if (bytewise[0] == 0xfe) return 1;
1338 /* up to this point, everything could more or less hide the multiple
1339 logical bitstream nature of chaining from the toplevel application
1340 if the toplevel application didn't particularly care. However, at
1341 the point that we actually read audio back, the multiple-section
1342 nature must surface: Multiple bitstream sections do not necessarily
1343 have to have the same number of channels or sampling rate.
1345 ov_read returns the sequential logical bitstream number currently
1346 being decoded along with the PCM data in order that the toplevel
1347 application can take action on channel/sample rate changes. This
1348 number will be incremented even for streamed (non-seekable) streams
1349 (for seekable streams, it represents the actual logical bitstream
1350 index within the physical bitstream. Note that the accessor
1351 functions above are aware of this dichotomy).
1353 input values: buffer) a buffer to hold packed PCM data for return
1354 length) the byte length requested to be placed into buffer
1355 bigendianp) should the data be packed LSB first (0) or
1357 word) word size for output. currently 1 (byte) or
1360 return values: <0) error/hole in data (OV_HOLE), partial open (OV_EINVAL)
1362 n) number of bytes of PCM actually returned. The
1363 below works on a packet-by-packet basis, so the
1364 return length is not related to the 'length' passed
1365 in, just guaranteed to fit.
1367 *section) set to the logical bitstream number */
1369 long ov_read(OggVorbis_File *vf,char *buffer,int length,
1370 int bigendianp,int word,int sgned,int *bitstream){
1372 int host_endian = host_is_big_endian();
1374 if(vf->ready_state<OPENED)return(OV_EINVAL);
1375 if(vf->ready_state==OPENED)return(OV_EOF); /* stream is always
1378 open)... unless there
1379 was no page at the end
1384 if(vf->ready_state>=STREAMSET){
1386 long samples=vorbis_synthesis_pcmout(&vf->vd,&pcm);
1388 /* yay! proceed to pack data into the byte buffer */
1390 long channels=ov_info(vf,-1)->channels;
1391 long bytespersample=word * channels;
1392 vorbis_fpu_control fpu;
1393 if(samples>length/bytespersample)samples=length/bytespersample;
1395 /* a tight loop to pack each size */
1399 int off=(sgned?0:128);
1400 vorbis_fpu_setround(&fpu);
1401 for(j=0;j<samples;j++)
1402 for(i=0;i<channels;i++){
1403 val=vorbis_ftoi(pcm[i][j]*128.f);
1405 else if(val<-128)val=-128;
1408 vorbis_fpu_restore(fpu);
1410 int off=(sgned?0:32768);
1412 if(host_endian==bigendianp){
1415 vorbis_fpu_setround(&fpu);
1416 for(i=0;i<channels;i++) { /* It's faster in this order */
1418 short *dest=((short *)buffer)+i;
1419 for(j=0;j<samples;j++) {
1420 val=vorbis_ftoi(src[j]*32768.f);
1421 if(val>32767)val=32767;
1422 else if(val<-32768)val=-32768;
1427 vorbis_fpu_restore(fpu);
1431 vorbis_fpu_setround(&fpu);
1432 for(i=0;i<channels;i++) {
1434 short *dest=((short *)buffer)+i;
1435 for(j=0;j<samples;j++) {
1436 val=vorbis_ftoi(src[j]*32768.f);
1437 if(val>32767)val=32767;
1438 else if(val<-32768)val=-32768;
1443 vorbis_fpu_restore(fpu);
1446 }else if(bigendianp){
1448 vorbis_fpu_setround(&fpu);
1449 for(j=0;j<samples;j++)
1450 for(i=0;i<channels;i++){
1451 val=vorbis_ftoi(pcm[i][j]*32768.f);
1452 if(val>32767)val=32767;
1453 else if(val<-32768)val=-32768;
1456 *buffer++=(val&0xff);
1458 vorbis_fpu_restore(fpu);
1462 vorbis_fpu_setround(&fpu);
1463 for(j=0;j<samples;j++)
1464 for(i=0;i<channels;i++){
1465 val=vorbis_ftoi(pcm[i][j]*32768.f);
1466 if(val>32767)val=32767;
1467 else if(val<-32768)val=-32768;
1469 *buffer++=(val&0xff);
1472 vorbis_fpu_restore(fpu);
1478 vorbis_synthesis_read(&vf->vd,samples);
1479 vf->pcm_offset+=samples;
1480 if(bitstream)*bitstream=vf->current_link;
1481 return(samples*bytespersample);
1485 /* suck in another packet */
1486 switch(_process_packet(vf,1)){
1492 return(OV_EBADLINK);