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
This commit is contained in:
parent
0a0c3f9763
commit
0bed2be414
5 changed files with 98 additions and 43 deletions
|
@ -14,3 +14,4 @@ synthesis.c
|
|||
vorbisfile.c
|
||||
window.c
|
||||
ctype.c
|
||||
oggmalloc.c
|
||||
|
|
71
apps/codecs/Tremor/oggmalloc.c
Normal file
71
apps/codecs/Tremor/oggmalloc.c
Normal file
|
@ -0,0 +1,71 @@
|
|||
#include <os_types.h>
|
||||
|
||||
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;
|
||||
}
|
|
@ -19,6 +19,9 @@
|
|||
#ifndef _OS_TYPES_H
|
||||
#define _OS_TYPES_H
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <codecs.h>
|
||||
|
||||
#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;
|
||||
|
|
|
@ -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;i<n;i++){
|
||||
|
@ -200,17 +183,12 @@ ogg_int32_t *_book_unquantize(const static_codebook *b,int n,int *sparsemap,
|
|||
int *maxpoint){
|
||||
long j,k,count=0;
|
||||
if(b->maptype==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;i<n;i++){
|
||||
codes[i]=bitreverse(codes[i]);
|
||||
|
@ -395,8 +364,7 @@ int vorbis_book_init_decode(codebook *c,const static_codebook *s){
|
|||
|
||||
qsort(codep,n,sizeof(*codep),sort32a);
|
||||
|
||||
/* sortindex=(int *)alloca(n*sizeof(*sortindex)); */
|
||||
sortindex=sortindex_buffer;
|
||||
sortindex=(int *)ogg_tmpmalloc(n*sizeof(*sortindex));
|
||||
c->codelist=(ogg_uint32_t *)_ogg_malloc(n*sizeof(*c->codelist));
|
||||
/* the index is a reverse index */
|
||||
for(i=0;i<n;i++){
|
||||
|
@ -468,9 +436,10 @@ int vorbis_book_init_decode(codebook *c,const static_codebook *s){
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
ogg_tmpmalloc_free(pos);
|
||||
return(0);
|
||||
err_out:
|
||||
ogg_tmpmalloc_free(pos);
|
||||
vorbis_book_clear(c);
|
||||
return(-1);
|
||||
}
|
||||
|
|
|
@ -130,6 +130,7 @@ next_track:
|
|||
error = CODEC_ERROR;
|
||||
goto exit;
|
||||
}
|
||||
ogg_malloc_init();
|
||||
|
||||
while (!*ci->taginfo_ready && !ci->stop_codec)
|
||||
ci->sleep(1);
|
||||
|
|
Loading…
Reference in a new issue