pipeline: add sink component

Adds sink component to pipeline. It will allow
for pipeline copy direction simplification.

Signed-off-by: Tomasz Lauda <tomasz.lauda@linux.intel.com>
This commit is contained in:
Tomasz Lauda 2019-02-25 12:04:36 +01:00 committed by Liam Girdwood
parent 9a6a38a609
commit 6077b57e19
4 changed files with 47 additions and 24 deletions

View File

@ -167,7 +167,8 @@ static int pipeline_comp_complete(struct comp_dev *current, void *data,
return 0;
}
int pipeline_complete(struct pipeline *p, struct comp_dev *source)
int pipeline_complete(struct pipeline *p, struct comp_dev *source,
struct comp_dev *sink)
{
struct pipeline_data data;
@ -189,6 +190,7 @@ int pipeline_complete(struct pipeline *p, struct comp_dev *source)
pipeline_comp_complete(source, &data, PPL_DIR_DOWNSTREAM);
p->source_comp = source;
p->sink_comp = sink;
p->status = COMP_STATE_READY;
/* show heap status */

View File

@ -100,6 +100,7 @@ struct pipeline {
struct task pipe_task; /* pipeline processing task */
struct comp_dev *sched_comp; /* component that drives scheduling in this pipe */
struct comp_dev *source_comp; /* source component for this pipe */
struct comp_dev *sink_comp; /* sink component for this pipe */
/* position update */
uint32_t posn_offset; /* position update array offset*/
@ -129,7 +130,8 @@ int pipeline_connect(struct comp_dev *comp, struct comp_buffer *buffer,
int dir);
/* complete the pipeline */
int pipeline_complete(struct pipeline *p, struct comp_dev *source);
int pipeline_complete(struct pipeline *p, struct comp_dev *source,
struct comp_dev *sink);
/* pipeline parameters */
int pipeline_params(struct pipeline *p, struct comp_dev *cd,

View File

@ -44,6 +44,14 @@
#include <sof/audio/pipeline.h>
#include <sof/audio/buffer.h>
/* Returns pipeline source component */
#define ipc_get_ppl_src_comp(ipc, ppl_id) \
ipc_get_ppl_comp(ipc, ppl_id, PPL_DIR_UPSTREAM)
/* Returns pipeline sink component */
#define ipc_get_ppl_sink_comp(ipc, ppl_id) \
ipc_get_ppl_comp(ipc, ppl_id, PPL_DIR_DOWNSTREAM)
/*
* Components, buffers and pipelines all use the same set of monotonic ID
* numbers passed in by the host. They are stored in different lists, hence
@ -78,19 +86,20 @@ struct ipc_comp_dev *ipc_get_comp(struct ipc *ipc, uint32_t id)
return NULL;
}
static struct ipc_comp_dev *ipc_get_ppl_src_comp(struct ipc *ipc,
uint32_t pipeline_id)
static struct ipc_comp_dev *ipc_get_ppl_comp(struct ipc *ipc,
uint32_t pipeline_id, int dir)
{
struct ipc_comp_dev *icd;
struct comp_buffer *buffer;
struct comp_dev *buff_comp;
struct list_item *clist;
/* first try to find the last module in the pipeline */
/* first try to find the module in the pipeline */
list_for_item(clist, &ipc->shared_ctx->comp_list) {
icd = container_of(clist, struct ipc_comp_dev, list);
if (icd->type == COMP_TYPE_COMPONENT &&
icd->cd->comp.pipeline_id == pipeline_id &&
list_is_empty(&icd->cd->bsource_list))
list_is_empty(comp_buffer_list(icd->cd, dir)))
return icd;
}
@ -99,11 +108,12 @@ static struct ipc_comp_dev *ipc_get_ppl_src_comp(struct ipc *ipc,
icd = container_of(clist, struct ipc_comp_dev, list);
if (icd->type == COMP_TYPE_COMPONENT &&
icd->cd->comp.pipeline_id == pipeline_id) {
buffer = list_first_item(&icd->cd->bsource_list,
struct comp_buffer,
sink_list);
if (buffer && buffer->source &&
buffer->source->comp.pipeline_id != pipeline_id)
buffer = buffer_from_list
(comp_buffer_list(icd->cd, dir)->next,
struct comp_buffer, dir);
buff_comp = buffer_get_comp(buffer, dir);
if (buff_comp &&
buff_comp->comp.pipeline_id != pipeline_id)
return icd;
}
}
@ -364,7 +374,8 @@ int ipc_pipeline_complete(struct ipc *ipc, uint32_t comp_id)
{
struct ipc_comp_dev *ipc_pipe;
uint32_t pipeline_id;
struct ipc_comp_dev *ipc_source;
struct ipc_comp_dev *ipc_ppl_source;
struct ipc_comp_dev *ipc_ppl_sink;
/* check whether pipeline exists */
ipc_pipe = ipc_get_comp(ipc, comp_id);
@ -374,11 +385,17 @@ int ipc_pipeline_complete(struct ipc *ipc, uint32_t comp_id)
pipeline_id = ipc_pipe->pipeline->ipc_pipe.pipeline_id;
/* get pipeline source component */
ipc_source = ipc_get_ppl_src_comp(ipc, pipeline_id);
if (!ipc_source)
ipc_ppl_source = ipc_get_ppl_src_comp(ipc, pipeline_id);
if (!ipc_ppl_source)
return -EINVAL;
return pipeline_complete(ipc_pipe->pipeline, ipc_source->cd);
/* get pipeline sink component */
ipc_ppl_sink = ipc_get_ppl_sink_comp(ipc, pipeline_id);
if (!ipc_ppl_sink)
return -EINVAL;
return pipeline_complete(ipc_pipe->pipeline, ipc_ppl_source->cd,
ipc_ppl_sink->cd);
}
int ipc_comp_dai_config(struct ipc *ipc, struct sof_ipc_dai_config *config)

View File

@ -61,7 +61,8 @@ static void test_audio_pipeline_complete_wrong_status(void **state)
result.status = COMP_STATE_READY;
/*Testing component*/
int error_code = pipeline_complete(&result, test_data->first);
int error_code = pipeline_complete(&result, test_data->first,
test_data->second);
assert_int_equal(error_code, -EINVAL);
}
@ -74,7 +75,8 @@ static void test_audio_pipeline_complete_ready_state(void **state)
cleanup_test_data(test_data);
/*Testing component*/
int error_code = pipeline_complete(&result, test_data->first);
int error_code = pipeline_complete(&result, test_data->first,
test_data->second);
assert_int_equal(error_code, 0);
assert_int_equal(result.status, COMP_STATE_READY);
@ -89,7 +91,7 @@ static void test_audio_pipeline_complete_connect_is_endpoint(void **state)
cleanup_test_data(test_data);
/*Testing component*/
pipeline_complete(&result, test_data->first);
pipeline_complete(&result, test_data->first, test_data->second);
/*Was not marked as endpoint (bsink and bsource lists empty)*/
assert_true(list_is_empty(&result.sched_comp->bsource_list));
@ -104,7 +106,7 @@ static void test_audio_pipeline_complete_connect_downstream_variable_set
cleanup_test_data(test_data);
/*Testing component*/
pipeline_complete(&result, test_data->first);
pipeline_complete(&result, test_data->first, test_data->second);
assert_int_equal
(
@ -133,7 +135,7 @@ static void test_audio_pipeline_complete_connect_downstream_ignore_sink
&test_data->second->bsource_list);
/*Testing component*/
pipeline_complete(&result, test_data->first);
pipeline_complete(&result, test_data->first, test_data->second);
assert_true(list_is_empty(&test_data->first->bsource_list));
assert_false(list_is_empty(&test_data->second->bsource_list));
@ -162,7 +164,7 @@ static void test_audio_pipeline_complete_connect_upstream_ignore_source
test_data->b2->sink = test_data->second;
/*Testing component*/
pipeline_complete(&result, test_data->first);
pipeline_complete(&result, test_data->first, test_data->second);
assert_true(list_is_empty(&test_data->first->bsink_list));
assert_false(list_is_empty(&test_data->second->bsink_list));
@ -191,7 +193,7 @@ static void test_audio_pipeline_complete_connect_downstream_full(void **state)
test_data->second->frames = 0;
/*Testing component*/
pipeline_complete(&result, test_data->first);
pipeline_complete(&result, test_data->first, test_data->second);
assert_int_equal(test_data->first->frames,
result.ipc_pipe.frames_per_sched);
@ -215,7 +217,7 @@ static void test_audio_pipeline_complete_connect_upstream_full(void **state)
test_data->b1->source = test_data->second;
/*Testing component*/
pipeline_complete(&result, test_data->first);
pipeline_complete(&result, test_data->first, test_data->second);
assert_int_equal(test_data->first->frames,
result.ipc_pipe.frames_per_sched);
@ -242,7 +244,7 @@ static void test_audio_pipeline_complete_connect_upstream_other_pipeline
&test_data->b1->source_list);
/*Testing component*/
pipeline_complete(&result, test_data->first);
pipeline_complete(&result, test_data->first, test_data->second);
assert_ptr_equal(test_data->first, result.source_comp);
}