diff --git a/apps/codecs/libtremor/framing.c b/apps/codecs/libtremor/framing.c index d67708f87a..582084853a 100644 --- a/apps/codecs/libtremor/framing.c +++ b/apps/codecs/libtremor/framing.c @@ -236,7 +236,7 @@ int ogg_stream_destroy(ogg_stream_state *os){ /* Helpers for ogg_stream_encode; this keeps the structure and what's happening fairly clear */ -static int _os_body_expand(ogg_stream_state *os,int needed){ +int _os_body_expand(ogg_stream_state *os,int needed){ if(os->body_storage<=os->body_fill+needed){ void *ret; ret=_ogg_realloc(os->body_data,(os->body_storage+needed+1024)* @@ -783,7 +783,7 @@ int ogg_sync_pageout(ogg_sync_state *oy, ogg_page *og){ /* add the incoming page to the stream state; we decompose the page into packet segments here as well. */ -int ogg_stream_pagein(ogg_stream_state *os, ogg_page *og){ +int ogg_stream_pagein(ogg_stream_state *os, ogg_page *og, bool copy_body){ unsigned char *header=og->header; unsigned char *body=og->body; long bodysize=og->body_len; @@ -868,8 +868,10 @@ int ogg_stream_pagein(ogg_stream_state *os, ogg_page *og){ } if(bodysize){ - if(_os_body_expand(os,bodysize)) return -1; - memcpy(os->body_data+os->body_fill,body,bodysize); + if(copy_body){ + if(_os_body_expand(os,bodysize)) return -1; + memcpy(os->body_data+os->body_fill,body,bodysize); + } os->body_fill+=bodysize; } diff --git a/apps/codecs/libtremor/info.c b/apps/codecs/libtremor/info.c index b21d08de49..d922711e34 100644 --- a/apps/codecs/libtremor/info.c +++ b/apps/codecs/libtremor/info.c @@ -37,6 +37,7 @@ static void _v_readstring(oggpack_buffer *o,char *buf,int bytes){ } } +/* void vorbis_comment_init(vorbis_comment *vc){ memset(vc,0,sizeof(*vc)); } @@ -54,6 +55,7 @@ void vorbis_comment_clear(vorbis_comment *vc){ memset(vc,0,sizeof(*vc)); } } +*/ /* blocksize 0 is guaranteed to be short, 1 is guarantted to be long. They may be equal, but short will never ge greater than long */ @@ -141,6 +143,7 @@ static int _vorbis_unpack_info(vorbis_info *vi,oggpack_buffer *opb){ return(OV_EBADHEADER); } +#if 0 static int _vorbis_unpack_comment(vorbis_comment *vc,oggpack_buffer *opb){ int vendorlen; vendorlen=oggpack_read(opb,32); @@ -156,6 +159,7 @@ static int _vorbis_unpack_comment(vorbis_comment *vc,oggpack_buffer *opb){ vorbis_comment_clear(vc); return(OV_EBADHEADER); } +#endif /* all of the real encoding details are here. The modes, books, everything */ @@ -267,9 +271,9 @@ int vorbis_synthesis_idheader(ogg_packet *op){ with bitstream comments and a third packet that holds the codebook. */ -int vorbis_synthesis_headerin(vorbis_info *vi,vorbis_comment *vc,ogg_packet *op){ +int vorbis_synthesis_headerin(vorbis_info *vi,ogg_packet *op){ oggpack_buffer opb; - + if(op){ oggpack_readinit(&opb,op->packet,op->bytes); @@ -303,10 +307,11 @@ int vorbis_synthesis_headerin(vorbis_info *vi,vorbis_comment *vc,ogg_packet *op) return(OV_EBADHEADER); } - return(_vorbis_unpack_comment(vc,&opb)); + /*return(_vorbis_unpack_comment(vc,&opb));*/ + return 0; case 0x05: /* least significant *bit* is read first */ - if(vi->rate==0 || vc->vendor==NULL){ + if(vi->rate==0 /*|| vc->vendor==NULL*/){ /* um... we didn;t get the initial header or comments yet */ return(OV_EBADHEADER); } diff --git a/apps/codecs/libtremor/ivorbiscodec.h b/apps/codecs/libtremor/ivorbiscodec.h index 73ba4aeb2a..4fb041603d 100644 --- a/apps/codecs/libtremor/ivorbiscodec.h +++ b/apps/codecs/libtremor/ivorbiscodec.h @@ -154,20 +154,20 @@ typedef struct vorbis_comment{ extern void vorbis_info_init(vorbis_info *vi); extern void vorbis_info_clear(vorbis_info *vi); extern int vorbis_info_blocksize(vorbis_info *vi,int zo); +/* extern void vorbis_comment_init(vorbis_comment *vc); extern void vorbis_comment_add(vorbis_comment *vc, char *comment); extern void vorbis_comment_add_tag(vorbis_comment *vc, char *tag, char *contents); extern void vorbis_comment_clear(vorbis_comment *vc); - +*/ extern int vorbis_block_init(vorbis_dsp_state *v, vorbis_block *vb); extern int vorbis_block_clear(vorbis_block *vb); extern void vorbis_dsp_clear(vorbis_dsp_state *v); /* Vorbis PRIMITIVES: synthesis layer *******************************/ extern int vorbis_synthesis_idheader(ogg_packet *op); -extern int vorbis_synthesis_headerin(vorbis_info *vi,vorbis_comment *vc, - ogg_packet *op); +extern int vorbis_synthesis_headerin(vorbis_info *vi,ogg_packet *op); extern int vorbis_synthesis_init(vorbis_dsp_state *v,vorbis_info *vi); extern int vorbis_synthesis_restart(vorbis_dsp_state *v); diff --git a/apps/codecs/libtremor/ivorbisfile.h b/apps/codecs/libtremor/ivorbisfile.h index 1aeb0ca84b..076783514e 100644 --- a/apps/codecs/libtremor/ivorbisfile.h +++ b/apps/codecs/libtremor/ivorbisfile.h @@ -66,7 +66,7 @@ typedef struct OggVorbis_File { ogg_uint32_t *serialnos; ogg_int64_t *pcmlengths; vorbis_info *vi; - vorbis_comment *vc; +/* vorbis_comment *vc; */ /* Decoding working state local storage */ ogg_int64_t pcm_offset; diff --git a/apps/codecs/libtremor/ogg.h b/apps/codecs/libtremor/ogg.h index 3ded7fc113..d3af919b85 100644 --- a/apps/codecs/libtremor/ogg.h +++ b/apps/codecs/libtremor/ogg.h @@ -227,6 +227,8 @@ extern int ogg_stream_flush(ogg_stream_state *os, ogg_page *og); #endif /* Ogg BITSTREAM PRIMITIVES: decoding **************************/ +extern int _os_body_expand(ogg_stream_state *os,int needed); + extern int ogg_sync_init(ogg_sync_state *oy); extern int ogg_sync_clear(ogg_sync_state *oy); extern int ogg_sync_reset(ogg_sync_state *oy); @@ -241,7 +243,7 @@ extern long ogg_sync_pageseek(ogg_sync_state *oy,ogg_page *og); /* extern int ogg_sync_pageout(ogg_sync_state *oy, ogg_page *og); */ -extern int ogg_stream_pagein(ogg_stream_state *os, ogg_page *og); +extern int ogg_stream_pagein(ogg_stream_state *os, ogg_page *og, bool copy_body); extern int ogg_stream_packetout(ogg_stream_state *os,ogg_packet *op); extern int ogg_stream_packetpeek(ogg_stream_state *os,ogg_packet *op); 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, } } +/* This is a nasty hack to work around the huge allocations we get from + huge comment packets, usually due to embedded album art */ +static int ogg_stream_discard_packet(OggVorbis_File *vf,ogg_page *og, + ogg_int64_t boundary){ + int ret; + while((ret = ogg_stream_packetout(&vf->os, NULL)) == 0) { + if(_get_next_page(vf, og, boundary)<0) + break; + ogg_stream_pagein(&vf->os,og,false); + } + if (ret < 0) + return -1; + if (vf->os.body_fill < og->body_len) + if(_os_body_expand(&vf->os, og->body_len)) + return -1; + memcpy(vf->os.body_data+vf->os.body_fill-og->body_len, og->body, og->body_len); + return 1; +} + /* find the latest page beginning before the current stream cursor position. Much dirtier than the above as Ogg doesn't have any 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, /* uses the local ogg_stream storage in vf; this is important for non-streaming input sources */ -static int _fetch_headers(OggVorbis_File *vf,vorbis_info *vi,vorbis_comment *vc, +static int _fetch_headers(OggVorbis_File *vf,vorbis_info *vi, ogg_uint32_t **serialno_list, int *serialno_n, ogg_page *og_ptr){ ogg_page og; @@ -288,7 +307,7 @@ static int _fetch_headers(OggVorbis_File *vf,vorbis_info *vi,vorbis_comment *vc, } vorbis_info_init(vi); - vorbis_comment_init(vc); +/* vorbis_comment_init(vc); */ vf->ready_state=OPENED; /* 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, /* we don't have a vorbis stream in this link yet, so begin prospective stream setup. We need a stream to get packets */ ogg_stream_reset_serialno(&vf->os,ogg_page_serialno(og_ptr)); - ogg_stream_pagein(&vf->os,og_ptr); + ogg_stream_pagein(&vf->os,og_ptr,true); if(ogg_stream_packetout(&vf->os,&op) > 0 && vorbis_synthesis_idheader(&op)){ /* vorbis header; continue setup */ vf->ready_state=STREAMSET; - if((ret=vorbis_synthesis_headerin(vi,vc,&op))){ + if((ret=vorbis_synthesis_headerin(vi,&op))){ ret=OV_EBADHEADER; goto bail_header; } @@ -340,7 +359,7 @@ static int _fetch_headers(OggVorbis_File *vf,vorbis_info *vi,vorbis_comment *vc, /* if this page also belongs to our vorbis stream, submit it and break */ if(vf->ready_state==STREAMSET && vf->os.serialno == ogg_page_serialno(og_ptr)){ - ogg_stream_pagein(&vf->os,og_ptr); + ogg_stream_pagein(&vf->os,og_ptr,true); break; } } @@ -354,10 +373,16 @@ static int _fetch_headers(OggVorbis_File *vf,vorbis_info *vi,vorbis_comment *vc, while(1){ i=0; + /* discard comment packet */ + if(ogg_stream_discard_packet(vf,og_ptr,CHUNKSIZE) < 0){ + ret=OV_EBADHEADER; + goto bail_header; + } + i++; + while(i<2){ /* get a page loop */ while(i<2){ /* get a packet loop */ - int result=ogg_stream_packetout(&vf->os,&op); if(result==0)break; if(result==-1){ @@ -365,7 +390,7 @@ static int _fetch_headers(OggVorbis_File *vf,vorbis_info *vi,vorbis_comment *vc, goto bail_header; } - if((ret=vorbis_synthesis_headerin(vi,vc,&op))) + if((ret=vorbis_synthesis_headerin(vi,&op))) goto bail_header; i++; @@ -379,7 +404,7 @@ static int _fetch_headers(OggVorbis_File *vf,vorbis_info *vi,vorbis_comment *vc, /* if this page belongs to the correct stream, go parse it */ if(vf->os.serialno == ogg_page_serialno(og_ptr)){ - ogg_stream_pagein(&vf->os,og_ptr); + ogg_stream_pagein(&vf->os,og_ptr,true); break; } @@ -402,7 +427,7 @@ static int _fetch_headers(OggVorbis_File *vf,vorbis_info *vi,vorbis_comment *vc, bail_header: vorbis_info_clear(vi); - vorbis_comment_clear(vc); +/* vorbis_comment_clear(vc); */ vf->ready_state=OPENED; return ret; @@ -428,7 +453,7 @@ static ogg_int64_t _initial_pcmoffset(OggVorbis_File *vf, vorbis_info *vi){ if(ogg_page_serialno(&og)!= serialno) continue; /* count blocksizes of all frames in the page */ - ogg_stream_pagein(&vf->os,&og); + ogg_stream_pagein(&vf->os,&og,true); while((result=ogg_stream_packetout(&vf->os,&op))){ if(result>0){ /* ignore holes */ long thisblock=vorbis_packet_blocksize(vi,&op); @@ -500,7 +525,7 @@ static int _bisect_forward_serialno(OggVorbis_File *vf, vf->offsets=_ogg_malloc((vf->links+1)*sizeof(*vf->offsets)); vf->vi=_ogg_realloc(vf->vi,vf->links*sizeof(*vf->vi)); - vf->vc=_ogg_realloc(vf->vc,vf->links*sizeof(*vf->vc)); +/* vf->vc=_ogg_realloc(vf->vc,vf->links*sizeof(*vf->vc));*/ vf->serialnos=_ogg_malloc(vf->links*sizeof(*vf->serialnos)); vf->dataoffsets=_ogg_malloc(vf->links*sizeof(*vf->dataoffsets)); vf->pcmlengths=_ogg_malloc(vf->links*2*sizeof(*vf->pcmlengths)); @@ -514,7 +539,7 @@ static int _bisect_forward_serialno(OggVorbis_File *vf, ogg_uint32_t *next_serialno_list=NULL; int next_serialnos=0; vorbis_info vi; - vorbis_comment vc; +/* vorbis_comment vc; */ /* the below guards against garbage seperating the last and first pages of two links. */ @@ -559,7 +584,7 @@ static int _bisect_forward_serialno(OggVorbis_File *vf, if(ret)return(ret); } - ret=_fetch_headers(vf,&vi,&vc,&next_serialno_list,&next_serialnos,NULL); + ret=_fetch_headers(vf,&vi,&next_serialno_list,&next_serialnos,NULL); if(ret)return(ret); serialno = vf->os.serialno; dataoffset = vf->offset; @@ -579,7 +604,7 @@ static int _bisect_forward_serialno(OggVorbis_File *vf, vf->dataoffsets[m+1]=dataoffset; vf->vi[m+1]=vi; - vf->vc[m+1]=vc; +/* vf->vc[m+1]=vc; */ vf->pcmlengths[m*2+1]=searchgran; vf->pcmlengths[m*2+2]=pcmoffset; @@ -789,7 +814,7 @@ static int _fetch_and_process_packet(OggVorbis_File *vf, if(!vf->seekable){ vorbis_info_clear(vf->vi); - vorbis_comment_clear(vf->vc); +/* vorbis_comment_clear(vf->vc); */ } break; @@ -842,7 +867,7 @@ static int _fetch_and_process_packet(OggVorbis_File *vf, /* we're streaming */ /* fetch the three header packets, build the info struct */ - int ret=_fetch_headers(vf,vf->vi,vf->vc,NULL,NULL,&og); + int ret=_fetch_headers(vf,vf->vi,NULL,NULL,&og); if(ret)return(ret); vf->current_serialno=vf->os.serialno; vf->current_link++; @@ -853,7 +878,7 @@ static int _fetch_and_process_packet(OggVorbis_File *vf, /* the buffered page is the data we want, and we're ready for it; add it to the stream state */ - ogg_stream_pagein(&vf->os,&og); + ogg_stream_pagein(&vf->os,&og,true); } } @@ -889,12 +914,12 @@ static int _ov_open1(void *f,OggVorbis_File *vf,const char *initial, entry for partial open */ vf->links=1; vf->vi=_ogg_calloc(vf->links,sizeof(*vf->vi)); - vf->vc=_ogg_calloc(vf->links,sizeof(*vf->vc)); +/* vf->vc=_ogg_calloc(vf->links,sizeof(*vf->vc)); */ ogg_stream_init(&vf->os,-1); /* fill in the serialno later */ /* Fetch all BOS pages, store the vorbis header and all seen serial numbers, load subsequent vorbis setup headers */ - if((ret=_fetch_headers(vf,vf->vi,vf->vc,&serialno_list,&serialno_list_size,NULL))<0){ + if((ret=_fetch_headers(vf,vf->vi,&serialno_list,&serialno_list_size,NULL))<0){ vf->datasource=NULL; ov_clear(vf); }else{ @@ -945,10 +970,10 @@ int ov_clear(OggVorbis_File *vf){ int i; for(i=0;ilinks;i++){ vorbis_info_clear(vf->vi+i); - vorbis_comment_clear(vf->vc+i); +/* vorbis_comment_clear(vf->vc+i); */ } _ogg_free(vf->vi); - _ogg_free(vf->vc); +/* _ogg_free(vf->vc); */ } if(vf->dataoffsets)_ogg_free(vf->dataoffsets); if(vf->pcmlengths)_ogg_free(vf->pcmlengths); @@ -1180,8 +1205,8 @@ int ov_raw_seek(OggVorbis_File *vf,ogg_int64_t pos){ firstflag=(pagepos<=vf->dataoffsets[link]); } - ogg_stream_pagein(&vf->os,&og); - ogg_stream_pagein(&work_os,&og); + ogg_stream_pagein(&vf->os,&og,true); + ogg_stream_pagein(&work_os,&og,true); lastflag=ogg_page_eos(&og); } @@ -1363,7 +1388,7 @@ int ov_pcm_seek_page(OggVorbis_File *vf,ogg_int64_t pos){ } ogg_stream_reset_serialno(&vf->os,vf->current_serialno); - ogg_stream_pagein(&vf->os,&og); + ogg_stream_pagein(&vf->os,&og,true); /* pull out all but last packet; the one with granulepos */ while(1){ @@ -1492,7 +1517,7 @@ int ov_pcm_seek(OggVorbis_File *vf,ogg_int64_t pos){ lastblock=0; } - ogg_stream_pagein(&vf->os,&og); + ogg_stream_pagein(&vf->os,&og,true); } }