summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMagnus Holmgren <magnushol@gmail.com>2009-08-29 12:23:40 +0000
committerMagnus Holmgren <magnushol@gmail.com>2009-08-29 12:23:40 +0000
commit3fad1523c78e13f61283d7b81e0990f8803dc2f2 (patch)
tree6cdbc97688e782d13cf0ee406ac8356a2ae98047
parent260ed991392a387ff9ae5bbd8dba7afd10c1faef (diff)
downloadrockbox-3fad1523c78e13f61283d7b81e0990f8803dc2f2.tar.gz
rockbox-3fad1523c78e13f61283d7b81e0990f8803dc2f2.tar.bz2
rockbox-3fad1523c78e13f61283d7b81e0990f8803dc2f2.zip
FS#10466: Introduce a real malloc for tremor.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@22528 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r--apps/codecs/codecs.make5
-rw-r--r--apps/codecs/lib/tlsf/COPYING23
-rw-r--r--apps/codecs/lib/tlsf/Changelog119
-rw-r--r--apps/codecs/lib/tlsf/README163
-rw-r--r--apps/codecs/lib/tlsf/SOURCES3
-rw-r--r--apps/codecs/lib/tlsf/TODO9
-rw-r--r--apps/codecs/lib/tlsf/libtlsf.make28
-rw-r--r--apps/codecs/libtremor/block.c2
-rw-r--r--apps/codecs/libtremor/oggmalloc.c80
-rw-r--r--apps/codecs/libtremor/os_types.h8
-rw-r--r--apps/codecs/libtremor/sharedbook.c26
-rw-r--r--apps/codecs/vorbis.c50
12 files changed, 426 insertions, 90 deletions
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" <sinan.kaya@siemens.com>
+ * 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 <amery@geeks.cl>
+
+ -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
+ <hermantenbrugge@home.nl>
+
+ -v2.3 (Jul 28 2007) Released a new version with all the contributions
+ received from Herman ten Brugge <hermantenbrugge@home.nl>
+ (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
+ <proteuskor@gmail.com>. 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;i<vi->channels;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 <setjmp.h>
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(size_t size)
+void ogg_malloc_destroy()
{
- void* x;
-
- 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
-
- x = &mallocbuf[mem_ptr];
- mem_ptr += size; /* Keep memory 32-bit aligned */
-
- return x;
+ size_t bufsize;
+ void* buf = ci->codec_get_buffer(&bufsize);
+ destroy_memory_pool(buf);
}
-void *ogg_tmpmalloc(size_t size)
+void *ogg_malloc(size_t size)
{
- size = (size + 3) & ~3;
+ void* x = tlsf_malloc(size);
- if (mem_ptr + size > tmp_ptr)
- return NULL;
+ if (x == NULL)
+ LONGJMP(1);
- tmp_ptr -= size;
- return &mallocbuf[tmp_ptr];
+ return x;
}
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);
- return x;
-}
+ void *x = tlsf_realloc(ptr, size);
-long ogg_tmpmalloc_pos(void)
-{
- return tmp_ptr;
+ if (x == NULL)
+ LONGJMP(1);
+
+ return x;
}
-void ogg_tmpmalloc_free(long pos)
+void ogg_free(void* ptr)
{
- 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<n;i++){
@@ -87,7 +87,7 @@ static ogg_uint32_t *_make_words(long *l,long n,long sparsecount){
/* update ourself */
if(length<32 && (entry>>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;i<n;i++){
codes[i]=bitreverse(codes[i]);
@@ -361,7 +363,7 @@ int vorbis_book_init_decode(codebook *c,const static_codebook *s){
qsort(codep,n,sizeof(*codep),sort32a);
- sortindex=(int *)ogg_tmpmalloc(n*sizeof(*sortindex));
+ sortindex=(int *)_ogg_malloc(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++){
@@ -371,7 +373,8 @@ int vorbis_book_init_decode(codebook *c,const static_codebook *s){
for(i=0;i<n;i++)
c->codelist[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 <setjmp.h>
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;
}
-