summaryrefslogtreecommitdiff
path: root/apps
diff options
context:
space:
mode:
Diffstat (limited to 'apps')
-rw-r--r--apps/codec_thread.c47
1 files changed, 27 insertions, 20 deletions
diff --git a/apps/codec_thread.c b/apps/codec_thread.c
index 523f0b8e35..308b2ff982 100644
--- a/apps/codec_thread.c
+++ b/apps/codec_thread.c
@@ -214,40 +214,41 @@ static void codec_pcmbuf_insert_callback(
214 const void *ch1, const void *ch2, int count) 214 const void *ch1, const void *ch2, int count)
215{ 215{
216 struct dsp_buffer src; 216 struct dsp_buffer src;
217
218 src.remcount = count; 217 src.remcount = count;
219 src.pin[0] = ch1; 218 src.pin[0] = ch1;
220 src.pin[1] = ch2; 219 src.pin[1] = ch2;
221 src.proc_mask = 0; 220 src.proc_mask = 0;
222 221
223 while (1) 222 while (LIKELY(queue_empty(&codec_queue)) ||
223 codec_check_queue__have_msg() >= 0)
224 { 224 {
225 struct dsp_buffer dst; 225 struct dsp_buffer dst;
226 dst.remcount = 0; 226 dst.remcount = 0;
227 dst.bufcount = MAX(src.remcount, 1024); /* Arbitrary min request */ 227 dst.bufcount = MAX(src.remcount, 1024); /* Arbitrary min request */
228 228
229 while ((dst.p16out = pcmbuf_request_buffer(&dst.bufcount)) == NULL) 229 if ((dst.p16out = pcmbuf_request_buffer(&dst.bufcount)) == NULL)
230 { 230 {
231 cancel_cpu_boost(); 231 cancel_cpu_boost();
232 232
233 /* It may be awhile before space is available but we want 233 /* It may be awhile before space is available but we want
234 "instant" response to any message */ 234 "instant" response to any message */
235 queue_wait_w_tmo(&codec_queue, NULL, HZ/20); 235 queue_wait_w_tmo(&codec_queue, NULL, HZ/20);
236 }
237 else
238 {
239 dsp_process(ci.dsp, &src, &dst);
236 240
237 if (!queue_empty(&codec_queue) && 241 if (dst.remcount > 0)
238 codec_check_queue__have_msg() < 0)
239 { 242 {
240 return; 243 pcmbuf_write_complete(dst.remcount, ci.id3->elapsed,
244 ci.id3->offset);
245 }
246 else if (src.remcount <= 0)
247 {
248 return; /* No input remains and DSP purged */
241 } 249 }
242 } 250 }
243 251 }
244 dsp_process(ci.dsp, &src, &dst);
245
246 if (dst.remcount > 0)
247 pcmbuf_write_complete(dst.remcount, ci.id3->elapsed, ci.id3->offset);
248 else if (src.remcount <= 0)
249 break; /* No input remains and DSP purged */
250 }
251} 252}
252 253
253/* helper function, not a callback */ 254/* helper function, not a callback */
@@ -360,9 +361,12 @@ static enum codec_command_action
360 { 361 {
361 enum codec_command_action action = CODEC_ACTION_NULL; 362 enum codec_command_action action = CODEC_ACTION_NULL;
362 struct queue_event ev; 363 struct queue_event ev;
363 queue_wait(&codec_queue, &ev);
364 364
365 switch (ev.id) 365 queue_peek(&codec_queue, &ev); /* Find out what it is */
366
367 long id = ev.id;
368
369 switch (id)
366 { 370 {
367 case Q_CODEC_RUN: /* Already running */ 371 case Q_CODEC_RUN: /* Already running */
368 LOGFQUEUE("codec < Q_CODEC_RUN"); 372 LOGFQUEUE("codec < Q_CODEC_RUN");
@@ -370,27 +374,30 @@ static enum codec_command_action
370 374
371 case Q_CODEC_PAUSE: /* Stay here and wait */ 375 case Q_CODEC_PAUSE: /* Stay here and wait */
372 LOGFQUEUE("codec < Q_CODEC_PAUSE"); 376 LOGFQUEUE("codec < Q_CODEC_PAUSE");
377 queue_wait(&codec_queue, &ev); /* Remove message */
373 codec_queue_ack(Q_CODEC_PAUSE); 378 codec_queue_ack(Q_CODEC_PAUSE);
379 queue_wait(&codec_queue, NULL); /* Wait for next (no remove) */
374 continue; 380 continue;
375 381
376 case Q_CODEC_SEEK: /* Audio wants codec to seek */ 382 case Q_CODEC_SEEK: /* Audio wants codec to seek */
377 LOGFQUEUE("codec < Q_CODEC_SEEK %ld", ev.data); 383 LOGFQUEUE("codec < Q_CODEC_SEEK %ld", ev.data);
378 *param = ev.data; 384 *param = ev.data;
379 action = CODEC_ACTION_SEEK_TIME; 385 action = CODEC_ACTION_SEEK_TIME;
386 trigger_cpu_boost();
380 break; 387 break;
381 388
382 case Q_CODEC_STOP: /* Must only return 0 in main loop */ 389 case Q_CODEC_STOP: /* Must only return 0 in main loop */
383 LOGFQUEUE("codec < Q_CODEC_STOP"); 390 LOGFQUEUE("codec < Q_CODEC_STOP");
384 action = CODEC_ACTION_HALT;
385 dsp_configure(ci.dsp, DSP_FLUSH, 0); /* Discontinuity */ 391 dsp_configure(ci.dsp, DSP_FLUSH, 0); /* Discontinuity */
386 break; 392 return CODEC_ACTION_HALT; /* Leave in queue */
387 393
388 default: /* This is in error in this context. */ 394 default: /* This is in error in this context. */
389 ev.id = Q_NULL;
390 logf("codec bad req %ld (%s)", ev.id, __func__); 395 logf("codec bad req %ld (%s)", ev.id, __func__);
396 id = Q_NULL;
391 } 397 }
392 398
393 codec_queue_ack(ev.id); 399 queue_wait(&codec_queue, &ev); /* Actually remove it */
400 codec_queue_ack(id);
394 return action; 401 return action;
395 } 402 }
396} 403}