1 /********************************************************************
3 * THIS FILE IS PART OF THE OggVorbis 'TREMOR' CODEC SOURCE CODE. *
5 * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS *
6 * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
7 * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
9 * THE OggVorbis 'TREMOR' SOURCE CODE IS (C) COPYRIGHT 1994-2014 *
10 * BY THE Xiph.Org FOUNDATION http://www.xiph.org/ *
12 ********************************************************************
14 function: stdio-based convenience library for opening/seeking/decoding
17 ********************************************************************/
25 #include "ivorbiscodec.h"
26 #include "ivorbisfile.h"
31 /* A 'chained bitstream' is a Vorbis bitstream that contains more than
32 one logical bitstream arranged end to end (the only form of Ogg
33 multiplexing allowed in a Vorbis bitstream; grouping [parallel
34 multiplexing] is not allowed in Vorbis) */
36 /* A Vorbis file can be played beginning to end (streamed) without
37 worrying ahead of time about chaining (see decoder_example.c). If
38 we have the whole file, however, and want random access
39 (seeking/scrubbing) or desire to know the total length/time of a
40 file, we need to account for the possibility of chaining. */
42 /* We can handle things a number of ways; we can determine the entire
43 bitstream structure right off the bat, or find pieces on demand.
44 This example determines and caches structure for the entire
45 bitstream, but builds a virtual decoder on the fly when moving
46 between links in the chain. */
48 /* There are also different ways to implement seeking. Enough
49 information exists in an Ogg bitstream to seek to
50 sample-granularity positions in the output. Or, one can seek by
51 picking some portion of the stream roughly in the desired area if
52 we only want coarse navigation through the stream. */
54 /*************************************************************************
55 * Many, many internal helpers. The intention is not to be confusing;
56 * rampant duplication and monolithic function implementation would be
57 * harder to understand anyway. The high level functions are last. Begin
58 * grokking near the end of the file */
61 /* read a little more data from the file/pipe into the ogg_sync framer */
62 static long _get_data(OggVorbis_File
*vf
){
64 if(!(vf
->callbacks
.read_func
))return(-1);
66 char *buffer
=ogg_sync_buffer(&vf
->oy
,READSIZE
);
67 long bytes
=(vf
->callbacks
.read_func
)(buffer
,1,READSIZE
,vf
->datasource
);
68 if(bytes
>0)ogg_sync_wrote(&vf
->oy
,bytes
);
69 if(bytes
==0 && errno
)return(-1);
75 /* save a tiny smidge of verbosity to make the code more readable */
76 static int _seek_helper(OggVorbis_File
*vf
,ogg_int64_t offset
){
78 /* only seek if the file position isn't already there */
79 if(vf
->offset
!= offset
){
80 if(!(vf
->callbacks
.seek_func
)||
81 (vf
->callbacks
.seek_func
)(vf
->datasource
, offset
, SEEK_SET
) == -1)
84 ogg_sync_reset(&vf
->oy
);
87 /* shouldn't happen unless someone writes a broken callback */
93 /* The read/seek functions track absolute position within the stream */
95 /* from the head of the stream, get the next page. boundary specifies
96 if the function is allowed to fetch more data from the stream (and
97 how much) or only use internally buffered data.
99 boundary: -1) unbounded search
100 0) read no additional data; use cached only
101 n) search for a new page beginning for n bytes
103 return: <0) did not find a page (OV_FALSE, OV_EOF, OV_EREAD)
104 n) found a page at absolute offset n */
106 static ogg_int64_t
_get_next_page(OggVorbis_File
*vf
,ogg_page
*og
,
107 ogg_int64_t boundary
){
108 if(boundary
>0)boundary
+=vf
->offset
;
112 if(boundary
>0 && vf
->offset
>=boundary
)return(OV_FALSE
);
113 more
=ogg_sync_pageseek(&vf
->oy
,og
);
116 /* skipped n bytes */
120 /* send more paramedics */
121 if(!boundary
)return(OV_FALSE
);
123 long ret
=_get_data(vf
);
124 if(ret
==0)return(OV_EOF
);
125 if(ret
<0)return(OV_EREAD
);
128 /* got a page. Return the offset at the page beginning,
129 advance the internal offset past the page end */
130 ogg_int64_t ret
=vf
->offset
;
139 /* find the latest page beginning before the passed in position. Much
140 dirtier than the above as Ogg doesn't have any backward search
141 linkage. no 'readp' as it will certainly have to read. */
142 /* returns offset or OV_EREAD, OV_FAULT */
143 static ogg_int64_t
_get_prev_page(OggVorbis_File
*vf
,ogg_int64_t begin
,ogg_page
*og
){
144 ogg_int64_t end
= begin
;
146 ogg_int64_t offset
=-1;
153 ret
=_seek_helper(vf
,begin
);
156 while(vf
->offset
<end
){
157 memset(og
,0,sizeof(*og
));
158 ret
=_get_next_page(vf
,og
,end
-vf
->offset
);
159 if(ret
==OV_EREAD
)return(OV_EREAD
);
168 /* In a fully compliant, non-multiplexed stream, we'll still be
169 holding the last page. In multiplexed (or noncompliant streams),
170 we will probably have to re-read the last page we saw */
171 if(og
->header_len
==0){
172 ret
=_seek_helper(vf
,offset
);
175 ret
=_get_next_page(vf
,og
,CHUNKSIZE
);
177 /* this shouldn't be possible */
184 static void _add_serialno(ogg_page
*og
,ogg_uint32_t
**serialno_list
, int *n
){
185 ogg_uint32_t s
= ogg_page_serialno(og
);
189 *serialno_list
= _ogg_realloc(*serialno_list
, sizeof(**serialno_list
)*(*n
));
191 *serialno_list
= _ogg_malloc(sizeof(**serialno_list
));
194 (*serialno_list
)[(*n
)-1] = s
;
197 /* returns nonzero if found */
198 static int _lookup_serialno(ogg_uint32_t s
, ogg_uint32_t
*serialno_list
, int n
){
201 if(*serialno_list
== s
) return 1;
208 static int _lookup_page_serialno(ogg_page
*og
, ogg_uint32_t
*serialno_list
, int n
){
209 ogg_uint32_t s
= ogg_page_serialno(og
);
210 return _lookup_serialno(s
,serialno_list
,n
);
213 /* performs the same search as _get_prev_page, but prefers pages of
214 the specified serial number. If a page of the specified serialno is
215 spotted during the seek-back-and-read-forward, it will return the
216 info of last page of the matching serial number instead of the very
217 last page. If no page of the specified serialno is seen, it will
218 return the info of last page and alter *serialno. */
219 static ogg_int64_t
_get_prev_page_serial(OggVorbis_File
*vf
, ogg_int64_t begin
,
220 ogg_uint32_t
*serial_list
, int serial_n
,
221 int *serialno
, ogg_int64_t
*granpos
){
223 ogg_int64_t end
=begin
;
226 ogg_int64_t prefoffset
=-1;
227 ogg_int64_t offset
=-1;
228 ogg_int64_t ret_serialno
=-1;
229 ogg_int64_t ret_gran
=-1;
236 ret
=_seek_helper(vf
,begin
);
239 while(vf
->offset
<end
){
240 ret
=_get_next_page(vf
,&og
,end
-vf
->offset
);
241 if(ret
==OV_EREAD
)return(OV_EREAD
);
245 ret_serialno
=ogg_page_serialno(&og
);
246 ret_gran
=ogg_page_granulepos(&og
);
249 if((ogg_uint32_t
)ret_serialno
== *serialno
){
254 if(!_lookup_serialno((ogg_uint32_t
)ret_serialno
,serial_list
,serial_n
)){
255 /* we fell off the end of the link, which means we seeked
256 back too far and shouldn't have been looking in that link
257 to begin with. If we found the preferred serial number,
258 forget that we saw it. */
265 /* we're not interested in the page... just the serialno and granpos. */
266 if(prefoffset
>=0)return(prefoffset
);
268 *serialno
= ret_serialno
;
274 /* uses the local ogg_stream storage in vf; this is important for
275 non-streaming input sources */
276 static int _fetch_headers(OggVorbis_File
*vf
,vorbis_info
*vi
,vorbis_comment
*vc
,
277 ogg_uint32_t
**serialno_list
, int *serialno_n
,
285 ogg_int64_t llret
=_get_next_page(vf
,&og
,CHUNKSIZE
);
286 if(llret
==OV_EREAD
)return(OV_EREAD
);
287 if(llret
<0)return(OV_ENOTVORBIS
);
291 vorbis_info_init(vi
);
292 vorbis_comment_init(vc
);
293 vf
->ready_state
=OPENED
;
295 /* extract the serialnos of all BOS pages + the first set of vorbis
296 headers we see in the link */
298 while(ogg_page_bos(og_ptr
)){
300 if(_lookup_page_serialno(og_ptr
,*serialno_list
,*serialno_n
)){
301 /* a dupe serialnumber in an initial header packet set == invalid stream */
302 if(*serialno_list
)_ogg_free(*serialno_list
);
309 _add_serialno(og_ptr
,serialno_list
,serialno_n
);
312 if(vf
->ready_state
<STREAMSET
){
313 /* we don't have a vorbis stream in this link yet, so begin
314 prospective stream setup. We need a stream to get packets */
315 ogg_stream_reset_serialno(&vf
->os
,ogg_page_serialno(og_ptr
));
316 ogg_stream_pagein(&vf
->os
,og_ptr
);
318 if(ogg_stream_packetout(&vf
->os
,&op
) > 0 &&
319 vorbis_synthesis_idheader(&op
)){
320 /* vorbis header; continue setup */
321 vf
->ready_state
=STREAMSET
;
322 if((ret
=vorbis_synthesis_headerin(vi
,vc
,&op
))){
331 ogg_int64_t llret
=_get_next_page(vf
,og_ptr
,CHUNKSIZE
);
341 /* if this page also belongs to our vorbis stream, submit it and break */
342 if(vf
->ready_state
==STREAMSET
&&
343 vf
->os
.serialno
== ogg_page_serialno(og_ptr
)){
344 ogg_stream_pagein(&vf
->os
,og_ptr
);
350 if(vf
->ready_state
!=STREAMSET
){
358 while(i
<2){ /* get a page loop */
360 while(i
<2){ /* get a packet loop */
362 int result
=ogg_stream_packetout(&vf
->os
,&op
);
369 if((ret
=vorbis_synthesis_headerin(vi
,vc
,&op
)))
376 if(_get_next_page(vf
,og_ptr
,CHUNKSIZE
)<0){
381 /* if this page belongs to the correct stream, go parse it */
382 if(vf
->os
.serialno
== ogg_page_serialno(og_ptr
)){
383 ogg_stream_pagein(&vf
->os
,og_ptr
);
387 /* if we never see the final vorbis headers before the link
389 if(ogg_page_bos(og_ptr
)){
397 /* otherwise, keep looking */
405 vorbis_info_clear(vi
);
406 vorbis_comment_clear(vc
);
407 vf
->ready_state
=OPENED
;
412 /* Starting from current cursor position, get initial PCM offset of
413 next page. Consumes the page in the process without decoding
414 audio, however this is only called during stream parsing upon
416 static ogg_int64_t
_initial_pcmoffset(OggVorbis_File
*vf
, vorbis_info
*vi
){
418 ogg_int64_t accumulated
=0;
421 int serialno
= vf
->os
.serialno
;
425 if(_get_next_page(vf
,&og
,-1)<0)
426 break; /* should not be possible unless the file is truncated/mangled */
428 if(ogg_page_bos(&og
)) break;
429 if(ogg_page_serialno(&og
)!=serialno
) continue;
431 /* count blocksizes of all frames in the page */
432 ogg_stream_pagein(&vf
->os
,&og
);
433 while((result
=ogg_stream_packetout(&vf
->os
,&op
))){
434 if(result
>0){ /* ignore holes */
435 long thisblock
=vorbis_packet_blocksize(vi
,&op
);
437 accumulated
+=(lastblock
+thisblock
)>>2;
442 if(ogg_page_granulepos(&og
)!=-1){
443 /* pcm offset of last packet on the first audio page */
444 accumulated
= ogg_page_granulepos(&og
)-accumulated
;
449 /* less than zero? This is a stream with samples trimmed off
450 the beginning, a normal occurrence; set the offset to zero */
451 if(accumulated
<0)accumulated
=0;
456 /* finds each bitstream link one at a time using a bisection search
457 (has to begin by knowing the offset of the lb's initial page).
458 Recurses for each link so it can alloc the link storage after
459 finding them all, then unroll and fill the cache at the same time */
460 static int _bisect_forward_serialno(OggVorbis_File
*vf
,
462 ogg_int64_t searched
,
466 ogg_uint32_t
*currentno_list
,
469 ogg_int64_t pcmoffset
;
470 ogg_int64_t dataoffset
=searched
;
471 ogg_int64_t endsearched
=end
;
472 ogg_int64_t next
=end
;
473 ogg_int64_t searchgran
=-1;
475 ogg_int64_t ret
,last
;
476 int serialno
= vf
->os
.serialno
;
479 we have the headers and serialnos for the link beginning at 'begin'
480 we have the offset and granpos of the last page in the file (potentially
481 not a page we care about)
484 /* Is the last page in our list of current serialnumbers? */
485 if(_lookup_serialno(endserial
,currentno_list
,currentnos
)){
487 /* last page is in the starting serialno list, so we've bisected
488 down to (or just started with) a single link. Now we need to
489 find the last vorbis page belonging to the first vorbis stream
492 while(endserial
!= serialno
){
493 endserial
= serialno
;
494 searched
=_get_prev_page_serial(vf
,searched
,currentno_list
,currentnos
,&endserial
,&endgran
);
498 if(vf
->offsets
)_ogg_free(vf
->offsets
);
499 if(vf
->serialnos
)_ogg_free(vf
->serialnos
);
500 if(vf
->dataoffsets
)_ogg_free(vf
->dataoffsets
);
502 vf
->offsets
=_ogg_malloc((vf
->links
+1)*sizeof(*vf
->offsets
));
503 vf
->vi
=_ogg_realloc(vf
->vi
,vf
->links
*sizeof(*vf
->vi
));
504 vf
->vc
=_ogg_realloc(vf
->vc
,vf
->links
*sizeof(*vf
->vc
));
505 vf
->serialnos
=_ogg_malloc(vf
->links
*sizeof(*vf
->serialnos
));
506 vf
->dataoffsets
=_ogg_malloc(vf
->links
*sizeof(*vf
->dataoffsets
));
507 vf
->pcmlengths
=_ogg_malloc(vf
->links
*2*sizeof(*vf
->pcmlengths
));
509 vf
->offsets
[m
+1]=end
;
510 vf
->offsets
[m
]=begin
;
511 vf
->pcmlengths
[m
*2+1]=(endgran
<0?0:endgran
);
515 /* last page is not in the starting stream's serial number list,
516 so we have multiple links. Find where the stream that begins
517 our bisection ends. */
519 ogg_uint32_t
*next_serialno_list
=NULL
;
520 int next_serialnos
=0;
523 int testserial
= serialno
+1;
525 /* the below guards against garbage seperating the last and
526 first pages of two links. */
527 while(searched
<endsearched
){
530 if(endsearched
-searched
<CHUNKSIZE
){
533 bisect
=(searched
+endsearched
)/2;
536 ret
=_seek_helper(vf
,bisect
);
539 last
=_get_next_page(vf
,&og
,-1);
540 if(last
==OV_EREAD
)return(OV_EREAD
);
541 if(last
<0 || !_lookup_page_serialno(&og
,currentno_list
,currentnos
)){
543 if(last
>=0)next
=last
;
549 /* Bisection point found */
550 /* for the time being, fetch end PCM offset the simple way */
552 while(testserial
!= serialno
){
553 testserial
= serialno
;
554 searched
= _get_prev_page_serial(vf
,searched
,currentno_list
,currentnos
,&testserial
,&searchgran
);
557 ret
=_seek_helper(vf
,next
);
560 ret
=_fetch_headers(vf
,&vi
,&vc
,&next_serialno_list
,&next_serialnos
,NULL
);
562 serialno
= vf
->os
.serialno
;
563 dataoffset
= vf
->offset
;
565 /* this will consume a page, however the next bisection always
566 starts with a raw seek */
567 pcmoffset
= _initial_pcmoffset(vf
,&vi
);
569 ret
=_bisect_forward_serialno(vf
,next
,vf
->offset
,end
,endgran
,endserial
,
570 next_serialno_list
,next_serialnos
,m
+1);
573 if(next_serialno_list
)_ogg_free(next_serialno_list
);
575 vf
->offsets
[m
+1]=next
;
576 vf
->serialnos
[m
+1]=serialno
;
577 vf
->dataoffsets
[m
+1]=dataoffset
;
582 vf
->pcmlengths
[m
*2+1]=searchgran
;
583 vf
->pcmlengths
[m
*2+2]=pcmoffset
;
584 vf
->pcmlengths
[m
*2+3]-=pcmoffset
;
585 if(vf
->pcmlengths
[m
*2+3]<0)vf
->pcmlengths
[m
*2+3]=0;
591 static int _make_decode_ready(OggVorbis_File
*vf
){
592 if(vf
->ready_state
>STREAMSET
)return 0;
593 if(vf
->ready_state
<STREAMSET
)return OV_EFAULT
;
595 if(vorbis_synthesis_init(&vf
->vd
,vf
->vi
+vf
->current_link
))
598 if(vorbis_synthesis_init(&vf
->vd
,vf
->vi
))
601 vorbis_block_init(&vf
->vd
,&vf
->vb
);
602 vf
->ready_state
=INITSET
;
608 static int _open_seekable2(OggVorbis_File
*vf
){
609 ogg_int64_t dataoffset
=vf
->dataoffsets
[0],end
,endgran
=-1;
610 int endserial
=vf
->os
.serialno
;
611 int serialno
=vf
->os
.serialno
;
613 /* we're partially open and have a first link header state in
616 /* fetch initial PCM offset */
617 ogg_int64_t pcmoffset
= _initial_pcmoffset(vf
,vf
->vi
);
619 /* we can seek, so set out learning all about this file */
620 if(vf
->callbacks
.seek_func
&& vf
->callbacks
.tell_func
){
621 (vf
->callbacks
.seek_func
)(vf
->datasource
,0,SEEK_END
);
622 vf
->offset
=vf
->end
=(vf
->callbacks
.tell_func
)(vf
->datasource
);
624 vf
->offset
=vf
->end
=-1;
627 /* If seek_func is implemented, tell_func must also be implemented */
628 if(vf
->end
==-1) return(OV_EINVAL
);
630 /* Get the offset of the last page of the physical bitstream, or, if
631 we're lucky the last vorbis page of this link as most OggVorbis
632 files will contain a single logical bitstream */
633 end
=_get_prev_page_serial(vf
,vf
->end
,vf
->serialnos
+2,vf
->serialnos
[1],&endserial
,&endgran
);
634 if(end
<0)return(end
);
636 /* now determine bitstream structure recursively */
637 if(_bisect_forward_serialno(vf
,0,dataoffset
,end
,endgran
,endserial
,
638 vf
->serialnos
+2,vf
->serialnos
[1],0)<0)return(OV_EREAD
);
641 vf
->serialnos
[0]=serialno
;
642 vf
->dataoffsets
[0]=dataoffset
;
643 vf
->pcmlengths
[0]=pcmoffset
;
644 vf
->pcmlengths
[1]-=pcmoffset
;
645 if(vf
->pcmlengths
[1]<0)vf
->pcmlengths
[1]=0;
647 return(ov_raw_seek(vf
,dataoffset
));
650 /* clear out the current logical bitstream decoder */
651 static void _decode_clear(OggVorbis_File
*vf
){
652 vorbis_dsp_clear(&vf
->vd
);
653 vorbis_block_clear(&vf
->vb
);
654 vf
->ready_state
=OPENED
;
657 /* fetch and process a packet. Handles the case where we're at a
658 bitstream boundary and dumps the decoding machine. If the decoding
659 machine is unloaded, it loads it. It also keeps pcm_offset up to
660 date (seek and read both use this. seek uses a special hack with
663 return: <0) error, OV_HOLE (lost packet) or OV_EOF
664 0) need more data (only if readp==0)
668 static int _fetch_and_process_packet(OggVorbis_File
*vf
,
674 /* handle one packet. Try to fetch it from current stream state */
675 /* extract packets from page */
678 if(vf
->ready_state
==STREAMSET
){
679 int ret
=_make_decode_ready(vf
);
683 /* process a packet if we can. If the machine isn't loaded,
685 if(vf
->ready_state
==INITSET
){
688 ogg_packet
*op_ptr
=(op_in
?op_in
:&op
);
689 int result
=ogg_stream_packetout(&vf
->os
,op_ptr
);
690 ogg_int64_t granulepos
;
693 if(result
==-1)return(OV_HOLE
); /* hole in the data. */
695 /* got a packet. process it */
696 granulepos
=op_ptr
->granulepos
;
697 if(!vorbis_synthesis(&vf
->vb
,op_ptr
)){ /* lazy check for lazy
699 header packets aren't
702 vorbis_synthesis will
705 /* suck in the synthesis data and track bitrate */
707 int oldsamples
=vorbis_synthesis_pcmout(&vf
->vd
,NULL
);
708 /* for proper use of libvorbis within libvorbisfile,
709 oldsamples will always be zero. */
710 if(oldsamples
)return(OV_EFAULT
);
712 vorbis_synthesis_blockin(&vf
->vd
,&vf
->vb
);
713 vf
->samptrack
+=vorbis_synthesis_pcmout(&vf
->vd
,NULL
);
714 vf
->bittrack
+=op_ptr
->bytes
*8;
717 /* update the pcm offset. */
718 if(granulepos
!=-1 && !op_ptr
->e_o_s
){
719 int link
=(vf
->seekable
?vf
->current_link
:0);
722 /* this packet has a pcm_offset on it (the last packet
723 completed on a page carries the offset) After processing
724 (above), we know the pcm position of the *last* sample
725 ready to be returned. Find the offset of the *first*
727 As an aside, this trick is inaccurate if we begin
728 reading anew right at the last page; the end-of-stream
729 granulepos declares the last frame in the stream, and the
730 last packet of the last page may be a partial frame.
731 So, we need a previous granulepos from an in-sequence page
732 to have a reference point. Thus the !op_ptr->e_o_s clause
735 if(vf
->seekable
&& link
>0)
736 granulepos
-=vf
->pcmlengths
[link
*2];
737 if(granulepos
<0)granulepos
=0; /* actually, this
738 shouldn't be possible
739 here unless the stream
742 samples
=vorbis_synthesis_pcmout(&vf
->vd
,NULL
);
746 granulepos
+=vf
->pcmlengths
[i
*2+1];
747 vf
->pcm_offset
=granulepos
;
757 if(vf
->ready_state
>=OPENED
){
761 /* the loop is not strictly necessary, but there's no sense in
762 doing the extra checks of the larger loop for the common
763 case in a multiplexed bistream where the page is simply
764 part of a different logical bitstream; keep reading until
765 we get one with the correct serialno */
768 if((ret
=_get_next_page(vf
,&og
,-1))<0){
769 return(OV_EOF
); /* eof. leave unitialized */
772 /* bitrate tracking; add the header's bytes here, the body bytes
773 are done by packet above */
774 vf
->bittrack
+=og
.header_len
*8;
776 if(vf
->ready_state
==INITSET
){
777 if(vf
->current_serialno
!=ogg_page_serialno(&og
)){
779 /* two possibilities:
780 1) our decoding just traversed a bitstream boundary
781 2) another stream is multiplexed into this logical section */
783 if(ogg_page_bos(&og
)){
791 vorbis_info_clear(vf
->vi
);
792 vorbis_comment_clear(vf
->vc
);
797 continue; /* possibility #2 */
805 /* Do we need to load a new machine before submitting the page? */
806 /* This is different in the seekable and non-seekable cases.
808 In the seekable case, we already have all the header
809 information loaded and cached; we just initialize the machine
810 with it and continue on our merry way.
812 In the non-seekable (streaming) case, we'll only be at a
813 boundary if we just left the previous logical bitstream and
814 we're now nominally at the header of the next bitstream
817 if(vf
->ready_state
!=INITSET
){
820 if(vf
->ready_state
<STREAMSET
){
822 ogg_uint32_t serialno
= ogg_page_serialno(&og
);
824 /* match the serialno to bitstream section. We use this rather than
825 offset positions to avoid problems near logical bitstream
828 for(link
=0;link
<vf
->links
;link
++)
829 if(vf
->serialnos
[link
]==serialno
)break;
831 if(link
==vf
->links
) continue; /* not the desired Vorbis
832 bitstream section; keep
835 vf
->current_serialno
=serialno
;
836 vf
->current_link
=link
;
838 ogg_stream_reset_serialno(&vf
->os
,vf
->current_serialno
);
839 vf
->ready_state
=STREAMSET
;
842 /* we're streaming */
843 /* fetch the three header packets, build the info struct */
845 int ret
=_fetch_headers(vf
,vf
->vi
,vf
->vc
,NULL
,NULL
,&og
);
847 vf
->current_serialno
=vf
->os
.serialno
;
854 /* the buffered page is the data we want, and we're ready for it;
855 add it to the stream state */
856 ogg_stream_pagein(&vf
->os
,&og
);
861 /* if, eg, 64 bit stdio is configured by default, this will build with
863 static int _fseek64_wrap(FILE *f
,ogg_int64_t off
,int whence
){
864 if(f
==NULL
)return(-1);
865 return fseek(f
,off
,whence
);
868 static int _ov_open1(void *f
,OggVorbis_File
*vf
,const char *initial
,
869 long ibytes
, ov_callbacks callbacks
){
870 int offsettest
=((f
&& callbacks
.seek_func
)?callbacks
.seek_func(f
,0,SEEK_CUR
):-1);
871 ogg_uint32_t
*serialno_list
=NULL
;
872 int serialno_list_size
=0;
875 memset(vf
,0,sizeof(*vf
));
877 vf
->callbacks
= callbacks
;
879 /* init the framing state */
880 ogg_sync_init(&vf
->oy
);
882 /* perhaps some data was previously read into a buffer for testing
883 against other stream types. Allow initialization from this
884 previously read data (especially as we may be reading from a
885 non-seekable stream) */
887 char *buffer
=ogg_sync_buffer(&vf
->oy
,ibytes
);
888 memcpy(buffer
,initial
,ibytes
);
889 ogg_sync_wrote(&vf
->oy
,ibytes
);
892 /* can we seek? Stevens suggests the seek test was portable */
893 if(offsettest
!=-1)vf
->seekable
=1;
895 /* No seeking yet; Set up a 'single' (current) logical bitstream
896 entry for partial open */
898 vf
->vi
=_ogg_calloc(vf
->links
,sizeof(*vf
->vi
));
899 vf
->vc
=_ogg_calloc(vf
->links
,sizeof(*vf
->vc
));
900 ogg_stream_init(&vf
->os
,-1); /* fill in the serialno later */
902 /* Fetch all BOS pages, store the vorbis header and all seen serial
903 numbers, load subsequent vorbis setup headers */
904 if((ret
=_fetch_headers(vf
,vf
->vi
,vf
->vc
,&serialno_list
,&serialno_list_size
,NULL
))<0){
908 /* serial number list for first link needs to be held somewhere
909 for second stage of seekable stream open; this saves having to
910 seek/reread first link's serialnumber data then. */
911 vf
->serialnos
=_ogg_calloc(serialno_list_size
+2,sizeof(*vf
->serialnos
));
912 vf
->serialnos
[0]=vf
->current_serialno
=vf
->os
.serialno
;
913 vf
->serialnos
[1]=serialno_list_size
;
914 memcpy(vf
->serialnos
+2,serialno_list
,serialno_list_size
*sizeof(*vf
->serialnos
));
916 vf
->offsets
=_ogg_calloc(1,sizeof(*vf
->offsets
));
917 vf
->dataoffsets
=_ogg_calloc(1,sizeof(*vf
->dataoffsets
));
919 vf
->dataoffsets
[0]=vf
->offset
;
921 vf
->ready_state
=PARTOPEN
;
923 if(serialno_list
)_ogg_free(serialno_list
);
927 static int _ov_open2(OggVorbis_File
*vf
){
928 if(vf
->ready_state
!= PARTOPEN
) return OV_EINVAL
;
929 vf
->ready_state
=OPENED
;
931 int ret
=_open_seekable2(vf
);
938 vf
->ready_state
=STREAMSET
;
944 /* clear out the OggVorbis_File struct */
945 int ov_clear(OggVorbis_File
*vf
){
947 vorbis_block_clear(&vf
->vb
);
948 vorbis_dsp_clear(&vf
->vd
);
949 ogg_stream_clear(&vf
->os
);
951 if(vf
->vi
&& vf
->links
){
953 for(i
=0;i
<vf
->links
;i
++){
954 vorbis_info_clear(vf
->vi
+i
);
955 vorbis_comment_clear(vf
->vc
+i
);
960 if(vf
->dataoffsets
)_ogg_free(vf
->dataoffsets
);
961 if(vf
->pcmlengths
)_ogg_free(vf
->pcmlengths
);
962 if(vf
->serialnos
)_ogg_free(vf
->serialnos
);
963 if(vf
->offsets
)_ogg_free(vf
->offsets
);
964 ogg_sync_clear(&vf
->oy
);
965 if(vf
->datasource
&& vf
->callbacks
.close_func
)
966 (vf
->callbacks
.close_func
)(vf
->datasource
);
967 memset(vf
,0,sizeof(*vf
));
975 /* inspects the OggVorbis file and finds/documents all the logical
976 bitstreams contained in it. Tries to be tolerant of logical
977 bitstream sections that are truncated/woogie.
983 int ov_open_callbacks(void *f
,OggVorbis_File
*vf
,
984 const char *initial
,long ibytes
,ov_callbacks callbacks
){
985 int ret
=_ov_open1(f
,vf
,initial
,ibytes
,callbacks
);
987 return _ov_open2(vf
);
990 int ov_open(FILE *f
,OggVorbis_File
*vf
,const char *initial
,long ibytes
){
991 ov_callbacks callbacks
= {
992 (size_t (*)(void *, size_t, size_t, void *)) fread
,
993 (int (*)(void *, ogg_int64_t
, int)) _fseek64_wrap
,
994 (int (*)(void *)) fclose
,
995 (long (*)(void *)) ftell
998 return ov_open_callbacks((void *)f
, vf
, initial
, ibytes
, callbacks
);
1001 int ov_fopen(const char *path
,OggVorbis_File
*vf
){
1003 FILE *f
= fopen(path
,"rb");
1006 ret
= ov_open(f
,vf
,NULL
,0);
1012 /* Only partially open the vorbis file; test for Vorbisness, and load
1013 the headers for the first chain. Do not seek (although test for
1014 seekability). Use ov_test_open to finish opening the file, else
1015 ov_clear to close/free it. Same return codes as open. */
1017 int ov_test_callbacks(void *f
,OggVorbis_File
*vf
,
1018 const char *initial
,long ibytes
,ov_callbacks callbacks
)
1020 return _ov_open1(f
,vf
,initial
,ibytes
,callbacks
);
1023 int ov_test(FILE *f
,OggVorbis_File
*vf
,const char *initial
,long ibytes
){
1024 ov_callbacks callbacks
= {
1025 (size_t (*)(void *, size_t, size_t, void *)) fread
,
1026 (int (*)(void *, ogg_int64_t
, int)) _fseek64_wrap
,
1027 (int (*)(void *)) fclose
,
1028 (long (*)(void *)) ftell
1031 return ov_test_callbacks((void *)f
, vf
, initial
, ibytes
, callbacks
);
1034 int ov_test_open(OggVorbis_File
*vf
){
1035 if(vf
->ready_state
!=PARTOPEN
)return(OV_EINVAL
);
1036 return _ov_open2(vf
);
1039 /* How many logical bitstreams in this physical bitstream? */
1040 long ov_streams(OggVorbis_File
*vf
){
1044 /* Is the FILE * associated with vf seekable? */
1045 long ov_seekable(OggVorbis_File
*vf
){
1046 return vf
->seekable
;
1049 /* returns the bitrate for a given logical bitstream or the entire
1050 physical bitstream. If the file is open for random access, it will
1051 find the *actual* average bitrate. If the file is streaming, it
1052 returns the nominal bitrate (if set) else the average of the
1053 upper/lower bounds (if set) else -1 (unset).
1055 If you want the actual bitrate field settings, get them from the
1056 vorbis_info structs */
1058 long ov_bitrate(OggVorbis_File
*vf
,int i
){
1059 if(vf
->ready_state
<OPENED
)return(OV_EINVAL
);
1060 if(i
>=vf
->links
)return(OV_EINVAL
);
1061 if(!vf
->seekable
&& i
!=0)return(ov_bitrate(vf
,0));
1065 for(i
=0;i
<vf
->links
;i
++)
1066 bits
+=(vf
->offsets
[i
+1]-vf
->dataoffsets
[i
])*8;
1067 /* This once read: return(rint(bits/ov_time_total(vf,-1)));
1068 * gcc 3.x on x86 miscompiled this at optimisation level 2 and above,
1069 * so this is slightly transformed to make it work.
1071 return(bits
*1000/ov_time_total(vf
,-1));
1074 /* return the actual bitrate */
1075 return((vf
->offsets
[i
+1]-vf
->dataoffsets
[i
])*8000/ov_time_total(vf
,i
));
1077 /* return nominal if set */
1078 if(vf
->vi
[i
].bitrate_nominal
>0){
1079 return vf
->vi
[i
].bitrate_nominal
;
1081 if(vf
->vi
[i
].bitrate_upper
>0){
1082 if(vf
->vi
[i
].bitrate_lower
>0){
1083 return (vf
->vi
[i
].bitrate_upper
+vf
->vi
[i
].bitrate_lower
)/2;
1085 return vf
->vi
[i
].bitrate_upper
;
1094 /* returns the actual bitrate since last call. returns -1 if no
1095 additional data to offer since last call (or at beginning of stream),
1096 EINVAL if stream is only partially open
1098 long ov_bitrate_instant(OggVorbis_File
*vf
){
1099 int link
=(vf
->seekable
?vf
->current_link
:0);
1101 if(vf
->ready_state
<OPENED
)return(OV_EINVAL
);
1102 if(vf
->samptrack
==0)return(OV_FALSE
);
1103 ret
=vf
->bittrack
/vf
->samptrack
*vf
->vi
[link
].rate
;
1110 long ov_serialnumber(OggVorbis_File
*vf
,int i
){
1111 if(i
>=vf
->links
)return(ov_serialnumber(vf
,vf
->links
-1));
1112 if(!vf
->seekable
&& i
>=0)return(ov_serialnumber(vf
,-1));
1114 return(vf
->current_serialno
);
1116 return(vf
->serialnos
[i
]);
1120 /* returns: total raw (compressed) length of content if i==-1
1121 raw (compressed) length of that logical bitstream for i==0 to n
1122 OV_EINVAL if the stream is not seekable (we can't know the length)
1123 or if stream is only partially open
1125 ogg_int64_t
ov_raw_total(OggVorbis_File
*vf
,int i
){
1126 if(vf
->ready_state
<OPENED
)return(OV_EINVAL
);
1127 if(!vf
->seekable
|| i
>=vf
->links
)return(OV_EINVAL
);
1131 for(i
=0;i
<vf
->links
;i
++)
1132 acc
+=ov_raw_total(vf
,i
);
1135 return(vf
->offsets
[i
+1]-vf
->offsets
[i
]);
1139 /* returns: total PCM length (samples) of content if i==-1 PCM length
1140 (samples) of that logical bitstream for i==0 to n
1141 OV_EINVAL if the stream is not seekable (we can't know the
1142 length) or only partially open
1144 ogg_int64_t
ov_pcm_total(OggVorbis_File
*vf
,int i
){
1145 if(vf
->ready_state
<OPENED
)return(OV_EINVAL
);
1146 if(!vf
->seekable
|| i
>=vf
->links
)return(OV_EINVAL
);
1150 for(i
=0;i
<vf
->links
;i
++)
1151 acc
+=ov_pcm_total(vf
,i
);
1154 return(vf
->pcmlengths
[i
*2+1]);
1158 /* returns: total milliseconds of content if i==-1
1159 milliseconds in that logical bitstream for i==0 to n
1160 OV_EINVAL if the stream is not seekable (we can't know the
1161 length) or only partially open
1163 ogg_int64_t
ov_time_total(OggVorbis_File
*vf
,int i
){
1164 if(vf
->ready_state
<OPENED
)return(OV_EINVAL
);
1165 if(!vf
->seekable
|| i
>=vf
->links
)return(OV_EINVAL
);
1169 for(i
=0;i
<vf
->links
;i
++)
1170 acc
+=ov_time_total(vf
,i
);
1173 return(((ogg_int64_t
)vf
->pcmlengths
[i
*2+1])*1000/vf
->vi
[i
].rate
);
1177 /* seek to an offset relative to the *compressed* data. This also
1178 scans packets to update the PCM cursor. It will cross a logical
1179 bitstream boundary, but only if it can't get any packets out of the
1180 tail of the bitstream we seek to (so no surprises).
1182 returns zero on success, nonzero on failure */
1184 int ov_raw_seek(OggVorbis_File
*vf
,ogg_int64_t pos
){
1185 ogg_stream_state work_os
;
1188 if(vf
->ready_state
<OPENED
)return(OV_EINVAL
);
1190 return(OV_ENOSEEK
); /* don't dump machine if we can't seek */
1192 if(pos
<0 || pos
>vf
->end
)return(OV_EINVAL
);
1194 /* is the seek position outside our current link [if any]? */
1195 if(vf
->ready_state
>=STREAMSET
){
1196 if(pos
<vf
->offsets
[vf
->current_link
] || pos
>=vf
->offsets
[vf
->current_link
+1])
1197 _decode_clear(vf
); /* clear out stream state */
1200 /* don't yet clear out decoding machine (if it's initialized), in
1201 the case we're in the same link. Restart the decode lapping, and
1202 let _fetch_and_process_packet deal with a potential bitstream
1205 ogg_stream_reset_serialno(&vf
->os
,
1206 vf
->current_serialno
); /* must set serialno */
1207 vorbis_synthesis_restart(&vf
->vd
);
1209 ret
=_seek_helper(vf
,pos
);
1210 if(ret
)goto seek_error
;
1212 /* we need to make sure the pcm_offset is set, but we don't want to
1213 advance the raw cursor past good packets just to get to the first
1214 with a granulepos. That's not equivalent behavior to beginning
1215 decoding as immediately after the seek position as possible.
1217 So, a hack. We use two stream states; a local scratch state and
1218 the shared vf->os stream state. We use the local state to
1219 scan, and the shared state as a buffer for later decode.
1221 Unfortuantely, on the last page we still advance to last packet
1222 because the granulepos on the last page is not necessarily on a
1223 packet boundary, and we need to make sure the granpos is
1235 ogg_int64_t pagepos
=-1;
1237 ogg_stream_init(&work_os
,vf
->current_serialno
); /* get the memory ready */
1238 ogg_stream_reset(&work_os
); /* eliminate the spurious OV_HOLE
1239 return from not necessarily
1240 starting from the beginning */
1243 if(vf
->ready_state
>=STREAMSET
){
1244 /* snarf/scan a packet if we can */
1245 int result
=ogg_stream_packetout(&work_os
,&op
);
1249 if(vf
->vi
[vf
->current_link
].codec_setup
){
1250 thisblock
=vorbis_packet_blocksize(vf
->vi
+vf
->current_link
,&op
);
1252 ogg_stream_packetout(&vf
->os
,NULL
);
1256 /* We can't get a guaranteed correct pcm position out of the
1257 last page in a stream because it might have a 'short'
1258 granpos, which can only be detected in the presence of a
1259 preceding page. However, if the last page is also the first
1260 page, the granpos rules of a first page take precedence. Not
1261 only that, but for first==last, the EOS page must be treated
1262 as if its a normal first page for the stream to open/play. */
1263 if(lastflag
&& !firstflag
)
1264 ogg_stream_packetout(&vf
->os
,NULL
);
1266 if(lastblock
)accblock
+=(lastblock
+thisblock
)>>2;
1269 if(op
.granulepos
!=-1){
1270 int i
,link
=vf
->current_link
;
1271 ogg_int64_t granulepos
=op
.granulepos
-vf
->pcmlengths
[link
*2];
1272 if(granulepos
<0)granulepos
=0;
1275 granulepos
+=vf
->pcmlengths
[i
*2+1];
1276 vf
->pcm_offset
=granulepos
-accblock
;
1277 if(vf
->pcm_offset
<0)vf
->pcm_offset
=0;
1280 lastblock
=thisblock
;
1283 ogg_stream_packetout(&vf
->os
,NULL
);
1288 pagepos
=_get_next_page(vf
,&og
,-1);
1290 vf
->pcm_offset
=ov_pcm_total(vf
,-1);
1294 /* huh? Bogus stream with packets but no granulepos */
1299 /* has our decoding just traversed a bitstream boundary? */
1300 if(vf
->ready_state
>=STREAMSET
){
1301 if(vf
->current_serialno
!=ogg_page_serialno(&og
)){
1303 /* two possibilities:
1304 1) our decoding just traversed a bitstream boundary
1305 2) another stream is multiplexed into this logical section? */
1307 if(ogg_page_bos(&og
)){
1309 _decode_clear(vf
); /* clear out stream state */
1310 ogg_stream_clear(&work_os
);
1311 } /* else, do nothing; next loop will scoop another page */
1315 if(vf
->ready_state
<STREAMSET
){
1317 ogg_uint32_t serialno
= ogg_page_serialno(&og
);
1319 for(link
=0;link
<vf
->links
;link
++)
1320 if(vf
->serialnos
[link
]==serialno
)break;
1322 if(link
==vf
->links
) continue; /* not the desired Vorbis
1323 bitstream section; keep
1325 vf
->current_link
=link
;
1326 vf
->current_serialno
=serialno
;
1327 ogg_stream_reset_serialno(&vf
->os
,serialno
);
1328 ogg_stream_reset_serialno(&work_os
,serialno
);
1329 vf
->ready_state
=STREAMSET
;
1330 firstflag
=(pagepos
<=vf
->dataoffsets
[link
]);
1333 ogg_stream_pagein(&vf
->os
,&og
);
1334 ogg_stream_pagein(&work_os
,&og
);
1335 lastflag
=ogg_page_eos(&og
);
1340 ogg_stream_clear(&work_os
);
1346 /* dump the machine so we're in a known state */
1348 ogg_stream_clear(&work_os
);
1353 /* rescales the number x from the range of [0,from] to [0,to]
1354 x is in the range [0,from]
1355 from, to are in the range [1, 1<<62-1] */
1356 ogg_int64_t
rescale64(ogg_int64_t x
, ogg_int64_t from
, ogg_int64_t to
){
1360 if(x
>= from
) return to
;
1361 if(x
<= 0) return 0;
1383 /* Page granularity seek (faster than sample granularity because we
1384 don't do the last bit of decode to find a specific sample).
1386 Seek to the last [granule marked] page preceding the specified pos
1387 location, such that decoding past the returned point will quickly
1388 arrive at the requested position. */
1389 int ov_pcm_seek_page(OggVorbis_File
*vf
,ogg_int64_t pos
){
1391 ogg_int64_t result
=0;
1392 ogg_int64_t total
=ov_pcm_total(vf
,-1);
1394 if(vf
->ready_state
<OPENED
)return(OV_EINVAL
);
1395 if(!vf
->seekable
)return(OV_ENOSEEK
);
1397 if(pos
<0 || pos
>total
)return(OV_EINVAL
);
1399 /* which bitstream section does this pcm offset occur in? */
1400 for(link
=vf
->links
-1;link
>=0;link
--){
1401 total
-=vf
->pcmlengths
[link
*2+1];
1402 if(pos
>=total
)break;
1405 /* Search within the logical bitstream for the page with the highest
1406 pcm_pos preceding pos. If we're looking for a position on the
1407 first page, bisection will halt without finding our position as
1408 it's before the first explicit granulepos fencepost. That case is
1409 handled separately below.
1411 There is a danger here; missing pages or incorrect frame number
1412 information in the bitstream could make our task impossible.
1413 Account for that (it would be an error condition) */
1415 /* new search algorithm originally by HB (Nicholas Vinen) */
1418 ogg_int64_t end
=vf
->offsets
[link
+1];
1419 ogg_int64_t begin
=vf
->dataoffsets
[link
];
1420 ogg_int64_t begintime
= vf
->pcmlengths
[link
*2];
1421 ogg_int64_t endtime
= vf
->pcmlengths
[link
*2+1]+begintime
;
1422 ogg_int64_t target
=pos
-total
+begintime
;
1423 ogg_int64_t best
=-1;
1428 /* if we have only one page, there will be no bisection. Grab the page here */
1430 result
=_seek_helper(vf
,begin
);
1431 if(result
) goto seek_error
;
1433 result
=_get_next_page(vf
,&og
,1);
1434 if(result
<0) goto seek_error
;
1439 /* bisection loop */
1443 if(end
-begin
<CHUNKSIZE
){
1446 /* take a (pretty decent) guess. */
1447 bisect
=begin
+ rescale64(target
-begintime
,
1449 end
-begin
) - CHUNKSIZE
;
1450 if(bisect
<begin
+CHUNKSIZE
)
1454 result
=_seek_helper(vf
,bisect
);
1455 if(result
) goto seek_error
;
1457 /* read loop within the bisection loop */
1459 result
=_get_next_page(vf
,&og
,end
-vf
->offset
);
1460 if(result
==OV_EREAD
) goto seek_error
;
1462 /* there is no next page! */
1464 /* No bisection left to perform. We've either found the
1465 best candidate already or failed. Exit loop. */
1468 /* We tried to load a fraction of the last page; back up a
1469 bit and try to get the whole last page */
1470 if(bisect
==0) goto seek_error
;
1473 /* don't repeat/loop on a read we've already performed */
1474 if(bisect
<=begin
)bisect
=begin
+1;
1476 /* seek and continue bisection */
1477 result
=_seek_helper(vf
,bisect
);
1478 if(result
) goto seek_error
;
1481 ogg_int64_t granulepos
;
1484 /* got a page. analyze it */
1485 /* only consider pages from primary vorbis stream */
1486 if(ogg_page_serialno(&og
)!=vf
->serialnos
[link
])
1489 /* only consider pages with the granulepos set */
1490 granulepos
=ogg_page_granulepos(&og
);
1491 if(granulepos
==-1)continue;
1493 if(granulepos
<target
){
1494 /* this page is a successful candidate! Set state */
1496 best
=result
; /* raw offset of packet with granulepos */
1497 begin
=vf
->offset
; /* raw offset of next page */
1498 begintime
=granulepos
;
1500 /* if we're before our target but within a short distance,
1501 don't bisect; read forward */
1502 if(target
-begintime
>44100)break;
1504 bisect
=begin
; /* *not* begin + 1 as above */
1507 /* This is one of our pages, but the granpos is
1508 post-target; it is not a bisection return
1509 candidate. (The only way we'd use it is if it's the
1510 first page in the stream; we handle that case later
1511 outside the bisection) */
1512 if(bisect
<=begin
+1){
1513 /* No bisection left to perform. We've either found the
1514 best candidate already or failed. Exit loop. */
1517 if(end
==vf
->offset
){
1518 /* bisection read to the end; use the known page
1519 boundary (result) to update bisection, back up a
1520 little bit, and try again */
1523 if(bisect
<=begin
)bisect
=begin
+1;
1524 result
=_seek_helper(vf
,bisect
);
1525 if(result
) goto seek_error
;
1527 /* Normal bisection */
1538 /* Out of bisection: did it 'fail?' */
1541 /* Check the 'looking for data in first page' special case;
1542 bisection would 'fail' because our search target was before the
1543 first PCM granule position fencepost. */
1546 begin
== vf
->dataoffsets
[link
] &&
1547 ogg_page_serialno(&og
)==vf
->serialnos
[link
]){
1549 /* Yes, this is the beginning-of-stream case. We already have
1550 our page, right at the beginning of PCM data. Set state
1553 vf
->pcm_offset
=total
;
1555 if(link
!=vf
->current_link
){
1556 /* Different link; dump entire decode machine */
1559 vf
->current_link
=link
;
1560 vf
->current_serialno
=vf
->serialnos
[link
];
1561 vf
->ready_state
=STREAMSET
;
1564 vorbis_synthesis_restart(&vf
->vd
);
1567 ogg_stream_reset_serialno(&vf
->os
,vf
->current_serialno
);
1568 ogg_stream_pagein(&vf
->os
,&og
);
1575 /* Bisection found our page. seek to it, update pcm offset. Easier case than
1576 raw_seek, don't keep packets preceding granulepos. */
1582 result
=_seek_helper(vf
,best
);
1584 if(result
) goto seek_error
;
1585 result
=_get_next_page(vf
,&og
,-1);
1586 if(result
<0) goto seek_error
;
1588 if(link
!=vf
->current_link
){
1589 /* Different link; dump entire decode machine */
1592 vf
->current_link
=link
;
1593 vf
->current_serialno
=vf
->serialnos
[link
];
1594 vf
->ready_state
=STREAMSET
;
1597 vorbis_synthesis_restart(&vf
->vd
);
1600 ogg_stream_reset_serialno(&vf
->os
,vf
->current_serialno
);
1601 ogg_stream_pagein(&vf
->os
,&og
);
1603 /* pull out all but last packet; the one with granulepos */
1605 result
=ogg_stream_packetpeek(&vf
->os
,&op
);
1607 /* No packet returned; we exited the bisection with 'best'
1608 pointing to a page with a granule position, so the packet
1609 finishing this page ('best') originated on a preceding
1610 page. Keep fetching previous pages until we get one with
1611 a granulepos or without the 'continued' flag set. Then
1612 just use raw_seek for simplicity. */
1613 /* Do not rewind past the beginning of link data; if we do,
1614 it's either a bug or a broken stream */
1616 while(result
>vf
->dataoffsets
[link
]){
1617 result
=_get_prev_page(vf
,result
,&og
);
1618 if(result
<0) goto seek_error
;
1619 if(ogg_page_serialno(&og
)==vf
->current_serialno
&&
1620 (ogg_page_granulepos(&og
)>-1 ||
1621 !ogg_page_continued(&og
))){
1622 return ov_raw_seek(vf
,result
);
1627 result
= OV_EBADPACKET
;
1630 if(op
.granulepos
!=-1){
1631 vf
->pcm_offset
=op
.granulepos
-vf
->pcmlengths
[vf
->current_link
*2];
1632 if(vf
->pcm_offset
<0)vf
->pcm_offset
=0;
1633 vf
->pcm_offset
+=total
;
1636 result
=ogg_stream_packetout(&vf
->os
,NULL
);
1642 if(vf
->pcm_offset
>pos
|| pos
>ov_pcm_total(vf
,-1)){
1651 /* dump machine so we're in a known state */
1657 /* seek to a sample offset relative to the decompressed pcm stream
1658 returns zero on success, nonzero on failure */
1660 int ov_pcm_seek(OggVorbis_File
*vf
,ogg_int64_t pos
){
1661 int thisblock
,lastblock
=0;
1662 int ret
=ov_pcm_seek_page(vf
,pos
);
1663 if(ret
<0)return(ret
);
1664 if((ret
=_make_decode_ready(vf
)))return ret
;
1666 /* discard leading packets we don't need for the lapping of the
1667 position we want; don't decode them */
1673 int ret
=ogg_stream_packetpeek(&vf
->os
,&op
);
1675 thisblock
=vorbis_packet_blocksize(vf
->vi
+vf
->current_link
,&op
);
1677 ogg_stream_packetout(&vf
->os
,NULL
);
1678 continue; /* non audio packet */
1680 if(lastblock
)vf
->pcm_offset
+=(lastblock
+thisblock
)>>2;
1682 if(vf
->pcm_offset
+((thisblock
+
1683 vorbis_info_blocksize(vf
->vi
,1))>>2)>=pos
)break;
1685 /* remove the packet from packet queue and track its granulepos */
1686 ogg_stream_packetout(&vf
->os
,NULL
);
1687 vorbis_synthesis_trackonly(&vf
->vb
,&op
); /* set up a vb with
1690 vorbis_synthesis_blockin(&vf
->vd
,&vf
->vb
);
1692 /* end of logical stream case is hard, especially with exact
1693 length positioning. */
1695 if(op
.granulepos
>-1){
1697 /* always believe the stream markers */
1698 vf
->pcm_offset
=op
.granulepos
-vf
->pcmlengths
[vf
->current_link
*2];
1699 if(vf
->pcm_offset
<0)vf
->pcm_offset
=0;
1700 for(i
=0;i
<vf
->current_link
;i
++)
1701 vf
->pcm_offset
+=vf
->pcmlengths
[i
*2+1];
1704 lastblock
=thisblock
;
1707 if(ret
<0 && ret
!=OV_HOLE
)break;
1709 /* suck in a new page */
1710 if(_get_next_page(vf
,&og
,-1)<0)break;
1711 if(ogg_page_bos(&og
))_decode_clear(vf
);
1713 if(vf
->ready_state
<STREAMSET
){
1714 ogg_uint32_t serialno
=ogg_page_serialno(&og
);
1717 for(link
=0;link
<vf
->links
;link
++)
1718 if(vf
->serialnos
[link
]==serialno
)break;
1719 if(link
==vf
->links
) continue;
1720 vf
->current_link
=link
;
1722 vf
->ready_state
=STREAMSET
;
1723 vf
->current_serialno
=ogg_page_serialno(&og
);
1724 ogg_stream_reset_serialno(&vf
->os
,serialno
);
1725 ret
=_make_decode_ready(vf
);
1730 ogg_stream_pagein(&vf
->os
,&og
);
1736 /* discard samples until we reach the desired position. Crossing a
1737 logical bitstream boundary with abandon is OK. */
1738 while(vf
->pcm_offset
<pos
){
1739 ogg_int64_t target
=pos
-vf
->pcm_offset
;
1740 long samples
=vorbis_synthesis_pcmout(&vf
->vd
,NULL
);
1742 if(samples
>target
)samples
=target
;
1743 vorbis_synthesis_read(&vf
->vd
,samples
);
1744 vf
->pcm_offset
+=samples
;
1747 if(_fetch_and_process_packet(vf
,NULL
,1,1)<=0)
1748 vf
->pcm_offset
=ov_pcm_total(vf
,-1); /* eof */
1753 /* seek to a playback time relative to the decompressed pcm stream
1754 returns zero on success, nonzero on failure */
1755 int ov_time_seek(OggVorbis_File
*vf
,ogg_int64_t milliseconds
){
1756 /* translate time to PCM position and call ov_pcm_seek */
1759 ogg_int64_t pcm_total
=0;
1760 ogg_int64_t time_total
=0;
1762 if(vf
->ready_state
<OPENED
)return(OV_EINVAL
);
1763 if(!vf
->seekable
)return(OV_ENOSEEK
);
1764 if(milliseconds
<0)return(OV_EINVAL
);
1766 /* which bitstream section does this time offset occur in? */
1767 for(link
=0;link
<vf
->links
;link
++){
1768 ogg_int64_t addsec
= ov_time_total(vf
,link
);
1769 if(milliseconds
<time_total
+addsec
)break;
1771 pcm_total
+=vf
->pcmlengths
[link
*2+1];
1774 if(link
==vf
->links
)return(OV_EINVAL
);
1776 /* enough information to convert time offset to pcm offset */
1778 ogg_int64_t target
=pcm_total
+(milliseconds
-time_total
)*vf
->vi
[link
].rate
/1000;
1779 return(ov_pcm_seek(vf
,target
));
1783 /* page-granularity version of ov_time_seek
1784 returns zero on success, nonzero on failure */
1785 int ov_time_seek_page(OggVorbis_File
*vf
,ogg_int64_t milliseconds
){
1786 /* translate time to PCM position and call ov_pcm_seek */
1789 ogg_int64_t pcm_total
=0;
1790 ogg_int64_t time_total
=0;
1792 if(vf
->ready_state
<OPENED
)return(OV_EINVAL
);
1793 if(!vf
->seekable
)return(OV_ENOSEEK
);
1794 if(milliseconds
<0)return(OV_EINVAL
);
1796 /* which bitstream section does this time offset occur in? */
1797 for(link
=0;link
<vf
->links
;link
++){
1798 ogg_int64_t addsec
= ov_time_total(vf
,link
);
1799 if(milliseconds
<time_total
+addsec
)break;
1801 pcm_total
+=vf
->pcmlengths
[link
*2+1];
1804 if(link
==vf
->links
)return(OV_EINVAL
);
1806 /* enough information to convert time offset to pcm offset */
1808 ogg_int64_t target
=pcm_total
+(milliseconds
-time_total
)*vf
->vi
[link
].rate
/1000;
1809 return(ov_pcm_seek_page(vf
,target
));
1813 /* tell the current stream offset cursor. Note that seek followed by
1814 tell will likely not give the set offset due to caching */
1815 ogg_int64_t
ov_raw_tell(OggVorbis_File
*vf
){
1816 if(vf
->ready_state
<OPENED
)return(OV_EINVAL
);
1820 /* return PCM offset (sample) of next PCM sample to be read */
1821 ogg_int64_t
ov_pcm_tell(OggVorbis_File
*vf
){
1822 if(vf
->ready_state
<OPENED
)return(OV_EINVAL
);
1823 return(vf
->pcm_offset
);
1826 /* return time offset (milliseconds) of next PCM sample to be read */
1827 ogg_int64_t
ov_time_tell(OggVorbis_File
*vf
){
1829 ogg_int64_t pcm_total
=0;
1830 ogg_int64_t time_total
=0;
1832 if(vf
->ready_state
<OPENED
)return(OV_EINVAL
);
1834 pcm_total
=ov_pcm_total(vf
,-1);
1835 time_total
=ov_time_total(vf
,-1);
1837 /* which bitstream section does this time offset occur in? */
1838 for(link
=vf
->links
-1;link
>=0;link
--){
1839 pcm_total
-=vf
->pcmlengths
[link
*2+1];
1840 time_total
-=ov_time_total(vf
,link
);
1841 if(vf
->pcm_offset
>=pcm_total
)break;
1845 return(time_total
+(1000*vf
->pcm_offset
-pcm_total
)/vf
->vi
[link
].rate
);
1848 /* link: -1) return the vorbis_info struct for the bitstream section
1849 currently being decoded
1850 0-n) to request information for a specific bitstream section
1852 In the case of a non-seekable bitstream, any call returns the
1853 current bitstream. NULL in the case that the machine is not
1856 vorbis_info
*ov_info(OggVorbis_File
*vf
,int link
){
1859 if(vf
->ready_state
>=STREAMSET
)
1860 return vf
->vi
+vf
->current_link
;
1873 /* grr, strong typing, grr, no templates/inheritence, grr */
1874 vorbis_comment
*ov_comment(OggVorbis_File
*vf
,int link
){
1877 if(vf
->ready_state
>=STREAMSET
)
1878 return vf
->vc
+vf
->current_link
;
1891 /* up to this point, everything could more or less hide the multiple
1892 logical bitstream nature of chaining from the toplevel application
1893 if the toplevel application didn't particularly care. However, at
1894 the point that we actually read audio back, the multiple-section
1895 nature must surface: Multiple bitstream sections do not necessarily
1896 have to have the same number of channels or sampling rate.
1898 ov_read returns the sequential logical bitstream number currently
1899 being decoded along with the PCM data in order that the toplevel
1900 application can take action on channel/sample rate changes. This
1901 number will be incremented even for streamed (non-seekable) streams
1902 (for seekable streams, it represents the actual logical bitstream
1903 index within the physical bitstream. Note that the accessor
1904 functions above are aware of this dichotomy).
1906 input values: buffer) a buffer to hold packed PCM data for return
1907 bytes_req) the byte length requested to be placed into buffer
1909 return values: <0) error/hole in data (OV_HOLE), partial open (OV_EINVAL)
1911 n) number of bytes of PCM actually returned. The
1912 below works on a packet-by-packet basis, so the
1913 return length is not related to the 'length' passed
1914 in, just guaranteed to fit.
1916 *section) set to the logical bitstream number */
1918 long ov_read(OggVorbis_File
*vf
,char *buffer
,int bytes_req
,int *bitstream
){
1924 if(vf
->ready_state
<OPENED
)return(OV_EINVAL
);
1927 if(vf
->ready_state
==INITSET
){
1928 samples
=vorbis_synthesis_pcmout(&vf
->vd
,&pcm
);
1932 /* suck in another packet */
1934 int ret
=_fetch_and_process_packet(vf
,NULL
,1,1);
1945 /* yay! proceed to pack data into the byte buffer */
1947 long channels
=ov_info(vf
,-1)->channels
;
1949 if(samples
>(bytes_req
/(2*channels
)))
1950 samples
=bytes_req
/(2*channels
);
1952 for(i
=0;i
<channels
;i
++) { /* It's faster in this order */
1953 ogg_int32_t
*src
=pcm
[i
];
1954 short *dest
=((short *)buffer
)+i
;
1955 for(j
=0;j
<samples
;j
++) {
1956 *dest
=CLIP_TO_15(src
[j
]>>9);
1961 vorbis_synthesis_read(&vf
->vd
,samples
);
1962 vf
->pcm_offset
+=samples
;
1963 if(bitstream
)*bitstream
=vf
->current_link
;
1964 return(samples
*2*channels
);