summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Sevakis <jethead71@rockbox.org>2008-02-28 22:37:46 +0000
committerMichael Sevakis <jethead71@rockbox.org>2008-02-28 22:37:46 +0000
commitf38274f2f9ee6d7b138cff42394f3b251d19b7e0 (patch)
tree4a8d60c68ac1e3d72df3c688be22c4c24887cd5c
parentdaf3ddc70d280533628b7340b054df5afb3e610d (diff)
downloadrockbox-f38274f2f9ee6d7b138cff42394f3b251d19b7e0.zip
rockbox-f38274f2f9ee6d7b138cff42394f3b251d19b7e0.tar.gz
rockbox-f38274f2f9ee6d7b138cff42394f3b251d19b7e0.tar.bz2
rockbox-f38274f2f9ee6d7b138cff42394f3b251d19b7e0.tar.xz
Use a safe way to get pcm buffer track change notifications to the audio thread.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@16450 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r--apps/playback.c49
1 files changed, 47 insertions, 2 deletions
diff --git a/apps/playback.c b/apps/playback.c
index ef6b851..198337c 100644
--- a/apps/playback.c
+++ b/apps/playback.c
@@ -280,6 +280,46 @@ IBSS_ATTR;
static const char codec_thread_name[] = "codec";
struct thread_entry *codec_thread_p; /* For modifying thread priority later. */
+/* PCM buffer messaging */
+static struct event_queue pcmbuf_queue NOCACHEBSS_ATTR;
+
+/* Function to be called by pcm buffer callbacks.
+ * Permissible Context(s): Audio interrupt
+ */
+static void pcmbuf_callback_queue_post(long id, intptr_t data)
+{
+ /* No lock since we're already in audio interrupt context */
+ queue_post(&pcmbuf_queue, id, data);
+}
+
+/* Scan the pcmbuf queue and return true if a message pulled.
+ * Permissible Context(s): Thread
+ */
+static bool pcmbuf_queue_scan(struct queue_event *ev)
+{
+ if (!queue_empty(&pcmbuf_queue))
+ {
+ /* Transfer message to audio queue */
+ pcm_play_lock();
+ /* Pull message - never, ever any blocking call! */
+ queue_wait_w_tmo(&pcmbuf_queue, ev, 0);
+ pcm_play_unlock();
+ return true;
+ }
+
+ return false;
+}
+
+/* Clear the pcmbuf queue of messages
+ * Permissible Context(s): Thread
+ */
+static void pcmbuf_queue_clear(void)
+{
+ pcm_play_lock();
+ queue_clear(&pcmbuf_queue);
+ pcm_play_unlock();
+}
+
/* --- Helper functions --- */
static struct mp3entry *bufgetid3(int handle_id)
@@ -1126,7 +1166,7 @@ static void codec_track_changed(void)
static void codec_pcmbuf_track_changed_callback(void)
{
pcmbuf_set_position_callback(NULL);
- codec_track_changed();
+ pcmbuf_callback_queue_post(Q_AUDIO_TRACK_CHANGED, 0);
}
static void codec_discard_codec_callback(void)
@@ -2160,7 +2200,10 @@ static void audio_stop_codec_flush(void)
* playing, it is now and _only_ now safe to call this function from the
* audio thread */
if (pcm_is_playing())
+ {
pcmbuf_play_stop();
+ pcmbuf_queue_clear();
+ }
pcmbuf_pause(paused);
}
@@ -2428,7 +2471,8 @@ static void audio_thread(void)
while (1)
{
cancel_cpu_boost();
- queue_wait_w_tmo(&audio_queue, &ev, HZ/2);
+ if (!pcmbuf_queue_scan(&ev))
+ queue_wait_w_tmo(&audio_queue, &ev, HZ/2);
switch (ev.id) {
case Q_AUDIO_FILL_BUFFER:
@@ -2578,6 +2622,7 @@ void audio_init(void)
queue_enable_queue_send(&audio_queue, &audio_queue_sender_list);
queue_init(&codec_queue, false);
queue_enable_queue_send(&codec_queue, &codec_queue_sender_list);
+ queue_init(&pcmbuf_queue, false);
pcm_init();