summaryrefslogtreecommitdiff
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.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
172$(CODECDIR)/sgc.codec : $(CODECDIR)/libsgc.a $(CODECDIR)/libemu2413.a 172$(CODECDIR)/sgc.codec : $(CODECDIR)/libsgc.a $(CODECDIR)/libemu2413.a
173$(CODECDIR)/vgm.codec : $(CODECDIR)/libvgm.a $(CODECDIR)/libemu2413.a 173$(CODECDIR)/vgm.codec : $(CODECDIR)/libvgm.a $(CODECDIR)/libemu2413.a
174$(CODECDIR)/kss.codec : $(CODECDIR)/libkss.a $(CODECDIR)/libemu2413.a 174$(CODECDIR)/kss.codec : $(CODECDIR)/libkss.a $(CODECDIR)/libemu2413.a
175$(CODECDIR)/opus.codec : $(CODECDIR)/libopus.a 175$(CODECDIR)/opus.codec : $(CODECDIR)/libopus.a $(TLSFLIB)
176 176
177$(CODECS): $(CODEC_LIBS) # this must be last in codec dependency list 177$(CODECS): $(CODEC_LIBS) # this must be last in codec dependency list
178 178
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 @@
1#include "config.h" 1#ifndef OS_TYPES_H
2#include <stdint.h> 2#define OS_TYPES_H
3#include "codeclib.h" 3#include "codeclib.h"
4#include <stdint.h>
5#include <tlsf.h>
4 6
5#ifdef SIMULATOR 7static inline void ogg_malloc_init(void)
6
7#include <stdio.h>
8
9static inline void* _ogg_malloc(size_t size)
10{ 8{
11 void *buf; 9 size_t bufsize;
12 10 void* buf = ci->codec_get_buffer(&bufsize);
13 printf("ogg_malloc %d", size); 11 init_memory_pool(bufsize, buf);
14 buf = codec_malloc(size);
15 printf(" = %p\n", buf);
16
17 return buf;
18} 12}
19 13
20static inline void* _ogg_calloc(size_t nmemb, size_t size) 14static inline void ogg_malloc_destroy(void)
21{ 15{
22 printf("ogg_calloc %d %d\n", nmemb, size); 16 size_t bufsize;
23 return codec_calloc(nmemb, size); 17 void* buf = ci->codec_get_buffer(&bufsize);
18 destroy_memory_pool(buf);
24} 19}
25 20
26static inline void* _ogg_realloc(void *ptr, size_t size) 21static inline void *_ogg_malloc(size_t size)
27{ 22{
28 void *buf; 23 void* x = tlsf_malloc(size);
29 24 DEBUGF("ogg_malloc %zu = %p\n", size, x);
30 printf("ogg_realloc %p %d", ptr, size); 25 return x;
31 buf = codec_realloc(ptr, size);
32 printf(" = %p\n", buf);
33 return buf;
34} 26}
35 27
36static inline void _ogg_free(void *ptr) 28static inline void *_ogg_calloc(size_t nmemb, size_t size)
37{ 29{
38 printf("ogg_free %p\n", ptr); 30 void *x = tlsf_calloc(nmemb, size);
39 codec_free(ptr); 31 DEBUGF("ogg_calloc %zu %zu\n", nmemb, size);
32 return x;
40} 33}
41 34
42#else 35static inline void *_ogg_realloc(void *ptr, size_t size)
43 36{
44#define _ogg_malloc codec_malloc 37 void *x = tlsf_realloc(ptr, size);
45#define _ogg_calloc codec_calloc 38 DEBUGF("ogg_realloc %p %zu = %p\n", ptr, size, x);
46#define _ogg_realloc codec_realloc 39 return x;
47#define _ogg_free codec_free 40}
48 41
49#endif 42static inline void _ogg_free(void* ptr)
43{
44 DEBUGF("ogg_free %p\n", ptr);
45 tlsf_free(ptr);
46}
50 47
51typedef int16_t ogg_int16_t; 48typedef int16_t ogg_int16_t;
52typedef uint16_t ogg_uint16_t; 49typedef uint16_t ogg_uint16_t;
53typedef int32_t ogg_int32_t; 50typedef int32_t ogg_int32_t;
54typedef uint32_t ogg_uint32_t; 51typedef uint32_t ogg_uint32_t;
55typedef int64_t ogg_int64_t; 52typedef int64_t ogg_int64_t;
53#endif /* OS_TYPES_H */
56 54
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 @@
3 3
4#include "config.h" 4#include "config.h"
5#include "codeclib.h" 5#include "codeclib.h"
6#include "ogg/ogg.h"
6 7
7/* general stuff */ 8/* general stuff */
8#define OPUS_BUILD 9#define OPUS_BUILD
@@ -14,9 +15,9 @@
14#define OVERRIDE_OPUS_FREE 15#define OVERRIDE_OPUS_FREE
15#define OVERRIDE_OPUS_ALLOC_SCRATCH 16#define OVERRIDE_OPUS_ALLOC_SCRATCH
16 17
17#define opus_alloc codec_malloc 18#define opus_alloc _ogg_malloc
18#define opus_free codec_free 19#define opus_free _ogg_free
19#define opus_alloc_scratch codec_malloc 20#define opus_alloc_scratch _ogg_malloc
20 21
21/* lrint */ 22/* lrint */
22#define HAVE_LRINTF 0 23#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)
329 int64_t seek_target; 329 int64_t seek_target;
330 uint64_t granule_pos; 330 uint64_t granule_pos;
331 331
332 /* reset our simple malloc */ 332 ogg_malloc_init();
333 if (codec_init()) { 333
334 goto done;
335 }
336 global_stack = 0; 334 global_stack = 0;
337 335
338#if defined(CPU_COLDFIRE) 336#if defined(CPU_COLDFIRE)
@@ -344,10 +342,10 @@ enum codec_status codec_run(void)
344 /* pre-init the ogg_sync_state buffer, so it won't need many reallocs */ 342 /* pre-init the ogg_sync_state buffer, so it won't need many reallocs */
345 ogg_sync_init(&oy); 343 ogg_sync_init(&oy);
346 oy.storage = 64*1024; 344 oy.storage = 64*1024;
347 oy.data = codec_malloc(oy.storage); 345 oy.data = _ogg_malloc(oy.storage);
348 346
349 /* allocate output buffer */ 347 /* allocate output buffer */
350 uint16_t *output = (uint16_t*) codec_malloc(MAX_FRAME_SIZE*sizeof(uint16_t)); 348 uint16_t *output = (uint16_t*) _ogg_malloc(MAX_FRAME_SIZE*sizeof(uint16_t));
351 349
352 ci->seek_buffer(0); 350 ci->seek_buffer(0);
353 ci->set_elapsed(0); 351 ci->set_elapsed(0);
@@ -465,6 +463,7 @@ enum codec_status codec_run(void)
465 LOGF("Returned OK"); 463 LOGF("Returned OK");
466 error = CODEC_OK; 464 error = CODEC_OK;
467done: 465done:
466 ogg_malloc_destroy();
468 return error; 467 return error;
469} 468}
470 469