From b05ec0066b7ecf2c4c9a85147f050ef374467e49 Mon Sep 17 00:00:00 2001 From: Slawomir Blauciak Date: Fri, 25 Jan 2019 15:49:22 +0800 Subject: [PATCH] pipeline: add a flag for FW xrun recovery disabling Add a flag NO_XRUN_RECOVERY to disable the FW internal xrun recovery, make it to false by default. Signed-off-by: Slawomir Blauciak Signed-off-by: Keyon Jie --- src/audio/pipeline.c | 39 +++++++++++++++++++++----------- src/include/sof/audio/pipeline.h | 7 ++++++ 2 files changed, 33 insertions(+), 13 deletions(-) diff --git a/src/audio/pipeline.c b/src/audio/pipeline.c index 54df2118cc92..54d0b038d4cf 100644 --- a/src/audio/pipeline.c +++ b/src/audio/pipeline.c @@ -677,6 +677,7 @@ void pipeline_xrun(struct pipeline *p, struct comp_dev *dev, { struct pipeline_data data; struct sof_ipc_stream_posn posn; + int ret; /* don't flood host */ if (p->xrun_bytes) @@ -686,6 +687,12 @@ void pipeline_xrun(struct pipeline *p, struct comp_dev *dev, if (dev->state != COMP_STATE_ACTIVE) return; + /* notify all pipeline comps we are in XRUN, and stop copying */ + ret = pipeline_trigger(p, p->source_comp, COMP_TRIGGER_XRUN); + if (ret < 0) + trace_pipe_error_with_ids(p, "pipeline_xrun() error: Pipelines notification about XRUN failed, ret = %d", + ret); + memset(&posn, 0, sizeof(posn)); p->xrun_bytes = bytes; posn.xrun_size = bytes; @@ -695,6 +702,14 @@ void pipeline_xrun(struct pipeline *p, struct comp_dev *dev, pipeline_comp_xrun(dev, &data, dev->params.direction); } +#if NO_XRUN_RECOVERY +/* recover the pipeline from a XRUN condition */ +static int pipeline_xrun_recover(struct pipeline *p) +{ + return -EINVAL; +} + +#else /* recover the pipeline from a XRUN condition */ static int pipeline_xrun_recover(struct pipeline *p) { @@ -702,16 +717,6 @@ static int pipeline_xrun_recover(struct pipeline *p) trace_pipe_error_with_ids(p, "pipeline_xrun_recover()"); - /* notify all pipeline comps we are in XRUN */ - ret = pipeline_trigger(p, p->source_comp, COMP_TRIGGER_XRUN); - if (ret < 0) { - trace_pipe_error_with_ids(p, "pipeline_xrun_recover() error: " - "Pipelines notification about XRUN " - "failed, ret = %d", ret); - return ret; - } - p->xrun_bytes = 0; - /* prepare the pipeline */ ret = pipeline_prepare(p, p->source_comp); if (ret < 0) { @@ -721,6 +726,9 @@ static int pipeline_xrun_recover(struct pipeline *p) return ret; } + /* reset xrun status as we already in prepared */ + p->xrun_bytes = 0; + /* restart pipeline comps */ ret = pipeline_trigger(p, p->source_comp, COMP_TRIGGER_START); if (ret < 0) { @@ -732,6 +740,7 @@ static int pipeline_xrun_recover(struct pipeline *p) return 0; } +#endif /* notify pipeline that this component requires buffers emptied/filled */ void pipeline_schedule_copy(struct pipeline *p, uint64_t start) @@ -744,6 +753,7 @@ void pipeline_schedule_copy(struct pipeline *p, uint64_t start) schedule_task(&p->pipe_task, start, p->ipc_pipe.deadline); } + } /* notify pipeline that this component requires buffers emptied/filled @@ -776,17 +786,20 @@ static void pipeline_task(void *arg) /* are we in xrun ? */ if (p->xrun_bytes) { + /* try to recover */ err = pipeline_xrun_recover(p); if (err < 0) - return; /* failed - host will stop this pipeline */ - goto sched; + goto sched;/* skip copy if still in xrun */ } err = pipeline_copy(p->sched_comp); if (err < 0) { + /* try to recover */ err = pipeline_xrun_recover(p); - if (err < 0) + if (err < 0) { + trace_pipe_error_with_ids(p, "pipeline_task(): xrun recover failed! pipeline will be stopped!"); return; /* failed - host will stop this pipeline */ + } } sched: diff --git a/src/include/sof/audio/pipeline.h b/src/include/sof/audio/pipeline.h index 5053559c619b..f77863067443 100644 --- a/src/include/sof/audio/pipeline.h +++ b/src/include/sof/audio/pipeline.h @@ -42,6 +42,13 @@ #include #include +/* + * This flag disables firmware-side xrun recovery. + * It should remain enabled in the situation when the + * recovery is delegated to the outside of firmware. + */ +#define NO_XRUN_RECOVERY 0 + /* pipeline tracing */ #define trace_pipe(format, ...) \ trace_event(TRACE_CLASS_PIPE, format, ##__VA_ARGS__)