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.53 2001/12/14 00:30:33 jack Exp $
16 ********************************************************************/
24 #include "vorbis/codec.h"
25 #include "vorbis/vorbisfile.h"
30 /* A 'chained bitstream' is a Vorbis bitstream that contains more than
31 one logical bitstream arranged end to end (the only form of Ogg
32 multiplexing allowed in a Vorbis bitstream; grouping [parallel
33 multiplexing] is not allowed in Vorbis) */
35 /* A Vorbis file can be played beginning to end (streamed) without
36 worrying ahead of time about chaining (see decoder_example.c). If
37 we have the whole file, however, and want random access
38 (seeking/scrubbing) or desire to know the total length/time of a
39 file, we need to account for the possibility of chaining. */
41 /* We can handle things a number of ways; we can determine the entire
42 bitstream structure right off the bat, or find pieces on demand.
43 This example determines and caches structure for the entire
44 bitstream, but builds a virtual decoder on the fly when moving
45 between links in the chain. */
47 /* There are also different ways to implement seeking. Enough
48 information exists in an Ogg bitstream to seek to
49 sample-granularity positions in the output. Or, one can seek by
50 picking some portion of the stream roughly in the desired area if
51 we only want coarse navigation through the stream. */
53 /*************************************************************************
54 * Many, many internal helpers. The intention is not to be confusing;
55 * rampant duplication and monolithic function implementation would be
56 * harder to understand anyway. The high level functions are last. Begin
57 * grokking near the end of the file */
59 /* read a little more data from the file/pipe into the ogg_sync framer
61 #define CHUNKSIZE 8500 /* a shade over 8k; anyone using pages well
62 over 8k gets what they deserve */
63 static long _get_data(OggVorbis_File *vf){
66 char *buffer=ogg_sync_buffer(&vf->oy,CHUNKSIZE);
67 long bytes=(vf->callbacks.read_func)(buffer,1,CHUNKSIZE,vf->datasource);
68 if(bytes>0)ogg_sync_wrote(&vf->oy,bytes);
69 if(bytes==0 && errno)return(-1);
75 /* save a tiny smidge of verbosity to make the code more readable */
76 static void _seek_helper(OggVorbis_File *vf,long offset){
78 (vf->callbacks.seek_func)(vf->datasource, offset, SEEK_SET);
80 ogg_sync_reset(&vf->oy);
82 /* shouldn't happen unless someone writes a broken callback */
87 /* The read/seek functions track absolute position within the stream */
89 /* from the head of the stream, get the next page. boundary specifies
90 if the function is allowed to fetch more data from the stream (and
91 how much) or only use internally buffered data.
93 boundary: -1) unbounded search
94 0) read no additional data; use cached only
95 n) search for a new page beginning for n bytes
97 return: <0) did not find a page (OV_FALSE, OV_EOF, OV_EREAD)
98 n) found a page at absolute offset n */
100 static long _get_next_page(OggVorbis_File *vf,ogg_page *og,int boundary){
101 if(boundary>0)boundary+=vf->offset;
105 if(boundary>0 && vf->offset>=boundary)return(OV_FALSE);
106 more=ogg_sync_pageseek(&vf->oy,og);
109 /* skipped n bytes */
113 /* send more paramedics */
114 if(!boundary)return(OV_FALSE);
116 long ret=_get_data(vf);
117 if(ret==0)return(OV_EOF);
118 if(ret<0)return(OV_EREAD);
121 /* got a page. Return the offset at the page beginning,
122 advance the internal offset past the page end */
132 /* find the latest page beginning before the current stream cursor
133 position. Much dirtier than the above as Ogg doesn't have any
134 backward search linkage. no 'readp' as it will certainly have to
136 /* returns offset or OV_EREAD, OV_FAULT */
137 static long _get_prev_page(OggVorbis_File *vf,ogg_page *og){
138 long begin=vf->offset;
146 _seek_helper(vf,begin);
147 while(vf->offset<begin+CHUNKSIZE){
148 ret=_get_next_page(vf,og,begin+CHUNKSIZE-vf->offset);
149 if(ret==OV_EREAD)return(OV_EREAD);
158 /* we have the offset. Actually snork and hold the page now */
159 _seek_helper(vf,offset);
160 ret=_get_next_page(vf,og,CHUNKSIZE);
162 /* this shouldn't be possible */
168 /* finds each bitstream link one at a time using a bisection search
169 (has to begin by knowing the offset of the lb's initial page).
170 Recurses for each link so it can alloc the link storage after
171 finding them all, then unroll and fill the cache at the same time */
172 static int _bisect_forward_serialno(OggVorbis_File *vf,
178 long endsearched=end;
183 /* the below guards against garbage seperating the last and
184 first pages of two links. */
185 while(searched<endsearched){
188 if(endsearched-searched<CHUNKSIZE){
191 bisect=(searched+endsearched)/2;
194 _seek_helper(vf,bisect);
195 ret=_get_next_page(vf,&og,-1);
196 if(ret==OV_EREAD)return(OV_EREAD);
197 if(ret<0 || ogg_page_serialno(&og)!=currentno){
201 searched=ret+og.header_len+og.body_len;
205 _seek_helper(vf,next);
206 ret=_get_next_page(vf,&og,-1);
207 if(ret==OV_EREAD)return(OV_EREAD);
209 if(searched>=end || ret<0){
211 vf->offsets=_ogg_malloc((m+2)*sizeof(*vf->offsets));
212 vf->offsets[m+1]=searched;
214 ret=_bisect_forward_serialno(vf,next,vf->offset,
215 end,ogg_page_serialno(&og),m+1);
216 if(ret==OV_EREAD)return(OV_EREAD);
219 vf->offsets[m]=begin;
223 /* uses the local ogg_stream storage in vf; this is important for
224 non-streaming input sources */
225 static int _fetch_headers(OggVorbis_File *vf,vorbis_info *vi,vorbis_comment *vc,
226 long *serialno,ogg_page *og_ptr){
232 ret=_get_next_page(vf,&og,CHUNKSIZE);
233 if(ret==OV_EREAD)return(OV_EREAD);
234 if(ret<0)return OV_ENOTVORBIS;
238 if(serialno)*serialno=ogg_page_serialno(og_ptr);
239 ogg_stream_init(&vf->os,ogg_page_serialno(og_ptr));
240 vf->ready_state=STREAMSET;
242 /* extract the initial header from the first page and verify that the
243 Ogg bitstream is in fact Vorbis data */
245 vorbis_info_init(vi);
246 vorbis_comment_init(vc);
250 ogg_stream_pagein(&vf->os,og_ptr);
252 int result=ogg_stream_packetout(&vf->os,&op);
258 if((ret=vorbis_synthesis_headerin(vi,vc,&op))){
264 if(_get_next_page(vf,og_ptr,CHUNKSIZE)<0){
272 vorbis_info_clear(vi);
273 vorbis_comment_clear(vc);
274 ogg_stream_clear(&vf->os);
275 vf->ready_state=OPENED;
280 /* last step of the OggVorbis_File initialization; get all the
281 vorbis_info structs and PCM positions. Only called by the seekable
282 initialization (local stream storage is hacked slightly; pay
283 attention to how that's done) */
285 /* this is void and does not propogate errors up because we want to be
286 able to open and use damaged bitstreams as well as we can. Just
287 watch out for missing information for links in the OggVorbis_File
289 static void _prefetch_all_headers(OggVorbis_File *vf, long dataoffset){
293 vf->vi=_ogg_realloc(vf->vi,vf->links*sizeof(*vf->vi));
294 vf->vc=_ogg_realloc(vf->vc,vf->links*sizeof(*vf->vc));
295 vf->dataoffsets=_ogg_malloc(vf->links*sizeof(*vf->dataoffsets));
296 vf->pcmlengths=_ogg_malloc(vf->links*sizeof(*vf->pcmlengths));
297 vf->serialnos=_ogg_malloc(vf->links*sizeof(*vf->serialnos));
299 for(i=0;i<vf->links;i++){
301 /* we already grabbed the initial header earlier. Just set the offset */
302 vf->dataoffsets[i]=dataoffset;
305 /* seek to the location of the initial header */
307 _seek_helper(vf,vf->offsets[i]);
308 if(_fetch_headers(vf,vf->vi+i,vf->vc+i,NULL,NULL)<0){
309 vf->dataoffsets[i]=-1;
311 vf->dataoffsets[i]=vf->offset;
312 ogg_stream_clear(&vf->os);
316 /* get the serial number and PCM length of this link. To do this,
317 get the last page of the stream */
319 long end=vf->offsets[i+1];
320 _seek_helper(vf,end);
323 ret=_get_prev_page(vf,&og);
325 /* this should not be possible */
326 vorbis_info_clear(vf->vi+i);
327 vorbis_comment_clear(vf->vc+i);
330 if(ogg_page_granulepos(&og)!=-1){
331 vf->serialnos[i]=ogg_page_serialno(&og);
332 vf->pcmlengths[i]=ogg_page_granulepos(&og);
341 static void _make_decode_ready(OggVorbis_File *vf){
342 if(vf->ready_state!=STREAMSET)return;
344 vorbis_synthesis_init(&vf->vd,vf->vi+vf->current_link);
346 vorbis_synthesis_init(&vf->vd,vf->vi);
348 vorbis_block_init(&vf->vd,&vf->vb);
349 vf->ready_state=INITSET;
353 static int _open_seekable2(OggVorbis_File *vf){
354 long serialno=vf->current_serialno,end;
355 long dataoffset=vf->offset;
358 /* we're partially open and have a first link header state in
360 /* we can seek, so set out learning all about this file */
361 (vf->callbacks.seek_func)(vf->datasource,0,SEEK_END);
362 vf->offset=vf->end=(vf->callbacks.tell_func)(vf->datasource);
364 /* We get the offset for the last page of the physical bitstream.
365 Most OggVorbis files will contain a single logical bitstream */
366 end=_get_prev_page(vf,&og);
372 /* more than one logical bitstream? */
373 if(ogg_page_serialno(&og)!=serialno){
375 /* Chained bitstream. Bisect-search each logical bitstream
376 section. Do so based on serial number only */
377 if(_bisect_forward_serialno(vf,0,0,end+1,serialno,0)<0){
384 /* Only one logical bitstream */
385 if(_bisect_forward_serialno(vf,0,end,end+1,serialno,0)){
392 /* the initial header memory is referenced by vf after; don't free it */
393 _prefetch_all_headers(vf,dataoffset);
394 return(ov_raw_seek(vf,0));
397 /* clear out the current logical bitstream decoder */
398 static void _decode_clear(OggVorbis_File *vf){
399 ogg_stream_clear(&vf->os);
400 vorbis_dsp_clear(&vf->vd);
401 vorbis_block_clear(&vf->vb);
402 vf->ready_state=OPENED;
408 /* fetch and process a packet. Handles the case where we're at a
409 bitstream boundary and dumps the decoding machine. If the decoding
410 machine is unloaded, it loads it. It also keeps pcm_offset up to
411 date (seek and read both use this. seek uses a special hack with
414 return: <0) error, OV_HOLE (lost packet) or OV_EOF
415 0) need more data (only if readp==0)
419 static int _process_packet(OggVorbis_File *vf,int readp){
422 /* handle one packet. Try to fetch it from current stream state */
423 /* extract packets from page */
426 /* process a packet if we can. If the machine isn't loaded,
428 if(vf->ready_state==INITSET){
431 int result=ogg_stream_packetout(&vf->os,&op);
432 ogg_int64_t granulepos;
434 if(result==-1)return(OV_HOLE); /* hole in the data. */
436 /* got a packet. process it */
437 granulepos=op.granulepos;
438 if(!vorbis_synthesis(&vf->vb,&op)){ /* lazy check for lazy
440 header packets aren't
443 vorbis_synthesis will
446 /* suck in the synthesis data and track bitrate */
448 int oldsamples=vorbis_synthesis_pcmout(&vf->vd,NULL);
449 vorbis_synthesis_blockin(&vf->vd,&vf->vb);
450 vf->samptrack+=vorbis_synthesis_pcmout(&vf->vd,NULL)-oldsamples;
451 vf->bittrack+=op.bytes*8;
454 /* update the pcm offset. */
455 if(granulepos!=-1 && !op.e_o_s){
456 int link=(vf->seekable?vf->current_link:0);
459 /* this packet has a pcm_offset on it (the last packet
460 completed on a page carries the offset) After processing
461 (above), we know the pcm position of the *last* sample
462 ready to be returned. Find the offset of the *first*
464 As an aside, this trick is inaccurate if we begin
465 reading anew right at the last page; the end-of-stream
466 granulepos declares the last frame in the stream, and the
467 last packet of the last page may be a partial frame.
468 So, we need a previous granulepos from an in-sequence page
469 to have a reference point. Thus the !op.e_o_s clause
472 samples=vorbis_synthesis_pcmout(&vf->vd,NULL);
476 granulepos+=vf->pcmlengths[i];
477 vf->pcm_offset=granulepos;
487 if(vf->ready_state>=OPENED){
489 if(_get_next_page(vf,&og,-1)<0)return(OV_EOF); /* eof.
491 /* bitrate tracking; add the header's bytes here, the body bytes
492 are done by packet above */
493 vf->bittrack+=og.header_len*8;
495 /* has our decoding just traversed a bitstream boundary? */
496 if(vf->ready_state==INITSET){
497 if(vf->current_serialno!=ogg_page_serialno(&og)){
501 vorbis_info_clear(vf->vi);
502 vorbis_comment_clear(vf->vc);
508 /* Do we need to load a new machine before submitting the page? */
509 /* This is different in the seekable and non-seekable cases.
511 In the seekable case, we already have all the header
512 information loaded and cached; we just initialize the machine
513 with it and continue on our merry way.
515 In the non-seekable (streaming) case, we'll only be at a
516 boundary if we just left the previous logical bitstream and
517 we're now nominally at the header of the next bitstream
520 if(vf->ready_state!=INITSET){
523 if(vf->ready_state<STREAMSET){
525 vf->current_serialno=ogg_page_serialno(&og);
527 /* match the serialno to bitstream section. We use this rather than
528 offset positions to avoid problems near logical bitstream
530 for(link=0;link<vf->links;link++)
531 if(vf->serialnos[link]==vf->current_serialno)break;
532 if(link==vf->links)return(OV_EBADLINK); /* sign of a bogus
537 vf->current_link=link;
539 ogg_stream_init(&vf->os,vf->current_serialno);
540 ogg_stream_reset(&vf->os);
541 vf->ready_state=STREAMSET;
544 /* we're streaming */
545 /* fetch the three header packets, build the info struct */
547 int ret=_fetch_headers(vf,vf->vi,vf->vc,&vf->current_serialno,&og);
554 _make_decode_ready(vf);
556 ogg_stream_pagein(&vf->os,&og);
560 static int _fseek64_wrap(FILE *f,ogg_int64_t off,int whence){
561 if(f==NULL)return(-1);
562 return fseek(f,(int)off,whence);
565 static int _ov_open1(void *f,OggVorbis_File *vf,char *initial,
566 long ibytes, ov_callbacks callbacks){
567 long offset=(f?callbacks.seek_func(f,0,SEEK_CUR):-1);
570 memset(vf,0,sizeof(*vf));
572 vf->callbacks = callbacks;
574 /* init the framing state */
575 ogg_sync_init(&vf->oy);
577 /* perhaps some data was previously read into a buffer for testing
578 against other stream types. Allow initialization from this
579 previously read data (as we may be reading from a non-seekable
582 char *buffer=ogg_sync_buffer(&vf->oy,ibytes);
583 memcpy(buffer,initial,ibytes);
584 ogg_sync_wrote(&vf->oy,ibytes);
587 /* can we seek? Stevens suggests the seek test was portable */
588 if(offset!=-1)vf->seekable=1;
590 /* No seeking yet; Set up a 'single' (current) logical bitstream
591 entry for partial open */
593 vf->vi=_ogg_calloc(vf->links,sizeof(*vf->vi));
594 vf->vc=_ogg_calloc(vf->links,sizeof(*vf->vc));
596 /* Try to fetch the headers, maintaining all the storage */
597 if((ret=_fetch_headers(vf,vf->vi,vf->vc,&vf->current_serialno,NULL))<0){
600 }else if(vf->ready_state < PARTOPEN)
601 vf->ready_state=PARTOPEN;
605 static int _ov_open2(OggVorbis_File *vf){
606 if(vf->ready_state < OPENED)
607 vf->ready_state=OPENED;
609 int ret=_open_seekable2(vf);
620 /* clear out the OggVorbis_File struct */
621 int ov_clear(OggVorbis_File *vf){
623 vorbis_block_clear(&vf->vb);
624 vorbis_dsp_clear(&vf->vd);
625 ogg_stream_clear(&vf->os);
627 if(vf->vi && vf->links){
629 for(i=0;i<vf->links;i++){
630 vorbis_info_clear(vf->vi+i);
631 vorbis_comment_clear(vf->vc+i);
636 if(vf->dataoffsets)_ogg_free(vf->dataoffsets);
637 if(vf->pcmlengths)_ogg_free(vf->pcmlengths);
638 if(vf->serialnos)_ogg_free(vf->serialnos);
639 if(vf->offsets)_ogg_free(vf->offsets);
640 ogg_sync_clear(&vf->oy);
641 if(vf->datasource)(vf->callbacks.close_func)(vf->datasource);
642 memset(vf,0,sizeof(*vf));
650 /* inspects the OggVorbis file and finds/documents all the logical
651 bitstreams contained in it. Tries to be tolerant of logical
652 bitstream sections that are truncated/woogie.
658 int ov_open_callbacks(void *f,OggVorbis_File *vf,char *initial,long ibytes,
659 ov_callbacks callbacks){
660 int ret=_ov_open1(f,vf,initial,ibytes,callbacks);
662 return _ov_open2(vf);
665 int ov_open(FILE *f,OggVorbis_File *vf,char *initial,long ibytes){
666 ov_callbacks callbacks = {
667 (size_t (*)(void *, size_t, size_t, void *)) fread,
668 (int (*)(void *, ogg_int64_t, int)) _fseek64_wrap,
669 (int (*)(void *)) fclose,
670 (long (*)(void *)) ftell
673 return ov_open_callbacks((void *)f, vf, initial, ibytes, callbacks);
676 /* Only partially open the vorbis file; test for Vorbisness, and load
677 the headers for the first chain. Do not seek (although test for
678 seekability). Use ov_test_open to finish opening the file, else
679 ov_clear to close/free it. Same return codes as open. */
681 int ov_test_callbacks(void *f,OggVorbis_File *vf,char *initial,long ibytes,
682 ov_callbacks callbacks)
684 return _ov_open1(f,vf,initial,ibytes,callbacks);
687 int ov_test(FILE *f,OggVorbis_File *vf,char *initial,long ibytes){
688 ov_callbacks callbacks = {
689 (size_t (*)(void *, size_t, size_t, void *)) fread,
690 (int (*)(void *, ogg_int64_t, int)) _fseek64_wrap,
691 (int (*)(void *)) fclose,
692 (long (*)(void *)) ftell
695 return ov_test_callbacks((void *)f, vf, initial, ibytes, callbacks);
698 int ov_test_open(OggVorbis_File *vf){
699 if(vf->ready_state!=PARTOPEN)return(OV_EINVAL);
700 return _ov_open2(vf);
703 /* How many logical bitstreams in this physical bitstream? */
704 long ov_streams(OggVorbis_File *vf){
708 /* Is the FILE * associated with vf seekable? */
709 long ov_seekable(OggVorbis_File *vf){
713 /* returns the bitrate for a given logical bitstream or the entire
714 physical bitstream. If the file is open for random access, it will
715 find the *actual* average bitrate. If the file is streaming, it
716 returns the nominal bitrate (if set) else the average of the
717 upper/lower bounds (if set) else -1 (unset).
719 If you want the actual bitrate field settings, get them from the
720 vorbis_info structs */
722 long ov_bitrate(OggVorbis_File *vf,int i){
723 if(vf->ready_state<OPENED)return(OV_EINVAL);
724 if(i>=vf->links)return(OV_EINVAL);
725 if(!vf->seekable && i!=0)return(ov_bitrate(vf,0));
729 for(i=0;i<vf->links;i++)
730 bits+=(vf->offsets[i+1]-vf->dataoffsets[i])*8;
731 return(rint(bits/ov_time_total(vf,-1)));
734 /* return the actual bitrate */
735 return(rint((vf->offsets[i+1]-vf->dataoffsets[i])*8/ov_time_total(vf,i)));
737 /* return nominal if set */
738 if(vf->vi[i].bitrate_nominal>0){
739 return vf->vi[i].bitrate_nominal;
741 if(vf->vi[i].bitrate_upper>0){
742 if(vf->vi[i].bitrate_lower>0){
743 return (vf->vi[i].bitrate_upper+vf->vi[i].bitrate_lower)/2;
745 return vf->vi[i].bitrate_upper;
754 /* returns the actual bitrate since last call. returns -1 if no
755 additional data to offer since last call (or at beginning of stream),
756 EINVAL if stream is only partially open
758 long ov_bitrate_instant(OggVorbis_File *vf){
759 int link=(vf->seekable?vf->current_link:0);
761 if(vf->ready_state<OPENED)return(OV_EINVAL);
762 if(vf->samptrack==0)return(OV_FALSE);
763 ret=vf->bittrack/vf->samptrack*vf->vi[link].rate+.5;
770 long ov_serialnumber(OggVorbis_File *vf,int i){
771 if(i>=vf->links)return(ov_serialnumber(vf,vf->links-1));
772 if(!vf->seekable && i>=0)return(ov_serialnumber(vf,-1));
774 return(vf->current_serialno);
776 return(vf->serialnos[i]);
780 /* returns: total raw (compressed) length of content if i==-1
781 raw (compressed) length of that logical bitstream for i==0 to n
782 OV_EINVAL if the stream is not seekable (we can't know the length)
783 or if stream is only partially open
785 ogg_int64_t ov_raw_total(OggVorbis_File *vf,int i){
786 if(vf->ready_state<OPENED)return(OV_EINVAL);
787 if(!vf->seekable || i>=vf->links)return(OV_EINVAL);
791 for(i=0;i<vf->links;i++)
792 acc+=ov_raw_total(vf,i);
795 return(vf->offsets[i+1]-vf->offsets[i]);
799 /* returns: total PCM length (samples) of content if i==-1 PCM length
800 (samples) of that logical bitstream for i==0 to n
801 OV_EINVAL if the stream is not seekable (we can't know the
802 length) or only partially open
804 ogg_int64_t ov_pcm_total(OggVorbis_File *vf,int i){
805 if(vf->ready_state<OPENED)return(OV_EINVAL);
806 if(!vf->seekable || i>=vf->links)return(OV_EINVAL);
810 for(i=0;i<vf->links;i++)
811 acc+=ov_pcm_total(vf,i);
814 return(vf->pcmlengths[i]);
818 /* returns: total seconds of content if i==-1
819 seconds in that logical bitstream for i==0 to n
820 OV_EINVAL if the stream is not seekable (we can't know the
821 length) or only partially open
823 double ov_time_total(OggVorbis_File *vf,int i){
824 if(vf->ready_state<OPENED)return(OV_EINVAL);
825 if(!vf->seekable || i>=vf->links)return(OV_EINVAL);
829 for(i=0;i<vf->links;i++)
830 acc+=ov_time_total(vf,i);
833 return((float)(vf->pcmlengths[i])/vf->vi[i].rate);
837 /* seek to an offset relative to the *compressed* data. This also
838 scans packets to update the PCM cursor. It will cross a logical
839 bitstream boundary, but only if it can't get any packets out of the
840 tail of the bitstream we seek to (so no surprises).
842 returns zero on success, nonzero on failure */
844 int ov_raw_seek(OggVorbis_File *vf,long pos){
845 ogg_stream_state work_os;
847 if(vf->ready_state<OPENED)return(OV_EINVAL);
849 return(OV_ENOSEEK); /* don't dump machine if we can't seek */
851 if(pos<0 || pos>vf->offsets[vf->links])return(OV_EINVAL);
853 /* clear out decoding machine state */
857 _seek_helper(vf,pos);
859 /* we need to make sure the pcm_offset is set, but we don't want to
860 advance the raw cursor past good packets just to get to the first
861 with a granulepos. That's not equivalent behavior to beginning
862 decoding as immediately after the seek position as possible.
864 So, a hack. We use two stream states; a local scratch state and
865 a the shared vf->os stream state. We use the local state to
866 scan, and the shared state as a buffer for later decode.
868 Unfortuantely, on the last page we still advance to last packet
869 because the granulepos on the last page is not necessarily on a
870 packet boundary, and we need to make sure the granpos is
882 memset(&work_os,0,sizeof(work_os));/* so that it's safe to clear
883 it later even if we don't
887 if(vf->ready_state==STREAMSET){
888 /* snarf/scan a packet if we can */
889 int result=ogg_stream_packetout(&work_os,&op);
893 if(vf->vi[vf->current_link].codec_setup)
894 thisblock=vorbis_packet_blocksize(vf->vi+vf->current_link,&op);
896 ogg_stream_packetout(&vf->os,NULL);
898 if(lastblock)accblock+=(lastblock+thisblock)>>2;
900 if(op.granulepos!=-1){
901 int i,link=vf->current_link;
902 ogg_int64_t granulepos=op.granulepos;
905 granulepos+=vf->pcmlengths[i];
906 vf->pcm_offset=granulepos-accblock;
915 if(_get_next_page(vf,&og,-1)<0){
916 vf->pcm_offset=ov_pcm_total(vf,-1);
920 /* huh? Bogus stream with packets but no granulepos */
925 /* has our decoding just traversed a bitstream boundary? */
926 if(vf->ready_state==STREAMSET)
927 if(vf->current_serialno!=ogg_page_serialno(&og)){
928 _decode_clear(vf); /* clear out stream state */
929 ogg_stream_clear(&work_os);
932 if(vf->ready_state<STREAMSET){
935 vf->current_serialno=ogg_page_serialno(&og);
936 for(link=0;link<vf->links;link++)
937 if(vf->serialnos[link]==vf->current_serialno)break;
938 if(link==vf->links)goto seek_error; /* sign of a bogus stream.
940 machine uninitialized */
941 vf->current_link=link;
943 ogg_stream_init(&vf->os,vf->current_serialno);
944 ogg_stream_reset(&vf->os);
945 ogg_stream_init(&work_os,vf->current_serialno);
946 ogg_stream_reset(&work_os);
947 vf->ready_state=STREAMSET;
951 ogg_stream_pagein(&vf->os,&og);
952 ogg_stream_pagein(&work_os,&og);
953 eosflag=ogg_page_eos(&og);
957 ogg_stream_clear(&work_os);
961 /* dump the machine so we're in a known state */
963 ogg_stream_clear(&work_os);
968 /* Page granularity seek (faster than sample granularity because we
969 don't do the last bit of decode to find a specific sample).
971 Seek to the last [granule marked] page preceeding the specified pos
972 location, such that decoding past the returned point will quickly
973 arrive at the requested position. */
974 int ov_pcm_seek_page(OggVorbis_File *vf,ogg_int64_t pos){
977 ogg_int64_t total=ov_pcm_total(vf,-1);
979 if(vf->ready_state<OPENED)return(OV_EINVAL);
980 if(!vf->seekable)return(OV_ENOSEEK);
981 if(pos<0 || pos>total)return(OV_EINVAL);
983 /* which bitstream section does this pcm offset occur in? */
984 for(link=vf->links-1;link>=0;link--){
985 total-=vf->pcmlengths[link];
989 /* search within the logical bitstream for the page with the highest
990 pcm_pos preceeding (or equal to) pos. There is a danger here;
991 missing pages or incorrect frame number information in the
992 bitstream could make our task impossible. Account for that (it
993 would be an error condition) */
995 /* new search algorithm by HB (Nicholas Vinen) */
997 ogg_int64_t target=pos-total;
998 long end=vf->offsets[link+1];
999 long begin=vf->offsets[link];
1000 ogg_int64_t endtime = vf->pcmlengths[link];
1001 ogg_int64_t begintime = 0;
1008 if(end-begin<CHUNKSIZE){
1011 /* take a (pretty decent) guess. */
1013 (target-begintime)*(end-begin)/(endtime-begintime) - CHUNKSIZE;
1017 _seek_helper(vf,bisect);
1020 ret=_get_next_page(vf,&og,end-bisect);
1021 if(ret==OV_EREAD) goto seek_error;
1024 end=begin; /* found it */
1026 if(bisect==0)goto seek_error;
1028 if(bisect<=begin)bisect=begin+1;
1029 _seek_helper(vf,bisect);
1032 ogg_int64_t granulepos=ogg_page_granulepos(&og);
1033 if(granulepos<target){
1034 best=ret; /* raw offset of packet with granulepos */
1035 begin=vf->offset; /* raw offset of next page */
1036 begintime=granulepos;
1038 if(target-begin>44100)break;
1039 bisect=begin; /* *not* begin + 1 */
1042 end=begin; /* found it */
1044 if(end==vf->offset){ /* we're pretty close - we'd be stuck in */
1046 bisect-=CHUNKSIZE; /* an endless loop otherwise. */
1047 if(bisect<=begin)bisect=begin+1;
1048 _seek_helper(vf,bisect);
1060 /* found our page. seek to it, update pcm offset. Easier case than
1061 raw_seek, don't keep packets preceeding granulepos. */
1065 /* clear out decoding machine state */
1068 _seek_helper(vf,best);
1070 if(_get_next_page(vf,&og,-1)<0)return(OV_EOF); /* shouldn't happen */
1071 vf->current_serialno=ogg_page_serialno(&og);
1072 vf->current_link=link;
1074 ogg_stream_init(&vf->os,vf->current_serialno);
1075 ogg_stream_reset(&vf->os);
1076 vf->ready_state=STREAMSET;
1077 ogg_stream_pagein(&vf->os,&og);
1079 /* pull out all but last packet; the one with granulepos */
1081 ret=ogg_stream_packetpeek(&vf->os,&op);
1083 /* !!! the packet finishing this page originated on a
1084 preceeding page. Keep fetching previous pages until we
1085 get one with a granulepos or without the 'continued' flag
1086 set. Then just use raw_seek for simplicity. */
1088 ret=_get_prev_page(vf,&og);
1089 if(ret<0)goto seek_error;
1090 if(ogg_page_granulepos(&og)>-1 ||
1091 !ogg_page_continued(&og)){
1092 return ov_raw_seek(vf,ret);
1097 if(ret<0)goto seek_error;
1098 if(op.granulepos!=-1){
1099 vf->pcm_offset=op.granulepos+total;
1102 ret=ogg_stream_packetout(&vf->os,NULL);
1108 if(vf->pcm_offset>pos || pos>ov_pcm_total(vf,-1)){
1115 /* dump machine so we're in a known state */
1121 /* seek to a sample offset relative to the decompressed pcm stream
1122 returns zero on success, nonzero on failure */
1124 int ov_pcm_seek(OggVorbis_File *vf,ogg_int64_t pos){
1125 int thisblock,lastblock=0;
1126 int ret=ov_pcm_seek_page(vf,pos);
1127 if(ret<0)return(ret);
1129 /* discard leading packets we don't need for the lapping of the
1130 position we want; don't decode them */
1136 int ret=ogg_stream_packetpeek(&vf->os,&op);
1138 thisblock=vorbis_packet_blocksize(vf->vi+vf->current_link,&op);
1139 if(lastblock)vf->pcm_offset+=(lastblock+thisblock)>>2;
1141 if(vf->pcm_offset+((thisblock+
1142 vorbis_info_blocksize(vf->vi,1))>>2)>=pos)break;
1144 ogg_stream_packetout(&vf->os,NULL);
1147 /* end of logical stream case is hard, especially with exact
1148 length positioning. */
1150 if(op.granulepos>-1){
1152 /* always believe the stream markers */
1153 vf->pcm_offset=op.granulepos;
1154 for(i=0;i<vf->current_link;i++)
1155 vf->pcm_offset+=vf->pcmlengths[i];
1158 lastblock=thisblock;
1161 if(ret<0 && ret!=OV_HOLE)break;
1163 /* suck in a new page */
1164 if(_get_next_page(vf,&og,-1)<0)break;
1165 if(vf->current_serialno!=ogg_page_serialno(&og))_decode_clear(vf);
1167 if(vf->ready_state<STREAMSET){
1170 vf->current_serialno=ogg_page_serialno(&og);
1171 for(link=0;link<vf->links;link++)
1172 if(vf->serialnos[link]==vf->current_serialno)break;
1173 if(link==vf->links)return(OV_EBADLINK);
1174 vf->current_link=link;
1176 ogg_stream_init(&vf->os,vf->current_serialno);
1177 ogg_stream_reset(&vf->os);
1178 vf->ready_state=STREAMSET;
1181 ogg_stream_pagein(&vf->os,&og);
1185 /* discard samples until we reach the desired position. Crossing a
1186 logical bitstream boundary with abandon is OK. */
1187 _make_decode_ready(vf);
1188 while(vf->pcm_offset<pos){
1190 long target=pos-vf->pcm_offset;
1191 long samples=vorbis_synthesis_pcmout(&vf->vd,&pcm);
1193 if(samples>target)samples=target;
1194 vorbis_synthesis_read(&vf->vd,samples);
1195 vf->pcm_offset+=samples;
1198 if(_process_packet(vf,1)<=0)
1199 vf->pcm_offset=ov_pcm_total(vf,-1); /* eof */
1204 /* seek to a playback time relative to the decompressed pcm stream
1205 returns zero on success, nonzero on failure */
1206 int ov_time_seek(OggVorbis_File *vf,double seconds){
1207 /* translate time to PCM position and call ov_pcm_seek */
1210 ogg_int64_t pcm_total=ov_pcm_total(vf,-1);
1211 double time_total=ov_time_total(vf,-1);
1213 if(vf->ready_state<OPENED)return(OV_EINVAL);
1214 if(!vf->seekable)return(OV_ENOSEEK);
1215 if(seconds<0 || seconds>time_total)return(OV_EINVAL);
1217 /* which bitstream section does this time offset occur in? */
1218 for(link=vf->links-1;link>=0;link--){
1219 pcm_total-=vf->pcmlengths[link];
1220 time_total-=ov_time_total(vf,link);
1221 if(seconds>=time_total)break;
1224 /* enough information to convert time offset to pcm offset */
1226 ogg_int64_t target=pcm_total+(seconds-time_total)*vf->vi[link].rate;
1227 return(ov_pcm_seek(vf,target));
1231 /* page-granularity version of ov_time_seek
1232 returns zero on success, nonzero on failure */
1233 int ov_time_seek_page(OggVorbis_File *vf,double seconds){
1234 /* translate time to PCM position and call ov_pcm_seek */
1237 ogg_int64_t pcm_total=ov_pcm_total(vf,-1);
1238 double time_total=ov_time_total(vf,-1);
1240 if(vf->ready_state<OPENED)return(OV_EINVAL);
1241 if(!vf->seekable)return(OV_ENOSEEK);
1242 if(seconds<0 || seconds>time_total)return(OV_EINVAL);
1244 /* which bitstream section does this time offset occur in? */
1245 for(link=vf->links-1;link>=0;link--){
1246 pcm_total-=vf->pcmlengths[link];
1247 time_total-=ov_time_total(vf,link);
1248 if(seconds>=time_total)break;
1251 /* enough information to convert time offset to pcm offset */
1253 ogg_int64_t target=pcm_total+(seconds-time_total)*vf->vi[link].rate;
1254 return(ov_pcm_seek_page(vf,target));
1258 /* tell the current stream offset cursor. Note that seek followed by
1259 tell will likely not give the set offset due to caching */
1260 ogg_int64_t ov_raw_tell(OggVorbis_File *vf){
1261 if(vf->ready_state<OPENED)return(OV_EINVAL);
1265 /* return PCM offset (sample) of next PCM sample to be read */
1266 ogg_int64_t ov_pcm_tell(OggVorbis_File *vf){
1267 if(vf->ready_state<OPENED)return(OV_EINVAL);
1268 return(vf->pcm_offset);
1271 /* return time offset (seconds) of next PCM sample to be read */
1272 double ov_time_tell(OggVorbis_File *vf){
1273 /* translate time to PCM position and call ov_pcm_seek */
1276 ogg_int64_t pcm_total=0;
1277 double time_total=0.f;
1279 if(vf->ready_state<OPENED)return(OV_EINVAL);
1281 pcm_total=ov_pcm_total(vf,-1);
1282 time_total=ov_time_total(vf,-1);
1284 /* which bitstream section does this time offset occur in? */
1285 for(link=vf->links-1;link>=0;link--){
1286 pcm_total-=vf->pcmlengths[link];
1287 time_total-=ov_time_total(vf,link);
1288 if(vf->pcm_offset>=pcm_total)break;
1292 return((double)time_total+(double)(vf->pcm_offset-pcm_total)/vf->vi[link].rate);
1295 /* link: -1) return the vorbis_info struct for the bitstream section
1296 currently being decoded
1297 0-n) to request information for a specific bitstream section
1299 In the case of a non-seekable bitstream, any call returns the
1300 current bitstream. NULL in the case that the machine is not
1303 vorbis_info *ov_info(OggVorbis_File *vf,int link){
1306 if(vf->ready_state>=STREAMSET)
1307 return vf->vi+vf->current_link;
1320 /* grr, strong typing, grr, no templates/inheritence, grr */
1321 vorbis_comment *ov_comment(OggVorbis_File *vf,int link){
1324 if(vf->ready_state>=STREAMSET)
1325 return vf->vc+vf->current_link;
1338 static int host_is_big_endian() {
1339 ogg_int32_t pattern = 0xfeedface; /* deadbeef */
1340 unsigned char *bytewise = (unsigned char *)&pattern;
1341 if (bytewise[0] == 0xfe) return 1;
1345 /* up to this point, everything could more or less hide the multiple
1346 logical bitstream nature of chaining from the toplevel application
1347 if the toplevel application didn't particularly care. However, at
1348 the point that we actually read audio back, the multiple-section
1349 nature must surface: Multiple bitstream sections do not necessarily
1350 have to have the same number of channels or sampling rate.
1352 ov_read returns the sequential logical bitstream number currently
1353 being decoded along with the PCM data in order that the toplevel
1354 application can take action on channel/sample rate changes. This
1355 number will be incremented even for streamed (non-seekable) streams
1356 (for seekable streams, it represents the actual logical bitstream
1357 index within the physical bitstream. Note that the accessor
1358 functions above are aware of this dichotomy).
1360 input values: buffer) a buffer to hold packed PCM data for return
1361 length) the byte length requested to be placed into buffer
1362 bigendianp) should the data be packed LSB first (0) or
1364 word) word size for output. currently 1 (byte) or
1367 return values: <0) error/hole in data (OV_HOLE), partial open (OV_EINVAL)
1369 n) number of bytes of PCM actually returned. The
1370 below works on a packet-by-packet basis, so the
1371 return length is not related to the 'length' passed
1372 in, just guaranteed to fit.
1374 *section) set to the logical bitstream number */
1376 long ov_read_float(OggVorbis_File *vf,float ***pcm_channels,int *bitstream){
1378 if(vf->ready_state<OPENED)return(OV_EINVAL);
1381 if(vf->ready_state>=STREAMSET){
1383 long samples=vorbis_synthesis_pcmout(&vf->vd,&pcm);
1385 if(pcm_channels)*pcm_channels=pcm;
1386 vorbis_synthesis_read(&vf->vd,samples);
1387 vf->pcm_offset+=samples;
1388 if(bitstream)*bitstream=vf->current_link;
1394 /* suck in another packet */
1396 int ret=_process_packet(vf,1);
1397 if(ret==OV_EOF)return(0);
1398 if(ret<=0)return(ret);
1404 long ov_read(OggVorbis_File *vf,char *buffer,int length,
1405 int bigendianp,int word,int sgned,int *bitstream){
1407 int host_endian = host_is_big_endian();
1410 long samples=ov_read_float(vf,&pcm,bitstream);
1413 /* yay! proceed to pack data into the byte buffer */
1415 long channels=ov_info(vf,-1)->channels;
1416 long bytespersample=word * channels;
1417 vorbis_fpu_control fpu;
1418 if(samples>length/bytespersample)samples=length/bytespersample;
1420 /* a tight loop to pack each size */
1424 int off=(sgned?0:128);
1425 vorbis_fpu_setround(&fpu);
1426 for(j=0;j<samples;j++)
1427 for(i=0;i<channels;i++){
1428 val=vorbis_ftoi(pcm[i][j]*128.f);
1430 else if(val<-128)val=-128;
1433 vorbis_fpu_restore(fpu);
1435 int off=(sgned?0:32768);
1437 if(host_endian==bigendianp){
1440 vorbis_fpu_setround(&fpu);
1441 for(i=0;i<channels;i++) { /* It's faster in this order */
1443 short *dest=((short *)buffer)+i;
1444 for(j=0;j<samples;j++) {
1445 val=vorbis_ftoi(src[j]*32768.f);
1446 if(val>32767)val=32767;
1447 else if(val<-32768)val=-32768;
1452 vorbis_fpu_restore(fpu);
1456 vorbis_fpu_setround(&fpu);
1457 for(i=0;i<channels;i++) {
1459 short *dest=((short *)buffer)+i;
1460 for(j=0;j<samples;j++) {
1461 val=vorbis_ftoi(src[j]*32768.f);
1462 if(val>32767)val=32767;
1463 else if(val<-32768)val=-32768;
1468 vorbis_fpu_restore(fpu);
1471 }else if(bigendianp){
1473 vorbis_fpu_setround(&fpu);
1474 for(j=0;j<samples;j++)
1475 for(i=0;i<channels;i++){
1476 val=vorbis_ftoi(pcm[i][j]*32768.f);
1477 if(val>32767)val=32767;
1478 else if(val<-32768)val=-32768;
1481 *buffer++=(val&0xff);
1483 vorbis_fpu_restore(fpu);
1487 vorbis_fpu_setround(&fpu);
1488 for(j=0;j<samples;j++)
1489 for(i=0;i<channels;i++){
1490 val=vorbis_ftoi(pcm[i][j]*32768.f);
1491 if(val>32767)val=32767;
1492 else if(val<-32768)val=-32768;
1494 *buffer++=(val&0xff);
1497 vorbis_fpu_restore(fpu);
1503 vorbis_synthesis_read(&vf->vd,samples);
1504 vf->pcm_offset+=samples;
1505 if(bitstream)*bitstream=vf->current_link;
1506 return(samples*bytespersample);