More strictly enforce "no PCM insert" rules for codecs.
Takes care of when codecs try to sneak-in another PCM buffer insert at the wrong time. Codecs are wiley and just can't always be trusted to cooperate. Change-Id: Idc2f51238a5fd69a9d9c0741fbc29addc6615bdf
This commit is contained in:
parent
1d21e54fc4
commit
80d5267a9b
1 changed files with 27 additions and 20 deletions
|
@ -214,39 +214,40 @@ static void codec_pcmbuf_insert_callback(
|
|||
const void *ch1, const void *ch2, int count)
|
||||
{
|
||||
struct dsp_buffer src;
|
||||
|
||||
src.remcount = count;
|
||||
src.pin[0] = ch1;
|
||||
src.pin[1] = ch2;
|
||||
src.proc_mask = 0;
|
||||
|
||||
while (1)
|
||||
while (LIKELY(queue_empty(&codec_queue)) ||
|
||||
codec_check_queue__have_msg() >= 0)
|
||||
{
|
||||
struct dsp_buffer dst;
|
||||
dst.remcount = 0;
|
||||
dst.bufcount = MAX(src.remcount, 1024); /* Arbitrary min request */
|
||||
|
||||
while ((dst.p16out = pcmbuf_request_buffer(&dst.bufcount)) == NULL)
|
||||
if ((dst.p16out = pcmbuf_request_buffer(&dst.bufcount)) == NULL)
|
||||
{
|
||||
cancel_cpu_boost();
|
||||
|
||||
/* It may be awhile before space is available but we want
|
||||
"instant" response to any message */
|
||||
queue_wait_w_tmo(&codec_queue, NULL, HZ/20);
|
||||
}
|
||||
else
|
||||
{
|
||||
dsp_process(ci.dsp, &src, &dst);
|
||||
|
||||
if (!queue_empty(&codec_queue) &&
|
||||
codec_check_queue__have_msg() < 0)
|
||||
if (dst.remcount > 0)
|
||||
{
|
||||
return;
|
||||
pcmbuf_write_complete(dst.remcount, ci.id3->elapsed,
|
||||
ci.id3->offset);
|
||||
}
|
||||
else if (src.remcount <= 0)
|
||||
{
|
||||
return; /* No input remains and DSP purged */
|
||||
}
|
||||
}
|
||||
|
||||
dsp_process(ci.dsp, &src, &dst);
|
||||
|
||||
if (dst.remcount > 0)
|
||||
pcmbuf_write_complete(dst.remcount, ci.id3->elapsed, ci.id3->offset);
|
||||
else if (src.remcount <= 0)
|
||||
break; /* No input remains and DSP purged */
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -360,9 +361,12 @@ static enum codec_command_action
|
|||
{
|
||||
enum codec_command_action action = CODEC_ACTION_NULL;
|
||||
struct queue_event ev;
|
||||
queue_wait(&codec_queue, &ev);
|
||||
|
||||
switch (ev.id)
|
||||
queue_peek(&codec_queue, &ev); /* Find out what it is */
|
||||
|
||||
long id = ev.id;
|
||||
|
||||
switch (id)
|
||||
{
|
||||
case Q_CODEC_RUN: /* Already running */
|
||||
LOGFQUEUE("codec < Q_CODEC_RUN");
|
||||
|
@ -370,27 +374,30 @@ static enum codec_command_action
|
|||
|
||||
case Q_CODEC_PAUSE: /* Stay here and wait */
|
||||
LOGFQUEUE("codec < Q_CODEC_PAUSE");
|
||||
queue_wait(&codec_queue, &ev); /* Remove message */
|
||||
codec_queue_ack(Q_CODEC_PAUSE);
|
||||
queue_wait(&codec_queue, NULL); /* Wait for next (no remove) */
|
||||
continue;
|
||||
|
||||
case Q_CODEC_SEEK: /* Audio wants codec to seek */
|
||||
LOGFQUEUE("codec < Q_CODEC_SEEK %ld", ev.data);
|
||||
*param = ev.data;
|
||||
action = CODEC_ACTION_SEEK_TIME;
|
||||
trigger_cpu_boost();
|
||||
break;
|
||||
|
||||
case Q_CODEC_STOP: /* Must only return 0 in main loop */
|
||||
LOGFQUEUE("codec < Q_CODEC_STOP");
|
||||
action = CODEC_ACTION_HALT;
|
||||
dsp_configure(ci.dsp, DSP_FLUSH, 0); /* Discontinuity */
|
||||
break;
|
||||
return CODEC_ACTION_HALT; /* Leave in queue */
|
||||
|
||||
default: /* This is in error in this context. */
|
||||
ev.id = Q_NULL;
|
||||
logf("codec bad req %ld (%s)", ev.id, __func__);
|
||||
id = Q_NULL;
|
||||
}
|
||||
|
||||
codec_queue_ack(ev.id);
|
||||
queue_wait(&codec_queue, &ev); /* Actually remove it */
|
||||
codec_queue_ack(id);
|
||||
return action;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue