summaryrefslogtreecommitdiff
path: root/apps
diff options
context:
space:
mode:
Diffstat (limited to 'apps')
-rw-r--r--apps/playback.c21
-rw-r--r--apps/playback.h2
-rw-r--r--apps/plugin.c10
-rw-r--r--apps/plugin.h13
-rw-r--r--apps/plugins/mpegplayer/audio_thread.c75
-rw-r--r--apps/plugins/test_codec.c60
6 files changed, 56 insertions, 125 deletions
diff --git a/apps/playback.c b/apps/playback.c
index 0f76666..91f85f9 100644
--- a/apps/playback.c
+++ b/apps/playback.c
@@ -150,6 +150,8 @@ enum {
Q_ENCODER_LOAD_DISK,
Q_ENCODER_RECORD,
#endif
+
+ Q_CODEC_DO_CALLBACK,
};
enum filling_state {
@@ -1303,6 +1305,13 @@ static void codec_thread(void)
status = codec_load_buf(CUR_TI->codec_hid, &ci);
break;
+ case Q_CODEC_DO_CALLBACK:
+ LOGFQUEUE("codec < Q_CODEC_DO_CALLBACK");
+ queue_reply(&codec_queue, 1);
+ if ((void*)ev.data != NULL)
+ ((void (*)(void))ev.data)();
+ break;
+
#ifdef AUDIO_HAVE_RECORDING
case Q_ENCODER_LOAD_DISK:
LOGFQUEUE("codec < Q_ENCODER_LOAD_DISK");
@@ -1419,6 +1428,18 @@ static void codec_thread(void)
}
}
+/* Borrow the codec thread and return the ID */
+void codec_thread_do_callback(void (*fn)(void), unsigned int *id)
+{
+ /* Set id before telling thread to call something; it may be
+ * needed before this function returns. */
+ if (id != NULL)
+ *id = codec_thread_id;
+
+ /* Codec thread will signal just before entering callback */
+ LOGFQUEUE("codec >| Q_CODEC_DO_CALLBACK");
+ queue_send(&codec_queue, Q_CODEC_DO_CALLBACK, (intptr_t)fn);
+}
/* --- Buffering callbacks --- */
diff --git a/apps/playback.h b/apps/playback.h
index e65d5da..3fcb454 100644
--- a/apps/playback.h
+++ b/apps/playback.h
@@ -42,6 +42,8 @@ enum
AUDIO_WANT_VOICE,
};
bool audio_restore_playback(int type); /* Restores the audio buffer to handle the requested playback */
+void codec_thread_do_callback(void (*fn)(void),
+ unsigned int *codec_thread_id);
#ifdef HAVE_ALBUMART
int audio_current_aa_hid(void);
diff --git a/apps/plugin.c b/apps/plugin.c
index 3efd31c..cc0a94b 100644
--- a/apps/plugin.c
+++ b/apps/plugin.c
@@ -71,8 +71,6 @@ static char current_plugin[MAX_PATH];
char *plugin_get_current_filename(void);
-extern struct thread_entry threads[MAXTHREADS];
-
static const struct plugin_api rockbox_api = {
/* lcd */
@@ -293,11 +291,14 @@ static const struct plugin_api rockbox_api = {
&current_tick,
default_event_handler,
default_event_handler_ex,
- threads,
create_thread,
thread_exit,
thread_wait,
#if (CONFIG_CODEC == SWCODEC)
+ thread_thaw,
+#ifdef HAVE_PRIORITY_SCHEDULING
+ thread_set_priority,
+#endif
mutex_init,
mutex_lock,
mutex_unlock,
@@ -544,6 +545,7 @@ static const struct plugin_api rockbox_api = {
&global_status,
talk_disable,
#if CONFIG_CODEC == SWCODEC
+ codec_thread_do_callback,
codec_load_file,
get_codec_filename,
get_metadata,
@@ -611,8 +613,6 @@ static const struct plugin_api rockbox_api = {
search_albumart_files,
#endif
- thread_thaw,
-
#ifdef HAVE_SEMAPHORE_OBJECTS
semaphore_init,
semaphore_wait,
diff --git a/apps/plugin.h b/apps/plugin.h
index a06f009..390a65c 100644
--- a/apps/plugin.h
+++ b/apps/plugin.h
@@ -132,12 +132,12 @@ 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 134
+#define PLUGIN_API_VERSION 135
/* update this to latest version if a change to the api struct breaks
backwards compatibility (and please take the opportunity to sort in any
new function which are "waiting" at the end of the function table) */
-#define PLUGIN_MIN_API_VERSION 134
+#define PLUGIN_MIN_API_VERSION 135
/* plugin return codes */
enum plugin_status {
@@ -410,7 +410,6 @@ struct plugin_api {
volatile long* current_tick;
long (*default_event_handler)(long event);
long (*default_event_handler_ex)(long event, void (*callback)(void *), void *parameter);
- struct thread_entry* threads;
unsigned int (*create_thread)(void (*function)(void), void* stack,
size_t stack_size, unsigned flags,
const char *name
@@ -419,6 +418,10 @@ struct plugin_api {
void (*thread_exit)(void);
void (*thread_wait)(unsigned int thread_id);
#if CONFIG_CODEC == SWCODEC
+ void (*thread_thaw)(unsigned int thread_id);
+#ifdef HAVE_PRIORITY_SCHEDULING
+ int (*thread_set_priority)(unsigned int thread_id, int priority);
+#endif
void (*mutex_init)(struct mutex *m);
void (*mutex_lock)(struct mutex *m);
void (*mutex_unlock)(struct mutex *m);
@@ -693,6 +696,8 @@ struct plugin_api {
struct system_status *global_status;
void (*talk_disable)(bool disable);
#if CONFIG_CODEC == SWCODEC
+ void (*codec_thread_do_callback)(void (*fn)(void),
+ unsigned int *audio_thread_id);
int (*codec_load_file)(const char* codec, struct codec_api *api);
const char *(*get_codec_filename)(int cod_spec);
bool (*get_metadata)(struct mp3entry* id3, int fd, const char* trackname);
@@ -775,8 +780,6 @@ struct plugin_api {
char *buf, int buflen);
#endif
- void (*thread_thaw)(unsigned int thread_id);
-
#ifdef HAVE_SEMAPHORE_OBJECTS
void (*semaphore_init)(struct semaphore *s, int max, int start);
void (*semaphore_wait)(struct semaphore *s);
diff --git a/apps/plugins/mpegplayer/audio_thread.c b/apps/plugins/mpegplayer/audio_thread.c
index 2fb46ef..f655221 100644
--- a/apps/plugins/mpegplayer/audio_thread.c
+++ b/apps/plugins/mpegplayer/audio_thread.c
@@ -38,14 +38,7 @@ struct audio_thread_data
struct dsp_config *dsp; /* The DSP we're using */
};
-/* The audio stack is stolen from the core codec thread (but not in uisim) */
-/* Used for stealing codec thread's stack */
-static uint32_t* audio_stack;
-static size_t audio_stack_size; /* Keep gcc happy and init */
-#define AUDIO_STACKSIZE (9*1024)
-#ifndef SIMULATOR
-static uint32_t codec_stack_copy[AUDIO_STACKSIZE / sizeof(uint32_t)];
-#endif
+/* The audio thread is stolen from the core codec thread */
static struct event_queue audio_str_queue SHAREDBSS_ATTR;
static struct queue_sender_list audio_str_queue_send SHAREDBSS_ATTR;
struct stream audio_str IBSS_ATTR;
@@ -473,6 +466,11 @@ static void audio_thread_msg(struct audio_thread_data *td)
static void audio_thread(void)
{
struct audio_thread_data td;
+#ifdef HAVE_PRIORITY_SCHEDULING
+ /* Up the priority since the core DSP over-yields internally */
+ int old_priority = rb->thread_set_priority(THREAD_ID_CURRENT,
+ PRIORITY_PLAYBACK-4);
+#endif
rb->memset(&td, 0, sizeof (td));
td.status = STREAM_STOPPED;
@@ -512,7 +510,13 @@ static void audio_thread(void)
case TSTATE_RENDER_WAIT: goto render_wait;
case TSTATE_RENDER_WAIT_END: goto render_wait_end;
/* Anything else is interpreted as an exit */
- default: return;
+ default:
+ {
+#ifdef HAVE_PRIORITY_SCHEDULING
+ rb->thread_set_priority(THREAD_ID_CURRENT, old_priority);
+#endif
+ return;
+ }
}
}
@@ -677,43 +681,6 @@ static void audio_thread(void)
/* Initializes the audio thread resources and starts the thread */
bool audio_thread_init(void)
{
- int i;
-#ifdef SIMULATOR
- /* The simulator thread implementation doesn't have stack buffers, and
- these parameters are ignored. */
- (void)i; /* Keep gcc happy */
- audio_stack = NULL;
- audio_stack_size = 0;
-#else
- /* Borrow the codec thread's stack (in IRAM on most targets) */
- audio_stack = NULL;
- for (i = 0; i < MAXTHREADS; i++)
- {
- if (rb->strcmp(rb->threads[i].name, "codec") == 0)
- {
- /* Wait to ensure the codec thread has blocked */
- while (rb->threads[i].state != STATE_BLOCKED)
- rb->yield();
-
- /* Now we can steal the stack */
- audio_stack = rb->threads[i].stack;
- audio_stack_size = rb->threads[i].stack_size;
-
- /* Backup the codec thread's stack */
- rb->memcpy(codec_stack_copy, audio_stack, audio_stack_size);
- break;
- }
- }
-
- if (audio_stack == NULL)
- {
- /* This shouldn't happen, but deal with it anyway by using
- the copy instead */
- audio_stack = codec_stack_copy;
- audio_stack_size = AUDIO_STACKSIZE;
- }
-#endif
-
/* Initialise the encoded audio buffer and its descriptors */
audio_queue.start = mpeg_malloc(AUDIOBUF_ALLOC_SIZE,
MPEG_ALLOC_AUDIOBUF);
@@ -724,17 +691,12 @@ bool audio_thread_init(void)
audio_str.hdr.q = &audio_str_queue;
rb->queue_init(audio_str.hdr.q, false);
- /* One-up on the priority since the core DSP over-yields internally */
- audio_str.thread = rb->create_thread(
- audio_thread, audio_stack, audio_stack_size, 0,
- "mpgaudio" IF_PRIO(,PRIORITY_PLAYBACK-4) IF_COP(, CPU));
+ /* We steal the codec thread for audio */
+ rb->codec_thread_do_callback(audio_thread, &audio_str.thread);
rb->queue_enable_queue_send(audio_str.hdr.q, &audio_str_queue_send,
audio_str.thread);
- if (audio_str.thread == 0)
- return false;
-
/* Wait for thread to initialize */
str_send_msg(&audio_str, STREAM_NULL, 0);
@@ -747,12 +709,7 @@ void audio_thread_exit(void)
if (audio_str.thread != 0)
{
str_post_msg(&audio_str, STREAM_QUIT, 0);
- rb->thread_wait(audio_str.thread);
+ rb->codec_thread_do_callback(NULL, NULL);
audio_str.thread = 0;
}
-
-#ifndef SIMULATOR
- /* Restore the codec thread's stack */
- rb->memcpy(audio_stack, codec_stack_copy, audio_stack_size);
-#endif
}
diff --git a/apps/plugins/test_codec.c b/apps/plugins/test_codec.c
index 17effd8..20a1feb 100644
--- a/apps/plugins/test_codec.c
+++ b/apps/plugins/test_codec.c
@@ -513,9 +513,6 @@ static void codec_thread(void)
codec_playing = false;
}
-static uintptr_t* codec_stack;
-static size_t codec_stack_size;
-
static enum plugin_status test_track(const char* filename)
{
size_t n;
@@ -525,7 +522,6 @@ static enum plugin_status test_track(const char* filename)
long ticks;
unsigned long speed;
unsigned long duration;
- unsigned int codecthread_id;
const char* ch;
/* Display filename (excluding any path)*/
@@ -588,13 +584,7 @@ static enum plugin_status test_track(const char* filename)
codec_playing = true;
- if ((codecthread_id = rb->create_thread(codec_thread,
- codec_stack, codec_stack_size, 0, "testcodec"
- IF_PRIO(,PRIORITY_PLAYBACK) IF_COP(, CPU))) == 0)
- {
- log_text("Cannot create codec thread!",true);
- goto exit;
- }
+ rb->codec_thread_do_callback(codec_thread, NULL);
/* Wait for codec thread to die */
while (codec_playing)
@@ -606,7 +596,7 @@ static enum plugin_status test_track(const char* filename)
ticks = endtick - starttick;
/* Be sure it is done */
- rb->thread_wait(codecthread_id);
+ rb->codec_thread_do_callback(NULL, NULL);
log_text(str,true);
@@ -656,11 +646,9 @@ exit:
/* plugin entry point */
enum plugin_status plugin_start(const struct plugin_api* api, const void* parameter)
{
- uintptr_t* codec_stack_copy;
int result, selection = 0;
enum plugin_status res = PLUGIN_OK;
int scandir;
- int i;
struct dirent *entry;
DIR* dir;
char* ch;
@@ -676,43 +664,8 @@ enum plugin_status plugin_start(const struct plugin_api* api, const void* parame
}
codec_mallocbuf = rb->plugin_get_audio_buffer(&audiosize);
-
-#ifdef SIMULATOR
- /* The simulator thread implementation doesn't have stack buffers */
- (void)i;
- codec_stack_size = 0;
-#else
- /* Borrow the codec thread's stack (in IRAM on most targets) */
- codec_stack = NULL;
- for (i = 0; i < MAXTHREADS; i++)
- {
- if (rb->strcmp(rb->threads[i].name,"codec")==0)
- {
- /* Wait to ensure the codec thread has blocked */
- while (rb->threads[i].state!=STATE_BLOCKED)
- rb->yield();
-
- codec_stack = rb->threads[i].stack;
- codec_stack_size = rb->threads[i].stack_size;
- break;
- }
- }
-
- if (codec_stack == NULL)
- {
- rb->splash(HZ*2, "No codec thread!");
- return PLUGIN_ERROR;
- }
-#endif
-
- codec_stack_copy = codec_mallocbuf + CODEC_SIZE;
- audiobuf = SKIPBYTES(codec_stack_copy, codec_stack_size);
- audiosize -= CODEC_SIZE + codec_stack_size;
-
-#ifndef SIMULATOR
- /* Backup the codec thread's stack */
- rb->memcpy(codec_stack_copy,codec_stack,codec_stack_size);
-#endif
+ audiobuf = SKIPBYTES(codec_mallocbuf, CODEC_SIZE);
+ audiosize -= CODEC_SIZE;
#ifdef HAVE_ADJUSTABLE_CPU_FREQ
rb->cpu_boost(true);
@@ -803,11 +756,6 @@ enum plugin_status plugin_start(const struct plugin_api* api, const void* parame
exit:
log_close();
-#ifndef SIMULATOR
- /* Restore the codec thread's stack */
- rb->memcpy(codec_stack, codec_stack_copy, codec_stack_size);
-#endif
-
#ifdef HAVE_ADJUSTABLE_CPU_FREQ
rb->cpu_boost(false);
#endif