From 0bed2be41427a2dbaa10faa7fbea198a0a5c43a8 Mon Sep 17 00:00:00 2001 From: Tomasz Malesinski Date: Sun, 26 Nov 2006 20:56:26 +0000 Subject: FS#6357, patch 3: implemented simple temporary malloc for the Vorbis decoder. git-svn-id: svn://svn.rockbox.org/rockbox/trunk@11610 a1c6a512-1295-4272-9138-f99709370657 --- apps/codecs/Tremor/SOURCES | 1 + apps/codecs/Tremor/oggmalloc.c | 71 +++++++++++++++++++++++++++++++++++++++++ apps/codecs/Tremor/os_types.h | 21 +++++++++--- apps/codecs/Tremor/sharedbook.c | 47 +++++---------------------- apps/codecs/vorbis.c | 1 + 5 files changed, 98 insertions(+), 43 deletions(-) create mode 100644 apps/codecs/Tremor/oggmalloc.c diff --git a/apps/codecs/Tremor/SOURCES b/apps/codecs/Tremor/SOURCES index 51b54cf6cd..0877941808 100644 --- a/apps/codecs/Tremor/SOURCES +++ b/apps/codecs/Tremor/SOURCES @@ -14,3 +14,4 @@ synthesis.c vorbisfile.c window.c ctype.c +oggmalloc.c diff --git a/apps/codecs/Tremor/oggmalloc.c b/apps/codecs/Tremor/oggmalloc.c new file mode 100644 index 0000000000..eae3d3f1ee --- /dev/null +++ b/apps/codecs/Tremor/oggmalloc.c @@ -0,0 +1,71 @@ +#include + +static unsigned char *mallocbuf; +static long bufsize, tmp_ptr, mem_ptr; + +void ogg_malloc_init(void) +{ + mallocbuf = (unsigned char *)ci->get_codec_memory((size_t *)&bufsize); + tmp_ptr = bufsize & ~3; + mem_ptr = 0; +} + +void *ogg_malloc(size_t size) +{ + void* x; + + if (mem_ptr + (long)size > tmp_ptr) + return NULL; + + x = &mallocbuf[mem_ptr]; + mem_ptr += (size + 3) & ~3; /* Keep memory 32-bit aligned */ + + return x; +} + +void *ogg_tmpmalloc(size_t size) +{ + if (mem_ptr + (long)size > tmp_ptr) + return NULL; + + tmp_ptr -= (size + 3) & ~3; + return &mallocbuf[tmp_ptr]; +} + +void *ogg_calloc(size_t nmemb, size_t size) +{ + void *x; + x = ogg_malloc(nmemb * size); + if (x == NULL) + return NULL; + ci->memset(x, 0, nmemb * size); + return x; +} + +void *ogg_tmpcalloc(size_t nmemb, size_t size) +{ + void *x; + x = ogg_tmpmalloc(nmemb * size); + if (x == NULL) + return NULL; + ci->memset(x, 0, nmemb * size); + return x; +} + +void *ogg_realloc(void *ptr, size_t size) +{ + void *x; + (void)ptr; + x = ogg_malloc(size); + return x; +} + +long ogg_tmpmalloc_pos(void) +{ + return tmp_ptr; +} + +void ogg_tmpmalloc_free(long pos) +{ + tmp_ptr = pos; +} diff --git a/apps/codecs/Tremor/os_types.h b/apps/codecs/Tremor/os_types.h index 1e0cb1332f..5738ef4911 100644 --- a/apps/codecs/Tremor/os_types.h +++ b/apps/codecs/Tremor/os_types.h @@ -19,6 +19,9 @@ #ifndef _OS_TYPES_H #define _OS_TYPES_H +#include +#include + #ifdef _LOW_ACCURACY_ # define X(n) (((((n)>>22)+1)>>1) - ((((n)>>22)+1)>>9)) # define LOOKUP_T const unsigned char @@ -29,10 +32,20 @@ /* make it easy on the folks that want to compile the libs with a different malloc than stdlib */ -#define _ogg_malloc malloc -#define _ogg_calloc calloc -#define _ogg_realloc realloc -#define _ogg_free free + +#define _ogg_malloc ogg_malloc +#define _ogg_calloc ogg_calloc +#define _ogg_realloc ogg_realloc +#define _ogg_free(x) do { } while(0) + +void ogg_malloc_init(void); +void *ogg_malloc(size_t size); +void *ogg_tmpmalloc(size_t size); +void *ogg_calloc(size_t nmemb, size_t size); +void *ogg_tmpcalloc(size_t nmemb, size_t size); +void *ogg_realloc(void *ptr, size_t size); +long ogg_tmpmalloc_pos(void); +void ogg_tmpmalloc_free(long pos); typedef short ogg_int16_t; typedef int ogg_int32_t; diff --git a/apps/codecs/Tremor/sharedbook.c b/apps/codecs/Tremor/sharedbook.c index d77c0c1275..c58ae55984 100644 --- a/apps/codecs/Tremor/sharedbook.c +++ b/apps/codecs/Tremor/sharedbook.c @@ -24,19 +24,6 @@ #include "ivorbiscodec.h" #include "codebook.h" -/* Size (in number of entries) for static buffers in book_init_decode, so - * that large alloca() calls can be avoided, which is needed in Rockbox. - * This is more than enough for one certain test file (which needs 6561 - * entries)... - */ -#define BOOK_INIT_MAXSIZE 8192 - -/* Max value in static_codebook.dim we expect to find in _book_unquantize. - * Used to avoid some temporary allocations. Again, enough for some test - * files... - */ -#define BOOK_DIM_MAX 4 - /**** pack/unpack helpers ******************************************/ int _ilog(unsigned int v){ int ret=0; @@ -84,11 +71,7 @@ static ogg_int32_t _float32_unpack(long val,int *point){ ogg_uint32_t *_make_words(long *l,long n,long sparsecount){ long i,j,count=0; ogg_uint32_t marker[33]; - /* Avoid temporary malloc; _make_words is only called from - * vorbis_book_init_decode, and the result is only used for a short while. - */ - static ogg_uint32_t r[BOOK_INIT_MAXSIZE]; - /* ogg_uint32_t *r=(ogg_uint32_t *)_ogg_malloc((sparsecount?sparsecount:n)*sizeof(*r)); */ + ogg_uint32_t *r=(ogg_uint32_t *)ogg_tmpmalloc((sparsecount?sparsecount:n)*sizeof(*r)); memset(marker,0,sizeof(marker)); for(i=0;imaptype==1 || b->maptype==2){ - /* Static buffer to avoid temporary calloc, which Rockbox (currently) - * doesn't handle well - */ - static int rp_buffer[BOOK_INIT_MAXSIZE*BOOK_DIM_MAX]; int quantvals; int minpoint,delpoint; ogg_int32_t mindel=_float32_unpack(b->q_min,&minpoint); ogg_int32_t delta=_float32_unpack(b->q_delta,&delpoint); ogg_int32_t *r=(ogg_int32_t *)_ogg_calloc(n*b->dim,sizeof(*r)); - /* int *rp=(int *)_ogg_calloc(n*b->dim,sizeof(*rp)); */ - int* rp=rp_buffer; + int *rp=(int *)ogg_tmpcalloc(n*b->dim,sizeof(*rp)); memset(rp, 0, n*b->dim*sizeof(*rp)); *maxpoint=minpoint; @@ -347,6 +325,7 @@ static int sort32a(const void *a,const void *b){ int vorbis_book_init_decode(codebook *c,const static_codebook *s){ int i,j,n=0,tabn; int *sortindex; + long pos = ogg_tmpmalloc_pos(); memset(c,0,sizeof(*c)); /* count actually used entries */ @@ -372,21 +351,11 @@ int vorbis_book_init_decode(codebook *c,const static_codebook *s){ by sorted bitreversed codeword to allow treeless decode. */ { - /* Static buffers to avoid heavy stack usage */ - static int sortindex_buffer[BOOK_INIT_MAXSIZE]; - static ogg_uint32_t* codep_buffer[BOOK_INIT_MAXSIZE]; - /* perform sort */ ogg_uint32_t *codes=_make_words(s->lengthlist,s->entries,c->used_entries); - /* ogg_uint32_t **codep=(ogg_uint32_t **)alloca(sizeof(*codep)*n); */ - ogg_uint32_t **codep=codep_buffer; + ogg_uint32_t **codep=(ogg_uint32_t **)ogg_tmpmalloc(sizeof(*codep)*n); - /* We have buffers for these sizes */ - if ((n>BOOK_INIT_MAXSIZE) - || (n*s->dim>BOOK_INIT_MAXSIZE*BOOK_DIM_MAX)) - goto err_out; - - if(codes==NULL)goto err_out; + if(codes==NULL||codep==NULL)goto err_out; for(i=0;icodelist=(ogg_uint32_t *)_ogg_malloc(n*sizeof(*c->codelist)); /* the index is a reverse index */ for(i=0;itaginfo_ready && !ci->stop_codec) ci->sleep(1); -- cgit v1.2.3