summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTomasz Malesinski <tomal@rockbox.org>2006-11-26 20:56:26 +0000
committerTomasz Malesinski <tomal@rockbox.org>2006-11-26 20:56:26 +0000
commit0bed2be41427a2dbaa10faa7fbea198a0a5c43a8 (patch)
tree2685d669b2fad93d6bc0a89f17476d93ca49831b
parent0a0c3f97631f4fbc37db7890196a3bbaa910d7b7 (diff)
downloadrockbox-0bed2be41427a2dbaa10faa7fbea198a0a5c43a8.tar.gz
rockbox-0bed2be41427a2dbaa10faa7fbea198a0a5c43a8.zip
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
-rw-r--r--apps/codecs/Tremor/SOURCES1
-rw-r--r--apps/codecs/Tremor/oggmalloc.c71
-rw-r--r--apps/codecs/Tremor/os_types.h21
-rw-r--r--apps/codecs/Tremor/sharedbook.c47
-rw-r--r--apps/codecs/vorbis.c1
5 files changed, 98 insertions, 43 deletions
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
14vorbisfile.c 14vorbisfile.c
15window.c 15window.c
16ctype.c 16ctype.c
17oggmalloc.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 @@
1#include <os_types.h>
2
3static unsigned char *mallocbuf;
4static long bufsize, tmp_ptr, mem_ptr;
5
6void ogg_malloc_init(void)
7{
8 mallocbuf = (unsigned char *)ci->get_codec_memory((size_t *)&bufsize);
9 tmp_ptr = bufsize & ~3;
10 mem_ptr = 0;
11}
12
13void *ogg_malloc(size_t size)
14{
15 void* x;
16
17 if (mem_ptr + (long)size > tmp_ptr)
18 return NULL;
19
20 x = &mallocbuf[mem_ptr];
21 mem_ptr += (size + 3) & ~3; /* Keep memory 32-bit aligned */
22
23 return x;
24}
25
26void *ogg_tmpmalloc(size_t size)
27{
28 if (mem_ptr + (long)size > tmp_ptr)
29 return NULL;
30
31 tmp_ptr -= (size + 3) & ~3;
32 return &mallocbuf[tmp_ptr];
33}
34
35void *ogg_calloc(size_t nmemb, size_t size)
36{
37 void *x;
38 x = ogg_malloc(nmemb * size);
39 if (x == NULL)
40 return NULL;
41 ci->memset(x, 0, nmemb * size);
42 return x;
43}
44
45void *ogg_tmpcalloc(size_t nmemb, size_t size)
46{
47 void *x;
48 x = ogg_tmpmalloc(nmemb * size);
49 if (x == NULL)
50 return NULL;
51 ci->memset(x, 0, nmemb * size);
52 return x;
53}
54
55void *ogg_realloc(void *ptr, size_t size)
56{
57 void *x;
58 (void)ptr;
59 x = ogg_malloc(size);
60 return x;
61}
62
63long ogg_tmpmalloc_pos(void)
64{
65 return tmp_ptr;
66}
67
68void ogg_tmpmalloc_free(long pos)
69{
70 tmp_ptr = pos;
71}
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 @@
19#ifndef _OS_TYPES_H 19#ifndef _OS_TYPES_H
20#define _OS_TYPES_H 20#define _OS_TYPES_H
21 21
22#include <stdlib.h>
23#include <codecs.h>
24
22#ifdef _LOW_ACCURACY_ 25#ifdef _LOW_ACCURACY_
23# define X(n) (((((n)>>22)+1)>>1) - ((((n)>>22)+1)>>9)) 26# define X(n) (((((n)>>22)+1)>>1) - ((((n)>>22)+1)>>9))
24# define LOOKUP_T const unsigned char 27# define LOOKUP_T const unsigned char
@@ -29,10 +32,20 @@
29 32
30/* make it easy on the folks that want to compile the libs with a 33/* make it easy on the folks that want to compile the libs with a
31 different malloc than stdlib */ 34 different malloc than stdlib */
32#define _ogg_malloc malloc 35
33#define _ogg_calloc calloc 36#define _ogg_malloc ogg_malloc
34#define _ogg_realloc realloc 37#define _ogg_calloc ogg_calloc
35#define _ogg_free free 38#define _ogg_realloc ogg_realloc
39#define _ogg_free(x) do { } while(0)
40
41void ogg_malloc_init(void);
42void *ogg_malloc(size_t size);
43void *ogg_tmpmalloc(size_t size);
44void *ogg_calloc(size_t nmemb, size_t size);
45void *ogg_tmpcalloc(size_t nmemb, size_t size);
46void *ogg_realloc(void *ptr, size_t size);
47long ogg_tmpmalloc_pos(void);
48void ogg_tmpmalloc_free(long pos);
36 49
37 typedef short ogg_int16_t; 50 typedef short ogg_int16_t;
38 typedef int ogg_int32_t; 51 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 @@
24#include "ivorbiscodec.h" 24#include "ivorbiscodec.h"
25#include "codebook.h" 25#include "codebook.h"
26 26
27/* Size (in number of entries) for static buffers in book_init_decode, so
28 * that large alloca() calls can be avoided, which is needed in Rockbox.
29 * This is more than enough for one certain test file (which needs 6561
30 * entries)...
31 */
32#define BOOK_INIT_MAXSIZE 8192
33
34/* Max value in static_codebook.dim we expect to find in _book_unquantize.
35 * Used to avoid some temporary allocations. Again, enough for some test
36 * files...
37 */
38#define BOOK_DIM_MAX 4
39
40/**** pack/unpack helpers ******************************************/ 27/**** pack/unpack helpers ******************************************/
41int _ilog(unsigned int v){ 28int _ilog(unsigned int v){
42 int ret=0; 29 int ret=0;
@@ -84,11 +71,7 @@ static ogg_int32_t _float32_unpack(long val,int *point){
84ogg_uint32_t *_make_words(long *l,long n,long sparsecount){ 71ogg_uint32_t *_make_words(long *l,long n,long sparsecount){
85 long i,j,count=0; 72 long i,j,count=0;
86 ogg_uint32_t marker[33]; 73 ogg_uint32_t marker[33];
87 /* Avoid temporary malloc; _make_words is only called from 74 ogg_uint32_t *r=(ogg_uint32_t *)ogg_tmpmalloc((sparsecount?sparsecount:n)*sizeof(*r));
88 * vorbis_book_init_decode, and the result is only used for a short while.
89 */
90 static ogg_uint32_t r[BOOK_INIT_MAXSIZE];
91 /* ogg_uint32_t *r=(ogg_uint32_t *)_ogg_malloc((sparsecount?sparsecount:n)*sizeof(*r)); */
92 memset(marker,0,sizeof(marker)); 75 memset(marker,0,sizeof(marker));
93 76
94 for(i=0;i<n;i++){ 77 for(i=0;i<n;i++){
@@ -200,17 +183,12 @@ ogg_int32_t *_book_unquantize(const static_codebook *b,int n,int *sparsemap,
200 int *maxpoint){ 183 int *maxpoint){
201 long j,k,count=0; 184 long j,k,count=0;
202 if(b->maptype==1 || b->maptype==2){ 185 if(b->maptype==1 || b->maptype==2){
203 /* Static buffer to avoid temporary calloc, which Rockbox (currently)
204 * doesn't handle well
205 */
206 static int rp_buffer[BOOK_INIT_MAXSIZE*BOOK_DIM_MAX];
207 int quantvals; 186 int quantvals;
208 int minpoint,delpoint; 187 int minpoint,delpoint;
209 ogg_int32_t mindel=_float32_unpack(b->q_min,&minpoint); 188 ogg_int32_t mindel=_float32_unpack(b->q_min,&minpoint);
210 ogg_int32_t delta=_float32_unpack(b->q_delta,&delpoint); 189 ogg_int32_t delta=_float32_unpack(b->q_delta,&delpoint);
211 ogg_int32_t *r=(ogg_int32_t *)_ogg_calloc(n*b->dim,sizeof(*r)); 190 ogg_int32_t *r=(ogg_int32_t *)_ogg_calloc(n*b->dim,sizeof(*r));
212 /* int *rp=(int *)_ogg_calloc(n*b->dim,sizeof(*rp)); */ 191 int *rp=(int *)ogg_tmpcalloc(n*b->dim,sizeof(*rp));
213 int* rp=rp_buffer;
214 192
215 memset(rp, 0, n*b->dim*sizeof(*rp)); 193 memset(rp, 0, n*b->dim*sizeof(*rp));
216 *maxpoint=minpoint; 194 *maxpoint=minpoint;
@@ -347,6 +325,7 @@ static int sort32a(const void *a,const void *b){
347int vorbis_book_init_decode(codebook *c,const static_codebook *s){ 325int vorbis_book_init_decode(codebook *c,const static_codebook *s){
348 int i,j,n=0,tabn; 326 int i,j,n=0,tabn;
349 int *sortindex; 327 int *sortindex;
328 long pos = ogg_tmpmalloc_pos();
350 memset(c,0,sizeof(*c)); 329 memset(c,0,sizeof(*c));
351 330
352 /* count actually used entries */ 331 /* count actually used entries */
@@ -372,21 +351,11 @@ int vorbis_book_init_decode(codebook *c,const static_codebook *s){
372 by sorted bitreversed codeword to allow treeless decode. */ 351 by sorted bitreversed codeword to allow treeless decode. */
373 352
374 { 353 {
375 /* Static buffers to avoid heavy stack usage */
376 static int sortindex_buffer[BOOK_INIT_MAXSIZE];
377 static ogg_uint32_t* codep_buffer[BOOK_INIT_MAXSIZE];
378
379 /* perform sort */ 354 /* perform sort */
380 ogg_uint32_t *codes=_make_words(s->lengthlist,s->entries,c->used_entries); 355 ogg_uint32_t *codes=_make_words(s->lengthlist,s->entries,c->used_entries);
381 /* ogg_uint32_t **codep=(ogg_uint32_t **)alloca(sizeof(*codep)*n); */ 356 ogg_uint32_t **codep=(ogg_uint32_t **)ogg_tmpmalloc(sizeof(*codep)*n);
382 ogg_uint32_t **codep=codep_buffer;
383 357
384 /* We have buffers for these sizes */ 358 if(codes==NULL||codep==NULL)goto err_out;
385 if ((n>BOOK_INIT_MAXSIZE)
386 || (n*s->dim>BOOK_INIT_MAXSIZE*BOOK_DIM_MAX))
387 goto err_out;
388
389 if(codes==NULL)goto err_out;
390 359
391 for(i=0;i<n;i++){ 360 for(i=0;i<n;i++){
392 codes[i]=bitreverse(codes[i]); 361 codes[i]=bitreverse(codes[i]);
@@ -395,8 +364,7 @@ int vorbis_book_init_decode(codebook *c,const static_codebook *s){
395 364
396 qsort(codep,n,sizeof(*codep),sort32a); 365 qsort(codep,n,sizeof(*codep),sort32a);
397 366
398 /* sortindex=(int *)alloca(n*sizeof(*sortindex)); */ 367 sortindex=(int *)ogg_tmpmalloc(n*sizeof(*sortindex));
399 sortindex=sortindex_buffer;
400 c->codelist=(ogg_uint32_t *)_ogg_malloc(n*sizeof(*c->codelist)); 368 c->codelist=(ogg_uint32_t *)_ogg_malloc(n*sizeof(*c->codelist));
401 /* the index is a reverse index */ 369 /* the index is a reverse index */
402 for(i=0;i<n;i++){ 370 for(i=0;i<n;i++){
@@ -468,9 +436,10 @@ int vorbis_book_init_decode(codebook *c,const static_codebook *s){
468 } 436 }
469 } 437 }
470 438
471 439 ogg_tmpmalloc_free(pos);
472 return(0); 440 return(0);
473 err_out: 441 err_out:
442 ogg_tmpmalloc_free(pos);
474 vorbis_book_clear(c); 443 vorbis_book_clear(c);
475 return(-1); 444 return(-1);
476} 445}
diff --git a/apps/codecs/vorbis.c b/apps/codecs/vorbis.c
index ca4aa9dd12..a6a90654b5 100644
--- a/apps/codecs/vorbis.c
+++ b/apps/codecs/vorbis.c
@@ -130,6 +130,7 @@ next_track:
130 error = CODEC_ERROR; 130 error = CODEC_ERROR;
131 goto exit; 131 goto exit;
132 } 132 }
133 ogg_malloc_init();
133 134
134 while (!*ci->taginfo_ready && !ci->stop_codec) 135 while (!*ci->taginfo_ready && !ci->stop_codec)
135 ci->sleep(1); 136 ci->sleep(1);