ASOC:Skip first buffer if not full

Mitigate the issue from ADSP side during low latency record where the PP service takes long time
to propagate the media format and causes buffer drops and time stamp discontinuity, discard the
first partial buffer received from ADSP.

Change-Id: Ib5ef817868ccd4ae597b764ddd85b18b7d870615
Signed-off-by: E V Ravi <evenka@codeaurora.org>
This commit is contained in:
E V Ravi 2021-04-12 17:39:48 +05:30 • committed by Gerrit - the friendly Code Review server
commit 8d11a166ff
3 changed files with 61 additions and 0 deletions

View file

@ -205,6 +205,23 @@ static void event_handler(uint32_t opcode,
prtd->in_frame_info[buf_index].offset = payload[5];
/* assume data size = 0 during flushing */
if (prtd->in_frame_info[buf_index].size) {
if ((int)substream->runtime->control->appl_ptr == 0 && prtd->in_frame_info[buf_index].size < prtd->pcm_count) {
pr_debug("%s:skip first buffer until get full buffer size=%d: prtd->pcm_count=%d\n",
__func__, prtd->in_frame_info[buf_index].size, prtd->pcm_count);
memset(&prtd->in_frame_info[buf_index], 0,
sizeof(struct msm_audio_in_frame_info));
if (q6asm_is_cpu_buf_avail_nolock(OUT, prtd->audio_client,&size, &idx) &&
(substream->runtime->status->state == SNDRV_PCM_STATE_RUNNING)) {
ret = q6asm_read_nolock(prtd->audio_client);
if (ret < 0) {
pr_err("%s:q6asm read failed\n",__func__);
ret = -EFAULT;
q6asm_cpu_buf_release_nolock(OUT, prtd->audio_client);
}
}
return;
}
prtd->pcm_irq_pos +=
prtd->in_frame_info[buf_index].size;
pr_debug("pcm_irq_pos=%d\n", prtd->pcm_irq_pos);

View file

@ -2759,6 +2759,48 @@ exit:
}
EXPORT_SYMBOL(q6asm_cpu_buf_release);
/**
* q6asm_cpu_buf_release_nolock -
* releases cpu buffer for ASM
*
* @dir: RX or TX direction
* @ac: Audio client handle
*
* Returns 0 on success or error on failure
**/
int q6asm_cpu_buf_release_nolock(int dir, struct audio_client *ac)
{
struct audio_port_data *port;
int ret = 0;
int idx;
if (!ac || ((dir != IN) && (dir != OUT))) {
pr_err("%s: ac %pK dir %d\n", __func__, ac, dir);
ret = -EINVAL;
goto exit;
}
if (ac->io_mode & SYNC_IO_MODE) {
port = &ac->port[dir];
idx = port->cpu_buf;
if (port->cpu_buf == 0) {
port->cpu_buf = port->max_buf_cnt - 1;
} else if (port->cpu_buf < port->max_buf_cnt) {
port->cpu_buf = port->cpu_buf - 1;
} else {
pr_err("%s: buffer index(%d) out of range\n",
__func__, port->cpu_buf);
ret = -EINVAL;
goto exit;
}
port->buf[port->cpu_buf].used = dir ^ 1;
}
exit:
return ret;
}
EXPORT_SYMBOL(q6asm_cpu_buf_release_nolock);
/**
* q6asm_is_cpu_buf_avail_nolock -
* retrieve next CPU buf avail without lock acquire

View file

@ -431,6 +431,8 @@ void *q6asm_is_cpu_buf_avail(int dir, struct audio_client *ac,
int q6asm_cpu_buf_release(int dir, struct audio_client *ac);
int q6asm_cpu_buf_release_nolock(int dir, struct audio_client *ac);
void *q6asm_is_cpu_buf_avail_nolock(int dir, struct audio_client *ac,
uint32_t *size, uint32_t *idx);