diff --git a/apps/plugin.c b/apps/plugin.c
index 5a02409..74c544d 100644
--- a/apps/plugin.c
+++ b/apps/plugin.c
@@ -114,7 +114,7 @@ extern unsigned char pluginbuf[];
#endif

/* for actual plugins only, not for codecs */
-static int plugin_size = 0;
+static size_t plugin_size = 0;
static bool (*pfn_tsr_exit)(bool reenter) = NULL; /* TSR exit callback */
static char current_plugin[MAX_PATH];
/* NULL if no plugin is loaded, otherwise the handle that lc_open() returned */
@@ -808,9 +808,7 @@ int plugin_load(const char* plugin, const void* parameter)
* this isn't needed yet but I place it here to not
* forget later when it will be really needed
*/
- mem_info.dram = (void *)(((uintptr_t)mem_info.dram+(CACHEALIGN_SIZE-1)) &
- ~(CACHEALIGN_SIZE - 1));
- mem_info.dram_size = (mem_info.dram_size & ~(CACHEALIGN_SIZE - 1));
+ ALIGN_BUFFER(mem_info.dram, mem_info.dram_size, CACHEALIGN_SIZE);

/* to be changed later */
mem_info.iram = (void *)PLUGIN_IRAMORIG;
@@ -839,7 +837,20 @@ int plugin_load(const char* plugin, const void* parameter)
#endif

current_plugin_handle = elf_open(plugin, &mem_info);
- if (current_plugin_handle == NULL) {
+
+ if ((current_plugin_handle == NULL) &&
+ (mem_info.dram_runtime_use > mem_info.dram_size))
+ {
+ /* Not enough memory, try to load it into audio buffer */
+ mem_info.dram = (void *)plugin_get_audio_buffer(&mem_info.dram_size);
+
+ ALIGN_BUFFER(mem_info.dram, mem_info.dram_size, CACHEALIGN_SIZE);
+
+ current_plugin_handle = elf_open(plugin, &mem_info);
+ }
+
+ if (current_plugin_handle == NULL)
+ {
splashf(HZ*2, str(LANG_PLUGIN_CANT_OPEN), plugin);
return -1;
}
@@ -902,9 +913,6 @@ int plugin_load(const char* plugin, const void* parameter)
open_files = 0;
#endif

- /* commit caches */
- commit_discard_idcache();
-
int rc = p_hdr->entry_point(parameter);

tree_unlock_cache(tree_get_context());
@@ -984,12 +992,14 @@ void* plugin_get_buffer(size_t *buffer_size)
{
int buffer_pos;

- if (current_plugin_handle)
+ /* Check if plugin is loaded in audiobuf or in pluginbuf */
+ if ((current_plugin_handle >= (void *)pluginbuf) &&
+ (current_plugin_handle <= (void *)(pluginbuf + PLUGIN_BUFFER_SIZE)))
{
if (plugin_size >= PLUGIN_BUFFER_SIZE)
return NULL;

- *buffer_size = PLUGIN_BUFFER_SIZE-plugin_size;
+ *buffer_size = PLUGIN_BUFFER_SIZE - plugin_size;
buffer_pos = plugin_size;
}
else
@@ -998,7 +1008,7 @@ void* plugin_get_buffer(size_t *buffer_size)
buffer_pos = 0;
}

- return &pluginbuf[buffer_pos];
+ return (void *)(pluginbuf + buffer_pos);
}

/* Returns a pointer to the mp3 buffer.
@@ -1007,8 +1017,31 @@ void* plugin_get_buffer(size_t *buffer_size)
*/
void* plugin_get_audio_buffer(size_t *buffer_size)
{
+ char *audiobuf;
+ int buffer_pos;
+ size_t audiobuf_size;
+
audio_stop();
- return audio_get_buffer(true, buffer_size);
+
+ audiobuf = (char *)audio_get_buffer(true, &audiobuf_size);
+
+ /* Check if plugin is loaded in audiobuf or in pluginbuf */
+ if ((current_plugin_handle >= (void *)audiobuf) &&
+ (current_plugin_handle < (void *)(audiobuf + audiobuf_size)))
+ {
+ if (plugin_size >= audiobuf_size)
+ return NULL;
+
+ *buffer_size = audiobuf_size - plugin_size;
+ buffer_pos = plugin_size;
+ }
+ else
+ {
+ *buffer_size = audiobuf_size;
+ buffer_pos = 0;
+ }
+
+ return (void *)(audiobuf + buffer_pos);
}

/* The plugin wants to stay resident after leaving its main function, e.g.