diff options
Diffstat (limited to 'apps')
-rw-r--r-- | apps/codec_thread.c | 47 |
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 | } |