diff options
author | Thomas Martitz <kugel@rockbox.org> | 2014-04-09 09:00:36 +0200 |
---|---|---|
committer | Thomas Martitz <kugel@rockbox.org> | 2014-04-09 09:04:10 +0200 |
commit | 957613420e9c4906e8bb8ac685e10fc0c24329b8 (patch) | |
tree | 810061339f17dbe30759fc0acc7d04070ce2ed40 | |
parent | 924a3c48d2b1a807bd7cd3b4b1e042fd2e3d7d06 (diff) | |
download | rockbox-9576134.tar.gz rockbox-9576134.zip |
plugins: Add plugin_release_audio_buffer().
Some plugins grab the whole audio buffer and still want to start playback
somehow (e.g. random_folder_advance_config). Since 22e802e the plugin buffer
is allocated via buflib and has to be released explicitely. For these plugins
the automatic free on exit is not sufficient and they need an API function for
that.
Fixes OOM panic on random_folder_advance_config when using start
shuffled playback.
Change-Id: I0d351daa782cb829f4ff80d34c05f40a2e0c142f
-rw-r--r-- | apps/codecs.c | 2 | ||||
-rw-r--r-- | apps/plugin.c | 19 | ||||
-rw-r--r-- | apps/plugin.h | 9 | ||||
-rw-r--r-- | apps/plugins/random_folder_advance_config.c | 3 |
4 files changed, 20 insertions, 13 deletions
diff --git a/apps/codecs.c b/apps/codecs.c index 18022d9df3..e84cdf88aa 100644 --- a/apps/codecs.c +++ b/apps/codecs.c @@ -71,8 +71,6 @@ extern unsigned char codecbuf[]; static size_t codec_size; -extern void* plugin_get_audio_buffer(size_t *buffer_size); - struct codec_api ci = { 0, /* filesize */ diff --git a/apps/plugin.c b/apps/plugin.c index f9179f3f08..93779d7a6c 100644 --- a/apps/plugin.c +++ b/apps/plugin.c @@ -129,6 +129,10 @@ static int close_wrapper(int fd); static int creat_wrapper(const char *pathname, mode_t mode); #endif +static void* plugin_get_audio_buffer(size_t *buffer_size); +static void plugin_release_audio_buffer(void); +static void plugin_tsr(bool (*exit_callback)(bool)); + static const struct plugin_api rockbox_api = { /* lcd */ @@ -692,8 +696,8 @@ static const struct plugin_api rockbox_api = { mktime, #endif plugin_get_buffer, - plugin_get_audio_buffer, - plugin_tsr, + plugin_get_audio_buffer, /* defined in plugin.c */ + plugin_tsr, /* defined in plugin.c */ plugin_get_current_filename, #if defined(DEBUG) || defined(SIMULATOR) debugf, @@ -800,6 +804,7 @@ static const struct plugin_api rockbox_api = { /* new stuff at the end, sort into place next time the API gets incompatible */ + plugin_release_audio_buffer, /* defined in plugin.c */ }; static int plugin_buffer_handle; @@ -994,7 +999,7 @@ void* plugin_get_buffer(size_t *buffer_size) Playback gets stopped, to avoid conflicts. Talk buffer is stolen as well. */ -void* plugin_get_audio_buffer(size_t *buffer_size) +static void* plugin_get_audio_buffer(size_t *buffer_size) { /* dummy ops with no callbacks, needed because by * default buflib buffers can be moved around which must be avoided */ @@ -1004,10 +1009,16 @@ void* plugin_get_audio_buffer(size_t *buffer_size) return core_get_data(plugin_buffer_handle); } +static void plugin_release_audio_buffer(void) +{ + if (plugin_buffer_handle > 0) + plugin_buffer_handle = core_free(plugin_buffer_handle); +} + /* The plugin wants to stay resident after leaving its main function, e.g. runs from timer or own thread. The callback is registered to later instruct it to free its resources before a new plugin gets loaded. */ -void plugin_tsr(bool (*exit_callback)(bool)) +static void plugin_tsr(bool (*exit_callback)(bool)) { pfn_tsr_exit = exit_callback; /* remember the callback for later */ } diff --git a/apps/plugin.h b/apps/plugin.h index 874f6e0069..6a15f86919 100644 --- a/apps/plugin.h +++ b/apps/plugin.h @@ -160,7 +160,7 @@ void* plugin_get_buffer(size_t *buffer_size); #define PLUGIN_MAGIC 0x526F634B /* RocK */ /* increase this every time the api struct changes */ -#define PLUGIN_API_VERSION 228 +#define PLUGIN_API_VERSION 229 /* update this to latest version if a change to the api struct breaks backwards compatibility (and please take the opportunity to sort in any @@ -976,6 +976,7 @@ struct plugin_api { /* new stuff at the end, sort into place next time the API gets incompatible */ + void (*plugin_release_audio_buffer)(void); }; /* plugin header */ @@ -1006,12 +1007,6 @@ extern unsigned char plugin_end_addr[]; #endif /* PLUGIN */ int plugin_load(const char* plugin, const void* parameter); -void* plugin_get_audio_buffer(size_t *buffer_size); - -/* plugin_tsr, - callback returns true to allow the new plugin to load, - reenter means the currently running plugin is being reloaded */ -void plugin_tsr(bool (*exit_callback)(bool reenter)); /* defined by the plugin */ extern const struct plugin_api *rb; diff --git a/apps/plugins/random_folder_advance_config.c b/apps/plugins/random_folder_advance_config.c index 0b3532dde0..add1fc5724 100644 --- a/apps/plugins/random_folder_advance_config.c +++ b/apps/plugins/random_folder_advance_config.c @@ -541,6 +541,9 @@ static int start_shuffled_play(void) } } rb->splash(HZ, "Done"); + /* the core needs the audio buffer back in order to start playback. */ + list = NULL; + rb->plugin_release_audio_buffer(); rb->playlist_start(0, 0, 0); return 1; } |