[Sound-open-firmware] [PATCH 1/2] pipeline: stop pipeline processing until data has entered pipe
No data will exist in DMA capture buffers when starting capture pipelines. This causes the downstream pipe to underrun and run XRUN recovery. Add a copy() return value of -ENODATA to indicate that no data has yet entered an active pipeline and stop pipeline processing at this point before rescheduling.
i.e. break from pipeline walk and reschedule.
This removes XRUN recovery work from the capture startup trace.
Signed-off-by: Liam Girdwood liam.r.girdwood@linux.intel.com --- src/audio/pipeline.c | 24 +++++++++++++++++++++++- src/include/reef/audio/component.h | 8 ++++++-- 2 files changed, 29 insertions(+), 3 deletions(-)
diff --git a/src/audio/pipeline.c b/src/audio/pipeline.c index 4fe7896..40a0ebf 100644 --- a/src/audio/pipeline.c +++ b/src/audio/pipeline.c @@ -750,6 +750,12 @@ static int pipeline_copy_from_upstream(struct comp_dev *start, /* continue upstream */ err = pipeline_copy_from_upstream(start, buffer->source); if (err < 0) { + + /* ENODATA is special case where data has not entered pipe yet */ + if (err == -ENODATA) + goto out; + + /* must be an error */ trace_pipe_error("ePU"); trace_value(current->comp.id); return err; @@ -760,6 +766,7 @@ copy: /* we are at the upstream end point component so copy the buffers */ err = comp_copy(current);
+out: /* return back downstream */ tracev_pipe("CD+"); return err; @@ -809,6 +816,12 @@ static int pipeline_copy_to_downstream(struct comp_dev *start, /* continue downstream */ err = pipeline_copy_to_downstream(start, buffer->sink); if (err < 0) { + + /* ENODATA is special case where data has not entered pipe yet */ + if (err == -ENODATA) + goto out; + + /* it must be an error */ trace_pipe_error("ePD"); trace_value(current->comp.id); return err; @@ -1082,6 +1095,11 @@ static void pipeline_task(void *arg) /* copy data from upstream source endpoints to downstream endpoints */ err = pipeline_copy_from_upstream(dev, dev); if (err < 0) { + + /* special case, we reschedule until data enters pipe */ + if (err == -ENODATA) + goto sched; + err = pipeline_xrun_recover(p); if (err < 0) return; /* failed - host will stop this pipeline */ @@ -1090,10 +1108,14 @@ static void pipeline_task(void *arg)
err = pipeline_copy_to_downstream(dev, dev); if (err < 0) { + + /* special case, we reschedule until data enters pipe */ + if (err == -ENODATA) + goto sched; + err = pipeline_xrun_recover(p); if (err < 0) return; /* failed - host will stop this pipeline */ - goto sched; }
sched: diff --git a/src/include/reef/audio/component.h b/src/include/reef/audio/component.h index f25ad3d..59682d4 100644 --- a/src/include/reef/audio/component.h +++ b/src/include/reef/audio/component.h @@ -118,8 +118,12 @@ struct pipeline; /* * Audio component operations - all mandatory. * - * All component operations must return 0 for success, negative values for - * errors and 1 to stop the pipeline walk operation. + * All component operations except copy() must return 0 for success, + * negative values for errors and 1 to stop the pipeline walk operation. + * + * copy() returns 0 for success, positive values for frames produced, + * negative values for errors (except -EDATA meaning no data has entered + * the pipeline and that it must be rescheduled). */ struct comp_ops { /* component creation and destruction */
Let the pipeline know if no data has entered the capture buffers at stream start.
Signed-off-by: Liam Girdwood liam.r.girdwood@linux.intel.com --- src/audio/dai.c | 7 +++++++ 1 file changed, 7 insertions(+)
diff --git a/src/audio/dai.c b/src/audio/dai.c index 2fbfc5f..558369f 100644 --- a/src/audio/dai.c +++ b/src/audio/dai.c @@ -528,6 +528,7 @@ static int dai_cmd(struct comp_dev *dev, int cmd, void *data) break; case COMP_CMD_XRUN: dd->xrun = 1; + /* fall through */ case COMP_CMD_PAUSE: case COMP_CMD_STOP: wait_init(&dd->complete); @@ -550,6 +551,12 @@ static int dai_cmd(struct comp_dev *dev, int cmd, void *data) /* copy and process stream data from source to sink buffers */ static int dai_copy(struct comp_dev *dev) { + /* has data entered the capture buffer yet ? */ + if (dev->params.direction == SOF_IPC_STREAM_CAPTURE && + dev->position == 0) { + /* tell pipeline not to process downstream */ + return -ENODATA; + } return 0; }
On Fri, 2017-12-08 at 22:57 +0000, Liam Girdwood wrote:
No data will exist in DMA capture buffers when starting capture pipelines. This causes the downstream pipe to underrun and run XRUN recovery. Add a copy() return value of -ENODATA to indicate that no data has yet entered an active pipeline and stop pipeline processing at this point before rescheduling.
i.e. break from pipeline walk and reschedule.
This removes XRUN recovery work from the capture startup trace.
Signed-off-by: Liam Girdwood liam.r.girdwood@linux.intel.com
Have a simpler idea, drop this series.
Liam
participants (1)
-
Liam Girdwood