diff options
Diffstat (limited to 'apps/codecs/libtremor/vorbisfile.c')
-rw-r--r-- | apps/codecs/libtremor/vorbisfile.c | 75 |
1 files changed, 50 insertions, 25 deletions
diff --git a/apps/codecs/libtremor/vorbisfile.c b/apps/codecs/libtremor/vorbisfile.c index 5721178b67..44a6d6e78a 100644 --- a/apps/codecs/libtremor/vorbisfile.c +++ b/apps/codecs/libtremor/vorbisfile.c | |||
@@ -132,6 +132,25 @@ static ogg_int64_t _get_next_page(OggVorbis_File *vf,ogg_page *og, | |||
132 | } | 132 | } |
133 | } | 133 | } |
134 | 134 | ||
135 | /* This is a nasty hack to work around the huge allocations we get from | ||
136 | huge comment packets, usually due to embedded album art */ | ||
137 | static int ogg_stream_discard_packet(OggVorbis_File *vf,ogg_page *og, | ||
138 | ogg_int64_t boundary){ | ||
139 | int ret; | ||
140 | while((ret = ogg_stream_packetout(&vf->os, NULL)) == 0) { | ||
141 | if(_get_next_page(vf, og, boundary)<0) | ||
142 | break; | ||
143 | ogg_stream_pagein(&vf->os,og,false); | ||
144 | } | ||
145 | if (ret < 0) | ||
146 | return -1; | ||
147 | if (vf->os.body_fill < og->body_len) | ||
148 | if(_os_body_expand(&vf->os, og->body_len)) | ||
149 | return -1; | ||
150 | memcpy(vf->os.body_data+vf->os.body_fill-og->body_len, og->body, og->body_len); | ||
151 | return 1; | ||
152 | } | ||
153 | |||
135 | /* find the latest page beginning before the current stream cursor | 154 | /* find the latest page beginning before the current stream cursor |
136 | position. Much dirtier than the above as Ogg doesn't have any | 155 | position. Much dirtier than the above as Ogg doesn't have any |
137 | backward search linkage. no 'readp' as it will certainly have to | 156 | backward search linkage. no 'readp' as it will certainly have to |
@@ -272,7 +291,7 @@ static ogg_int64_t _get_prev_page_serial(OggVorbis_File *vf, | |||
272 | 291 | ||
273 | /* uses the local ogg_stream storage in vf; this is important for | 292 | /* uses the local ogg_stream storage in vf; this is important for |
274 | non-streaming input sources */ | 293 | non-streaming input sources */ |
275 | static int _fetch_headers(OggVorbis_File *vf,vorbis_info *vi,vorbis_comment *vc, | 294 | static int _fetch_headers(OggVorbis_File *vf,vorbis_info *vi, |
276 | ogg_uint32_t **serialno_list, int *serialno_n, | 295 | ogg_uint32_t **serialno_list, int *serialno_n, |
277 | ogg_page *og_ptr){ | 296 | ogg_page *og_ptr){ |
278 | ogg_page og; | 297 | ogg_page og; |
@@ -288,7 +307,7 @@ static int _fetch_headers(OggVorbis_File *vf,vorbis_info *vi,vorbis_comment *vc, | |||
288 | } | 307 | } |
289 | 308 | ||
290 | vorbis_info_init(vi); | 309 | vorbis_info_init(vi); |
291 | vorbis_comment_init(vc); | 310 | /* vorbis_comment_init(vc); */ |
292 | vf->ready_state=OPENED; | 311 | vf->ready_state=OPENED; |
293 | 312 | ||
294 | /* extract the serialnos of all BOS pages + the first set of vorbis | 313 | /* extract the serialnos of all BOS pages + the first set of vorbis |
@@ -312,13 +331,13 @@ static int _fetch_headers(OggVorbis_File *vf,vorbis_info *vi,vorbis_comment *vc, | |||
312 | /* we don't have a vorbis stream in this link yet, so begin | 331 | /* we don't have a vorbis stream in this link yet, so begin |
313 | prospective stream setup. We need a stream to get packets */ | 332 | prospective stream setup. We need a stream to get packets */ |
314 | ogg_stream_reset_serialno(&vf->os,ogg_page_serialno(og_ptr)); | 333 | ogg_stream_reset_serialno(&vf->os,ogg_page_serialno(og_ptr)); |
315 | ogg_stream_pagein(&vf->os,og_ptr); | 334 | ogg_stream_pagein(&vf->os,og_ptr,true); |
316 | 335 | ||
317 | if(ogg_stream_packetout(&vf->os,&op) > 0 && | 336 | if(ogg_stream_packetout(&vf->os,&op) > 0 && |
318 | vorbis_synthesis_idheader(&op)){ | 337 | vorbis_synthesis_idheader(&op)){ |
319 | /* vorbis header; continue setup */ | 338 | /* vorbis header; continue setup */ |
320 | vf->ready_state=STREAMSET; | 339 | vf->ready_state=STREAMSET; |
321 | if((ret=vorbis_synthesis_headerin(vi,vc,&op))){ | 340 | if((ret=vorbis_synthesis_headerin(vi,&op))){ |
322 | ret=OV_EBADHEADER; | 341 | ret=OV_EBADHEADER; |
323 | goto bail_header; | 342 | goto bail_header; |
324 | } | 343 | } |
@@ -340,7 +359,7 @@ static int _fetch_headers(OggVorbis_File *vf,vorbis_info *vi,vorbis_comment *vc, | |||
340 | /* if this page also belongs to our vorbis stream, submit it and break */ | 359 | /* if this page also belongs to our vorbis stream, submit it and break */ |
341 | if(vf->ready_state==STREAMSET && | 360 | if(vf->ready_state==STREAMSET && |
342 | vf->os.serialno == ogg_page_serialno(og_ptr)){ | 361 | vf->os.serialno == ogg_page_serialno(og_ptr)){ |
343 | ogg_stream_pagein(&vf->os,og_ptr); | 362 | ogg_stream_pagein(&vf->os,og_ptr,true); |
344 | break; | 363 | break; |
345 | } | 364 | } |
346 | } | 365 | } |
@@ -354,10 +373,16 @@ static int _fetch_headers(OggVorbis_File *vf,vorbis_info *vi,vorbis_comment *vc, | |||
354 | while(1){ | 373 | while(1){ |
355 | 374 | ||
356 | i=0; | 375 | i=0; |
376 | /* discard comment packet */ | ||
377 | if(ogg_stream_discard_packet(vf,og_ptr,CHUNKSIZE) < 0){ | ||
378 | ret=OV_EBADHEADER; | ||
379 | goto bail_header; | ||
380 | } | ||
381 | i++; | ||
382 | |||
357 | while(i<2){ /* get a page loop */ | 383 | while(i<2){ /* get a page loop */ |
358 | 384 | ||
359 | while(i<2){ /* get a packet loop */ | 385 | while(i<2){ /* get a packet loop */ |
360 | |||
361 | int result=ogg_stream_packetout(&vf->os,&op); | 386 | int result=ogg_stream_packetout(&vf->os,&op); |
362 | if(result==0)break; | 387 | if(result==0)break; |
363 | if(result==-1){ | 388 | if(result==-1){ |
@@ -365,7 +390,7 @@ static int _fetch_headers(OggVorbis_File *vf,vorbis_info *vi,vorbis_comment *vc, | |||
365 | goto bail_header; | 390 | goto bail_header; |
366 | } | 391 | } |
367 | 392 | ||
368 | if((ret=vorbis_synthesis_headerin(vi,vc,&op))) | 393 | if((ret=vorbis_synthesis_headerin(vi,&op))) |
369 | goto bail_header; | 394 | goto bail_header; |
370 | 395 | ||
371 | i++; | 396 | i++; |
@@ -379,7 +404,7 @@ static int _fetch_headers(OggVorbis_File *vf,vorbis_info *vi,vorbis_comment *vc, | |||
379 | 404 | ||
380 | /* if this page belongs to the correct stream, go parse it */ | 405 | /* if this page belongs to the correct stream, go parse it */ |
381 | if(vf->os.serialno == ogg_page_serialno(og_ptr)){ | 406 | if(vf->os.serialno == ogg_page_serialno(og_ptr)){ |
382 | ogg_stream_pagein(&vf->os,og_ptr); | 407 | ogg_stream_pagein(&vf->os,og_ptr,true); |
383 | break; | 408 | break; |
384 | } | 409 | } |
385 | 410 | ||
@@ -402,7 +427,7 @@ static int _fetch_headers(OggVorbis_File *vf,vorbis_info *vi,vorbis_comment *vc, | |||
402 | 427 | ||
403 | bail_header: | 428 | bail_header: |
404 | vorbis_info_clear(vi); | 429 | vorbis_info_clear(vi); |
405 | vorbis_comment_clear(vc); | 430 | /* vorbis_comment_clear(vc); */ |
406 | vf->ready_state=OPENED; | 431 | vf->ready_state=OPENED; |
407 | 432 | ||
408 | return ret; | 433 | return ret; |
@@ -428,7 +453,7 @@ static ogg_int64_t _initial_pcmoffset(OggVorbis_File *vf, vorbis_info *vi){ | |||
428 | if(ogg_page_serialno(&og)!= serialno) continue; | 453 | if(ogg_page_serialno(&og)!= serialno) continue; |
429 | 454 | ||
430 | /* count blocksizes of all frames in the page */ | 455 | /* count blocksizes of all frames in the page */ |
431 | ogg_stream_pagein(&vf->os,&og); | 456 | ogg_stream_pagein(&vf->os,&og,true); |
432 | while((result=ogg_stream_packetout(&vf->os,&op))){ | 457 | while((result=ogg_stream_packetout(&vf->os,&op))){ |
433 | if(result>0){ /* ignore holes */ | 458 | if(result>0){ /* ignore holes */ |
434 | long thisblock=vorbis_packet_blocksize(vi,&op); | 459 | long thisblock=vorbis_packet_blocksize(vi,&op); |
@@ -500,7 +525,7 @@ static int _bisect_forward_serialno(OggVorbis_File *vf, | |||
500 | 525 | ||
501 | vf->offsets=_ogg_malloc((vf->links+1)*sizeof(*vf->offsets)); | 526 | vf->offsets=_ogg_malloc((vf->links+1)*sizeof(*vf->offsets)); |
502 | vf->vi=_ogg_realloc(vf->vi,vf->links*sizeof(*vf->vi)); | 527 | vf->vi=_ogg_realloc(vf->vi,vf->links*sizeof(*vf->vi)); |
503 | vf->vc=_ogg_realloc(vf->vc,vf->links*sizeof(*vf->vc)); | 528 | /* vf->vc=_ogg_realloc(vf->vc,vf->links*sizeof(*vf->vc));*/ |
504 | vf->serialnos=_ogg_malloc(vf->links*sizeof(*vf->serialnos)); | 529 | vf->serialnos=_ogg_malloc(vf->links*sizeof(*vf->serialnos)); |
505 | vf->dataoffsets=_ogg_malloc(vf->links*sizeof(*vf->dataoffsets)); | 530 | vf->dataoffsets=_ogg_malloc(vf->links*sizeof(*vf->dataoffsets)); |
506 | vf->pcmlengths=_ogg_malloc(vf->links*2*sizeof(*vf->pcmlengths)); | 531 | vf->pcmlengths=_ogg_malloc(vf->links*2*sizeof(*vf->pcmlengths)); |
@@ -514,7 +539,7 @@ static int _bisect_forward_serialno(OggVorbis_File *vf, | |||
514 | ogg_uint32_t *next_serialno_list=NULL; | 539 | ogg_uint32_t *next_serialno_list=NULL; |
515 | int next_serialnos=0; | 540 | int next_serialnos=0; |
516 | vorbis_info vi; | 541 | vorbis_info vi; |
517 | vorbis_comment vc; | 542 | /* vorbis_comment vc; */ |
518 | 543 | ||
519 | /* the below guards against garbage seperating the last and | 544 | /* the below guards against garbage seperating the last and |
520 | first pages of two links. */ | 545 | first pages of two links. */ |
@@ -559,7 +584,7 @@ static int _bisect_forward_serialno(OggVorbis_File *vf, | |||
559 | if(ret)return(ret); | 584 | if(ret)return(ret); |
560 | } | 585 | } |
561 | 586 | ||
562 | ret=_fetch_headers(vf,&vi,&vc,&next_serialno_list,&next_serialnos,NULL); | 587 | ret=_fetch_headers(vf,&vi,&next_serialno_list,&next_serialnos,NULL); |
563 | if(ret)return(ret); | 588 | if(ret)return(ret); |
564 | serialno = vf->os.serialno; | 589 | serialno = vf->os.serialno; |
565 | dataoffset = vf->offset; | 590 | dataoffset = vf->offset; |
@@ -579,7 +604,7 @@ static int _bisect_forward_serialno(OggVorbis_File *vf, | |||
579 | vf->dataoffsets[m+1]=dataoffset; | 604 | vf->dataoffsets[m+1]=dataoffset; |
580 | 605 | ||
581 | vf->vi[m+1]=vi; | 606 | vf->vi[m+1]=vi; |
582 | vf->vc[m+1]=vc; | 607 | /* vf->vc[m+1]=vc; */ |
583 | 608 | ||
584 | vf->pcmlengths[m*2+1]=searchgran; | 609 | vf->pcmlengths[m*2+1]=searchgran; |
585 | vf->pcmlengths[m*2+2]=pcmoffset; | 610 | vf->pcmlengths[m*2+2]=pcmoffset; |
@@ -789,7 +814,7 @@ static int _fetch_and_process_packet(OggVorbis_File *vf, | |||
789 | 814 | ||
790 | if(!vf->seekable){ | 815 | if(!vf->seekable){ |
791 | vorbis_info_clear(vf->vi); | 816 | vorbis_info_clear(vf->vi); |
792 | vorbis_comment_clear(vf->vc); | 817 | /* vorbis_comment_clear(vf->vc); */ |
793 | } | 818 | } |
794 | break; | 819 | break; |
795 | 820 | ||
@@ -842,7 +867,7 @@ static int _fetch_and_process_packet(OggVorbis_File *vf, | |||
842 | /* we're streaming */ | 867 | /* we're streaming */ |
843 | /* fetch the three header packets, build the info struct */ | 868 | /* fetch the three header packets, build the info struct */ |
844 | 869 | ||
845 | int ret=_fetch_headers(vf,vf->vi,vf->vc,NULL,NULL,&og); | 870 | int ret=_fetch_headers(vf,vf->vi,NULL,NULL,&og); |
846 | if(ret)return(ret); | 871 | if(ret)return(ret); |
847 | vf->current_serialno=vf->os.serialno; | 872 | vf->current_serialno=vf->os.serialno; |
848 | vf->current_link++; | 873 | vf->current_link++; |
@@ -853,7 +878,7 @@ static int _fetch_and_process_packet(OggVorbis_File *vf, | |||
853 | 878 | ||
854 | /* the buffered page is the data we want, and we're ready for it; | 879 | /* the buffered page is the data we want, and we're ready for it; |
855 | add it to the stream state */ | 880 | add it to the stream state */ |
856 | ogg_stream_pagein(&vf->os,&og); | 881 | ogg_stream_pagein(&vf->os,&og,true); |
857 | 882 | ||
858 | } | 883 | } |
859 | } | 884 | } |
@@ -889,12 +914,12 @@ static int _ov_open1(void *f,OggVorbis_File *vf,const char *initial, | |||
889 | entry for partial open */ | 914 | entry for partial open */ |
890 | vf->links=1; | 915 | vf->links=1; |
891 | vf->vi=_ogg_calloc(vf->links,sizeof(*vf->vi)); | 916 | vf->vi=_ogg_calloc(vf->links,sizeof(*vf->vi)); |
892 | vf->vc=_ogg_calloc(vf->links,sizeof(*vf->vc)); | 917 | /* vf->vc=_ogg_calloc(vf->links,sizeof(*vf->vc)); */ |
893 | ogg_stream_init(&vf->os,-1); /* fill in the serialno later */ | 918 | ogg_stream_init(&vf->os,-1); /* fill in the serialno later */ |
894 | 919 | ||
895 | /* Fetch all BOS pages, store the vorbis header and all seen serial | 920 | /* Fetch all BOS pages, store the vorbis header and all seen serial |
896 | numbers, load subsequent vorbis setup headers */ | 921 | numbers, load subsequent vorbis setup headers */ |
897 | if((ret=_fetch_headers(vf,vf->vi,vf->vc,&serialno_list,&serialno_list_size,NULL))<0){ | 922 | if((ret=_fetch_headers(vf,vf->vi,&serialno_list,&serialno_list_size,NULL))<0){ |
898 | vf->datasource=NULL; | 923 | vf->datasource=NULL; |
899 | ov_clear(vf); | 924 | ov_clear(vf); |
900 | }else{ | 925 | }else{ |
@@ -945,10 +970,10 @@ int ov_clear(OggVorbis_File *vf){ | |||
945 | int i; | 970 | int i; |
946 | for(i=0;i<vf->links;i++){ | 971 | for(i=0;i<vf->links;i++){ |
947 | vorbis_info_clear(vf->vi+i); | 972 | vorbis_info_clear(vf->vi+i); |
948 | vorbis_comment_clear(vf->vc+i); | 973 | /* vorbis_comment_clear(vf->vc+i); */ |
949 | } | 974 | } |
950 | _ogg_free(vf->vi); | 975 | _ogg_free(vf->vi); |
951 | _ogg_free(vf->vc); | 976 | /* _ogg_free(vf->vc); */ |
952 | } | 977 | } |
953 | if(vf->dataoffsets)_ogg_free(vf->dataoffsets); | 978 | if(vf->dataoffsets)_ogg_free(vf->dataoffsets); |
954 | if(vf->pcmlengths)_ogg_free(vf->pcmlengths); | 979 | if(vf->pcmlengths)_ogg_free(vf->pcmlengths); |
@@ -1180,8 +1205,8 @@ int ov_raw_seek(OggVorbis_File *vf,ogg_int64_t pos){ | |||
1180 | firstflag=(pagepos<=vf->dataoffsets[link]); | 1205 | firstflag=(pagepos<=vf->dataoffsets[link]); |
1181 | } | 1206 | } |
1182 | 1207 | ||
1183 | ogg_stream_pagein(&vf->os,&og); | 1208 | ogg_stream_pagein(&vf->os,&og,true); |
1184 | ogg_stream_pagein(&work_os,&og); | 1209 | ogg_stream_pagein(&work_os,&og,true); |
1185 | lastflag=ogg_page_eos(&og); | 1210 | lastflag=ogg_page_eos(&og); |
1186 | 1211 | ||
1187 | } | 1212 | } |
@@ -1363,7 +1388,7 @@ int ov_pcm_seek_page(OggVorbis_File *vf,ogg_int64_t pos){ | |||
1363 | } | 1388 | } |
1364 | 1389 | ||
1365 | ogg_stream_reset_serialno(&vf->os,vf->current_serialno); | 1390 | ogg_stream_reset_serialno(&vf->os,vf->current_serialno); |
1366 | ogg_stream_pagein(&vf->os,&og); | 1391 | ogg_stream_pagein(&vf->os,&og,true); |
1367 | 1392 | ||
1368 | /* pull out all but last packet; the one with granulepos */ | 1393 | /* pull out all but last packet; the one with granulepos */ |
1369 | while(1){ | 1394 | while(1){ |
@@ -1492,7 +1517,7 @@ int ov_pcm_seek(OggVorbis_File *vf,ogg_int64_t pos){ | |||
1492 | lastblock=0; | 1517 | lastblock=0; |
1493 | } | 1518 | } |
1494 | 1519 | ||
1495 | ogg_stream_pagein(&vf->os,&og); | 1520 | ogg_stream_pagein(&vf->os,&og,true); |
1496 | } | 1521 | } |
1497 | } | 1522 | } |
1498 | 1523 | ||