1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
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.