summaryrefslogtreecommitdiff
path: root/apps/codecs/libtremor/vorbisfile.c
diff options
context:
space:
mode:
Diffstat (limited to 'apps/codecs/libtremor/vorbisfile.c')
-rw-r--r--apps/codecs/libtremor/vorbisfile.c509
1 files changed, 240 insertions, 269 deletions
diff --git a/apps/codecs/libtremor/vorbisfile.c b/apps/codecs/libtremor/vorbisfile.c
index 50a57affbd..9365ba344b 100644
--- a/apps/codecs/libtremor/vorbisfile.c
+++ b/apps/codecs/libtremor/vorbisfile.c
@@ -53,18 +53,19 @@
53 we only want coarse navigation through the stream. */ 53 we only want coarse navigation through the stream. */
54 54
55/************************************************************************* 55/*************************************************************************
56 * Many, many internal helpers. The intention is not to be confusing; 56 * Many, many internal helpers. The intention is not to be confusing;
57 * rampant duplication and monolithic function implementation would be 57 * rampant duplication and monolithic function implementation would be
58 * harder to understand anyway. The high level functions are last. Begin 58 * harder to understand anyway. The high level functions are last. Begin
59 * grokking near the end of the file */ 59 * grokking near the end of the file */
60 60
61 61
62/* read a little more data from the file/pipe into the ogg_sync framer */ 62/* read a little more data from the file/pipe into the ogg_sync framer */
63static long _get_data(OggVorbis_File *vf){ 63static long _get_data(OggVorbis_File *vf){
64 if(!(vf->callbacks.read_func))return(-1);
64 if(vf->datasource){ 65 if(vf->datasource){
65 char *buffer=(char *)ogg_sync_bufferin(vf->oy,CHUNKSIZE); 66 char *buffer=ogg_sync_buffer(&vf->oy,CHUNKSIZE);
66 long bytes=(vf->callbacks.read_func)(buffer,1,CHUNKSIZE,vf->datasource); 67 long bytes=(vf->callbacks.read_func)(buffer,1,CHUNKSIZE,vf->datasource);
67 if(bytes>0)ogg_sync_wrote(vf->oy,bytes); 68 if(bytes>0)ogg_sync_wrote(&vf->oy,bytes);
68 return(bytes); 69 return(bytes);
69 }else 70 }else
70 return(0); 71 return(0);
@@ -77,7 +78,7 @@ static int _seek_helper(OggVorbis_File *vf,ogg_int64_t offset){
77 (vf->callbacks.seek_func)(vf->datasource, offset, SEEK_SET) == -1) 78 (vf->callbacks.seek_func)(vf->datasource, offset, SEEK_SET) == -1)
78 return OV_EREAD; 79 return OV_EREAD;
79 vf->offset=offset; 80 vf->offset=offset;
80 ogg_sync_reset(vf->oy); 81 ogg_sync_reset(&vf->oy);
81 }else{ 82 }else{
82 /* shouldn't happen unless someone writes a broken callback */ 83 /* shouldn't happen unless someone writes a broken callback */
83 return OV_EFAULT; 84 return OV_EFAULT;
@@ -96,9 +97,7 @@ static int _seek_helper(OggVorbis_File *vf,ogg_int64_t offset){
96 n) search for a new page beginning for n bytes 97 n) search for a new page beginning for n bytes
97 98
98 return: <0) did not find a page (OV_FALSE, OV_EOF, OV_EREAD) 99 return: <0) did not find a page (OV_FALSE, OV_EOF, OV_EREAD)
99 n) found a page at absolute offset n 100 n) found a page at absolute offset n */
100
101 produces a refcounted page */
102 101
103static ogg_int64_t _get_next_page(OggVorbis_File *vf,ogg_page *og, 102static ogg_int64_t _get_next_page(OggVorbis_File *vf,ogg_page *og,
104 ogg_int64_t boundary){ 103 ogg_int64_t boundary){
@@ -107,8 +106,8 @@ static ogg_int64_t _get_next_page(OggVorbis_File *vf,ogg_page *og,
107 long more; 106 long more;
108 107
109 if(boundary>0 && vf->offset>=boundary)return(OV_FALSE); 108 if(boundary>0 && vf->offset>=boundary)return(OV_FALSE);
110 more=ogg_sync_pageseek(vf->oy,og); 109 more=ogg_sync_pageseek(&vf->oy,og);
111 110
112 if(more<0){ 111 if(more<0){
113 /* skipped n bytes */ 112 /* skipped n bytes */
114 vf->offset-=more; 113 vf->offset-=more;
@@ -127,7 +126,7 @@ static ogg_int64_t _get_next_page(OggVorbis_File *vf,ogg_page *og,
127 ogg_int64_t ret=vf->offset; 126 ogg_int64_t ret=vf->offset;
128 vf->offset+=more; 127 vf->offset+=more;
129 return(ret); 128 return(ret);
130 129
131 } 130 }
132 } 131 }
133 } 132 }
@@ -137,8 +136,7 @@ static ogg_int64_t _get_next_page(OggVorbis_File *vf,ogg_page *og,
137 position. Much dirtier than the above as Ogg doesn't have any 136 position. Much dirtier than the above as Ogg doesn't have any
138 backward search linkage. no 'readp' as it will certainly have to 137 backward search linkage. no 'readp' as it will certainly have to
139 read. */ 138 read. */
140/* returns offset or OV_EREAD, OV_FAULT and produces a refcounted page */ 139/* returns offset or OV_EREAD, OV_FAULT */
141
142static ogg_int64_t _get_prev_page(OggVorbis_File *vf,ogg_page *og){ 140static ogg_int64_t _get_prev_page(OggVorbis_File *vf,ogg_page *og){
143 ogg_int64_t begin=vf->offset; 141 ogg_int64_t begin=vf->offset;
144 ogg_int64_t end=begin; 142 ogg_int64_t end=begin;
@@ -151,9 +149,10 @@ static ogg_int64_t _get_prev_page(OggVorbis_File *vf,ogg_page *og){
151 begin=0; 149 begin=0;
152 150
153 ret=_seek_helper(vf,begin); 151 ret=_seek_helper(vf,begin);
154 if(ret)return(ret); 152 if(ret)return(ret);
155 153
156 while(vf->offset<end){ 154 while(vf->offset<end){
155 memset(og,0,sizeof(*og));
157 ret=_get_next_page(vf,og,end-vf->offset); 156 ret=_get_next_page(vf,og,end-vf->offset);
158 if(ret==OV_EREAD)return(OV_EREAD); 157 if(ret==OV_EREAD)return(OV_EREAD);
159 if(ret<0){ 158 if(ret<0){
@@ -168,7 +167,6 @@ static ogg_int64_t _get_prev_page(OggVorbis_File *vf,ogg_page *og){
168 holding the last page. In multiplexed (or noncompliant streams), 167 holding the last page. In multiplexed (or noncompliant streams),
169 we will probably have to re-read the last page we saw */ 168 we will probably have to re-read the last page we saw */
170 if(og->header_len==0){ 169 if(og->header_len==0){
171 ogg_page_release(og);
172 ret=_seek_helper(vf,offset); 170 ret=_seek_helper(vf,offset);
173 if(ret)return(ret); 171 if(ret)return(ret);
174 172
@@ -219,14 +217,14 @@ static int _lookup_page_serialno(ogg_page *og, ogg_uint32_t *serialno_list, int
219static ogg_int64_t _get_prev_page_serial(OggVorbis_File *vf, 217static ogg_int64_t _get_prev_page_serial(OggVorbis_File *vf,
220 ogg_uint32_t *serial_list, int serial_n, 218 ogg_uint32_t *serial_list, int serial_n,
221 int *serialno, ogg_int64_t *granpos){ 219 int *serialno, ogg_int64_t *granpos){
222 ogg_page og={0,0,0,0}; 220 ogg_page og;
223 ogg_int64_t begin=vf->offset; 221 ogg_int64_t begin=vf->offset;
224 ogg_int64_t end=begin; 222 ogg_int64_t end=begin;
225 ogg_int64_t ret; 223 ogg_int64_t ret;
226 224
227 ogg_int64_t prefoffset=-1; 225 ogg_int64_t prefoffset=-1;
228 ogg_int64_t offset=-1; 226 ogg_int64_t offset=-1;
229 ogg_uint32_t ret_serialno=-1; 227 ogg_int64_t ret_serialno=-1;
230 ogg_int64_t ret_gran=-1; 228 ogg_int64_t ret_gran=-1;
231 229
232 while(offset==-1){ 230 while(offset==-1){
@@ -241,13 +239,11 @@ static ogg_int64_t _get_prev_page_serial(OggVorbis_File *vf,
241 ret=_get_next_page(vf,&og,end-vf->offset); 239 ret=_get_next_page(vf,&og,end-vf->offset);
242 if(ret==OV_EREAD)return(OV_EREAD); 240 if(ret==OV_EREAD)return(OV_EREAD);
243 if(ret<0){ 241 if(ret<0){
244 ogg_page_release(&og);
245 break; 242 break;
246 }else{ 243 }else{
247 ret_serialno=ogg_page_serialno(&og); 244 ret_serialno=ogg_page_serialno(&og);
248 ret_gran=ogg_page_granulepos(&og); 245 ret_gran=ogg_page_granulepos(&og);
249 offset=ret; 246 offset=ret;
250 ogg_page_release(&og);
251 247
252 if(ret_serialno == (ogg_uint32_t) *serialno){ 248 if(ret_serialno == (ogg_uint32_t) *serialno){
253 prefoffset=ret; 249 prefoffset=ret;
@@ -276,23 +272,18 @@ static ogg_int64_t _get_prev_page_serial(OggVorbis_File *vf,
276 272
277/* uses the local ogg_stream storage in vf; this is important for 273/* uses the local ogg_stream storage in vf; this is important for
278 non-streaming input sources */ 274 non-streaming input sources */
279/* consumes the page that's passed in (if any) */ 275static int _fetch_headers(OggVorbis_File *vf,vorbis_info *vi,vorbis_comment *vc,
280 276 ogg_uint32_t **serialno_list, int *serialno_n,
281static int _fetch_headers(OggVorbis_File *vf,
282 vorbis_info *vi,
283 vorbis_comment *vc,
284 ogg_uint32_t **serialno_list,
285 int *serialno_n,
286 ogg_page *og_ptr){ 277 ogg_page *og_ptr){
287 ogg_page og={0,0,0,0}; 278 ogg_page og;
288 ogg_packet op={0,0,0,0,0,0}; 279 ogg_packet op;
289 int i,ret; 280 int i,ret;
290 int allbos=0; 281 int allbos=0;
291 282
292 if(!og_ptr){ 283 if(!og_ptr){
293 ogg_int64_t llret=_get_next_page(vf,&og,CHUNKSIZE); 284 ogg_int64_t llret=_get_next_page(vf,&og,CHUNKSIZE);
294 if(llret==OV_EREAD)return(OV_EREAD); 285 if(llret==OV_EREAD)return(OV_EREAD);
295 if(llret<0)return OV_ENOTVORBIS; 286 if(llret<0)return(OV_ENOTVORBIS);
296 og_ptr=&og; 287 og_ptr=&og;
297 } 288 }
298 289
@@ -320,10 +311,10 @@ static int _fetch_headers(OggVorbis_File *vf,
320 if(vf->ready_state<STREAMSET){ 311 if(vf->ready_state<STREAMSET){
321 /* we don't have a vorbis stream in this link yet, so begin 312 /* we don't have a vorbis stream in this link yet, so begin
322 prospective stream setup. We need a stream to get packets */ 313 prospective stream setup. We need a stream to get packets */
323 ogg_stream_reset_serialno(vf->os,ogg_page_serialno(og_ptr)); 314 ogg_stream_reset_serialno(&vf->os,ogg_page_serialno(og_ptr));
324 ogg_stream_pagein(vf->os,og_ptr); 315 ogg_stream_pagein(&vf->os,og_ptr);
325 316
326 if(ogg_stream_packetout(vf->os,&op) > 0 && 317 if(ogg_stream_packetout(&vf->os,&op) > 0 &&
327 vorbis_synthesis_idheader(&op)){ 318 vorbis_synthesis_idheader(&op)){
328 /* vorbis header; continue setup */ 319 /* vorbis header; continue setup */
329 vf->ready_state=STREAMSET; 320 vf->ready_state=STREAMSET;
@@ -348,8 +339,8 @@ static int _fetch_headers(OggVorbis_File *vf,
348 339
349 /* if this page also belongs to our vorbis stream, submit it and break */ 340 /* if this page also belongs to our vorbis stream, submit it and break */
350 if(vf->ready_state==STREAMSET && 341 if(vf->ready_state==STREAMSET &&
351 (ogg_uint32_t) vf->os->serialno == ogg_page_serialno(og_ptr)){ 342 vf->os.serialno == ogg_page_serialno(og_ptr)){
352 ogg_stream_pagein(vf->os,og_ptr); 343 ogg_stream_pagein(&vf->os,og_ptr);
353 break; 344 break;
354 } 345 }
355 } 346 }
@@ -367,7 +358,7 @@ static int _fetch_headers(OggVorbis_File *vf,
367 358
368 while(i<2){ /* get a packet loop */ 359 while(i<2){ /* get a packet loop */
369 360
370 int result=ogg_stream_packetout(vf->os,&op); 361 int result=ogg_stream_packetout(&vf->os,&op);
371 if(result==0)break; 362 if(result==0)break;
372 if(result==-1){ 363 if(result==-1){
373 ret=OV_EBADHEADER; 364 ret=OV_EBADHEADER;
@@ -387,8 +378,8 @@ static int _fetch_headers(OggVorbis_File *vf,
387 } 378 }
388 379
389 /* if this page belongs to the correct stream, go parse it */ 380 /* if this page belongs to the correct stream, go parse it */
390 if((ogg_uint32_t) vf->os->serialno == ogg_page_serialno(og_ptr)){ 381 if(vf->os.serialno == ogg_page_serialno(og_ptr)){
391 ogg_stream_pagein(vf->os,og_ptr); 382 ogg_stream_pagein(&vf->os,og_ptr);
392 break; 383 break;
393 } 384 }
394 385
@@ -406,15 +397,10 @@ static int _fetch_headers(OggVorbis_File *vf,
406 } 397 }
407 } 398 }
408 399
409 ogg_packet_release(&op);
410 ogg_page_release(&og);
411
412 return 0; 400 return 0;
413 } 401 }
414 402
415 bail_header: 403 bail_header:
416 ogg_packet_release(&op);
417 ogg_page_release(&og);
418 vorbis_info_clear(vi); 404 vorbis_info_clear(vi);
419 vorbis_comment_clear(vc); 405 vorbis_comment_clear(vc);
420 vf->ready_state=OPENED; 406 vf->ready_state=OPENED;
@@ -427,25 +413,23 @@ static int _fetch_headers(OggVorbis_File *vf,
427 audio, however this is only called during stream parsing upon 413 audio, however this is only called during stream parsing upon
428 seekable open. */ 414 seekable open. */
429static ogg_int64_t _initial_pcmoffset(OggVorbis_File *vf, vorbis_info *vi){ 415static ogg_int64_t _initial_pcmoffset(OggVorbis_File *vf, vorbis_info *vi){
430 ogg_page og={0,0,0,0}; 416 ogg_page og;
431 ogg_int64_t accumulated=0,pos; 417 ogg_int64_t accumulated=0;
432 long lastblock=-1; 418 long lastblock=-1;
433 int result; 419 int result;
434 int serialno = vf->os->serialno; 420 ogg_uint32_t serialno = vf->os.serialno;
435 421
436 while(1){ 422 while(1){
437 ogg_packet op={0,0,0,0,0,0}; 423 ogg_packet op;
438
439 if(_get_next_page(vf,&og,-1)<0) 424 if(_get_next_page(vf,&og,-1)<0)
440 break; /* should not be possible unless the file is truncated/mangled */ 425 break; /* should not be possible unless the file is truncated/mangled */
441 426
442 if(ogg_page_bos(&og)) break; 427 if(ogg_page_bos(&og)) break;
443 if(ogg_page_serialno(&og)!=(ogg_uint32_t) serialno) continue; 428 if(ogg_page_serialno(&og)!= serialno) continue;
444 pos=ogg_page_granulepos(&og);
445 429
446 /* count blocksizes of all frames in the page */ 430 /* count blocksizes of all frames in the page */
447 ogg_stream_pagein(vf->os,&og); 431 ogg_stream_pagein(&vf->os,&og);
448 while((result=ogg_stream_packetout(vf->os,&op))){ 432 while((result=ogg_stream_packetout(&vf->os,&op))){
449 if(result>0){ /* ignore holes */ 433 if(result>0){ /* ignore holes */
450 long thisblock=vorbis_packet_blocksize(vi,&op); 434 long thisblock=vorbis_packet_blocksize(vi,&op);
451 if(lastblock!=-1) 435 if(lastblock!=-1)
@@ -453,11 +437,10 @@ static ogg_int64_t _initial_pcmoffset(OggVorbis_File *vf, vorbis_info *vi){
453 lastblock=thisblock; 437 lastblock=thisblock;
454 } 438 }
455 } 439 }
456 ogg_packet_release(&op);
457 440
458 if(pos!=-1){ 441 if(ogg_page_granulepos(&og)!=-1){
459 /* pcm offset of last packet on the first audio page */ 442 /* pcm offset of last packet on the first audio page */
460 accumulated= pos-accumulated; 443 accumulated= ogg_page_granulepos(&og)-accumulated;
461 break; 444 break;
462 } 445 }
463 } 446 }
@@ -466,11 +449,9 @@ static ogg_int64_t _initial_pcmoffset(OggVorbis_File *vf, vorbis_info *vi){
466 the beginning, a normal occurrence; set the offset to zero */ 449 the beginning, a normal occurrence; set the offset to zero */
467 if(accumulated<0)accumulated=0; 450 if(accumulated<0)accumulated=0;
468 451
469 ogg_page_release(&og);
470 return accumulated; 452 return accumulated;
471} 453}
472 454
473
474/* finds each bitstream link one at a time using a bisection search 455/* finds each bitstream link one at a time using a bisection search
475 (has to begin by knowing the offset of the lb's initial page). 456 (has to begin by knowing the offset of the lb's initial page).
476 Recurses for each link so it can alloc the link storage after 457 Recurses for each link so it can alloc the link storage after
@@ -484,14 +465,14 @@ static int _bisect_forward_serialno(OggVorbis_File *vf,
484 ogg_uint32_t *currentno_list, 465 ogg_uint32_t *currentno_list,
485 int currentnos, 466 int currentnos,
486 long m){ 467 long m){
487
488 ogg_int64_t pcmoffset; 468 ogg_int64_t pcmoffset;
489 ogg_int64_t dataoffset=searched; 469 ogg_int64_t dataoffset=searched;
490 ogg_int64_t endsearched=end; 470 ogg_int64_t endsearched=end;
491 ogg_int64_t next=end; 471 ogg_int64_t next=end;
492 ogg_int64_t searchgran=-1; 472 ogg_int64_t searchgran=-1;
473 ogg_page og;
493 ogg_int64_t ret,last; 474 ogg_int64_t ret,last;
494 int serialno = vf->os->serialno; 475 int serialno = vf->os.serialno;
495 476
496 /* invariants: 477 /* invariants:
497 we have the headers and serialnos for the link beginning at 'begin' 478 we have the headers and serialnos for the link beginning at 'begin'
@@ -538,7 +519,6 @@ static int _bisect_forward_serialno(OggVorbis_File *vf,
538 /* the below guards against garbage seperating the last and 519 /* the below guards against garbage seperating the last and
539 first pages of two links. */ 520 first pages of two links. */
540 while(searched<endsearched){ 521 while(searched<endsearched){
541 ogg_page og={0,0,0,0};
542 ogg_int64_t bisect; 522 ogg_int64_t bisect;
543 523
544 if(endsearched-searched<CHUNKSIZE){ 524 if(endsearched-searched<CHUNKSIZE){
@@ -547,8 +527,10 @@ static int _bisect_forward_serialno(OggVorbis_File *vf,
547 bisect=(searched+endsearched)/2; 527 bisect=(searched+endsearched)/2;
548 } 528 }
549 529
550 ret=_seek_helper(vf,bisect); 530 if(bisect != vf->offset){
551 if(ret)return(ret); 531 ret=_seek_helper(vf,bisect);
532 if(ret)return(ret);
533 }
552 534
553 last=_get_next_page(vf,&og,-1); 535 last=_get_next_page(vf,&og,-1);
554 if(last==OV_EREAD)return(OV_EREAD); 536 if(last==OV_EREAD)return(OV_EREAD);
@@ -556,9 +538,8 @@ static int _bisect_forward_serialno(OggVorbis_File *vf,
556 endsearched=bisect; 538 endsearched=bisect;
557 if(last>=0)next=last; 539 if(last>=0)next=last;
558 }else{ 540 }else{
559 searched=last+og.header_len+og.body_len; 541 searched=vf->offset;
560 } 542 }
561 ogg_page_release(&og);
562 } 543 }
563 544
564 /* Bisection point found */ 545 /* Bisection point found */
@@ -580,7 +561,7 @@ static int _bisect_forward_serialno(OggVorbis_File *vf,
580 561
581 ret=_fetch_headers(vf,&vi,&vc,&next_serialno_list,&next_serialnos,NULL); 562 ret=_fetch_headers(vf,&vi,&vc,&next_serialno_list,&next_serialnos,NULL);
582 if(ret)return(ret); 563 if(ret)return(ret);
583 serialno = vf->os->serialno; 564 serialno = vf->os.serialno;
584 dataoffset = vf->offset; 565 dataoffset = vf->offset;
585 566
586 /* this will consume a page, however the next bistection always 567 /* this will consume a page, however the next bistection always
@@ -627,8 +608,8 @@ static int _make_decode_ready(OggVorbis_File *vf){
627 608
628static int _open_seekable2(OggVorbis_File *vf){ 609static int _open_seekable2(OggVorbis_File *vf){
629 ogg_int64_t dataoffset=vf->dataoffsets[0],end,endgran=-1; 610 ogg_int64_t dataoffset=vf->dataoffsets[0],end,endgran=-1;
630 int endserial=vf->os->serialno; 611 int endserial=vf->os.serialno;
631 int serialno=vf->os->serialno; 612 int serialno=vf->os.serialno;
632 613
633 /* we're partially open and have a first link header state in 614 /* we're partially open and have a first link header state in
634 storage in vf */ 615 storage in vf */
@@ -666,7 +647,7 @@ static int _open_seekable2(OggVorbis_File *vf){
666 return(ov_raw_seek(vf,dataoffset)); 647 return(ov_raw_seek(vf,dataoffset));
667} 648}
668 649
669/* clear out the current logical bitstream decoder */ 650/* clear out the current logical bitstream decoder */
670static void _decode_clear(OggVorbis_File *vf){ 651static void _decode_clear(OggVorbis_File *vf){
671 vorbis_dsp_clear(&vf->vd); 652 vorbis_dsp_clear(&vf->vd);
672 vorbis_block_clear(&vf->vb); 653 vorbis_block_clear(&vf->vb);
@@ -677,74 +658,67 @@ static void _decode_clear(OggVorbis_File *vf){
677 bitstream boundary and dumps the decoding machine. If the decoding 658 bitstream boundary and dumps the decoding machine. If the decoding
678 machine is unloaded, it loads it. It also keeps pcm_offset up to 659 machine is unloaded, it loads it. It also keeps pcm_offset up to
679 date (seek and read both use this. seek uses a special hack with 660 date (seek and read both use this. seek uses a special hack with
680 readp). 661 readp).
681 662
682 return: <0) error, OV_HOLE (lost packet) or OV_EOF 663 return: <0) error, OV_HOLE (lost packet) or OV_EOF
683 0) need more data (only if readp==0) 664 0) need more data (only if readp==0)
684 1) got a packet 665 1) got a packet
685*/ 666*/
686 667
687STATICIRAM_NOT_MDCT int _fetch_and_process_packet(OggVorbis_File *vf, 668static int _fetch_and_process_packet(OggVorbis_File *vf,
688 int readp, 669 ogg_packet *op_in,
689 int spanp) ICODE_ATTR_TREMOR_NOT_MDCT;
690STATICIRAM_NOT_MDCT int _fetch_and_process_packet(OggVorbis_File *vf,
691 int readp, 670 int readp,
692 int spanp){ 671 int spanp){
693 ogg_page og={0,0,0,0}; 672 ogg_page og;
694 ogg_packet op={0,0,0,0,0,0};
695 int ret=0;
696 673
697 /* handle one packet. Try to fetch it from current stream state */ 674 /* handle one packet. Try to fetch it from current stream state */
698 /* extract packets from page */ 675 /* extract packets from page */
699 while(1){ 676 while(1){
700 677
701 if(vf->ready_state==STREAMSET){ 678 if(vf->ready_state==STREAMSET){
702 ret=_make_decode_ready(vf); 679 int ret=_make_decode_ready(vf);
703 if(ret<0) goto cleanup; 680 if(ret<0)return ret;
704 } 681 }
705 682
706 /* process a packet if we can. If the machine isn't loaded, 683 /* process a packet if we can. If the machine isn't loaded,
707 neither is a page */ 684 neither is a page */
708 if(vf->ready_state==INITSET){ 685 if(vf->ready_state==INITSET){
709 while(1) { 686 while(1) {
710 int result=ogg_stream_packetout(vf->os,&op); 687 ogg_packet op;
688 ogg_packet *op_ptr=(op_in?op_in:&op);
689 int result=ogg_stream_packetout(&vf->os,op_ptr);
711 ogg_int64_t granulepos; 690 ogg_int64_t granulepos;
712 691
713 if(result==-1){ 692 op_in=NULL;
714 ret=OV_HOLE; /* hole in the data. */ 693 if(result==-1)return(OV_HOLE); /* hole in the data. */
715 goto cleanup;
716 }
717 if(result>0){ 694 if(result>0){
718 /* got a packet. process it */ 695 /* got a packet. process it */
719 granulepos=op.granulepos; 696 granulepos=op_ptr->granulepos;
720 if(!vorbis_synthesis(&vf->vb,&op)){ /* lazy check for lazy 697 if(!vorbis_synthesis(&vf->vb,op_ptr)){ /* lazy check for lazy
721 header handling. The 698 header handling. The
722 header packets aren't 699 header packets aren't
723 audio, so if/when we 700 audio, so if/when we
724 submit them, 701 submit them,
725 vorbis_synthesis will 702 vorbis_synthesis will
726 reject them */ 703 reject them */
727 704
728 /* suck in the synthesis data and track bitrate */ 705 /* suck in the synthesis data and track bitrate */
729 { 706 {
730 int oldsamples=vorbis_synthesis_pcmout(&vf->vd,NULL); 707 int oldsamples=vorbis_synthesis_pcmout(&vf->vd,NULL);
731 /* for proper use of libvorbis within libvorbisfile, 708 /* for proper use of libvorbis within libvorbisfile,
732 oldsamples will always be zero. */ 709 oldsamples will always be zero. */
733 if(oldsamples){ 710 if(oldsamples)return(OV_EFAULT);
734 ret=OV_EFAULT;
735 goto cleanup;
736 }
737 711
738 vorbis_synthesis_blockin(&vf->vd,&vf->vb); 712 vorbis_synthesis_blockin(&vf->vd,&vf->vb);
739 vf->samptrack+=vorbis_synthesis_pcmout(&vf->vd,NULL)-oldsamples; 713 vf->samptrack+=vorbis_synthesis_pcmout(&vf->vd,NULL)-oldsamples;
740 vf->bittrack+=op.bytes*8; 714 vf->bittrack+=op_ptr->bytes*8;
741 } 715 }
742 716
743 /* update the pcm offset. */ 717 /* update the pcm offset. */
744 if(granulepos!=-1 && !op.e_o_s){ 718 if(granulepos!=-1 && !op_ptr->e_o_s){
745 int link=(vf->seekable?vf->current_link:0); 719 int link=(vf->seekable?vf->current_link:0);
746 int i,samples; 720 int i,samples;
747 721
748 /* this packet has a pcm_offset on it (the last packet 722 /* this packet has a pcm_offset on it (the last packet
749 completed on a page carries the offset) After processing 723 completed on a page carries the offset) After processing
750 (above), we know the pcm position of the *last* sample 724 (above), we know the pcm position of the *last* sample
@@ -755,7 +729,7 @@ STATICIRAM_NOT_MDCT int _fetch_and_process_packet(OggVorbis_File *vf,
755 granulepos declares the last frame in the stream, and the 729 granulepos declares the last frame in the stream, and the
756 last packet of the last page may be a partial frame. 730 last packet of the last page may be a partial frame.
757 So, we need a previous granulepos from an in-sequence page 731 So, we need a previous granulepos from an in-sequence page
758 to have a reference point. Thus the !op.e_o_s clause 732 to have a reference point. Thus the !op_ptr->e_o_s clause
759 above */ 733 above */
760 734
761 if(vf->seekable && link>0) 735 if(vf->seekable && link>0)
@@ -766,23 +740,22 @@ STATICIRAM_NOT_MDCT int _fetch_and_process_packet(OggVorbis_File *vf,
766 is very broken */ 740 is very broken */
767 741
768 samples=vorbis_synthesis_pcmout(&vf->vd,NULL); 742 samples=vorbis_synthesis_pcmout(&vf->vd,NULL);
769 743
770 granulepos-=samples; 744 granulepos-=samples;
771 for(i=0;i<link;i++) 745 for(i=0;i<link;i++)
772 granulepos+=vf->pcmlengths[i*2+1]; 746 granulepos+=vf->pcmlengths[i*2+1];
773 vf->pcm_offset=granulepos; 747 vf->pcm_offset=granulepos;
774 } 748 }
775 ret=1; 749 return(1);
776 goto cleanup;
777 } 750 }
778 } 751 }
779 else 752 else
780 break; 753 break;
781 } 754 }
782 } 755 }
783 756
784 if(vf->ready_state>=OPENED){ 757 if(vf->ready_state>=OPENED){
785 ogg_int64_t lret; 758 ogg_int64_t ret;
786 759
787 while(1){ 760 while(1){
788 /* the loop is not strictly necessary, but there's no sense in 761 /* the loop is not strictly necessary, but there's no sense in
@@ -791,13 +764,9 @@ STATICIRAM_NOT_MDCT int _fetch_and_process_packet(OggVorbis_File *vf,
791 part of a different logical bitstream; keep reading until 764 part of a different logical bitstream; keep reading until
792 we get one with the correct serialno */ 765 we get one with the correct serialno */
793 766
794 if(!readp){ 767 if(!readp)return(0);
795 ret=0; 768 if((ret=_get_next_page(vf,&og,-1))<0){
796 goto cleanup; 769 return(OV_EOF); /* eof. leave unitialized */
797 }
798 if((lret=_get_next_page(vf,&og,-1))<0){
799 ret=OV_EOF; /* eof. leave unitialized */
800 goto cleanup;
801 } 770 }
802 771
803 /* bitrate tracking; add the header's bytes here, the body bytes 772 /* bitrate tracking; add the header's bytes here, the body bytes
@@ -813,10 +782,8 @@ STATICIRAM_NOT_MDCT int _fetch_and_process_packet(OggVorbis_File *vf,
813 782
814 if(ogg_page_bos(&og)){ 783 if(ogg_page_bos(&og)){
815 /* boundary case */ 784 /* boundary case */
816 if(!spanp){ 785 if(!spanp)
817 ret=OV_EOF; 786 return(OV_EOF);
818 goto cleanup;
819 }
820 787
821 _decode_clear(vf); 788 _decode_clear(vf);
822 789
@@ -830,12 +797,13 @@ STATICIRAM_NOT_MDCT int _fetch_and_process_packet(OggVorbis_File *vf,
830 continue; /* possibility #2 */ 797 continue; /* possibility #2 */
831 } 798 }
832 } 799 }
800
833 break; 801 break;
834 } 802 }
835 } 803 }
836 804
837 /* Do we need to load a new machine before submitting the page? */ 805 /* Do we need to load a new machine before submitting the page? */
838 /* This is different in the seekable and non-seekable cases. 806 /* This is different in the seekable and non-seekable cases.
839 807
840 In the seekable case, we already have all the header 808 In the seekable case, we already have all the header
841 information loaded and cached; we just initialize the machine 809 information loaded and cached; we just initialize the machine
@@ -846,37 +814,37 @@ STATICIRAM_NOT_MDCT int _fetch_and_process_packet(OggVorbis_File *vf,
846 we're now nominally at the header of the next bitstream 814 we're now nominally at the header of the next bitstream
847 */ 815 */
848 816
849 if(vf->ready_state!=INITSET){ 817 if(vf->ready_state!=INITSET){
850 int link; 818 int link;
851 819
852 if(vf->ready_state<STREAMSET){ 820 if(vf->ready_state<STREAMSET){
853 if(vf->seekable){ 821 if(vf->seekable){
854 long serialno=ogg_page_serialno(&og); 822 ogg_uint32_t serialno = ogg_page_serialno(&og);
855 823
856 /* match the serialno to bitstream section. We use this rather than 824 /* match the serialno to bitstream section. We use this rather than
857 offset positions to avoid problems near logical bitstream 825 offset positions to avoid problems near logical bitstream
858 boundaries */ 826 boundaries */
859 827
860 for(link=0;link<vf->links;link++) 828 for(link=0;link<vf->links;link++)
861 if(vf->serialnos[link]==(ogg_uint32_t) serialno)break; 829 if(vf->serialnos[link]==serialno)break;
862 830
863 if(link==vf->links) continue; /* not the desired Vorbis 831 if(link==vf->links) continue; /* not the desired Vorbis
864 bitstream section; keep 832 bitstream section; keep
865 trying */ 833 trying */
866 834
867 vf->current_serialno=serialno; 835 vf->current_serialno=serialno;
868 vf->current_link=link; 836 vf->current_link=link;
869 837
870 ogg_stream_reset_serialno(vf->os,vf->current_serialno); 838 ogg_stream_reset_serialno(&vf->os,vf->current_serialno);
871 vf->ready_state=STREAMSET; 839 vf->ready_state=STREAMSET;
872 840
873 }else{ 841 }else{
874 /* we're streaming */ 842 /* we're streaming */
875 /* fetch the three header packets, build the info struct */ 843 /* fetch the three header packets, build the info struct */
876 844
877 int ret=_fetch_headers(vf,vf->vi,vf->vc,NULL,NULL,&og); 845 int ret=_fetch_headers(vf,vf->vi,vf->vc,NULL,NULL,&og);
878 if(ret) goto cleanup; 846 if(ret)return(ret);
879 vf->current_serialno=vf->os->serialno; 847 vf->current_serialno=vf->os.serialno;
880 vf->current_link++; 848 vf->current_link++;
881 link=0; 849 link=0;
882 } 850 }
@@ -885,17 +853,14 @@ STATICIRAM_NOT_MDCT int _fetch_and_process_packet(OggVorbis_File *vf,
885 853
886 /* the buffered page is the data we want, and we're ready for it; 854 /* the buffered page is the data we want, and we're ready for it;
887 add it to the stream state */ 855 add it to the stream state */
888 ogg_stream_pagein(vf->os,&og); 856 ogg_stream_pagein(&vf->os,&og);
857
889 } 858 }
890 cleanup:
891 ogg_packet_release(&op);
892 ogg_page_release(&og);
893 return ret;
894} 859}
895 860
896static int _ov_open1(void *f,OggVorbis_File *vf,char *initial, 861static int _ov_open1(void *f,OggVorbis_File *vf,const char *initial,
897 long ibytes, ov_callbacks callbacks){ 862 long ibytes, ov_callbacks callbacks){
898 int offsettest=(f?callbacks.seek_func(f,0,SEEK_CUR):-1); 863 int offsettest=((f && callbacks.seek_func)?callbacks.seek_func(f,0,SEEK_CUR):-1);
899 ogg_uint32_t *serialno_list=NULL; 864 ogg_uint32_t *serialno_list=NULL;
900 int serialno_list_size=0; 865 int serialno_list_size=0;
901 int ret; 866 int ret;
@@ -905,16 +870,16 @@ static int _ov_open1(void *f,OggVorbis_File *vf,char *initial,
905 vf->callbacks = callbacks; 870 vf->callbacks = callbacks;
906 871
907 /* init the framing state */ 872 /* init the framing state */
908 vf->oy=ogg_sync_create(); 873 ogg_sync_init(&vf->oy);
909 874
910 /* perhaps some data was previously read into a buffer for testing 875 /* perhaps some data was previously read into a buffer for testing
911 against other stream types. Allow initialization from this 876 against other stream types. Allow initialization from this
912 previously read data (especially as we may be reading from a 877 previously read data (especially as we may be reading from a
913 non-seekable stream) */ 878 non-seekable stream) */
914 if(initial){ 879 if(initial){
915 unsigned char *buffer=ogg_sync_bufferin(vf->oy,ibytes); 880 char *buffer=ogg_sync_buffer(&vf->oy,ibytes);
916 memcpy(buffer,initial,ibytes); 881 memcpy(buffer,initial,ibytes);
917 ogg_sync_wrote(vf->oy,ibytes); 882 ogg_sync_wrote(&vf->oy,ibytes);
918 } 883 }
919 884
920 /* can we seek? Stevens suggests the seek test was portable */ 885 /* can we seek? Stevens suggests the seek test was portable */
@@ -925,7 +890,7 @@ static int _ov_open1(void *f,OggVorbis_File *vf,char *initial,
925 vf->links=1; 890 vf->links=1;
926 vf->vi=_ogg_calloc(vf->links,sizeof(*vf->vi)); 891 vf->vi=_ogg_calloc(vf->links,sizeof(*vf->vi));
927 vf->vc=_ogg_calloc(vf->links,sizeof(*vf->vc)); 892 vf->vc=_ogg_calloc(vf->links,sizeof(*vf->vc));
928 vf->os=ogg_stream_create(-1); /* fill in the serialno later */ 893 ogg_stream_init(&vf->os,-1); /* fill in the serialno later */
929 894
930 /* Fetch all BOS pages, store the vorbis header and all seen serial 895 /* Fetch all BOS pages, store the vorbis header and all seen serial
931 numbers, load subsequent vorbis setup headers */ 896 numbers, load subsequent vorbis setup headers */
@@ -945,7 +910,7 @@ static int _ov_open1(void *f,OggVorbis_File *vf,char *initial,
945 vf->dataoffsets=_ogg_calloc(1,sizeof(*vf->dataoffsets)); 910 vf->dataoffsets=_ogg_calloc(1,sizeof(*vf->dataoffsets));
946 vf->offsets[0]=0; 911 vf->offsets[0]=0;
947 vf->dataoffsets[0]=vf->offset; 912 vf->dataoffsets[0]=vf->offset;
948 vf->current_serialno=vf->os->serialno; 913 vf->current_serialno=vf->os.serialno;
949 914
950 vf->ready_state=PARTOPEN; 915 vf->ready_state=PARTOPEN;
951 } 916 }
@@ -954,8 +919,8 @@ static int _ov_open1(void *f,OggVorbis_File *vf,char *initial,
954} 919}
955 920
956static int _ov_open2(OggVorbis_File *vf){ 921static int _ov_open2(OggVorbis_File *vf){
957 if(vf->ready_state < OPENED) 922 if(vf->ready_state != PARTOPEN) return OV_EINVAL;
958 vf->ready_state=OPENED; 923 vf->ready_state=OPENED;
959 if(vf->seekable){ 924 if(vf->seekable){
960 int ret=_open_seekable2(vf); 925 int ret=_open_seekable2(vf);
961 if(ret){ 926 if(ret){
@@ -963,7 +928,9 @@ static int _ov_open2(OggVorbis_File *vf){
963 ov_clear(vf); 928 ov_clear(vf);
964 } 929 }
965 return(ret); 930 return(ret);
966 } 931 }else
932 vf->ready_state=STREAMSET;
933
967 return 0; 934 return 0;
968} 935}
969 936
@@ -973,8 +940,8 @@ int ov_clear(OggVorbis_File *vf){
973 if(vf){ 940 if(vf){
974 vorbis_block_clear(&vf->vb); 941 vorbis_block_clear(&vf->vb);
975 vorbis_dsp_clear(&vf->vd); 942 vorbis_dsp_clear(&vf->vd);
976 ogg_stream_destroy(vf->os); 943 ogg_stream_clear(&vf->os);
977 944
978 if(vf->vi && vf->links){ 945 if(vf->vi && vf->links){
979 int i; 946 int i;
980 for(i=0;i<vf->links;i++){ 947 for(i=0;i<vf->links;i++){
@@ -988,8 +955,7 @@ int ov_clear(OggVorbis_File *vf){
988 if(vf->pcmlengths)_ogg_free(vf->pcmlengths); 955 if(vf->pcmlengths)_ogg_free(vf->pcmlengths);
989 if(vf->serialnos)_ogg_free(vf->serialnos); 956 if(vf->serialnos)_ogg_free(vf->serialnos);
990 if(vf->offsets)_ogg_free(vf->offsets); 957 if(vf->offsets)_ogg_free(vf->offsets);
991 ogg_sync_destroy(vf->oy); 958 ogg_sync_clear(&vf->oy);
992
993 if(vf->datasource && vf->callbacks.close_func) 959 if(vf->datasource && vf->callbacks.close_func)
994 (vf->callbacks.close_func)(vf->datasource); 960 (vf->callbacks.close_func)(vf->datasource);
995 memset(vf,0,sizeof(*vf)); 961 memset(vf,0,sizeof(*vf));
@@ -1002,14 +968,14 @@ int ov_clear(OggVorbis_File *vf){
1002 968
1003/* inspects the OggVorbis file and finds/documents all the logical 969/* inspects the OggVorbis file and finds/documents all the logical
1004 bitstreams contained in it. Tries to be tolerant of logical 970 bitstreams contained in it. Tries to be tolerant of logical
1005 bitstream sections that are truncated/woogie. 971 bitstream sections that are truncated/woogie.
1006 972
1007 return: -1) error 973 return: -1) error
1008 0) OK 974 0) OK
1009*/ 975*/
1010 976
1011int ov_open_callbacks(void *f,OggVorbis_File *vf,char *initial,long ibytes, 977int ov_open_callbacks(void *f,OggVorbis_File *vf,
1012 ov_callbacks callbacks){ 978 const char *initial,long ibytes,ov_callbacks callbacks){
1013 #if defined(CPU_COLDFIRE) 979 #if defined(CPU_COLDFIRE)
1014 /* this seems to be the closest we get to an init function, let's init emac 980 /* this seems to be the closest we get to an init function, let's init emac
1015 here. rounding is disabled because of MULT31_SHIFT15, which will be 981 here. rounding is disabled because of MULT31_SHIFT15, which will be
@@ -1067,9 +1033,7 @@ ogg_int64_t ov_time_total(OggVorbis_File *vf,int i){
1067 returns zero on success, nonzero on failure */ 1033 returns zero on success, nonzero on failure */
1068 1034
1069int ov_raw_seek(OggVorbis_File *vf,ogg_int64_t pos){ 1035int ov_raw_seek(OggVorbis_File *vf,ogg_int64_t pos){
1070 ogg_stream_state *work_os=NULL; 1036 ogg_stream_state work_os;
1071 ogg_page og={0,0,0,0};
1072 ogg_packet op={0,0,0,0,0,0};
1073 int ret; 1037 int ret;
1074 1038
1075 if(vf->ready_state<OPENED)return(OV_EINVAL); 1039 if(vf->ready_state<OPENED)return(OV_EINVAL);
@@ -1078,15 +1042,21 @@ int ov_raw_seek(OggVorbis_File *vf,ogg_int64_t pos){
1078 1042
1079 if(pos<0 || pos>vf->end)return(OV_EINVAL); 1043 if(pos<0 || pos>vf->end)return(OV_EINVAL);
1080 1044
1045 /* is the seek position outside our current link [if any]? */
1046 if(vf->ready_state>=STREAMSET){
1047 if(pos<vf->offsets[vf->current_link] || pos>=vf->offsets[vf->current_link+1])
1048 _decode_clear(vf); /* clear out stream state */
1049 }
1050
1081 /* don't yet clear out decoding machine (if it's initialized), in 1051 /* don't yet clear out decoding machine (if it's initialized), in
1082 the case we're in the same link. Restart the decode lapping, and 1052 the case we're in the same link. Restart the decode lapping, and
1083 let _fetch_and_process_packet deal with a potential bitstream 1053 let _fetch_and_process_packet deal with a potential bitstream
1084 boundary */ 1054 boundary */
1085 vf->pcm_offset=-1; 1055 vf->pcm_offset=-1;
1086 ogg_stream_reset_serialno(vf->os, 1056 ogg_stream_reset_serialno(&vf->os,
1087 vf->current_serialno); /* must set serialno */ 1057 vf->current_serialno); /* must set serialno */
1088 vorbis_synthesis_restart(&vf->vd); 1058 vorbis_synthesis_restart(&vf->vd);
1089 1059
1090 ret=_seek_helper(vf,pos); 1060 ret=_seek_helper(vf,pos);
1091 if(ret)goto seek_error; 1061 if(ret)goto seek_error;
1092 1062
@@ -1097,55 +1067,61 @@ int ov_raw_seek(OggVorbis_File *vf,ogg_int64_t pos){
1097 1067
1098 So, a hack. We use two stream states; a local scratch state and 1068 So, a hack. We use two stream states; a local scratch state and
1099 the shared vf->os stream state. We use the local state to 1069 the shared vf->os stream state. We use the local state to
1100 scan, and the shared state as a buffer for later decode. 1070 scan, and the shared state as a buffer for later decode.
1101 1071
1102 Unfortuantely, on the last page we still advance to last packet 1072 Unfortuantely, on the last page we still advance to last packet
1103 because the granulepos on the last page is not necessarily on a 1073 because the granulepos on the last page is not necessarily on a
1104 packet boundary, and we need to make sure the granpos is 1074 packet boundary, and we need to make sure the granpos is
1105 correct. 1075 correct.
1106 */ 1076 */
1107 1077
1108 { 1078 {
1079 ogg_page og;
1080 ogg_packet op;
1109 int lastblock=0; 1081 int lastblock=0;
1110 int accblock=0; 1082 int accblock=0;
1111 int thisblock; 1083 int thisblock=0;
1112 int lastflag=0; 1084 int lastflag=0;
1113 int firstflag=0; 1085 int firstflag=0;
1114 ogg_int64_t pagepos=-1; 1086 ogg_int64_t pagepos=-1;
1115 1087
1116 work_os=ogg_stream_create(vf->current_serialno); /* get the memory ready */ 1088 ogg_stream_init(&work_os,vf->current_serialno); /* get the memory ready */
1089 ogg_stream_reset(&work_os); /* eliminate the spurious OV_HOLE
1090 return from not necessarily
1091 starting from the beginning */
1092
1117 while(1){ 1093 while(1){
1118 if(vf->ready_state>=STREAMSET){ 1094 if(vf->ready_state>=STREAMSET){
1119 /* snarf/scan a packet if we can */ 1095 /* snarf/scan a packet if we can */
1120 int result=ogg_stream_packetout(work_os,&op); 1096 int result=ogg_stream_packetout(&work_os,&op);
1121 1097
1122 if(result>0){ 1098 if(result>0){
1123 1099
1124 if(vf->vi[vf->current_link].codec_setup){ 1100 if(vf->vi[vf->current_link].codec_setup){
1125 thisblock=vorbis_packet_blocksize(vf->vi+vf->current_link,&op); 1101 thisblock=vorbis_packet_blocksize(vf->vi+vf->current_link,&op);
1126 if(thisblock<0){ 1102 if(thisblock<0){
1127 ogg_stream_packetout(vf->os,NULL); 1103 ogg_stream_packetout(&vf->os,NULL);
1128 thisblock=0; 1104 thisblock=0;
1129 }else{ 1105 }else{
1130 1106
1131 /* We can't get a guaranteed correct pcm position out of the 1107 /* We can't get a guaranteed correct pcm position out of the
1132 last page in a stream because it might have a 'short' 1108 last page in a stream because it might have a 'short'
1133 granpos, which can only be detected in the presence of a 1109 granpos, which can only be detected in the presence of a
1134 preceeding page. However, if the last page is also the first 1110 preceding page. However, if the last page is also the first
1135 page, the granpos rules of a first page take precedence. Not 1111 page, the granpos rules of a first page take precedence. Not
1136 only that, but for first==last, the EOS page must be treated 1112 only that, but for first==last, the EOS page must be treated
1137 as if its a normal first page for the stream to open/play. */ 1113 as if its a normal first page for the stream to open/play. */
1138 if(lastflag && !firstflag) 1114 if(lastflag && !firstflag)
1139 ogg_stream_packetout(vf->os,NULL); 1115 ogg_stream_packetout(&vf->os,NULL);
1140 else 1116 else
1141 if(lastblock)accblock+=(lastblock+thisblock)>>2; 1117 if(lastblock)accblock+=(lastblock+thisblock)>>2;
1142 } 1118 }
1143 1119
1144 if(op.granulepos!=-1){ 1120 if(op.granulepos!=-1){
1145 int i,link=vf->current_link; 1121 int i,link=vf->current_link;
1146 ogg_int64_t granulepos=op.granulepos-vf->pcmlengths[link*2]; 1122 ogg_int64_t granulepos=op.granulepos-vf->pcmlengths[link*2];
1147 if(granulepos<0)granulepos=0; 1123 if(granulepos<0)granulepos=0;
1148 1124
1149 for(i=0;i<link;i++) 1125 for(i=0;i<link;i++)
1150 granulepos+=vf->pcmlengths[i*2+1]; 1126 granulepos+=vf->pcmlengths[i*2+1];
1151 vf->pcm_offset=granulepos-accblock; 1127 vf->pcm_offset=granulepos-accblock;
@@ -1155,10 +1131,10 @@ int ov_raw_seek(OggVorbis_File *vf,ogg_int64_t pos){
1155 lastblock=thisblock; 1131 lastblock=thisblock;
1156 continue; 1132 continue;
1157 }else 1133 }else
1158 ogg_stream_packetout(vf->os,NULL); 1134 ogg_stream_packetout(&vf->os,NULL);
1159 } 1135 }
1160 } 1136 }
1161 1137
1162 if(!lastblock){ 1138 if(!lastblock){
1163 pagepos=_get_next_page(vf,&og,-1); 1139 pagepos=_get_next_page(vf,&og,-1);
1164 if(pagepos<0){ 1140 if(pagepos<0){
@@ -1170,10 +1146,11 @@ int ov_raw_seek(OggVorbis_File *vf,ogg_int64_t pos){
1170 vf->pcm_offset=-1; 1146 vf->pcm_offset=-1;
1171 break; 1147 break;
1172 } 1148 }
1173 1149
1174 /* has our decoding just traversed a bitstream boundary? */ 1150 /* has our decoding just traversed a bitstream boundary? */
1175 if(vf->ready_state>=STREAMSET){ 1151 if(vf->ready_state>=STREAMSET){
1176 if(vf->current_serialno!=ogg_page_serialno(&og)){ 1152 if(vf->current_serialno!=ogg_page_serialno(&og)){
1153
1177 /* two possibilities: 1154 /* two possibilities:
1178 1) our decoding just traversed a bitstream boundary 1155 1) our decoding just traversed a bitstream boundary
1179 2) another stream is multiplexed into this logical section? */ 1156 2) another stream is multiplexed into this logical section? */
@@ -1181,53 +1158,45 @@ int ov_raw_seek(OggVorbis_File *vf,ogg_int64_t pos){
1181 if(ogg_page_bos(&og)){ 1158 if(ogg_page_bos(&og)){
1182 /* we traversed */ 1159 /* we traversed */
1183 _decode_clear(vf); /* clear out stream state */ 1160 _decode_clear(vf); /* clear out stream state */
1184 ogg_stream_destroy(work_os); 1161 ogg_stream_clear(&work_os);
1185 } /* else, do nothing; next loop will scoop another page */ 1162 } /* else, do nothing; next loop will scoop another page */
1186 } 1163 }
1187 } 1164 }
1188 1165
1189 if(vf->ready_state<STREAMSET){ 1166 if(vf->ready_state<STREAMSET){
1190 int link; 1167 int link;
1191 long serialno = ogg_page_serialno(&og); 1168 ogg_uint32_t serialno = ogg_page_serialno(&og);
1192 1169
1193 for(link=0;link<vf->links;link++) 1170 for(link=0;link<vf->links;link++)
1194 if(vf->serialnos[link]==vf->current_serialno)break; 1171 if(vf->serialnos[link]==serialno)break;
1195 1172
1196 if(link==vf->links) continue; /* not the desired Vorbis 1173 if(link==vf->links) continue; /* not the desired Vorbis
1197 bitstream section; keep 1174 bitstream section; keep
1198 trying */ 1175 trying */
1199 vf->current_link=link; 1176 vf->current_link=link;
1200 vf->current_serialno=serialno; 1177 vf->current_serialno=serialno;
1201 ogg_stream_reset_serialno(vf->os,vf->current_serialno); 1178 ogg_stream_reset_serialno(&vf->os,serialno);
1202 ogg_stream_reset_serialno(work_os,vf->current_serialno); 1179 ogg_stream_reset_serialno(&work_os,serialno);
1203 vf->ready_state=STREAMSET; 1180 vf->ready_state=STREAMSET;
1204 firstflag=(pagepos<=vf->dataoffsets[link]); 1181 firstflag=(pagepos<=vf->dataoffsets[link]);
1205 } 1182 }
1206 1183
1207 { 1184 ogg_stream_pagein(&vf->os,&og);
1208 ogg_page dup; 1185 ogg_stream_pagein(&work_os,&og);
1209 ogg_page_dup(&dup,&og); 1186 lastflag=ogg_page_eos(&og);
1210 lastflag=ogg_page_eos(&og); 1187
1211 ogg_stream_pagein(vf->os,&og);
1212 ogg_stream_pagein(work_os,&dup);
1213 }
1214 } 1188 }
1215 } 1189 }
1216 1190
1217 ogg_packet_release(&op); 1191 ogg_stream_clear(&work_os);
1218 ogg_page_release(&og);
1219 ogg_stream_destroy(work_os);
1220 vf->bittrack=0; 1192 vf->bittrack=0;
1221 vf->samptrack=0; 1193 vf->samptrack=0;
1222 return(0); 1194 return(0);
1223 1195
1224 seek_error: 1196 seek_error:
1225 ogg_packet_release(&op);
1226 ogg_page_release(&og);
1227
1228 /* dump the machine so we're in a known state */ 1197 /* dump the machine so we're in a known state */
1229 vf->pcm_offset=-1; 1198 vf->pcm_offset=-1;
1230 ogg_stream_destroy(work_os); 1199 ogg_stream_clear(&work_os);
1231 _decode_clear(vf); 1200 _decode_clear(vf);
1232 return OV_EBADLINK; 1201 return OV_EBADLINK;
1233} 1202}
@@ -1235,20 +1204,19 @@ int ov_raw_seek(OggVorbis_File *vf,ogg_int64_t pos){
1235/* Page granularity seek (faster than sample granularity because we 1204/* Page granularity seek (faster than sample granularity because we
1236 don't do the last bit of decode to find a specific sample). 1205 don't do the last bit of decode to find a specific sample).
1237 1206
1238 Seek to the last [granule marked] page preceeding the specified pos 1207 Seek to the last [granule marked] page preceding the specified pos
1239 location, such that decoding past the returned point will quickly 1208 location, such that decoding past the returned point will quickly
1240 arrive at the requested position. */ 1209 arrive at the requested position. */
1241int ov_pcm_seek_page(OggVorbis_File *vf,ogg_int64_t pos){ 1210int ov_pcm_seek_page(OggVorbis_File *vf,ogg_int64_t pos){
1242 int link=-1; 1211 int link=-1;
1243 ogg_int64_t result=0; 1212 ogg_int64_t result=0;
1244 ogg_int64_t total=ov_pcm_total(vf,-1); 1213 ogg_int64_t total=ov_pcm_total(vf,-1);
1245 ogg_page og={0,0,0,0};
1246 ogg_packet op={0,0,0,0,0,0};
1247 1214
1248 if(vf->ready_state<OPENED)return(OV_EINVAL); 1215 if(vf->ready_state<OPENED)return(OV_EINVAL);
1249 if(!vf->seekable)return(OV_ENOSEEK); 1216 if(!vf->seekable)return(OV_ENOSEEK);
1217
1250 if(pos<0 || pos>total)return(OV_EINVAL); 1218 if(pos<0 || pos>total)return(OV_EINVAL);
1251 1219
1252 /* which bitstream section does this pcm offset occur in? */ 1220 /* which bitstream section does this pcm offset occur in? */
1253 for(link=vf->links-1;link>=0;link--){ 1221 for(link=vf->links-1;link>=0;link--){
1254 total-=vf->pcmlengths[link*2+1]; 1222 total-=vf->pcmlengths[link*2+1];
@@ -1256,7 +1224,7 @@ int ov_pcm_seek_page(OggVorbis_File *vf,ogg_int64_t pos){
1256 } 1224 }
1257 1225
1258 /* search within the logical bitstream for the page with the highest 1226 /* search within the logical bitstream for the page with the highest
1259 pcm_pos preceeding (or equal to) pos. There is a danger here; 1227 pcm_pos preceding (or equal to) pos. There is a danger here;
1260 missing pages or incorrect frame number information in the 1228 missing pages or incorrect frame number information in the
1261 bitstream could make our task impossible. Account for that (it 1229 bitstream could make our task impossible. Account for that (it
1262 would be an error condition) */ 1230 would be an error condition) */
@@ -1269,22 +1237,26 @@ int ov_pcm_seek_page(OggVorbis_File *vf,ogg_int64_t pos){
1269 ogg_int64_t endtime = vf->pcmlengths[link*2+1]+begintime; 1237 ogg_int64_t endtime = vf->pcmlengths[link*2+1]+begintime;
1270 ogg_int64_t target=pos-total+begintime; 1238 ogg_int64_t target=pos-total+begintime;
1271 ogg_int64_t best=begin; 1239 ogg_int64_t best=begin;
1272 1240
1241 ogg_page og;
1273 while(begin<end){ 1242 while(begin<end){
1274 ogg_int64_t bisect; 1243 ogg_int64_t bisect;
1275 1244
1276 if(end-begin<CHUNKSIZE){ 1245 if(end-begin<CHUNKSIZE){
1277 bisect=begin; 1246 bisect=begin;
1278 }else{ 1247 }else{
1279 /* take a (pretty decent) guess. */ 1248 /* take a (pretty decent) guess. */
1280 bisect=begin + 1249 bisect=begin +
1281 (target-begintime)*(end-begin)/(endtime-begintime) - CHUNKSIZE; 1250 (target-begintime)*(end-begin)/(endtime-begintime) - CHUNKSIZE;
1282 if(bisect<=begin) 1251 if(bisect<begin+CHUNKSIZE)
1283 bisect=begin+1; 1252 bisect=begin;
1284 } 1253 }
1285 1254
1286 _seek_helper(vf,bisect); 1255 if(bisect!=vf->offset){
1287 1256 result=_seek_helper(vf,bisect);
1257 if(result) goto seek_error;
1258 }
1259
1288 while(begin<end){ 1260 while(begin<end){
1289 result=_get_next_page(vf,&og,end-vf->offset); 1261 result=_get_next_page(vf,&og,end-vf->offset);
1290 if(result==OV_EREAD) goto seek_error; 1262 if(result==OV_EREAD) goto seek_error;
@@ -1295,16 +1267,23 @@ int ov_pcm_seek_page(OggVorbis_File *vf,ogg_int64_t pos){
1295 if(bisect==0) goto seek_error; 1267 if(bisect==0) goto seek_error;
1296 bisect-=CHUNKSIZE; 1268 bisect-=CHUNKSIZE;
1297 if(bisect<=begin)bisect=begin+1; 1269 if(bisect<=begin)bisect=begin+1;
1298 _seek_helper(vf,bisect); 1270 result=_seek_helper(vf,bisect);
1271 if(result) goto seek_error;
1299 } 1272 }
1300 }else{ 1273 }else{
1301 ogg_int64_t granulepos=ogg_page_granulepos(&og); 1274 ogg_int64_t granulepos;
1275
1276 if(ogg_page_serialno(&og)!=vf->serialnos[link])
1277 continue;
1278
1279 granulepos=ogg_page_granulepos(&og);
1302 if(granulepos==-1)continue; 1280 if(granulepos==-1)continue;
1281
1303 if(granulepos<target){ 1282 if(granulepos<target){
1304 best=result; /* raw offset of packet with granulepos */ 1283 best=result; /* raw offset of packet with granulepos */
1305 begin=vf->offset; /* raw offset of next page */ 1284 begin=vf->offset; /* raw offset of next page */
1306 begintime=granulepos; 1285 begintime=granulepos;
1307 1286
1308 if(target-begintime>44100)break; 1287 if(target-begintime>44100)break;
1309 bisect=begin; /* *not* begin + 1 */ 1288 bisect=begin; /* *not* begin + 1 */
1310 }else{ 1289 }else{
@@ -1315,9 +1294,10 @@ int ov_pcm_seek_page(OggVorbis_File *vf,ogg_int64_t pos){
1315 end=result; 1294 end=result;
1316 bisect-=CHUNKSIZE; /* an endless loop otherwise. */ 1295 bisect-=CHUNKSIZE; /* an endless loop otherwise. */
1317 if(bisect<=begin)bisect=begin+1; 1296 if(bisect<=begin)bisect=begin+1;
1318 _seek_helper(vf,bisect); 1297 result=_seek_helper(vf,bisect);
1298 if(result) goto seek_error;
1319 }else{ 1299 }else{
1320 end=result; 1300 end=bisect;
1321 endtime=granulepos; 1301 endtime=granulepos;
1322 break; 1302 break;
1323 } 1303 }
@@ -1328,9 +1308,11 @@ int ov_pcm_seek_page(OggVorbis_File *vf,ogg_int64_t pos){
1328 } 1308 }
1329 1309
1330 /* found our page. seek to it, update pcm offset. Easier case than 1310 /* found our page. seek to it, update pcm offset. Easier case than
1331 raw_seek, don't keep packets preceeding granulepos. */ 1311 raw_seek, don't keep packets preceding granulepos. */
1332 { 1312 {
1333 1313 ogg_page og;
1314 ogg_packet op;
1315
1334 /* seek */ 1316 /* seek */
1335 result=_seek_helper(vf,best); 1317 result=_seek_helper(vf,best);
1336 vf->pcm_offset=-1; 1318 vf->pcm_offset=-1;
@@ -1340,28 +1322,28 @@ int ov_pcm_seek_page(OggVorbis_File *vf,ogg_int64_t pos){
1340 1322
1341 if(link!=vf->current_link){ 1323 if(link!=vf->current_link){
1342 /* Different link; dump entire decode machine */ 1324 /* Different link; dump entire decode machine */
1343 _decode_clear(vf); 1325 _decode_clear(vf);
1344 1326
1345 vf->current_link=link; 1327 vf->current_link=link;
1346 vf->current_serialno=ogg_page_serialno(&og); 1328 vf->current_serialno=vf->serialnos[link];
1347 vf->ready_state=STREAMSET; 1329 vf->ready_state=STREAMSET;
1348 1330
1349 }else{ 1331 }else{
1350 vorbis_synthesis_restart(&vf->vd); 1332 vorbis_synthesis_restart(&vf->vd);
1351 } 1333 }
1352 1334
1353 ogg_stream_reset_serialno(vf->os,vf->current_serialno); 1335 ogg_stream_reset_serialno(&vf->os,vf->current_serialno);
1354 ogg_stream_pagein(vf->os,&og); 1336 ogg_stream_pagein(&vf->os,&og);
1355 1337
1356 /* pull out all but last packet; the one with granulepos */ 1338 /* pull out all but last packet; the one with granulepos */
1357 while(1){ 1339 while(1){
1358 result=ogg_stream_packetpeek(vf->os,&op); 1340 result=ogg_stream_packetpeek(&vf->os,&op);
1359 if(result==0){ 1341 if(result==0){
1360 /* !!! the packet finishing this page originated on a 1342 /* !!! the packet finishing this page originated on a
1361 preceeding page. Keep fetching previous pages until we 1343 preceding page. Keep fetching previous pages until we
1362 get one with a granulepos or without the 'continued' flag 1344 get one with a granulepos or without the 'continued' flag
1363 set. Then just use raw_seek for simplicity. */ 1345 set. Then just use raw_seek for simplicity. */
1364 1346
1365 result=_seek_helper(vf,best); 1347 result=_seek_helper(vf,best);
1366 if(result<0) goto seek_error; 1348 if(result<0) goto seek_error;
1367 1349
@@ -1377,7 +1359,7 @@ int ov_pcm_seek_page(OggVorbis_File *vf,ogg_int64_t pos){
1377 } 1359 }
1378 } 1360 }
1379 if(result<0){ 1361 if(result<0){
1380 result = OV_EBADPACKET; 1362 result = OV_EBADPACKET;
1381 goto seek_error; 1363 goto seek_error;
1382 } 1364 }
1383 if(op.granulepos!=-1){ 1365 if(op.granulepos!=-1){
@@ -1386,11 +1368,11 @@ int ov_pcm_seek_page(OggVorbis_File *vf,ogg_int64_t pos){
1386 vf->pcm_offset+=total; 1368 vf->pcm_offset+=total;
1387 break; 1369 break;
1388 }else 1370 }else
1389 result=ogg_stream_packetout(vf->os,NULL); 1371 result=ogg_stream_packetout(&vf->os,NULL);
1390 } 1372 }
1391 } 1373 }
1392 } 1374 }
1393 1375
1394 /* verify result */ 1376 /* verify result */
1395 if(vf->pcm_offset>pos || pos>ov_pcm_total(vf,-1)){ 1377 if(vf->pcm_offset>pos || pos>ov_pcm_total(vf,-1)){
1396 result=OV_EFAULT; 1378 result=OV_EFAULT;
@@ -1398,60 +1380,53 @@ int ov_pcm_seek_page(OggVorbis_File *vf,ogg_int64_t pos){
1398 } 1380 }
1399 vf->bittrack=0; 1381 vf->bittrack=0;
1400 vf->samptrack=0; 1382 vf->samptrack=0;
1401
1402 ogg_page_release(&og);
1403 ogg_packet_release(&op);
1404 return(0); 1383 return(0);
1405
1406 seek_error:
1407
1408 ogg_page_release(&og);
1409 ogg_packet_release(&op);
1410 1384
1385 seek_error:
1411 /* dump machine so we're in a known state */ 1386 /* dump machine so we're in a known state */
1412 vf->pcm_offset=-1; 1387 vf->pcm_offset=-1;
1413 _decode_clear(vf); 1388 _decode_clear(vf);
1414 return (int)result; 1389 return (int)result;
1415} 1390}
1416 1391
1417/* seek to a sample offset relative to the decompressed pcm stream 1392/* seek to a sample offset relative to the decompressed pcm stream
1418 returns zero on success, nonzero on failure */ 1393 returns zero on success, nonzero on failure */
1419 1394
1420int ov_pcm_seek(OggVorbis_File *vf,ogg_int64_t pos){ 1395int ov_pcm_seek(OggVorbis_File *vf,ogg_int64_t pos){
1421 ogg_packet op={0,0,0,0,0,0};
1422 ogg_page og={0,0,0,0};
1423 int thisblock,lastblock=0; 1396 int thisblock,lastblock=0;
1424 int ret=ov_pcm_seek_page(vf,pos); 1397 int ret=ov_pcm_seek_page(vf,pos);
1425 if(ret<0)return(ret); 1398 if(ret<0)return(ret);
1426 _make_decode_ready(vf); 1399 if((ret=_make_decode_ready(vf)))return ret;
1427 1400
1428 /* discard leading packets we don't need for the lapping of the 1401 /* discard leading packets we don't need for the lapping of the
1429 position we want; don't decode them */ 1402 position we want; don't decode them */
1430 1403
1431 while(1){ 1404 while(1){
1405 ogg_packet op;
1406 ogg_page og;
1432 1407
1433 int ret=ogg_stream_packetpeek(vf->os,&op); 1408 int ret=ogg_stream_packetpeek(&vf->os,&op);
1434 if(ret>0){ 1409 if(ret>0){
1435 thisblock=vorbis_packet_blocksize(vf->vi+vf->current_link,&op); 1410 thisblock=vorbis_packet_blocksize(vf->vi+vf->current_link,&op);
1436 if(thisblock<0){ 1411 if(thisblock<0){
1437 ogg_stream_packetout(vf->os,NULL); 1412 ogg_stream_packetout(&vf->os,NULL);
1438 continue; /* non audio packet */ 1413 continue; /* non audio packet */
1439 } 1414 }
1440 if(lastblock)vf->pcm_offset+=(lastblock+thisblock)>>2; 1415 if(lastblock)vf->pcm_offset+=(lastblock+thisblock)>>2;
1441 1416
1442 if(vf->pcm_offset+((thisblock+ 1417 if(vf->pcm_offset+((thisblock+
1443 vorbis_info_blocksize(vf->vi,1))>>2)>=pos)break; 1418 vorbis_info_blocksize(vf->vi,1))>>2)>=pos)break;
1444 1419
1445 /* remove the packet from packet queue and track its granulepos */ 1420 /* remove the packet from packet queue and track its granulepos */
1446 ogg_stream_packetout(vf->os,NULL); 1421 ogg_stream_packetout(&vf->os,NULL);
1447 vorbis_synthesis_trackonly(&vf->vb,&op); /* set up a vb with 1422 vorbis_synthesis_trackonly(&vf->vb,&op); /* set up a vb with
1448 only tracking, no 1423 only tracking, no
1449 pcm_decode */ 1424 pcm_decode */
1450 vorbis_synthesis_blockin(&vf->vd,&vf->vb); 1425 vorbis_synthesis_blockin(&vf->vd,&vf->vb);
1451 1426
1452 /* end of logical stream case is hard, especially with exact 1427 /* end of logical stream case is hard, especially with exact
1453 length positioning. */ 1428 length positioning. */
1454 1429
1455 if(op.granulepos>-1){ 1430 if(op.granulepos>-1){
1456 int i; 1431 int i;
1457 /* always believe the stream markers */ 1432 /* always believe the stream markers */
@@ -1460,20 +1435,20 @@ int ov_pcm_seek(OggVorbis_File *vf,ogg_int64_t pos){
1460 for(i=0;i<vf->current_link;i++) 1435 for(i=0;i<vf->current_link;i++)
1461 vf->pcm_offset+=vf->pcmlengths[i*2+1]; 1436 vf->pcm_offset+=vf->pcmlengths[i*2+1];
1462 } 1437 }
1463 1438
1464 lastblock=thisblock; 1439 lastblock=thisblock;
1465 1440
1466 }else{ 1441 }else{
1467 if(ret<0 && ret!=OV_HOLE)break; 1442 if(ret<0 && ret!=OV_HOLE)break;
1468 1443
1469 /* suck in a new page */ 1444 /* suck in a new page */
1470 if(_get_next_page(vf,&og,-1)<0)break; 1445 if(_get_next_page(vf,&og,-1)<0)break;
1471 if(ogg_page_bos(&og))_decode_clear(vf); 1446 if(ogg_page_bos(&og))_decode_clear(vf);
1472 1447
1473 if(vf->ready_state<STREAMSET){ 1448 if(vf->ready_state<STREAMSET){
1474 long serialno=ogg_page_serialno(&og); 1449 long serialno=ogg_page_serialno(&og);
1475 int link; 1450 int link;
1476 1451
1477 for(link=0;link<vf->links;link++) 1452 for(link=0;link<vf->links;link++)
1478 if(vf->serialnos[link]==(ogg_uint32_t) serialno)break; 1453 if(vf->serialnos[link]==(ogg_uint32_t) serialno)break;
1479 if(link==vf->links) continue; 1454 if(link==vf->links) continue;
@@ -1481,17 +1456,13 @@ int ov_pcm_seek(OggVorbis_File *vf,ogg_int64_t pos){
1481 1456
1482 vf->ready_state=STREAMSET; 1457 vf->ready_state=STREAMSET;
1483 vf->current_serialno=ogg_page_serialno(&og); 1458 vf->current_serialno=ogg_page_serialno(&og);
1484 ogg_stream_reset_serialno(vf->os,serialno); 1459 ogg_stream_reset_serialno(&vf->os,serialno);
1485 ret=_make_decode_ready(vf); 1460 ret=_make_decode_ready(vf);
1486 if(ret){ 1461 if(ret)return ret;
1487 ogg_page_release(&og);
1488 ogg_packet_release(&op);
1489 return ret;
1490 }
1491 lastblock=0; 1462 lastblock=0;
1492 } 1463 }
1493 1464
1494 ogg_stream_pagein(vf->os,&og); 1465 ogg_stream_pagein(&vf->os,&og);
1495 } 1466 }
1496 } 1467 }
1497 1468
@@ -1506,18 +1477,15 @@ int ov_pcm_seek(OggVorbis_File *vf,ogg_int64_t pos){
1506 if(samples>target)samples=target; 1477 if(samples>target)samples=target;
1507 vorbis_synthesis_read(&vf->vd,samples); 1478 vorbis_synthesis_read(&vf->vd,samples);
1508 vf->pcm_offset+=samples; 1479 vf->pcm_offset+=samples;
1509 1480
1510 if(samples<target) 1481 if(samples<target)
1511 if(_fetch_and_process_packet(vf,1,1)<=0) 1482 if(_fetch_and_process_packet(vf,NULL,1,1)<=0)
1512 vf->pcm_offset=ov_pcm_total(vf,-1); /* eof */ 1483 vf->pcm_offset=ov_pcm_total(vf,-1); /* eof */
1513 } 1484 }
1514
1515 ogg_page_release(&og);
1516 ogg_packet_release(&op);
1517 return 0; 1485 return 0;
1518} 1486}
1519 1487
1520/* seek to a playback time relative to the decompressed pcm stream 1488/* seek to a playback time relative to the decompressed pcm stream
1521 returns zero on success, nonzero on failure */ 1489 returns zero on success, nonzero on failure */
1522int ov_time_seek(OggVorbis_File *vf,ogg_int64_t milliseconds){ 1490int ov_time_seek(OggVorbis_File *vf,ogg_int64_t milliseconds){
1523 /* translate time to PCM position and call ov_pcm_seek */ 1491 /* translate time to PCM position and call ov_pcm_seek */
@@ -1529,7 +1497,7 @@ int ov_time_seek(OggVorbis_File *vf,ogg_int64_t milliseconds){
1529 if(vf->ready_state<OPENED)return(OV_EINVAL); 1497 if(vf->ready_state<OPENED)return(OV_EINVAL);
1530 if(!vf->seekable)return(OV_ENOSEEK); 1498 if(!vf->seekable)return(OV_ENOSEEK);
1531 if(milliseconds<0)return(OV_EINVAL); 1499 if(milliseconds<0)return(OV_EINVAL);
1532 1500
1533 /* which bitstream section does this time offset occur in? */ 1501 /* which bitstream section does this time offset occur in? */
1534 for(link=0;link<vf->links;link++){ 1502 for(link=0;link<vf->links;link++){
1535 ogg_int64_t addsec = ov_time_total(vf,link); 1503 ogg_int64_t addsec = ov_time_total(vf,link);
@@ -1559,7 +1527,7 @@ ogg_int64_t ov_time_tell(OggVorbis_File *vf){
1559 int link=0; 1527 int link=0;
1560 ogg_int64_t pcm_total=0; 1528 ogg_int64_t pcm_total=0;
1561 ogg_int64_t time_total=0; 1529 ogg_int64_t time_total=0;
1562 1530
1563 if(vf->ready_state<OPENED)return(OV_EINVAL); 1531 if(vf->ready_state<OPENED)return(OV_EINVAL);
1564 if(vf->seekable){ 1532 if(vf->seekable){
1565 pcm_total=ov_pcm_total(vf,-1); 1533 pcm_total=ov_pcm_total(vf,-1);
@@ -1579,7 +1547,7 @@ ogg_int64_t ov_time_tell(OggVorbis_File *vf){
1579/* link: -1) return the vorbis_info struct for the bitstream section 1547/* link: -1) return the vorbis_info struct for the bitstream section
1580 currently being decoded 1548 currently being decoded
1581 0-n) to request information for a specific bitstream section 1549 0-n) to request information for a specific bitstream section
1582 1550
1583 In the case of a non-seekable bitstream, any call returns the 1551 In the case of a non-seekable bitstream, any call returns the
1584 current bitstream. NULL in the case that the machine is not 1552 current bitstream. NULL in the case that the machine is not
1585 initialized */ 1553 initialized */
@@ -1634,9 +1602,12 @@ long ov_read_fixed(OggVorbis_File *vf,ogg_int32_t ***pcm_channels,int length,
1634 1602
1635 /* suck in another packet */ 1603 /* suck in another packet */
1636 { 1604 {
1637 int ret=_fetch_and_process_packet(vf,1,1); 1605 int ret=_fetch_and_process_packet(vf,NULL,1,1);
1638 if(ret==OV_EOF)return(0); 1606 if(ret==OV_EOF)
1639 if(ret<=0)return(ret); 1607 return(0);
1608 if(ret<=0)
1609 return(ret);
1640 } 1610 }
1641 } 1611 }
1642} 1612}
1613