Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 26 additions & 13 deletions src/audio/pipeline.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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;
Expand All @@ -695,23 +702,21 @@ 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;

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should return 0 so it always succeeds (except where it may fail on system that have XRUN recovery in FW enabled).

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should return 0 so it always succeeds (except where it may fail on system that have XRUN recovery in FW enabled).

with the logic inside pipeline_task(), if we return 0 here, it means xrun recover success, it will continue copy or next schedule(those will fail again), that's not what we want?

}

#else
/* recover the pipeline from a XRUN condition */
static int pipeline_xrun_recover(struct pipeline *p)
{
int ret;

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) {
Expand All @@ -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) {
Expand All @@ -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)
Expand All @@ -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
Expand Down Expand Up @@ -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:
Expand Down
7 changes: 7 additions & 0 deletions src/include/sof/audio/pipeline.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,13 @@
#include <sof/schedule.h>
#include <uapi/ipc/topology.h>

/*
* 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__)
Expand Down