mirror of https://github.com/thesofproject/sof.git
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:
parent
9a6a38a609
commit
6077b57e19
|
@ -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 */
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue