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.46 2001/05/27 08:16:00 xiphmont 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 course 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 */
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;
144 _seek_helper(vf,begin);
145 while(vf->offset<begin+CHUNKSIZE){
146 ret=_get_next_page(vf,og,begin+CHUNKSIZE-vf->offset);
147 if(ret==OV_EREAD)return(OV_EREAD);
156 /* we have the offset. Actually snork and hold the page now */
157 _seek_helper(vf,offset);
158 ret=_get_next_page(vf,og,CHUNKSIZE);
160 /* this shouldn't be possible */
166 /* finds each bitstream link one at a time using a bisection search
167 (has to begin by knowing the offset of the lb's initial page).
168 Recurses for each link so it can alloc the link storage after
169 finding them all, then unroll and fill the cache at the same time */
170 static int _bisect_forward_serialno(OggVorbis_File *vf,
176 long endsearched=end;
181 /* the below guards against garbage seperating the last and
182 first pages of two links. */
183 while(searched<endsearched){
186 if(endsearched-searched<CHUNKSIZE){
189 bisect=(searched+endsearched)/2;
192 _seek_helper(vf,bisect);
193 ret=_get_next_page(vf,&og,-1);
194 if(ret==OV_EREAD)return(OV_EREAD);
195 if(ret<0 || ogg_page_serialno(&og)!=currentno){
199 searched=ret+og.header_len+og.body_len;
203 _seek_helper(vf,next);
204 ret=_get_next_page(vf,&og,-1);
205 if(ret==OV_EREAD)return(OV_EREAD);
207 if(searched>=end || ret<0){
209 vf->offsets=_ogg_malloc((m+2)*sizeof(ogg_int64_t));
210 vf->offsets[m+1]=searched;
212 ret=_bisect_forward_serialno(vf,next,vf->offset,
213 end,ogg_page_serialno(&og),m+1);
214 if(ret==OV_EREAD)return(OV_EREAD);
217 vf->offsets[m]=begin;
221 /* uses the local ogg_stream storage in vf; this is important for
222 non-streaming input sources */
223 static int _fetch_headers(OggVorbis_File *vf,vorbis_info *vi,vorbis_comment *vc,
224 long *serialno,ogg_page *og_ptr){
230 ret=_get_next_page(vf,&og,CHUNKSIZE);
231 if(ret==OV_EREAD)return(OV_EREAD);
232 if(ret<0)return OV_ENOTVORBIS;
236 if(serialno)*serialno=ogg_page_serialno(og_ptr);
237 ogg_stream_init(&vf->os,ogg_page_serialno(og_ptr));
238 vf->ready_state=STREAMSET;
240 /* extract the initial header from the first page and verify that the
241 Ogg bitstream is in fact Vorbis data */
243 vorbis_info_init(vi);
244 vorbis_comment_init(vc);
248 ogg_stream_pagein(&vf->os,og_ptr);
250 int result=ogg_stream_packetout(&vf->os,&op);
256 if((ret=vorbis_synthesis_headerin(vi,vc,&op))){
262 if(_get_next_page(vf,og_ptr,1)<0){
270 vorbis_info_clear(vi);
271 vorbis_comment_clear(vc);
272 ogg_stream_clear(&vf->os);
276 /* last step of the OggVorbis_File initialization; get all the
277 vorbis_info structs and PCM positions. Only called by the seekable
278 initialization (local stream storage is hacked slightly; pay
279 attention to how that's done) */
281 /* this is void and does not propogate errors up because we want to be
282 able to open and use damaged bitstreams as well as we can. Just
283 watch out for missing information for links in the OggVorbis_File
285 static void _prefetch_all_headers(OggVorbis_File *vf, long dataoffset){
289 vf->vi=_ogg_realloc(vf->vi,vf->links*sizeof(vorbis_info));
290 vf->vc=_ogg_realloc(vf->vc,vf->links*sizeof(vorbis_info));
291 vf->dataoffsets=_ogg_malloc(vf->links*sizeof(ogg_int64_t));
292 vf->pcmlengths=_ogg_malloc(vf->links*sizeof(ogg_int64_t));
293 vf->serialnos=_ogg_malloc(vf->links*sizeof(long));
295 for(i=0;i<vf->links;i++){
297 /* we already grabbed the initial header earlier. Just set the offset */
298 vf->dataoffsets[i]=dataoffset;
301 /* seek to the location of the initial header */
303 _seek_helper(vf,vf->offsets[i]);
304 if(_fetch_headers(vf,vf->vi+i,vf->vc+i,NULL,NULL)<0){
305 vf->dataoffsets[i]=-1;
307 vf->dataoffsets[i]=vf->offset;
308 ogg_stream_clear(&vf->os);
312 /* get the serial number and PCM length of this link. To do this,
313 get the last page of the stream */
315 long end=vf->offsets[i+1];
316 _seek_helper(vf,end);
319 ret=_get_prev_page(vf,&og);
321 /* this should not be possible */
322 vorbis_info_clear(vf->vi+i);
323 vorbis_comment_clear(vf->vc+i);
326 if(ogg_page_granulepos(&og)!=-1){
327 vf->serialnos[i]=ogg_page_serialno(&og);
328 vf->pcmlengths[i]=ogg_page_granulepos(&og);
337 static void _make_decode_ready(OggVorbis_File *vf){
338 if(vf->ready_state!=STREAMSET)return;
340 vorbis_synthesis_init(&vf->vd,vf->vi+vf->current_link);
342 vorbis_synthesis_init(&vf->vd,vf->vi);
344 vorbis_block_init(&vf->vd,&vf->vb);
345 vf->ready_state=INITSET;
349 static int _open_seekable2(OggVorbis_File *vf){
350 long serialno=vf->current_serialno,end;
351 long dataoffset=vf->offset;
354 /* we're partially open and have a first link header state in
356 /* we can seek, so set out learning all about this file */
357 (vf->callbacks.seek_func)(vf->datasource,0,SEEK_END);
358 vf->offset=vf->end=(vf->callbacks.tell_func)(vf->datasource);
360 /* We get the offset for the last page of the physical bitstream.
361 Most OggVorbis files will contain a single logical bitstream */
362 end=_get_prev_page(vf,&og);
368 /* more than one logical bitstream? */
369 if(ogg_page_serialno(&og)!=serialno){
371 /* Chained bitstream. Bisect-search each logical bitstream
372 section. Do so based on serial number only */
373 if(_bisect_forward_serialno(vf,0,0,end+1,serialno,0)<0){
380 /* Only one logical bitstream */
381 if(_bisect_forward_serialno(vf,0,end,end+1,serialno,0)){
388 /* the initial header memory is referenced by vf after; don't free it */
389 _prefetch_all_headers(vf,dataoffset);
390 return(ov_raw_seek(vf,0));
393 /* clear out the current logical bitstream decoder */
394 static void _decode_clear(OggVorbis_File *vf){
395 ogg_stream_clear(&vf->os);
396 vorbis_dsp_clear(&vf->vd);
397 vorbis_block_clear(&vf->vb);
398 vf->ready_state=OPENED;
404 /* fetch and process a packet. Handles the case where we're at a
405 bitstream boundary and dumps the decoding machine. If the decoding
406 machine is unloaded, it loads it. It also keeps pcm_offset up to
407 date (seek and read both use this. seek uses a special hack with
410 return: <0) error, OV_HOLE (lost packet) or OV_EOF
411 0) need more data (only if readp==0)
415 static int _process_packet(OggVorbis_File *vf,int readp){
418 /* handle one packet. Try to fetch it from current stream state */
419 /* extract packets from page */
422 /* process a packet if we can. If the machine isn't loaded,
424 if(vf->ready_state==INITSET){
426 int result=ogg_stream_packetout(&vf->os,&op);
427 ogg_int64_t granulepos;
429 if(result==-1)return(OV_HOLE); /* hole in the data. */
431 /* got a packet. process it */
432 granulepos=op.granulepos;
433 if(!vorbis_synthesis(&vf->vb,&op)){ /* lazy check for lazy
435 header packets aren't
438 vorbis_synthesis will
441 /* suck in the synthesis data and track bitrate */
443 int oldsamples=vorbis_synthesis_pcmout(&vf->vd,NULL);
444 vorbis_synthesis_blockin(&vf->vd,&vf->vb);
445 vf->samptrack+=vorbis_synthesis_pcmout(&vf->vd,NULL)-oldsamples;
446 vf->bittrack+=op.bytes*8;
449 /* update the pcm offset. */
450 if(granulepos!=-1 && !op.e_o_s){
451 int link=(vf->seekable?vf->current_link:0);
454 /* this packet has a pcm_offset on it (the last packet
455 completed on a page carries the offset) After processing
456 (above), we know the pcm position of the *last* sample
457 ready to be returned. Find the offset of the *first*
459 As an aside, this trick is inaccurate if we begin
460 reading anew right at the last page; the end-of-stream
461 granulepos declares the last frame in the stream, and the
462 last packet of the last page may be a partial frame.
463 So, we need a previous granulepos from an in-sequence page
464 to have a reference point. Thus the !op.e_o_s clause
467 samples=vorbis_synthesis_pcmout(&vf->vd,NULL);
471 granulepos+=vf->pcmlengths[i];
472 vf->pcm_offset=granulepos;
479 if(vf->ready_state>=STREAMSET){
481 if(_get_next_page(vf,&og,-1)<0)return(OV_EOF); /* eof.
484 /* bitrate tracking; add the header's bytes here, the body bytes
485 are done by packet above */
486 vf->bittrack+=og.header_len*8;
488 /* has our decoding just traversed a bitstream boundary? */
489 if(vf->ready_state==INITSET){
490 if(vf->current_serialno!=ogg_page_serialno(&og)){
494 vorbis_info_clear(vf->vi);
495 vorbis_comment_clear(vf->vc);
501 /* Do we need to load a new machine before submitting the page? */
502 /* This is different in the seekable and non-seekable cases.
504 In the seekable case, we already have all the header
505 information loaded and cached; we just initialize the machine
506 with it and continue on our merry way.
508 In the non-seekable (streaming) case, we'll only be at a
509 boundary if we just left the previous logical bitstream and
510 we're now nominally at the header of the next bitstream
513 if(vf->ready_state!=INITSET){
516 if(vf->ready_state<STREAMSET){
518 vf->current_serialno=ogg_page_serialno(&og);
520 /* match the serialno to bitstream section. We use this rather than
521 offset positions to avoid problems near logical bitstream
523 for(link=0;link<vf->links;link++)
524 if(vf->serialnos[link]==vf->current_serialno)break;
525 if(link==vf->links)return(OV_EBADLINK); /* sign of a bogus
530 vf->current_link=link;
532 ogg_stream_init(&vf->os,vf->current_serialno);
533 ogg_stream_reset(&vf->os);
534 vf->ready_state=STREAMSET;
537 /* we're streaming */
538 /* fetch the three header packets, build the info struct */
540 _fetch_headers(vf,vf->vi,vf->vc,&vf->current_serialno,&og);
546 _make_decode_ready(vf);
548 ogg_stream_pagein(&vf->os,&og);
552 static int _fseek64_wrap(FILE *f,ogg_int64_t off,int whence){
553 if(f==NULL)return(-1);
554 return fseek(f,(int)off,whence);
557 static int _ov_open1(void *f,OggVorbis_File *vf,char *initial,
558 long ibytes, ov_callbacks callbacks){
559 long offset=(f?callbacks.seek_func(f,0,SEEK_CUR):-1);
562 memset(vf,0,sizeof(OggVorbis_File));
564 vf->callbacks = callbacks;
566 /* init the framing state */
567 ogg_sync_init(&vf->oy);
569 /* perhaps some data was previously read into a buffer for testing
570 against other stream types. Allow initialization from this
571 previously read data (as we may be reading from a non-seekable
574 char *buffer=ogg_sync_buffer(&vf->oy,ibytes);
575 memcpy(buffer,initial,ibytes);
576 ogg_sync_wrote(&vf->oy,ibytes);
579 /* can we seek? Stevens suggests the seek test was portable */
580 if(offset!=-1)vf->seekable=1;
582 /* No seeking yet; Set up a 'single' (current) logical bitstream
583 entry for partial open */
585 vf->vi=_ogg_calloc(vf->links,sizeof(vorbis_info));
586 vf->vc=_ogg_calloc(vf->links,sizeof(vorbis_info));
588 /* Try to fetch the headers, maintaining all the storage */
589 if((ret=_fetch_headers(vf,vf->vi,vf->vc,&vf->current_serialno,NULL))<0){
593 vf->ready_state=PARTOPEN;
597 static int _ov_open2(OggVorbis_File *vf){
598 vf->ready_state=OPENED;
600 int ret=_open_seekable2(vf);
611 /* clear out the OggVorbis_File struct */
612 int ov_clear(OggVorbis_File *vf){
614 vorbis_block_clear(&vf->vb);
615 vorbis_dsp_clear(&vf->vd);
616 ogg_stream_clear(&vf->os);
618 if(vf->vi && vf->links){
620 for(i=0;i<vf->links;i++){
621 vorbis_info_clear(vf->vi+i);
622 vorbis_comment_clear(vf->vc+i);
627 if(vf->dataoffsets)_ogg_free(vf->dataoffsets);
628 if(vf->pcmlengths)_ogg_free(vf->pcmlengths);
629 if(vf->serialnos)_ogg_free(vf->serialnos);
630 if(vf->offsets)_ogg_free(vf->offsets);
631 ogg_sync_clear(&vf->oy);
632 if(vf->datasource)(vf->callbacks.close_func)(vf->datasource);
633 memset(vf,0,sizeof(OggVorbis_File));
641 /* inspects the OggVorbis file and finds/documents all the logical
642 bitstreams contained in it. Tries to be tolerant of logical
643 bitstream sections that are truncated/woogie.
649 int ov_open_callbacks(void *f,OggVorbis_File *vf,char *initial,long ibytes,
650 ov_callbacks callbacks){
651 int ret=_ov_open1(f,vf,initial,ibytes,callbacks);
653 return _ov_open2(vf);
656 int ov_open(FILE *f,OggVorbis_File *vf,char *initial,long ibytes){
657 ov_callbacks callbacks = {
658 (size_t (*)(void *, size_t, size_t, void *)) fread,
659 (int (*)(void *, ogg_int64_t, int)) _fseek64_wrap,
660 (int (*)(void *)) fclose,
661 (long (*)(void *)) ftell
664 return ov_open_callbacks((void *)f, vf, initial, ibytes, callbacks);
667 /* Only partially open the vorbis file; test for Vorbisness, and load
668 the headers for the first chain. Do not seek (although test for
669 seekability). Use ov_test_open to finish opening the file, else
670 ov_clear to close/free it. Same return codes as open. */
672 int ov_test_callbacks(void *f,OggVorbis_File *vf,char *initial,long ibytes,
673 ov_callbacks callbacks)
675 return _ov_open1(f,vf,initial,ibytes,callbacks);
678 int ov_test(FILE *f,OggVorbis_File *vf,char *initial,long ibytes){
679 ov_callbacks callbacks = {
680 (size_t (*)(void *, size_t, size_t, void *)) fread,
681 (int (*)(void *, ogg_int64_t, int)) _fseek64_wrap,
682 (int (*)(void *)) fclose,
683 (long (*)(void *)) ftell
686 return ov_test_callbacks((void *)f, vf, initial, ibytes, callbacks);
689 int ov_test_open(OggVorbis_File *vf){
690 if(vf->ready_state!=PARTOPEN)return(OV_EINVAL);
691 return _ov_open2(vf);
694 /* How many logical bitstreams in this physical bitstream? */
695 long ov_streams(OggVorbis_File *vf){
699 /* Is the FILE * associated with vf seekable? */
700 long ov_seekable(OggVorbis_File *vf){
704 /* returns the bitrate for a given logical bitstream or the entire
705 physical bitstream. If the file is open for random access, it will
706 find the *actual* average bitrate. If the file is streaming, it
707 returns the nominal bitrate (if set) else the average of the
708 upper/lower bounds (if set) else -1 (unset).
710 If you want the actual bitrate field settings, get them from the
711 vorbis_info structs */
713 long ov_bitrate(OggVorbis_File *vf,int i){
714 if(vf->ready_state<OPENED)return(OV_EINVAL);
715 if(i>=vf->links)return(OV_EINVAL);
716 if(!vf->seekable && i!=0)return(ov_bitrate(vf,0));
720 for(i=0;i<vf->links;i++)
721 bits+=(vf->offsets[i+1]-vf->dataoffsets[i])*8;
722 return(rint(bits/ov_time_total(vf,-1)));
725 /* return the actual bitrate */
726 return(rint((vf->offsets[i+1]-vf->dataoffsets[i])*8/ov_time_total(vf,i)));
728 /* return nominal if set */
729 if(vf->vi[i].bitrate_nominal>0){
730 return vf->vi[i].bitrate_nominal;
732 if(vf->vi[i].bitrate_upper>0){
733 if(vf->vi[i].bitrate_lower>0){
734 return (vf->vi[i].bitrate_upper+vf->vi[i].bitrate_lower)/2;
736 return vf->vi[i].bitrate_upper;
745 /* returns the actual bitrate since last call. returns -1 if no
746 additional data to offer since last call (or at beginning of stream),
747 EINVAL if stream is only partially open
749 long ov_bitrate_instant(OggVorbis_File *vf){
750 int link=(vf->seekable?vf->current_link:0);
752 if(vf->ready_state<OPENED)return(OV_EINVAL);
753 if(vf->samptrack==0)return(OV_FALSE);
754 ret=vf->bittrack/vf->samptrack*vf->vi[link].rate+.5;
761 long ov_serialnumber(OggVorbis_File *vf,int i){
762 if(i>=vf->links)return(ov_serialnumber(vf,vf->links-1));
763 if(!vf->seekable && i>=0)return(ov_serialnumber(vf,-1));
765 return(vf->current_serialno);
767 return(vf->serialnos[i]);
771 /* returns: total raw (compressed) length of content if i==-1
772 raw (compressed) length of that logical bitstream for i==0 to n
773 OV_EINVAL if the stream is not seekable (we can't know the length)
774 or if stream is only partially open
776 ogg_int64_t ov_raw_total(OggVorbis_File *vf,int i){
777 if(vf->ready_state<OPENED)return(OV_EINVAL);
778 if(!vf->seekable || i>=vf->links)return(OV_EINVAL);
782 for(i=0;i<vf->links;i++)
783 acc+=ov_raw_total(vf,i);
786 return(vf->offsets[i+1]-vf->offsets[i]);
790 /* returns: total PCM length (samples) of content if i==-1 PCM length
791 (samples) of that logical bitstream for i==0 to n
792 OV_EINVAL if the stream is not seekable (we can't know the
793 length) or only partially open
795 ogg_int64_t ov_pcm_total(OggVorbis_File *vf,int i){
796 if(vf->ready_state<OPENED)return(OV_EINVAL);
797 if(!vf->seekable || i>=vf->links)return(OV_EINVAL);
801 for(i=0;i<vf->links;i++)
802 acc+=ov_pcm_total(vf,i);
805 return(vf->pcmlengths[i]);
809 /* returns: total seconds of content if i==-1
810 seconds in that logical bitstream for i==0 to n
811 OV_EINVAL if the stream is not seekable (we can't know the
812 length) or only partially open
814 double ov_time_total(OggVorbis_File *vf,int i){
815 if(vf->ready_state<OPENED)return(OV_EINVAL);
816 if(!vf->seekable || i>=vf->links)return(OV_EINVAL);
820 for(i=0;i<vf->links;i++)
821 acc+=ov_time_total(vf,i);
824 return((float)(vf->pcmlengths[i])/vf->vi[i].rate);
828 /* seek to an offset relative to the *compressed* data. This also
829 scans packets to update the PCM cursor. It will cross a logical
830 bitstream boundary, but only if it can't get any packets out of the
831 tail of the bitstream we seek to (so no surprises).
833 returns zero on success, nonzero on failure */
835 int ov_raw_seek(OggVorbis_File *vf,long pos){
836 ogg_stream_state work_os;
838 if(vf->ready_state<OPENED)return(OV_EINVAL);
840 return(OV_ENOSEEK); /* don't dump machine if we can't seek */
842 if(pos<0 || pos>vf->offsets[vf->links])return(OV_EINVAL);
844 /* clear out decoding machine state */
848 _seek_helper(vf,pos);
850 /* we need to make sure the pcm_offset is set, but we don't want to
851 advance the raw cursor past good packets just to get to the first
852 with a granulepos. That's not equivalent behavior to beginning
853 decoding as immediately after the seek position as possible.
855 So, a hack. We use two stream states; a local scratch state and
856 a the shared vf->os stream state. We use the local state to
857 scan, and the shared state as a buffer for later decode.
859 Unfortuantely, on the last page we still advance to last packet
860 because the granulepos on the last page is not necessarily on a
861 packet boundary, and we need to make sure the granpos is
873 memset(&work_os,0,sizeof(work_os));/* so that it's safe to clear
874 it later even if we don't
878 if(vf->ready_state==STREAMSET){
879 /* snarf/scan a packet if we can */
880 int result=ogg_stream_packetout(&work_os,&op);
884 if(vf->vi[vf->current_link].codec_setup)
885 thisblock=vorbis_packet_blocksize(vf->vi+vf->current_link,&op);
887 ogg_stream_packetout(&vf->os,NULL);
889 if(lastblock)accblock+=(lastblock+thisblock)>>2;
891 if(op.granulepos!=-1){
892 int i,link=vf->current_link;
893 ogg_int64_t granulepos=op.granulepos;
896 granulepos+=vf->pcmlengths[i];
897 vf->pcm_offset=granulepos-accblock;
906 if(_get_next_page(vf,&og,-1)<0){
907 vf->pcm_offset=ov_pcm_total(vf,-1);
911 /* huh? Bogus stream with packets but no granulepos */
916 /* has our decoding just traversed a bitstream boundary? */
917 if(vf->ready_state==STREAMSET)
918 if(vf->current_serialno!=ogg_page_serialno(&og)){
919 _decode_clear(vf); /* clear out stream state */
920 ogg_stream_clear(&work_os);
923 if(vf->ready_state<STREAMSET){
926 vf->current_serialno=ogg_page_serialno(&og);
927 for(link=0;link<vf->links;link++)
928 if(vf->serialnos[link]==vf->current_serialno)break;
929 if(link==vf->links)goto seek_error; /* sign of a bogus stream.
931 machine uninitialized */
932 vf->current_link=link;
934 ogg_stream_init(&vf->os,vf->current_serialno);
935 ogg_stream_reset(&vf->os);
936 ogg_stream_init(&work_os,vf->current_serialno);
937 ogg_stream_reset(&work_os);
938 vf->ready_state=STREAMSET;
942 ogg_stream_pagein(&vf->os,&og);
943 ogg_stream_pagein(&work_os,&og);
944 eosflag=ogg_page_eos(&og);
948 ogg_stream_clear(&work_os);
952 /* dump the machine so we're in a known state */
954 ogg_stream_clear(&work_os);
959 /* Page granularity seek (faster than sample granularity because we
960 don't do the last bit of decode to find a specific sample).
962 Seek to the last [granule marked] page preceeding the specified pos
963 location, such that decoding past the returned point will quickly
964 arrive at the requested position. */
965 int ov_pcm_seek_page(OggVorbis_File *vf,ogg_int64_t pos){
968 ogg_int64_t total=ov_pcm_total(vf,-1);
970 if(vf->ready_state<OPENED)return(OV_EINVAL);
971 if(!vf->seekable)return(OV_ENOSEEK);
972 if(pos<0 || pos>total)return(OV_EINVAL);
974 /* which bitstream section does this pcm offset occur in? */
975 for(link=vf->links-1;link>=0;link--){
976 total-=vf->pcmlengths[link];
980 /* search within the logical bitstream for the page with the highest
981 pcm_pos preceeding (or equal to) pos. There is a danger here;
982 missing pages or incorrect frame number information in the
983 bitstream could make our task impossible. Account for that (it
984 would be an error condition) */
986 /* new search algorithm by HB (Nicholas Vinen) */
988 ogg_int64_t target=pos-total;
989 long end=vf->offsets[link+1];
990 long begin=vf->offsets[link];
991 ogg_int64_t endtime = vf->pcmlengths[link];
992 ogg_int64_t begintime = 0;
999 if(end-begin<CHUNKSIZE){
1002 /* take a (pretty decent) guess. */
1004 (target-begintime)*(end-begin)/(endtime-begintime) - CHUNKSIZE;
1008 _seek_helper(vf,bisect);
1011 ret=_get_next_page(vf,&og,end-bisect);
1012 if(ret==OV_EREAD) goto seek_error;
1015 end=begin; /* found it */
1017 if(bisect==0)goto seek_error;
1019 if(bisect<=begin)bisect=begin+1;
1020 _seek_helper(vf,bisect);
1023 ogg_int64_t granulepos=ogg_page_granulepos(&og);
1024 if(granulepos<target){
1025 best=ret; /* raw offset of packet with granulepos */
1026 begin=vf->offset; /* raw offset of next page */
1027 begintime=granulepos;
1029 if(target-begin>44100)break;
1030 bisect=begin; /* *not* begin + 1 */
1033 end=begin; /* found it */
1035 if(end==vf->offset){ /* we're pretty close - we'd be stuck in */
1037 bisect-=CHUNKSIZE; /* an endless loop otherwise. */
1038 if(bisect<=begin)bisect=begin+1;
1039 _seek_helper(vf,bisect);
1051 /* found our page. seek to it, update pcm offset. Easier case than
1052 raw_seek, don't keep packets preceeding granulepos. */
1056 /* clear out decoding machine state */
1059 _seek_helper(vf,best);
1061 if(_get_next_page(vf,&og,-1)<0)return(OV_EOF); /* shouldn't happen */
1062 vf->current_serialno=ogg_page_serialno(&og);
1063 vf->current_link=link;
1065 ogg_stream_init(&vf->os,vf->current_serialno);
1066 ogg_stream_reset(&vf->os);
1067 vf->ready_state=STREAMSET;
1068 ogg_stream_pagein(&vf->os,&og);
1070 /* pull out all but last packet; the one with granulepos */
1072 ret=ogg_stream_packetpeek(&vf->os,&op);
1074 /* !!! the packet finishing this page originated on a
1075 preceeding page. Keep fetching previous pages until we
1076 get one with a granulepos or without the 'continued' flag
1077 set. Then just use raw_seek for simplicity. */
1079 ret=_get_prev_page(vf,&og);
1080 if(ret<0)goto seek_error;
1081 if(ogg_page_granulepos(&og)>-1 ||
1082 !ogg_page_continued(&og)){
1083 return ov_raw_seek(vf,ret);
1088 if(ret<0)goto seek_error;
1089 if(op.granulepos!=-1){
1090 vf->pcm_offset=op.granulepos+total;
1093 ret=ogg_stream_packetout(&vf->os,NULL);
1099 if(vf->pcm_offset>pos || pos>ov_pcm_total(vf,-1)){
1106 /* dump machine so we're in a known state */
1112 /* seek to a sample offset relative to the decompressed pcm stream
1113 returns zero on success, nonzero on failure */
1115 int ov_pcm_seek(OggVorbis_File *vf,ogg_int64_t pos){
1116 int thisblock,lastblock=0;
1117 int ret=ov_pcm_seek_page(vf,pos);
1118 codec_setup_info *ci=vf->vi->codec_setup;
1119 if(ret<0)return(ret);
1121 /* discard leading packets we don't need for the lapping of the
1122 position we want; don't decode them */
1128 int ret=ogg_stream_packetpeek(&vf->os,&op);
1130 thisblock=vorbis_packet_blocksize(vf->vi+vf->current_link,&op);
1131 if(lastblock)vf->pcm_offset+=(lastblock+thisblock)>>2;
1133 if(vf->pcm_offset+((thisblock+ci->blocksizes[1])>>2)>=pos)break;
1135 ogg_stream_packetout(&vf->os,NULL);
1138 /* end of logical stream case is hard, especially with exact
1139 length positioning. */
1141 if(op.granulepos>-1){
1143 /* always believe the stream markers */
1144 vf->pcm_offset=op.granulepos;
1145 for(i=0;i<vf->current_link;i++)
1146 vf->pcm_offset+=vf->pcmlengths[i];
1149 lastblock=thisblock;
1152 if(ret<0 && ret!=OV_HOLE)break;
1154 /* suck in a new page */
1155 if(_get_next_page(vf,&og,-1)<0)break;
1156 if(vf->current_serialno!=ogg_page_serialno(&og))_decode_clear(vf);
1158 if(vf->ready_state<STREAMSET){
1161 vf->current_serialno=ogg_page_serialno(&og);
1162 for(link=0;link<vf->links;link++)
1163 if(vf->serialnos[link]==vf->current_serialno)break;
1164 if(link==vf->links)return(OV_EBADLINK);
1165 vf->current_link=link;
1167 ogg_stream_init(&vf->os,vf->current_serialno);
1168 ogg_stream_reset(&vf->os);
1169 vf->ready_state=STREAMSET;
1172 ogg_stream_pagein(&vf->os,&og);
1176 /* discard samples until we reach the desired position. Crossing a
1177 logical bitstream boundary with abandon is OK. */
1178 _make_decode_ready(vf);
1179 while(vf->pcm_offset<pos){
1181 long target=pos-vf->pcm_offset;
1182 long samples=vorbis_synthesis_pcmout(&vf->vd,&pcm);
1184 if(samples>target)samples=target;
1185 vorbis_synthesis_read(&vf->vd,samples);
1186 vf->pcm_offset+=samples;
1189 if(_process_packet(vf,1)<=0)
1190 vf->pcm_offset=ov_pcm_total(vf,-1); /* eof */
1195 /* seek to a playback time relative to the decompressed pcm stream
1196 returns zero on success, nonzero on failure */
1197 int ov_time_seek(OggVorbis_File *vf,double seconds){
1198 /* translate time to PCM position and call ov_pcm_seek */
1201 ogg_int64_t pcm_total=ov_pcm_total(vf,-1);
1202 double time_total=ov_time_total(vf,-1);
1204 if(vf->ready_state<OPENED)return(OV_EINVAL);
1205 if(!vf->seekable)return(OV_ENOSEEK);
1206 if(seconds<0 || seconds>time_total)return(OV_EINVAL);
1208 /* which bitstream section does this time offset occur in? */
1209 for(link=vf->links-1;link>=0;link--){
1210 pcm_total-=vf->pcmlengths[link];
1211 time_total-=ov_time_total(vf,link);
1212 if(seconds>=time_total)break;
1215 /* enough information to convert time offset to pcm offset */
1217 ogg_int64_t target=pcm_total+(seconds-time_total)*vf->vi[link].rate;
1218 return(ov_pcm_seek(vf,target));
1222 /* page-granularity version of ov_time_seek
1223 returns zero on success, nonzero on failure */
1224 int ov_time_seek_page(OggVorbis_File *vf,double seconds){
1225 /* translate time to PCM position and call ov_pcm_seek */
1228 ogg_int64_t pcm_total=ov_pcm_total(vf,-1);
1229 double time_total=ov_time_total(vf,-1);
1231 if(vf->ready_state<OPENED)return(OV_EINVAL);
1232 if(!vf->seekable)return(OV_ENOSEEK);
1233 if(seconds<0 || seconds>time_total)return(OV_EINVAL);
1235 /* which bitstream section does this time offset occur in? */
1236 for(link=vf->links-1;link>=0;link--){
1237 pcm_total-=vf->pcmlengths[link];
1238 time_total-=ov_time_total(vf,link);
1239 if(seconds>=time_total)break;
1242 /* enough information to convert time offset to pcm offset */
1244 ogg_int64_t target=pcm_total+(seconds-time_total)*vf->vi[link].rate;
1245 return(ov_pcm_seek_page(vf,target));
1249 /* tell the current stream offset cursor. Note that seek followed by
1250 tell will likely not give the set offset due to caching */
1251 ogg_int64_t ov_raw_tell(OggVorbis_File *vf){
1252 if(vf->ready_state<OPENED)return(OV_EINVAL);
1256 /* return PCM offset (sample) of next PCM sample to be read */
1257 ogg_int64_t ov_pcm_tell(OggVorbis_File *vf){
1258 if(vf->ready_state<OPENED)return(OV_EINVAL);
1259 return(vf->pcm_offset);
1262 /* return time offset (seconds) of next PCM sample to be read */
1263 double ov_time_tell(OggVorbis_File *vf){
1264 /* translate time to PCM position and call ov_pcm_seek */
1267 ogg_int64_t pcm_total=0;
1268 double time_total=0.f;
1270 if(vf->ready_state<OPENED)return(OV_EINVAL);
1272 pcm_total=ov_pcm_total(vf,-1);
1273 time_total=ov_time_total(vf,-1);
1275 /* which bitstream section does this time offset occur in? */
1276 for(link=vf->links-1;link>=0;link--){
1277 pcm_total-=vf->pcmlengths[link];
1278 time_total-=ov_time_total(vf,link);
1279 if(vf->pcm_offset>=pcm_total)break;
1283 return((double)time_total+(double)(vf->pcm_offset-pcm_total)/vf->vi[link].rate);
1286 /* link: -1) return the vorbis_info struct for the bitstream section
1287 currently being decoded
1288 0-n) to request information for a specific bitstream section
1290 In the case of a non-seekable bitstream, any call returns the
1291 current bitstream. NULL in the case that the machine is not
1294 vorbis_info *ov_info(OggVorbis_File *vf,int link){
1297 if(vf->ready_state>=STREAMSET)
1298 return vf->vi+vf->current_link;
1311 /* grr, strong typing, grr, no templates/inheritence, grr */
1312 vorbis_comment *ov_comment(OggVorbis_File *vf,int link){
1315 if(vf->ready_state>=STREAMSET)
1316 return vf->vc+vf->current_link;
1329 int host_is_big_endian() {
1330 ogg_int32_t pattern = 0xfeedface; /* deadbeef */
1331 unsigned char *bytewise = (unsigned char *)&pattern;
1332 if (bytewise[0] == 0xfe) return 1;
1336 /* up to this point, everything could more or less hide the multiple
1337 logical bitstream nature of chaining from the toplevel application
1338 if the toplevel application didn't particularly care. However, at
1339 the point that we actually read audio back, the multiple-section
1340 nature must surface: Multiple bitstream sections do not necessarily
1341 have to have the same number of channels or sampling rate.
1343 ov_read returns the sequential logical bitstream number currently
1344 being decoded along with the PCM data in order that the toplevel
1345 application can take action on channel/sample rate changes. This
1346 number will be incremented even for streamed (non-seekable) streams
1347 (for seekable streams, it represents the actual logical bitstream
1348 index within the physical bitstream. Note that the accessor
1349 functions above are aware of this dichotomy).
1351 input values: buffer) a buffer to hold packed PCM data for return
1352 length) the byte length requested to be placed into buffer
1353 bigendianp) should the data be packed LSB first (0) or
1355 word) word size for output. currently 1 (byte) or
1358 return values: <0) error/hole in data (OV_HOLE), partial open (OV_EINVAL)
1360 n) number of bytes of PCM actually returned. The
1361 below works on a packet-by-packet basis, so the
1362 return length is not related to the 'length' passed
1363 in, just guaranteed to fit.
1365 *section) set to the logical bitstream number */
1367 long ov_read(OggVorbis_File *vf,char *buffer,int length,
1368 int bigendianp,int word,int sgned,int *bitstream){
1370 int host_endian = host_is_big_endian();
1372 if(vf->ready_state<OPENED)return(OV_EINVAL);
1373 if(vf->ready_state==OPENED)return(OV_EOF); /* stream is always
1376 open)... unless there
1377 was no page at the end
1382 if(vf->ready_state>=STREAMSET){
1384 long samples=vorbis_synthesis_pcmout(&vf->vd,&pcm);
1386 /* yay! proceed to pack data into the byte buffer */
1388 long channels=ov_info(vf,-1)->channels;
1389 long bytespersample=word * channels;
1390 vorbis_fpu_control fpu;
1391 if(samples>length/bytespersample)samples=length/bytespersample;
1393 /* a tight loop to pack each size */
1397 int off=(sgned?0:128);
1398 vorbis_fpu_setround(&fpu);
1399 for(j=0;j<samples;j++)
1400 for(i=0;i<channels;i++){
1401 val=vorbis_ftoi(pcm[i][j]*128.f);
1403 else if(val<-128)val=-128;
1406 vorbis_fpu_restore(fpu);
1408 int off=(sgned?0:32768);
1410 if(host_endian==bigendianp){
1413 vorbis_fpu_setround(&fpu);
1414 for(i=0;i<channels;i++) { /* It's faster in this order */
1416 short *dest=((short *)buffer)+i;
1417 for(j=0;j<samples;j++) {
1418 val=vorbis_ftoi(src[j]*32768.f);
1419 if(val>32767)val=32767;
1420 else if(val<-32768)val=-32768;
1425 vorbis_fpu_restore(fpu);
1429 vorbis_fpu_setround(&fpu);
1430 for(i=0;i<channels;i++) {
1432 short *dest=((short *)buffer)+i;
1433 for(j=0;j<samples;j++) {
1434 val=vorbis_ftoi(src[j]*32768.f);
1435 if(val>32767)val=32767;
1436 else if(val<-32768)val=-32768;
1441 vorbis_fpu_restore(fpu);
1444 }else if(bigendianp){
1446 vorbis_fpu_setround(&fpu);
1447 for(j=0;j<samples;j++)
1448 for(i=0;i<channels;i++){
1449 val=vorbis_ftoi(pcm[i][j]*32768.f);
1450 if(val>32767)val=32767;
1451 else if(val<-32768)val=-32768;
1454 *buffer++=(val&0xff);
1456 vorbis_fpu_restore(fpu);
1460 vorbis_fpu_setround(&fpu);
1461 for(j=0;j<samples;j++)
1462 for(i=0;i<channels;i++){
1463 val=vorbis_ftoi(pcm[i][j]*32768.f);
1464 if(val>32767)val=32767;
1465 else if(val<-32768)val=-32768;
1467 *buffer++=(val&0xff);
1470 vorbis_fpu_restore(fpu);
1476 vorbis_synthesis_read(&vf->vd,samples);
1477 vf->pcm_offset+=samples;
1478 if(bitstream)*bitstream=vf->current_link;
1479 return(samples*bytespersample);
1483 /* suck in another packet */
1484 switch(_process_packet(vf,1)){
1490 return(OV_EBADLINK);