diff --git a/apps/codecs/codecs.make b/apps/codecs/codecs.make index 85c10158d7..87ed5f2b40 100644 --- a/apps/codecs/codecs.make +++ b/apps/codecs/codecs.make @@ -14,6 +14,9 @@ OTHER_SRC += $(CODECS_SRC) CODECS := $(CODECS_SRC:.c=.codec) CODECS := $(subst $(ROOTDIR),$(BUILDDIR),$(CODECS)) +# TLSF memory allocator library +include $(APPSDIR)/codecs/lib/tlsf/libtlsf.make + # the codec helper library include $(APPSDIR)/codecs/lib/libcodec.make OTHER_INC += -I$(APPSDIR)/codecs/lib @@ -66,7 +69,7 @@ $(CODECDIR)/spc.codec : $(CODECDIR)/libspc.a $(CODECDIR)/mpa.codec : $(CODECDIR)/libmad.a $(CODECDIR)/a52.codec : $(CODECDIR)/liba52.a $(CODECDIR)/flac.codec : $(CODECDIR)/libffmpegFLAC.a -$(CODECDIR)/vorbis.codec : $(CODECDIR)/libtremor.a +$(CODECDIR)/vorbis.codec : $(CODECDIR)/libtremor.a $(TLSFLIB) $(CODECDIR)/speex.codec : $(CODECDIR)/libspeex.a $(CODECDIR)/mpc.codec : $(CODECDIR)/libmusepack.a $(CODECDIR)/wavpack.codec : $(CODECDIR)/libwavpack.a diff --git a/apps/codecs/lib/tlsf/COPYING b/apps/codecs/lib/tlsf/COPYING new file mode 100644 index 0000000000..78fdbdc061 --- /dev/null +++ b/apps/codecs/lib/tlsf/COPYING @@ -0,0 +1,23 @@ + LICENSE INFORMATION + +TLSF is released as LGPL and GPL. A copy of both licences can be found in this +directoy. For the GPL licence, the following exception applies. + + +TLSF is free software; you can redistribute it and/or modify it under terms of +the GNU General Public License as published by the Free Software Foundation; +either version 2, or (at your option) any later version. TLSF is distributed +in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the +implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See +the GNU General Public License for more details. You should have received a +copy of the GNU General Public License along with TLSF; see file COPYING. If +not, write to the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, +USA. + +As a special exception, including TLSF header files in a file, or linking with +other files objects to produce an executable application, is merely considered +normal use of the library, and does *not* fall under the heading of "derived +work". Therfore does not by itself cause the resulting executable application +to be covered by the GNU General Public License. This exception does not +however invalidate any other reasons why the executable file might be covered +by the GNU Public License. diff --git a/apps/codecs/lib/tlsf/Changelog b/apps/codecs/lib/tlsf/Changelog new file mode 100644 index 0000000000..0cdb34a8ab --- /dev/null +++ b/apps/codecs/lib/tlsf/Changelog @@ -0,0 +1,119 @@ + Version History + --------------- + -v2.4.4 (October 13 2008) + * Corrected minor syntactic bug on statistic gathering code. + Reported by Tim Cussins and P. Mantegazza. + + -v2.4.3 (July 30 2008) + * Minor fixes to compile with the greenhills compiler. + Reported by "Kaya, Sinan SEA" + * Small change in the license in order to include TLSF in the RTEMS + project. + + -v2.4.2 (May 16 2008) (Herman ten Brugge) + * Memory usage statistics added again, with cleaner and more compacted + code. + + -v2.4.1 (April 30 2008) + * Fixed a bug in the tlsf_realloc function: init the pool automatically + on the first call. + Reported by: Alejandro Mery + + -v2.4 (Feb 19 2008) + * "rtl_*" functions renamed to "tlsf_*". + * Added the add_new_area function to insert new memory areas to an + existing memory pool. + * A single TLSF pool can manage non-contiguous memory areas. + * Support for mmap and sbrk added. + * The init_memory_pool is not longer needed when used on a system + with mmap or sbrk. + * Removed the get_used_size counting.The same functionality can be + implemented outside the TLSF code. + + -v2.3.2 (Sep 27 2007) + * Minor cosmetic code improvements. + + -v2.3.1 (Jul 30 2007) + * Fixed some minor bugs in the version 2.3. Herman ten Brugge + + + -v2.3 (Jul 28 2007) Released a new version with all the contributions + received from Herman ten Brugge + (This is his summary of changes in the TLSF's code): + * Add 64 bit support. It now runs on x86_64 and solaris64. + * I also tested this on vxworks/32 and solaris/32 and i386/32 + processors. + * Remove assembly code. I could not measure any performance difference + on my core2 processor. This also makes the code more portable. + * Moved defines/typedefs from tlsf.h to tlsf.c + * Changed MIN_BLOCK_SIZE to sizeof (free_ptr_t) and BHDR_OVERHEAD to + (sizeof (bhdr_t) - MIN_BLOCK_SIZE). This does not change the fact + that the minumum size is still sizeof (bhdr_t). + * Changed all C++ comment style to C style. (// -> /* ... *./) + * Used ls_bit instead of ffs and ms_bit instead of fls. I did this to + avoid confusion with the standard ffs function which returns + different values. + * Created set_bit/clear_bit fuctions because they are not present + on x86_64. + * Added locking support + extra file target.h to show how to use it. + * Added get_used_size function + * Added rtl_realloc and rtl_calloc function + * Implemented realloc clever support. + * Added some test code in the example directory. + + -- Thank you very much for your help Herman! + + -v2.2.1 (Oct 23 2006) + * Support for ARMv5 implemented by Adam Scislowicz + . Thank you for your contribution. + + - v2.2.0 (Jun 30 2006) Miguel Masmano & Ismael Ripoll. + + * Blocks smaller than 128 bytes are stored on a single + segregated list. The already existing bits maps and data + structures are used. + * Minor code speed-up improvements. + * Worst case response time both on malloc and free improved. + * External fragmantation also improved!. + * Segragared lists are AGAIN sorted by LIFO order. Version + 2.1b was proven to be no better than 2.1. + + - v2.1b: Allocation policy has been always a LIFO Good-Fit, that + is, between several free blocks in the same range, TLSF will + always allocate the most recently released. In this version of + TLSF, we have implemented a FIFO Good-Fit. However, + fragmentation doesn't seems to be altered so is it worth it?. + + - v2.1: Realloc and calloc included again in TLSF 2.0. + + - v2.0: In this version, TLSF has been programmed from scratch. + Now the allocator is provided as an unique file. Realloc and + calloc are not longer implemented. + + + - v1.4: Created the section "Version History". Studied real + behaviour of actual applications (regular applications tend + to require small memory blocks (less than 16 bytes) whereas + TLSF is optimised to be used with blocks larger than 16 + bytes: Added special lists to deal with blocks smaller than + 16 bytes. + + + - v1.3: Change of concept, now the main TLSF structure is created + inside of the beginning of the block instead of being an + static structure, allowing multiple TLSFs working at the + same time. Now, TLSF uses specific processor instructions to + deal with bitmaps. TLSF sanity functions added to find TLSF + overflows. The TLSF code will not be RTLinux-oriented any + more. + + - v1.1 ... v1.2: Many little bugs fixed, code cleaned and splitted + in several files because of cosmetic requirements. + Starting from TLSF v1.1, MaRTE OS + (http://marte.unican.es) uses the TLSF allocator + as its default memory allocator. + + - v0.1 ... v1.0: First implementations were created for testing and + research purposes. Basically TLSF is implemented to + be used by RTLinux-GPL (www.rtlinux-gpl.org), so + it is RTLinux-oriented. diff --git a/apps/codecs/lib/tlsf/README b/apps/codecs/lib/tlsf/README new file mode 100644 index 0000000000..d755905b16 --- /dev/null +++ b/apps/codecs/lib/tlsf/README @@ -0,0 +1,163 @@ + +TLSF Memory Storage allocator implementation. +Version 2.4 Feb 2008 + +Authors: Miguel Masmano, Ismael Ripoll & Alfons Crespo. +Copyright UPVLC, OCERA Consortium. + +TLSF is released in the GPL/LGPL licence. The exact terms of the licence +are described in the COPYING file. + +This component provides basic memory allocation functions: +malloc and free, as defined in the standard "C" library. + +This allocator was designed to provide real-time performance, that is: +1.- Bounded time malloc and free. +2.- Fast response time. +3.- Efficient memory management, that is low fragmentation. + + +The worst response time for both malloc and free is O(1). + + + +How to use it: + +This code is prepared to be used as a stand-alone code that can be +linked with a regular application or it can be compiled to be a Linux +module (which required the BigPhysicalArea patch). Initially the +module was designed to work jointly with RTLinux-GPL, but it can be +used as a stand alone Linux module. + +When compiled as a regular linux process the API is: + +Initialisation and destruction functions +---------------------------------------- + +init_memory_pool may be called before any request or release call: + +- size_t init_memory_pool(size_t, void *); +- void destroy_memory_pool(void *); + +Request and release functions +----------------------------- + +As can be seen, there are two functions for each traditional memory +allocation function (malloc, free, realloc, and calloc). One with the +prefix "tlsf_" and the other with the suffix "_ex". + +The versions with the prefix "tlsf_" provides the expected behaviour, +that is, allocating/releasing memory from the default memory pool. The +default memory pool is the last pool initialised by the +init_memory_pool function. + +On the other hand, the functions with the prefix "_ex" enable the use of several memory pools. + +- void *tlsf_malloc(size_t); +- void *malloc_ex(size_t, void *); + +- void tlsf_free(void *ptr); +- void free_ex(void *, void *); + +- void *tlsf_realloc(void *ptr, size_t size); +- void *realloc_ex(void *, size_t, void *); + +- void *tlsf_calloc(size_t nelem, size_t elem_size); +- void *calloc_ex(size_t, size_t, void *); + +EXAMPLE OF USE: + +char memory_pool[1024*1024]; + +{ + ... + + init_memory_pool(1024*1024, memory_pool); + + ... + + ptr1=malloc_ex(100, memory_pool); + ptr2=tlsf_malloc(100); // This function will use memory_pool + + ... + + tlsf_free(ptr2); + free_ex(ptr1, memory_pool); +} + +Growing the memory pool +----------------------- + +Starting from the version 2.4, the function add_new_area adds an +memory area to an existing memory pool. + +- size_t add_new_area(void *, size_t, void *); + +This feature is pretty useful when an existing memory pool is running +low and we want to add more free memory to it. +EXAMPLE OF USE: + +char memory_pool[1024*1024]; +char memory_pool2[1024*1024]; + +{ + ... + + init_memory_pool(1024*1024, memory_pool); + + ... + + ptr[0]=malloc_ex(1024*256 memory_pool); + ptr[1]=malloc_ex(1024*512, memory_pool); + add_new_area(memory_pool2, 1024*1024, memory_pool); + // Now we have an extra free memory area of 1Mb + // The next malloc may not fail + ptr[2]=malloc_ex(1024*512, memory_pool); + + ... + +} + + +SBRK and MMAP support +--------------------- + +The version 2.4 can use the functions SBRK and MMAP to _automatically_ +growing the memory pool, before running out of memory. + +So, when this feature is enabled, unless the operating system were out +of memory, a malloc operation would not fail due to an "out-of-memory" +error. + +To enable this support, compile tlsf.c with the FLAGS -DUSE_MMAP=1 or +-DUSE_SBRK=1 depending on whether you want to use "mmap" or "sbrk" or both. + +** By default (default Makefile) this feature is enabled. + +EXAMPLE OF USE: + +gcc -o tlsf.o -O2 -Wall -DUSE_MMAP=1 -DUSE_SBRK=1 + +--- + +If the sbrk/mmap support is enabled and we are _only_ going to use one +memory pool, it is not necessary to call init_memory_pool + +EXAMPLE OF USE (with MMAP/SBRK support enabled): + +{ + ... + + ptr2=tlsf_malloc(100); // This function will use memory_pool + + ... + + tlsf_free(ptr2); +} + + + + +This work has been supported by the followin projects: +EUROPEAN: IST-2001-35102(OCERA) http://www.ocera.org. +SPANISH: TIN2005-08665-C3-03 diff --git a/apps/codecs/lib/tlsf/SOURCES b/apps/codecs/lib/tlsf/SOURCES new file mode 100644 index 0000000000..eb9d93756e --- /dev/null +++ b/apps/codecs/lib/tlsf/SOURCES @@ -0,0 +1,3 @@ +#if CONFIG_CODEC == SWCODEC /* software codec platforms */ +src/tlsf.c +#endif diff --git a/apps/codecs/lib/tlsf/TODO b/apps/codecs/lib/tlsf/TODO new file mode 100644 index 0000000000..d7c07b8421 --- /dev/null +++ b/apps/codecs/lib/tlsf/TODO @@ -0,0 +1,9 @@ +To do list +========== + +* Add mmap/sbrk support (DONE - V2.4). + +* TLSF rounds-up request size to the head of a free list. + It has been shown to be a good policy for small blocks (<2048). + But for larger blocks this policy may cause excesive fragmentation. + A deeper analisys should be done. diff --git a/apps/codecs/lib/tlsf/libtlsf.make b/apps/codecs/lib/tlsf/libtlsf.make new file mode 100644 index 0000000000..464487f87f --- /dev/null +++ b/apps/codecs/lib/tlsf/libtlsf.make @@ -0,0 +1,28 @@ +# __________ __ ___. +# Open \______ \ ____ ____ | | _\_ |__ _______ ___ +# Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / +# Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < +# Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ +# \/ \/ \/ \/ \/ +# $Id$ +# + +TLSFLIB := $(CODECDIR)/libtlsf.a +TLSFLIB_SRC := $(call preprocess, $(APPSDIR)/codecs/lib/tlsf/SOURCES) +TLSFLIB_OBJ := $(call c2obj, $(TLSFLIB_SRC)) +OTHER_SRC += $(TLSFLIB_SRC) + +$(TLSFLIB): $(TLSFLIB_OBJ) + $(SILENT)$(shell rm -f $@) + $(call PRINTS,AR $(@F))$(AR) rcs $@ $^ >/dev/null + +TLSFLIBFLAGS = $(CODECFLAGS) -ffunction-sections + +ifdef SIMVER + TLSFLIBFLAGS += -DTLSF_STATISTIC=1 +endif + +$(CODECDIR)/lib/tlsf/src/%.o: $(APPSDIR)/codecs/lib/tlsf/src/%.c + $(SILENT)mkdir -p $(dir $@) + $(call PRINTS,CC $(subst $(ROOTDIR)/,,$<))$(CC) \ + -I$(dir $<) $(TLSFLIBFLAGS) -c $< -o $@ diff --git a/apps/codecs/libtremor/block.c b/apps/codecs/libtremor/block.c index 3947b90239..8a461e325f 100644 --- a/apps/codecs/libtremor/block.c +++ b/apps/codecs/libtremor/block.c @@ -283,7 +283,7 @@ void vorbis_dsp_clear(vorbis_dsp_state *v){ codec_setup_info *ci=(codec_setup_info *)(vi?vi->codec_setup:NULL); private_state *b=(private_state *)v->backend_state; - if(NULL == v->iram_double_pcm) + if(NULL == v->iram_double_pcm && vi != NULL) { /* pcm buffer came from oggmalloc rather than iram */ for(i=0;ichannels;i++) diff --git a/apps/codecs/libtremor/oggmalloc.c b/apps/codecs/libtremor/oggmalloc.c index 6da7cfcedc..3d60370641 100644 --- a/apps/codecs/libtremor/oggmalloc.c +++ b/apps/codecs/libtremor/oggmalloc.c @@ -1,85 +1,63 @@ #include "os_types.h" +#include "../lib/tlsf/src/tlsf.h" -#if defined(CPU_ARM) || defined(CPU_COLDFIRE) +#if defined(CPU_ARM) || defined(CPU_COLDFIRE) || defined(CPU_MIPS) #include extern jmp_buf rb_jump_buf; +#define LONGJMP(x) longjmp(rb_jump_buf, x) +#elif defined(SIMULATOR) +#define LONGJMP(x) do { DEBUGF("Vorbis: allocation failed!\n"); return NULL; } while (false) +#else +#define LONGJMP(x) return NULL #endif -static size_t tmp_ptr; - void ogg_malloc_init(void) { - mallocbuf = ci->codec_get_buffer(&bufsize); - tmp_ptr = bufsize & ~3; - mem_ptr = 0; + size_t bufsize; + void* buf = ci->codec_get_buffer(&bufsize); + init_memory_pool(bufsize, buf); +} + +void ogg_malloc_destroy() +{ + size_t bufsize; + void* buf = ci->codec_get_buffer(&bufsize); + destroy_memory_pool(buf); } void *ogg_malloc(size_t size) { - void* x; + void* x = tlsf_malloc(size); - size = (size + 3) & ~3; - - if (mem_ptr + size > tmp_ptr) -#if defined(CPU_ARM) || defined(CPU_COLDFIRE) - longjmp(rb_jump_buf, 1); -#else - return NULL; -#endif + if (x == NULL) + LONGJMP(1); - x = &mallocbuf[mem_ptr]; - mem_ptr += size; /* Keep memory 32-bit aligned */ - return x; } -void *ogg_tmpmalloc(size_t size) -{ - size = (size + 3) & ~3; - - if (mem_ptr + size > tmp_ptr) - return NULL; - - tmp_ptr -= size; - 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 *x = tlsf_calloc(nmemb, size); -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); + LONGJMP(1); + return x; } void *ogg_realloc(void *ptr, size_t size) { - void *x; - (void)ptr; - x = ogg_malloc(size); + void *x = tlsf_realloc(ptr, size); + + if (x == NULL) + LONGJMP(1); + return x; } -long ogg_tmpmalloc_pos(void) +void ogg_free(void* ptr) { - return tmp_ptr; -} - -void ogg_tmpmalloc_free(long pos) -{ - tmp_ptr = pos; + tlsf_free(ptr); } /* Allocate IRAM buffer */ diff --git a/apps/codecs/libtremor/os_types.h b/apps/codecs/libtremor/os_types.h index 4c7d17ef3a..337c055d54 100644 --- a/apps/codecs/libtremor/os_types.h +++ b/apps/codecs/libtremor/os_types.h @@ -38,16 +38,14 @@ #define _ogg_malloc ogg_malloc #define _ogg_calloc ogg_calloc #define _ogg_realloc ogg_realloc -#define _ogg_free(x) do { } while(0) +#define _ogg_free ogg_free void ogg_malloc_init(void); +void ogg_malloc_destroy(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); +void ogg_free(void *ptr); void iram_malloc_init(void); void *iram_malloc(size_t size); diff --git a/apps/codecs/libtremor/sharedbook.c b/apps/codecs/libtremor/sharedbook.c index edabf3ccb3..853d1f5d61 100644 --- a/apps/codecs/libtremor/sharedbook.c +++ b/apps/codecs/libtremor/sharedbook.c @@ -71,7 +71,7 @@ static ogg_int32_t _float32_unpack(long val,int *point){ static ogg_uint32_t *_make_words(long *l,long n,long sparsecount){ long i,j,count=0; ogg_uint32_t marker[33]; - ogg_uint32_t *r=(ogg_uint32_t *)ogg_tmpmalloc((sparsecount?sparsecount:n)*sizeof(*r)); + ogg_uint32_t *r=(ogg_uint32_t *)_ogg_malloc((sparsecount?sparsecount:n)*sizeof(*r)); memset(marker,0,sizeof(marker)); for(i=0;i>length)){ /* error condition; the lengths must specify an overpopulated tree */ - /* _ogg_free(r); */ + _ogg_free(r); return(NULL); } r[count++]=entry; @@ -188,9 +188,8 @@ static ogg_int32_t *_book_unquantize(const static_codebook *b,int n, 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_tmpcalloc(n*b->dim,sizeof(*rp)); + int *rp=(int *)_ogg_calloc(n*b->dim,sizeof(*rp)); - memset(rp, 0, n*b->dim*sizeof(*rp)); *maxpoint=minpoint; /* maptype 1 and 2 both use a quantized value vector, but @@ -277,7 +276,7 @@ static ogg_int32_t *_book_unquantize(const static_codebook *b,int n, if(rp[j]<*maxpoint) r[j]>>=*maxpoint-rp[j]; - /* _ogg_free(rp); */ + _ogg_free(rp); return(r); } return(NULL); @@ -325,7 +324,6 @@ 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 */ @@ -350,9 +348,13 @@ int vorbis_book_init_decode(codebook *c,const static_codebook *s){ /* perform sort */ ogg_uint32_t *codes=_make_words(s->lengthlist,s->entries,c->used_entries); - ogg_uint32_t **codep=(ogg_uint32_t **)ogg_tmpmalloc(sizeof(*codep)*n); + ogg_uint32_t **codep=(ogg_uint32_t **)_ogg_malloc(sizeof(*codep)*n); - if(codes==NULL||codep==NULL)goto err_out; + if(codes==NULL||codep==NULL){ + _ogg_free(codep); + _ogg_free(codes); + 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;icodelist[sortindex[i]]=codes[i]; - /* _ogg_free(codes); */ + _ogg_free(codep); + _ogg_free(codes); @@ -387,6 +390,7 @@ int vorbis_book_init_decode(codebook *c,const static_codebook *s){ if(s->lengthlist[i]>0) c->dec_codelengths[sortindex[n++]]=s->lengthlist[i]; + _ogg_free(sortindex); c->dec_firsttablen=_ilog(c->used_entries)-4; /* this is magic */ if(c->dec_firsttablen<5)c->dec_firsttablen=5; if(c->dec_firsttablen>8)c->dec_firsttablen=8; @@ -434,10 +438,8 @@ 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); } diff --git a/apps/codecs/vorbis.c b/apps/codecs/vorbis.c index f14aeead84..7e078139ce 100644 --- a/apps/codecs/vorbis.c +++ b/apps/codecs/vorbis.c @@ -22,10 +22,13 @@ #include "codeclib.h" #include "libtremor/ivorbisfile.h" #include "libtremor/ogg.h" +#ifdef SIMULATOR +#include "lib/tlsf/src/tlsf.h" +#endif CODEC_HEADER -#if defined(CPU_ARM) || defined(CPU_COLDFIRE) +#if defined(CPU_ARM) || defined(CPU_COLDFIRE) || defined(CPU_MIPS) #include jmp_buf rb_jump_buf; #endif @@ -76,8 +79,7 @@ static long tell_handler(void *datasource) } /* This sets the DSP parameters based on the current logical bitstream - * (sampling rate, number of channels, etc). It also tries to guess - * reasonable buffer parameters based on the current quality setting. + * (sampling rate, number of channels, etc). */ static bool vorbis_set_codec_parameters(OggVorbis_File *vf) { @@ -86,7 +88,6 @@ static bool vorbis_set_codec_parameters(OggVorbis_File *vf) vi = ov_info(vf, -1); if (vi == NULL) { - //ci->splash(HZ*2, "Vorbis Error"); return false; } @@ -120,27 +121,23 @@ enum codec_status codec_main(void) ogg_int64_t vf_pcmlengths[2]; ci->configure(DSP_SET_SAMPLE_DEPTH, 24); - /* Note: These are sane defaults for these values. Perhaps - * they should be set differently based on quality setting - */ -#if defined(CPU_ARM) || defined(CPU_COLDFIRE) - if (setjmp(rb_jump_buf) != 0) - { + if (codec_init()) { + error = CODEC_ERROR; + goto exit; + } + + ogg_malloc_init(); + +#if defined(CPU_ARM) || defined(CPU_COLDFIRE) || defined(CPU_MIPS) + if (setjmp(rb_jump_buf) != 0) { /* malloc failed; skip to next track */ error = CODEC_ERROR; goto done; } #endif -/* We need to flush reserver memory every track load. */ next_track: - if (codec_init()) { - error = CODEC_ERROR; - goto exit; - } - ogg_malloc_init(); - while (!*ci->taginfo_ready && !ci->stop_codec) ci->sleep(1); @@ -166,6 +163,10 @@ next_track: * get here. */ if (!error) { + ogg_free(vf.offsets); + ogg_free(vf.dataoffsets); + ogg_free(vf.serialnos); + vf.offsets = vf_offsets; vf.dataoffsets = &vf_dataoffsets; vf.serialnos = &vf_serialnos; @@ -183,7 +184,7 @@ next_track: vf.ready_state = OPENED; vf.links = 1; } else { - //ci->logf("ov_open: %d", error); + DEBUGF("Vorbis: ov_open failed: %d", error); error = CODEC_ERROR; goto done; } @@ -225,7 +226,7 @@ next_track: if (n == 0) { eof = 1; } else if (n < 0) { - DEBUGF("Error decoding frame\n"); + DEBUGF("Vorbis: Error decoding frame\n"); } else { ci->pcmbuf_insert(pcm[0], pcm[1], n); ci->set_offset(ov_raw_tell(&vf)); @@ -235,6 +236,15 @@ next_track: error = CODEC_OK; done: +#if 0 /* defined(SIMULATOR) */ + { + size_t bufsize; + void* buf = ci->codec_get_buffer(&bufsize); + + DEBUGF("Vorbis: Memory max: %u\n", get_max_size(buf)); + } +#endif + if (ci->request_next_track()) { /* Clean things up for the next track */ vf.dataoffsets = NULL; @@ -246,6 +256,6 @@ done: } exit: + ogg_malloc_destroy(); return error; } -