Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 8d11a166 authored by E V Ravi's avatar E V Ravi Committed by Gerrit - the friendly Code Review server
Browse files

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: default avatarE V Ravi <evenka@codeaurora.org>
parent e2c2fd50
Loading
Loading
Loading
Loading
+17 −0
Original line number Diff line number Diff line
@@ -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);
+42 −0
Original line number Diff line number Diff line
@@ -2759,6 +2759,48 @@ int q6asm_cpu_buf_release(int dir, struct audio_client *ac)
}
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
+2 −0
Original line number Diff line number Diff line
@@ -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);