summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNils Wallménius <nils@rockbox.org>2011-06-06 13:27:12 +0000
committerNils Wallménius <nils@rockbox.org>2011-06-06 13:27:12 +0000
commite62b9a9aaee94d18550a1788b910d023bc257a89 (patch)
tree3fb054717bdb0995ec5323cd178e7d65d7597b20
parent684b74147f203662fb6767f65b4ca8fc9b8eeeac (diff)
downloadrockbox-e62b9a9aaee94d18550a1788b910d023bc257a89.tar.gz
rockbox-e62b9a9aaee94d18550a1788b910d023bc257a89.zip
libtremor: Implement a memory configuration for targets that don't use separate iram for codecs.
Such targets would previously default to using the configuration for targets with small iram which uses an extra memcpy per block. This saves 2MHz decoding a 128kbps vorbis file on the Gigabeat S and saves a bit of codec buffer. Patch from FS#11268, also replaces patch from FS#12147. git-svn-id: svn://svn.rockbox.org/rockbox/trunk@29976 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r--apps/codecs/libtremor/block.c94
-rw-r--r--apps/codecs/libtremor/config-tremor.h9
-rw-r--r--apps/codecs/libtremor/ivorbiscodec.h2
-rw-r--r--apps/codecs/libtremor/oggmalloc.c2
4 files changed, 67 insertions, 40 deletions
diff --git a/apps/codecs/libtremor/block.c b/apps/codecs/libtremor/block.c
index b88896dd15..d678719cbe 100644
--- a/apps/codecs/libtremor/block.c
+++ b/apps/codecs/libtremor/block.c
@@ -40,8 +40,8 @@ static int ilog(unsigned int v){
40static ogg_int32_t* _pcmp [CHANNELS] IBSS_ATTR; 40static ogg_int32_t* _pcmp [CHANNELS] IBSS_ATTR;
41static ogg_int32_t* _pcmbp[CHANNELS] IBSS_ATTR; 41static ogg_int32_t* _pcmbp[CHANNELS] IBSS_ATTR;
42static ogg_int32_t* _pcmret[CHANNELS] IBSS_ATTR; 42static ogg_int32_t* _pcmret[CHANNELS] IBSS_ATTR;
43/* save original pointer returned by malloc so we can free it easily */ 43/* save original pointers returned by malloc so we can free it easily */
44static ogg_int32_t* _first_pcm = NULL; 44static ogg_int32_t* pcm_copy[CHANNELS] = {NULL};
45 45
46/* pcm accumulator examples (not exhaustive): 46/* pcm accumulator examples (not exhaustive):
47 47
@@ -165,18 +165,21 @@ static int _vds_init(vorbis_dsp_state *v,vorbis_info *vi){
165 165
166 v->vi=vi; 166 v->vi=vi;
167 b->modebits=ilog(ci->modes); 167 b->modebits=ilog(ci->modes);
168 168
169#ifdef TREMOR_USE_IRAM
169 /* allocate IRAM buffer for the PCM data generated by synthesis */ 170 /* allocate IRAM buffer for the PCM data generated by synthesis */
170 iram_malloc_init(); 171 iram_malloc_init();
171 v->first_pcm = iram_malloc(vi->channels*ci->blocksizes[1]*sizeof(ogg_int32_t)); 172 v->first_pcm = iram_malloc(vi->channels*ci->blocksizes[1]*sizeof(ogg_int32_t));
172 /* when can't allocate IRAM buffer, allocate normal RAM buffer */ 173 /* when can't allocate IRAM buffer, allocate normal RAM buffer */
173 if(v->first_pcm == NULL){ 174 if(v->first_pcm == NULL)
174 _first_pcm = _ogg_malloc(vi->channels*ci->blocksizes[1]*sizeof(ogg_int32_t)); 175#endif
175 v->first_pcm= _first_pcm; 176 {
177 pcm_copy[0] = _ogg_malloc(vi->channels*ci->blocksizes[1]*sizeof(ogg_int32_t));
178 v->first_pcm = pcm_copy[0];
176 } 179 }
177 180
178 v->centerW=0; 181 v->centerW=0;
179 182
180 /* Vorbis I uses only window type 0 */ 183 /* Vorbis I uses only window type 0 */
181 b_size[0]=ci->blocksizes[0]/2; 184 b_size[0]=ci->blocksizes[0]/2;
182 b_size[1]=ci->blocksizes[1]/2; 185 b_size[1]=ci->blocksizes[1]/2;
@@ -222,6 +225,8 @@ static int _vds_init(vorbis_dsp_state *v,vorbis_info *vi){
222 _pcmp[1]=NULL; 225 _pcmp[1]=NULL;
223 _pcmbp[0]=NULL; 226 _pcmbp[0]=NULL;
224 _pcmbp[1]=NULL; 227 _pcmbp[1]=NULL;
228
229#ifdef TREMOR_USE_IRAM
225 if(NULL != (v->iram_double_pcm = iram_malloc(vi->channels*v->pcm_storage*sizeof(ogg_int32_t)))) 230 if(NULL != (v->iram_double_pcm = iram_malloc(vi->channels*v->pcm_storage*sizeof(ogg_int32_t))))
226 { 231 {
227 /* one-time initialisation at codec start or on switch from 232 /* one-time initialisation at codec start or on switch from
@@ -230,12 +235,15 @@ static int _vds_init(vorbis_dsp_state *v,vorbis_info *vi){
230 v->pcm[i]=&v->iram_double_pcm[i*v->pcm_storage]; 235 v->pcm[i]=&v->iram_double_pcm[i*v->pcm_storage];
231 } 236 }
232 else 237 else
238#endif
233 { 239 {
234 /* one-time initialisation at codec start or on switch from 240 /* one-time initialisation at codec start or on switch from
235 blocksizes that fit in IRAM_PCM_END to those that don't */ 241 blocksizes that fit in IRAM_PCM_END to those that don't */
242 /* save copy of the pointer so we can free it easily later */
243 pcm_copy[1] = _ogg_calloc(vi->channels*v->pcm_storage,sizeof(*v->pcm[i]));
236 for(i=0;i<vi->channels;i++) 244 for(i=0;i<vi->channels;i++)
237 v->pcm[i]=(ogg_int32_t *)_ogg_calloc(v->pcm_storage,sizeof(*v->pcm[i])); 245 v->pcm[i] = pcm_copy[1]+i*v->pcm_storage;
238 } 246 }
239 247
240 /* all 1 (large block) or 0 (small block) */ 248 /* all 1 (large block) or 0 (small block) */
241 /* explicitly set for the sake of clarity */ 249 /* explicitly set for the sake of clarity */
@@ -285,10 +293,16 @@ int vorbis_synthesis_restart(vorbis_dsp_state *v){
285 (if we're using double pcm buffer) and will need to reset them */ 293 (if we're using double pcm buffer) and will need to reset them */
286 v->reset_pcmb = true; 294 v->reset_pcmb = true;
287 /* also reset our copy of the double buffer pointers if we have one */ 295 /* also reset our copy of the double buffer pointers if we have one */
296#ifdef TREMOR_USE_IRAM
288 if(v->iram_double_pcm) 297 if(v->iram_double_pcm)
298 {
289 for(i=0;i<vi->channels;i++) 299 for(i=0;i<vi->channels;i++)
290 v->pcm[i]=&v->iram_double_pcm[i*v->pcm_storage]; 300 v->pcm[i]=&v->iram_double_pcm[i*v->pcm_storage];
291 301 }
302#else
303 for(i=0;i<vi->channels;i++)
304 v->pcm[i] = pcm_copy[1]+i*v->pcm_storage;
305#endif
292 return(0); 306 return(0);
293} 307}
294 308
@@ -306,14 +320,15 @@ void vorbis_dsp_clear(vorbis_dsp_state *v){
306 codec_setup_info *ci=(codec_setup_info *)(vi?vi->codec_setup:NULL); 320 codec_setup_info *ci=(codec_setup_info *)(vi?vi->codec_setup:NULL);
307 private_state *b=(private_state *)v->backend_state; 321 private_state *b=(private_state *)v->backend_state;
308 322
309 if(_first_pcm != NULL) 323 if(vi != NULL)
310 _ogg_free(_first_pcm);
311
312 if(NULL == v->iram_double_pcm && vi != NULL)
313 { 324 {
314 /* pcm buffer came from oggmalloc rather than iram */ 325 /* pcm buffer came from oggmalloc rather than iram */
315 for(i=0;i<vi->channels;i++) 326 for(i=0;i<2;i++)
316 if(v->pcm[i])_ogg_free(v->pcm[i]); 327 if(pcm_copy[i])
328 {
329 _ogg_free(pcm_copy[i]);
330 pcm_copy[i] = NULL;
331 }
317 } 332 }
318 333
319 /* free mode lookups; these are actually vorbis_look_mapping structs */ 334 /* free mode lookups; these are actually vorbis_look_mapping structs */
@@ -345,7 +360,9 @@ int vorbis_synthesis_blockin(vorbis_dsp_state *v,vorbis_block *vb){
345 codec_setup_info *ci=(codec_setup_info *)vi->codec_setup; 360 codec_setup_info *ci=(codec_setup_info *)vi->codec_setup;
346 private_state *b=v->backend_state; 361 private_state *b=v->backend_state;
347 int j; 362 int j;
363#ifdef TREMOR_USE_IRAM
348 bool iram_pcm_doublebuffer = (NULL != v->iram_double_pcm); 364 bool iram_pcm_doublebuffer = (NULL != v->iram_double_pcm);
365#endif
349 366
350 if(v->pcm_current>v->pcm_returned && v->pcm_returned!=-1)return(OV_EINVAL); 367 if(v->pcm_current>v->pcm_returned && v->pcm_returned!=-1)return(OV_EINVAL);
351 368
@@ -369,16 +386,16 @@ int vorbis_synthesis_blockin(vorbis_dsp_state *v,vorbis_block *vb){
369 int n0=ci->blocksizes[0]/2; 386 int n0=ci->blocksizes[0]/2;
370 int n1=ci->blocksizes[1]/2; 387 int n1=ci->blocksizes[1]/2;
371 388
372 if(iram_pcm_doublebuffer) 389#ifdef TREMOR_USE_IRAM
373 { 390 if(!iram_pcm_doublebuffer)
374 prevCenter = ln;
375 }
376 else
377 { 391 {
378 prevCenter = v->centerW; 392 prevCenter = v->centerW;
379 v->centerW = n1 - v->centerW; 393 v->centerW = n1 - v->centerW;
380 } 394 }
381 395 else
396#endif
397 prevCenter = ln;
398
382 /* overlap/add PCM */ 399 /* overlap/add PCM */
383 /* nb nothing to overlap with on first block so don't bother */ 400 /* nb nothing to overlap with on first block so don't bother */
384 if(LIKELY(v->pcm_returned!=-1)) 401 if(LIKELY(v->pcm_returned!=-1))
@@ -410,20 +427,9 @@ int vorbis_synthesis_blockin(vorbis_dsp_state *v,vorbis_block *vb){
410 } 427 }
411 } 428 }
412 } 429 }
413 430#ifdef TREMOR_USE_IRAM
414 /* the copy section */ 431 /* the copy section */
415 if(iram_pcm_doublebuffer) 432 if(!iram_pcm_doublebuffer)
416 {
417 /* just flip the pointers over as we have a double buffer in iram */
418 ogg_int32_t *p;
419 p=v->pcm[0];
420 v->pcm[0]=vb->pcm[0];
421 vb->pcm[0] = p;
422 p=v->pcm[1];
423 v->pcm[1]=vb->pcm[1];
424 vb->pcm[1] = p;
425 }
426 else
427 { 433 {
428 for(j=0;j<vi->channels;j++) 434 for(j=0;j<vi->channels;j++)
429 { 435 {
@@ -434,7 +440,19 @@ int vorbis_synthesis_blockin(vorbis_dsp_state *v,vorbis_block *vb){
434 vect_copy(v->pcm[j]+v->centerW, vb->pcm[j]+n, n); 440 vect_copy(v->pcm[j]+v->centerW, vb->pcm[j]+n, n);
435 } 441 }
436 } 442 }
437 443 else
444#endif
445 {
446 /* just flip the pointers over as we have a double buffer in iram */
447 ogg_int32_t *p;
448 p=v->pcm[0];
449 v->pcm[0]=vb->pcm[0];
450 vb->pcm[0] = p;
451 p=v->pcm[1];
452 v->pcm[1]=vb->pcm[1];
453 vb->pcm[1] = p;
454 }
455
438 /* deal with initial packet state; we do this using the explicit 456 /* deal with initial packet state; we do this using the explicit
439 pcm_returned==-1 flag otherwise we're sensitive to first block 457 pcm_returned==-1 flag otherwise we're sensitive to first block
440 being short or long */ 458 being short or long */
@@ -448,7 +466,7 @@ int vorbis_synthesis_blockin(vorbis_dsp_state *v,vorbis_block *vb){
448 } 466 }
449 467
450 } 468 }
451 469
452 /* track the frame number... This is for convenience, but also 470 /* track the frame number... This is for convenience, but also
453 making sure our last packet doesn't end with added padding. If 471 making sure our last packet doesn't end with added padding. If
454 the last packet is partial, the number of samples we'll have to 472 the last packet is partial, the number of samples we'll have to
diff --git a/apps/codecs/libtremor/config-tremor.h b/apps/codecs/libtremor/config-tremor.h
index 2f93072d63..eba0fe0912 100644
--- a/apps/codecs/libtremor/config-tremor.h
+++ b/apps/codecs/libtremor/config-tremor.h
@@ -23,9 +23,13 @@
23#define ICODE_ATTR_TREMOR_NOT_MDCT ICODE_ATTR 23#define ICODE_ATTR_TREMOR_NOT_MDCT ICODE_ATTR
24#endif 24#endif
25 25
26/* Enable special handling of buffers in faster ram, not usefull when no
27 such different ram is available. There are 3 different memory configurations
28 * No special iram, uses double buffers to avoid copying data
29 * Small special iram, copies buffers to run hottest processing in iram
30 * Large iram, uses double buffers in iram */
26#ifdef USE_IRAM 31#ifdef USE_IRAM
27#define TREMOR_USE_IRAM 32#define TREMOR_USE_IRAM
28#endif
29 33
30/* Define CPU of large IRAM (PP5022/5024, MCF5250) */ 34/* Define CPU of large IRAM (PP5022/5024, MCF5250) */
31#if (CONFIG_CPU == PP5022) || (CONFIG_CPU == PP5024) || defined(CPU_S5L870X) || (CONFIG_CPU == MCF5250) 35#if (CONFIG_CPU == PP5022) || (CONFIG_CPU == PP5024) || defined(CPU_S5L870X) || (CONFIG_CPU == MCF5250)
@@ -34,13 +38,14 @@
34 * TOTAL : 41984 */ 38 * TOTAL : 41984 */
35#define IRAM_IBSS_SIZE 41984 39#define IRAM_IBSS_SIZE 41984
36 40
37/* Define CPU of Normal IRAM (96KB) (and SIM also) */ 41/* Define CPU of Normal IRAM (96KB) */
38#else 42#else
39/* PCM_BUFFER : 16384 Byte (2048*2*4) * 43/* PCM_BUFFER : 16384 Byte (2048*2*4) *
40 * WINDOW_LOOKUP : 4608 Byte (128*4 + 1024*4) * 44 * WINDOW_LOOKUP : 4608 Byte (128*4 + 1024*4) *
41 * TOTAL : 20992 */ 45 * TOTAL : 20992 */
42#define IRAM_IBSS_SIZE 20992 46#define IRAM_IBSS_SIZE 20992
43#endif 47#endif
48#endif
44 49
45/* max 2 channels */ 50/* max 2 channels */
46#define CHANNELS 2 51#define CHANNELS 2
diff --git a/apps/codecs/libtremor/ivorbiscodec.h b/apps/codecs/libtremor/ivorbiscodec.h
index 5bc33aaea5..23b62c48bd 100644
--- a/apps/codecs/libtremor/ivorbiscodec.h
+++ b/apps/codecs/libtremor/ivorbiscodec.h
@@ -79,7 +79,9 @@ typedef struct vorbis_dsp_state{
79 void *backend_state; 79 void *backend_state;
80 80
81 ogg_int32_t *first_pcm; /* PCM buffer (for normal RAM or IRAM)*/ 81 ogg_int32_t *first_pcm; /* PCM buffer (for normal RAM or IRAM)*/
82#ifdef TREMOR_USE_IRAM
82 ogg_int32_t *iram_double_pcm; /* PCM 2nd buffer for IRAM */ 83 ogg_int32_t *iram_double_pcm; /* PCM 2nd buffer for IRAM */
84#endif
83 bool reset_pcmb; 85 bool reset_pcmb;
84} vorbis_dsp_state; 86} vorbis_dsp_state;
85 87
diff --git a/apps/codecs/libtremor/oggmalloc.c b/apps/codecs/libtremor/oggmalloc.c
index 3a5fecf910..dd7fd5b69d 100644
--- a/apps/codecs/libtremor/oggmalloc.c
+++ b/apps/codecs/libtremor/oggmalloc.c
@@ -60,6 +60,7 @@ void ogg_free(void* ptr)
60 tlsf_free(ptr); 60 tlsf_free(ptr);
61} 61}
62 62
63#ifdef TREMOR_USE_IRAM
63/* Allocate IRAM buffer */ 64/* Allocate IRAM buffer */
64static unsigned char iram_buff[IRAM_IBSS_SIZE] IBSS_ATTR MEM_ALIGN_ATTR; 65static unsigned char iram_buff[IRAM_IBSS_SIZE] IBSS_ATTR MEM_ALIGN_ATTR;
65static size_t iram_remain; 66static size_t iram_remain;
@@ -82,3 +83,4 @@ void *iram_malloc(size_t size){
82 83
83 return x; 84 return x;
84} 85}
86#endif