Skip to content

Commit ad64629

Browse files
tlaudalgirdwood
authored andcommitted
pipeline: change copy flow
Changes copy flow to unify it no matter what is the source of scheduling. Capture pipelines will always start from source component and go downstream to sink component. Playback pipelines for the first time will start from sink component and go upstream to source component (preload run). Further playback pipeline copies will first copy sink component and then go upstream to source component. Signed-off-by: Tomasz Lauda <tomasz.lauda@linux.intel.com>
1 parent 6077b57 commit ad64629

4 files changed

Lines changed: 75 additions & 22 deletions

File tree

src/audio/pipeline.c

Lines changed: 46 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -353,6 +353,8 @@ int pipeline_prepare(struct pipeline *p, struct comp_dev *dev)
353353
goto out;
354354
}
355355

356+
/* pipeline preload needed only for playback streams */
357+
p->preload = dev->params.direction == SOF_IPC_STREAM_PLAYBACK;
356358
p->status = COMP_STATE_PREPARE;
357359

358360
out:
@@ -574,8 +576,7 @@ static int pipeline_comp_copy(struct comp_dev *current, void *data, int dir)
574576
struct pipeline_data *ppl_data = data;
575577
int is_single_ppl = comp_is_single_pipeline(current, ppl_data->start);
576578
int is_same_sched =
577-
pipeline_is_same_sched_comp(current->pipeline,
578-
ppl_data->start->pipeline);
579+
pipeline_is_same_sched_comp(current->pipeline, ppl_data->p);
579580
int err = 0;
580581

581582
tracev_pipe("pipeline_comp_copy(), current->comp.id = %u, dir = %u",
@@ -593,7 +594,7 @@ static int pipeline_comp_copy(struct comp_dev *current, void *data, int dir)
593594
}
594595

595596
/* copy to downstream immediately */
596-
if (current != ppl_data->start && dir == PPL_DIR_DOWNSTREAM) {
597+
if (dir == PPL_DIR_DOWNSTREAM) {
597598
err = comp_copy(current);
598599
if (err < 0)
599600
return err;
@@ -610,29 +611,53 @@ static int pipeline_comp_copy(struct comp_dev *current, void *data, int dir)
610611
return err;
611612
}
612613

613-
/* copy data from upstream source endpoints to downstream endpoints */
614-
static int pipeline_copy(struct comp_dev *dev)
614+
/* Copy data across all pipeline components.
615+
* For capture pipelines it always starts from source component
616+
* and continues downstream. For playback pipelines there are two
617+
* possibilities: for preload it starts from sink component and
618+
* continues upstream and if not preload, then it first copies
619+
* sink component itself and then goes upstream.
620+
*/
621+
static int pipeline_copy(struct pipeline *p)
615622
{
616623
struct pipeline_data data;
624+
struct comp_dev *start;
625+
uint32_t dir;
617626
int ret = 0;
618627

619-
data.start = dev;
620-
621-
ret = pipeline_comp_copy(dev, &data, PPL_DIR_UPSTREAM);
622-
if (ret < 0) {
623-
trace_ipc_error("pipeline_copy() error: ret = %d, dev->comp."
624-
"id = %u, dir = %u", ret, dev->comp.id,
625-
PPL_DIR_UPSTREAM);
626-
return ret;
628+
if (p->source_comp->params.direction == SOF_IPC_STREAM_PLAYBACK) {
629+
dir = PPL_DIR_UPSTREAM;
630+
start = p->sink_comp;
631+
632+
/* if not pipeline preload then copy sink comp first */
633+
if (!p->preload) {
634+
ret = comp_copy(start);
635+
if (ret < 0) {
636+
trace_pipe_error("pipeline_copy() error: "
637+
"ret = %d", ret);
638+
return ret;
639+
}
640+
641+
start = comp_get_previous(start, dir);
642+
if (!start)
643+
/* nothing else to do */
644+
return ret;
645+
}
646+
} else {
647+
dir = PPL_DIR_DOWNSTREAM;
648+
start = p->source_comp;
627649
}
628650

629-
ret = pipeline_comp_copy(dev, &data, PPL_DIR_DOWNSTREAM);
630-
if (ret < 0) {
631-
trace_ipc_error("pipeline_copy() error: ret = %d, dev->comp."
632-
"id = %u, dir = %u", ret, dev->comp.id,
633-
PPL_DIR_DOWNSTREAM);
634-
return ret;
635-
}
651+
data.start = start;
652+
data.p = p;
653+
654+
ret = pipeline_comp_copy(start, &data, dir);
655+
if (ret < 0)
656+
trace_pipe_error("pipeline_copy() error: ret = %d, start"
657+
"->comp.id = %u, dir = %u", ret,
658+
start->comp.id, dir);
659+
660+
p->preload = false;
636661

637662
return ret;
638663
}
@@ -809,7 +834,7 @@ static void pipeline_task(void *arg)
809834
goto sched;/* skip copy if still in xrun */
810835
}
811836

812-
err = pipeline_copy(p->sched_comp);
837+
err = pipeline_copy(p);
813838
if (err < 0) {
814839
/* try to recover */
815840
err = pipeline_xrun_recover(p);

src/include/sof/audio/component.h

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -580,6 +580,27 @@ static inline int comp_is_active(struct comp_dev *current)
580580
return current->state == COMP_STATE_ACTIVE;
581581
}
582582

583+
/**
584+
* Retrieves previous connected component.
585+
* @param dev Component device.
586+
* @param dir Component stream direction.
587+
* @return Previous connected component device.
588+
*/
589+
static inline struct comp_dev *comp_get_previous(struct comp_dev *dev, int dir)
590+
{
591+
struct list_item *buffer_list = comp_buffer_list(dev, dir);
592+
struct comp_dev *prev = NULL;
593+
struct comp_buffer *buffer;
594+
595+
if (!list_is_empty(buffer_list)) {
596+
buffer = buffer_from_list(buffer_list->next,
597+
struct comp_buffer, dir);
598+
prev = buffer_get_comp(buffer, dir);
599+
}
600+
601+
return prev;
602+
}
603+
583604
/**
584605
* Calculates period size in bytes based on component device's parameters.
585606
* @param dev Component device.

src/include/sof/audio/pipeline.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,7 @@ struct pipeline {
9595
/* runtime status */
9696
int32_t xrun_bytes; /* last xrun length */
9797
uint32_t status; /* pipeline status */
98+
bool preload; /* is pipeline preload needed */
9899

99100
/* scheduling */
100101
struct task pipe_task; /* pipeline processing task */
@@ -116,6 +117,12 @@ static inline bool pipeline_is_same_sched_comp(struct pipeline *current,
116117
return current->sched_comp == previous->sched_comp;
117118
}
118119

120+
/* checks if pipeline is in preload phase */
121+
static inline bool pipeline_is_preload(struct pipeline *p)
122+
{
123+
return p->preload;
124+
}
125+
119126
/* pipeline creation and destruction */
120127
struct pipeline *pipeline_new(struct sof_ipc_pipe_new *pipe_desc,
121128
struct comp_dev *cd);

test/cmocka/src/audio/mixer/comp_mock.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ static int mock_comp_cmd(struct comp_dev *dev, int cmd, void *data,
5858
return 0;
5959
}
6060

61-
static int mock_comp_copy(struct comp_dev *dev)
61+
static int mock_comp_copy(struct comp_dev *dev, bool preload)
6262
{
6363
return 0;
6464
}

0 commit comments

Comments
 (0)