summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNils Wallménius <nils@rockbox.org>2013-05-18 19:48:08 +0200
committerNils Wallménius <nils@rockbox.org>2013-05-18 23:38:23 +0200
commitc7124b552044ef92a128481d32df081d1210cbe1 (patch)
tree4e596edb09396ef96ab93d064fddcae179d51ef7
parentfc0cf8d91b1710d7843981d56ef2ac9a6dfeb294 (diff)
downloadrockbox-c7124b552044ef92a128481d32df081d1210cbe1.tar.gz
rockbox-c7124b552044ef92a128481d32df081d1210cbe1.tar.bz2
rockbox-c7124b552044ef92a128481d32df081d1210cbe1.zip
Fix opus craches with large embedded album art
Use the tlsf malloc and friends instead of the silly codec_malloc to get actually working free and saner realloc that doesn't leak memory. Makes files with moderately sized embedded AA play on targets with large enough codec buffers and files with too large AA are now skipped rather than crashing. Fixes crash when playing example file in FS#12842. Change-Id: I06562955c4d9a95bd90f55738214fba462092b71
-rw-r--r--lib/rbcodec/codecs/codecs.make2
-rw-r--r--lib/rbcodec/codecs/libopus/ogg/os_types.h66
-rw-r--r--lib/rbcodec/codecs/libopus/opus_config.h7
-rw-r--r--lib/rbcodec/codecs/opus.c11
4 files changed, 42 insertions, 44 deletions
diff --git a/lib/rbcodec/codecs/codecs.make b/lib/rbcodec/codecs/codecs.make
index 21bb9332b3..08554d9628 100644
--- a/lib/rbcodec/codecs/codecs.make
+++ b/lib/rbcodec/codecs/codecs.make
@@ -172,7 +172,7 @@ $(CODECDIR)/nsf.codec : $(CODECDIR)/libnsf.a $(CODECDIR)/libemu2413.a
$(CODECDIR)/sgc.codec : $(CODECDIR)/libsgc.a $(CODECDIR)/libemu2413.a
$(CODECDIR)/vgm.codec : $(CODECDIR)/libvgm.a $(CODECDIR)/libemu2413.a
$(CODECDIR)/kss.codec : $(CODECDIR)/libkss.a $(CODECDIR)/libemu2413.a
-$(CODECDIR)/opus.codec : $(CODECDIR)/libopus.a
+$(CODECDIR)/opus.codec : $(CODECDIR)/libopus.a $(TLSFLIB)
$(CODECS): $(CODEC_LIBS) # this must be last in codec dependency list
diff --git a/lib/rbcodec/codecs/libopus/ogg/os_types.h b/lib/rbcodec/codecs/libopus/ogg/os_types.h
index 55f0bf559c..c97f4072a3 100644
--- a/lib/rbcodec/codecs/libopus/ogg/os_types.h
+++ b/lib/rbcodec/codecs/libopus/ogg/os_types.h
@@ -1,56 +1,54 @@
-#include "config.h"
-#include <stdint.h>
+#ifndef OS_TYPES_H
+#define OS_TYPES_H
#include "codeclib.h"
+#include <stdint.h>
+#include <tlsf.h>
-#ifdef SIMULATOR
-
-#include <stdio.h>
-
-static inline void* _ogg_malloc(size_t size)
+static inline void ogg_malloc_init(void)
{
- void *buf;
-
- printf("ogg_malloc %d", size);
- buf = codec_malloc(size);
- printf(" = %p\n", buf);
-
- return buf;
+ size_t bufsize;
+ void* buf = ci->codec_get_buffer(&bufsize);
+ init_memory_pool(bufsize, buf);
}
-static inline void* _ogg_calloc(size_t nmemb, size_t size)
+static inline void ogg_malloc_destroy(void)
{
- printf("ogg_calloc %d %d\n", nmemb, size);
- return codec_calloc(nmemb, size);
+ size_t bufsize;
+ void* buf = ci->codec_get_buffer(&bufsize);
+ destroy_memory_pool(buf);
}
-static inline void* _ogg_realloc(void *ptr, size_t size)
+static inline void *_ogg_malloc(size_t size)
{
- void *buf;
-
- printf("ogg_realloc %p %d", ptr, size);
- buf = codec_realloc(ptr, size);
- printf(" = %p\n", buf);
- return buf;
+ void* x = tlsf_malloc(size);
+ DEBUGF("ogg_malloc %zu = %p\n", size, x);
+ return x;
}
-static inline void _ogg_free(void *ptr)
+static inline void *_ogg_calloc(size_t nmemb, size_t size)
{
- printf("ogg_free %p\n", ptr);
- codec_free(ptr);
+ void *x = tlsf_calloc(nmemb, size);
+ DEBUGF("ogg_calloc %zu %zu\n", nmemb, size);
+ return x;
}
-#else
-
-#define _ogg_malloc codec_malloc
-#define _ogg_calloc codec_calloc
-#define _ogg_realloc codec_realloc
-#define _ogg_free codec_free
+static inline void *_ogg_realloc(void *ptr, size_t size)
+{
+ void *x = tlsf_realloc(ptr, size);
+ DEBUGF("ogg_realloc %p %zu = %p\n", ptr, size, x);
+ return x;
+}
-#endif
+static inline void _ogg_free(void* ptr)
+{
+ DEBUGF("ogg_free %p\n", ptr);
+ tlsf_free(ptr);
+}
typedef int16_t ogg_int16_t;
typedef uint16_t ogg_uint16_t;
typedef int32_t ogg_int32_t;
typedef uint32_t ogg_uint32_t;
typedef int64_t ogg_int64_t;
+#endif /* OS_TYPES_H */
diff --git a/lib/rbcodec/codecs/libopus/opus_config.h b/lib/rbcodec/codecs/libopus/opus_config.h
index 86210df52b..922ec607e5 100644
--- a/lib/rbcodec/codecs/libopus/opus_config.h
+++ b/lib/rbcodec/codecs/libopus/opus_config.h
@@ -3,6 +3,7 @@
#include "config.h"
#include "codeclib.h"
+#include "ogg/ogg.h"
/* general stuff */
#define OPUS_BUILD
@@ -14,9 +15,9 @@
#define OVERRIDE_OPUS_FREE
#define OVERRIDE_OPUS_ALLOC_SCRATCH
-#define opus_alloc codec_malloc
-#define opus_free codec_free
-#define opus_alloc_scratch codec_malloc
+#define opus_alloc _ogg_malloc
+#define opus_free _ogg_free
+#define opus_alloc_scratch _ogg_malloc
/* lrint */
#define HAVE_LRINTF 0
diff --git a/lib/rbcodec/codecs/opus.c b/lib/rbcodec/codecs/opus.c
index 3eb316de68..d72b9cc708 100644
--- a/lib/rbcodec/codecs/opus.c
+++ b/lib/rbcodec/codecs/opus.c
@@ -329,10 +329,8 @@ enum codec_status codec_run(void)
int64_t seek_target;
uint64_t granule_pos;
- /* reset our simple malloc */
- if (codec_init()) {
- goto done;
- }
+ ogg_malloc_init();
+
global_stack = 0;
#if defined(CPU_COLDFIRE)
@@ -344,10 +342,10 @@ enum codec_status codec_run(void)
/* pre-init the ogg_sync_state buffer, so it won't need many reallocs */
ogg_sync_init(&oy);
oy.storage = 64*1024;
- oy.data = codec_malloc(oy.storage);
+ oy.data = _ogg_malloc(oy.storage);
/* allocate output buffer */
- uint16_t *output = (uint16_t*) codec_malloc(MAX_FRAME_SIZE*sizeof(uint16_t));
+ uint16_t *output = (uint16_t*) _ogg_malloc(MAX_FRAME_SIZE*sizeof(uint16_t));
ci->seek_buffer(0);
ci->set_elapsed(0);
@@ -465,6 +463,7 @@ enum codec_status codec_run(void)
LOGF("Returned OK");
error = CODEC_OK;
done:
+ ogg_malloc_destroy();
return error;
}