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.c75
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 */
137static 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 */
275static int _fetch_headers(OggVorbis_File *vf,vorbis_info *vi,vorbis_comment *vc, 294static 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