[Sound-open-firmware] [PATCH] pipeline: preload: Fix preload completion detection and add limit

Liam Girdwood liam.r.girdwood at linux.intel.com
Mon Aug 21 21:34:40 CEST 2017


Make sure the preloader can detect when all buffers are loaded prior
to trigger and add a limiter to make sure we dont pre-load forever.

Signed-off-by: Liam Girdwood <liam.r.girdwood at linux.intel.com>
---
 src/audio/host.c                                  |  4 +--
 src/audio/pipeline.c                              | 43 ++++++++++++++++-------
 src/audio/volume.c                                | 11 ++++++
 src/platform/baytrail/include/platform/platform.h |  3 ++
 4 files changed, 46 insertions(+), 15 deletions(-)

diff --git a/src/audio/host.c b/src/audio/host.c
index c95a957..b467036 100644
--- a/src/audio/host.c
+++ b/src/audio/host.c
@@ -471,11 +471,11 @@ static int host_preload(struct comp_dev *dev)
 	ret = wait_for_completion_timeout(&hd->complete);
 	if (ret < 0) {
 		trace_comp_error("eHp");
-		return 0;
+		return -EIO;
 	}
 
 	/* one period copied */
-	return 1;
+	return hd->period_bytes;
 }
 
 static int host_prepare(struct comp_dev *dev)
diff --git a/src/audio/pipeline.c b/src/audio/pipeline.c
index 3bc1f68..1b421da 100644
--- a/src/audio/pipeline.c
+++ b/src/audio/pipeline.c
@@ -300,8 +300,15 @@ static int component_op_downstream(struct op_data *op_data,
 	/* do operation on this component */
 	switch (op_data->op) {
 	case COMP_OPS_PARAMS:
+
+		/* dont do any params downstream if current is running */
+		if (current->state == COMP_STATE_RUNNING)
+			return 0;
+
 		/* send params to the component */
-		err = comp_params(current, op_data->params);
+		if (current != start)
+			comp_install_params(current, SOF_IPC_STREAM_PLAYBACK);
+		err = comp_params(current);
 		break;
 	case COMP_OPS_CMD:
 		/* send command to the component */
@@ -365,8 +372,15 @@ static int component_op_upstream(struct op_data *op_data,
 	/* do operation on this component */
 	switch (op_data->op) {
 	case COMP_OPS_PARAMS:
+
+		/* dont do any params upstream if current is running */
+		if (current->state == COMP_STATE_RUNNING)
+			return 0;
+
 		/* send params to the component */
-		err = comp_params(current, op_data->params);
+		if (current != start)
+			comp_install_params(current, SOF_IPC_STREAM_CAPTURE);
+		err = comp_params(current);
 		break;
 	case COMP_OPS_CMD:
 		/* send command to the component */
@@ -419,7 +433,7 @@ static int preload_downstream(struct comp_dev *start, struct comp_dev *current)
 {
 	struct sof_ipc_comp_config *config = COMP_GET_CONFIG(current);
 	struct list_item *clist;
-	int i, count = 0;
+	int i, total = 0, count = 0;
 
 	trace_pipe("PR-");
 	tracev_value(current->comp.id);
@@ -429,12 +443,13 @@ static int preload_downstream(struct comp_dev *start, struct comp_dev *current)
 		return 0;
 
 	/* now preload the buffers */
-	for (i = 0; i < config->preload_count; i++)
-		count += comp_preload(current);
+	for (i = 0; i < config->preload_count; i++) {
+		count = comp_preload(current);
 
-	/* finished at this level and downstream if no data is preloaded */
-	if (count == 0)
-		return count;
+		if (count < 0)
+			return count;
+		total += count;
+	}
 
 	/* now run this operation downstream */
 	list_for_item(clist, &current->bsink_list) {
@@ -446,14 +461,16 @@ static int preload_downstream(struct comp_dev *start, struct comp_dev *current)
 		if (!buffer->connected)
 			continue;
 
-		count += preload_downstream(start, buffer->sink);
+		count = preload_downstream(start, buffer->sink);
+		if (count < 0)
+			return count;
+
+		total += count;
 	}
 
-	return count;
+	return total;
 }
 
-#define MAX_PRELOAD_SIZE	3
-
 /* prepare the pipeline for usage - preload host buffers here */
 int pipeline_prepare(struct pipeline *p, struct comp_dev *dev)
 {
@@ -483,7 +500,7 @@ int pipeline_prepare(struct pipeline *p, struct comp_dev *dev)
 			count = preload_downstream(dev, dev);
 
 			/* complete ? */
-			if (count == 0)
+			if (count <= 0)
 				goto out;
 		}
 
diff --git a/src/audio/volume.c b/src/audio/volume.c
index 1ceab4f..4728d91 100644
--- a/src/audio/volume.c
+++ b/src/audio/volume.c
@@ -583,6 +583,17 @@ found:
 
 static int volume_preload(struct comp_dev *dev)
 {
+	struct comp_data *cd = comp_get_drvdata(dev);
+	struct comp_buffer *sink;
+
+	trace_volume("PrL");
+
+	/* make sure there is enough space in sink buffer */
+	sink = list_first_item(&dev->bsink_list, struct comp_buffer,
+		source_list);
+	if (sink->free < cd->sink_period_bytes)
+		return 0;
+
 	return volume_copy(dev);
 }
 
diff --git a/src/platform/baytrail/include/platform/platform.h b/src/platform/baytrail/include/platform/platform.h
index d083479..1ad0a22 100644
--- a/src/platform/baytrail/include/platform/platform.h
+++ b/src/platform/baytrail/include/platform/platform.h
@@ -54,6 +54,9 @@ struct reef;
 
 #define PLATFORM_SCHEDULE_COST	200
 
+/* maximum preload pipeline depth */
+#define MAX_PRELOAD_SIZE	20
+
 /* DMA treats PHY addresses as host address unless within DSP region */
 #define PLATFORM_HOST_DMA_MASK	0xFF000000
 
-- 
2.11.0



More information about the Sound-open-firmware mailing list