Skip to content

Commit

Permalink
buf: make pipeline management code using comp_buffer API
Browse files Browse the repository at this point in the history
This commit make all pipeline management code
using comp_buffer API. Since now, no access to comp_buffer
internals should be performed by the SOF code
(with exception of uint test)

Signed-off-by: Marcin Szkudlinski <[email protected]>
  • Loading branch information
marcinszkudlinski committed Feb 4, 2025
1 parent 0e82d18 commit 91a562f
Show file tree
Hide file tree
Showing 9 changed files with 91 additions and 140 deletions.
4 changes: 2 additions & 2 deletions src/audio/buffers/comp_buffer.c
Original file line number Diff line number Diff line change
Expand Up @@ -212,8 +212,8 @@ static struct comp_buffer *buffer_alloc_struct(void *stream_addr, size_t size, u
audio_stream_set_underrun(&buffer->stream, !!(flags & SOF_BUF_UNDERRUN_PERMITTED));
audio_stream_set_overrun(&buffer->stream, !!(flags & SOF_BUF_OVERRUN_PERMITTED));

list_init(&buffer->source_list);
list_init(&buffer->sink_list);
comp_buffer_reset_source_list(buffer);
comp_buffer_reset_sink_list(buffer);

return buffer;
}
Expand Down
56 changes: 19 additions & 37 deletions src/audio/module_adapter/module_adapter.c
Original file line number Diff line number Diff line change
Expand Up @@ -230,7 +230,7 @@ int module_adapter_prepare(struct comp_dev *dev)
/* Get period_bytes first on prepare(). At this point it is guaranteed that the stream
* parameter from sink buffer is settled, and still prior to all references to period_bytes.
*/
sink = list_first_item(&dev->bsink_list, struct comp_buffer, source_list);
sink = comp_dev_get_first_data_consumer(dev);

mod->period_bytes = audio_stream_period_bytes(&sink->stream, dev->frames);
comp_dbg(dev, "module_adapter_prepare(): got period_bytes = %u", mod->period_bytes);
Expand Down Expand Up @@ -621,17 +621,14 @@ static void module_adapter_process_output(struct comp_dev *dev)

/* copy from all output local buffers to sink buffers */
i = 0;
list_for_item(blist, &dev->bsink_list) {
struct list_item *_blist;
comp_dev_for_each_consumer(dev, sink) {
int j = 0;

list_for_item(_blist, &mod->raw_data_buffers_list) {
list_for_item(blist, &mod->raw_data_buffers_list) {
if (i == j) {
struct comp_buffer *source;

sink = container_of(blist, struct comp_buffer, source_list);
source = container_of(_blist, struct comp_buffer, buffers_list);

source = container_of(blist, struct comp_buffer, buffers_list);
module_copy_samples(dev, source, sink,
mod->output_buffers[i].size);

Expand Down Expand Up @@ -756,7 +753,7 @@ static int module_adapter_audio_stream_copy_1to1(struct comp_dev *dev)
/* Note: Source buffer state is not checked to enable mixout to generate zero
* PCM codes when source is not active.
*/
if (mod->sink_comp_buffer->sink->state == dev->state)
if (comp_buffer_get_sink_state(mod->sink_comp_buffer) == dev->state)
num_output_buffers = 1;

ret = module_process_legacy(mod, mod->input_buffers, 1,
Expand All @@ -783,10 +780,11 @@ static int module_adapter_audio_stream_type_copy(struct comp_dev *dev)
{
struct comp_buffer *sources[PLATFORM_MAX_STREAMS];
struct comp_buffer *sinks[PLATFORM_MAX_STREAMS];
struct comp_buffer *sink;
struct comp_buffer *source;
struct processing_module *mod = comp_mod(dev);
struct list_item *blist;
uint32_t num_input_buffers, num_output_buffers;
int ret, i = 0;
int ret, i;

/* handle special case of HOST/DAI type components */
if (dev->ipc_config.type == SOF_COMP_HOST || dev->ipc_config.type == SOF_COMP_DAI)
Expand All @@ -796,25 +794,18 @@ static int module_adapter_audio_stream_type_copy(struct comp_dev *dev)
return module_adapter_audio_stream_copy_1to1(dev);

/* acquire all sink and source buffers */
list_for_item(blist, &dev->bsink_list) {
struct comp_buffer *sink;

sink = container_of(blist, struct comp_buffer, source_list);
i = 0;
comp_dev_for_each_consumer(dev, sink)
sinks[i++] = sink;
}
num_output_buffers = i;
if (num_output_buffers > mod->max_sinks) {
comp_err(dev, "Invalid number of sinks %d\n", num_output_buffers);
return -EINVAL;
}

i = 0;
list_for_item(blist, &dev->bsource_list) {
struct comp_buffer *source;

source = container_of(blist, struct comp_buffer, sink_list);
comp_dev_for_each_producer(dev, source)
sources[i++] = source;
}
num_input_buffers = i;
if (num_input_buffers > mod->max_sources) {
comp_err(dev, "Invalid number of sources %d\n", num_input_buffers);
Expand All @@ -824,11 +815,11 @@ static int module_adapter_audio_stream_type_copy(struct comp_dev *dev)
/* setup active input/output buffers for processing */
if (num_output_buffers == 1) {
module_single_sink_setup(dev, sources, sinks);
if (sinks[0]->sink->state != dev->state)
if (comp_buffer_get_sink_state(sinks[0]) != dev->state)
num_output_buffers = 0;
} else if (num_input_buffers == 1) {
module_single_source_setup(dev, sources, sinks);
if (sources[0]->source->state != dev->state) {
if (comp_buffer_get_source_state(sources[0]) != dev->state) {
num_input_buffers = 0;
}
} else {
Expand Down Expand Up @@ -910,15 +901,13 @@ static int module_adapter_copy_ring_buffers(struct comp_dev *dev)
* This is an adapter, to be removed when pipeline2.0 is ready
*/
struct processing_module *mod = comp_mod(dev);
struct list_item *blist;
struct comp_buffer *buffer;
int err;

list_for_item(blist, &dev->bsource_list) {
comp_dev_for_each_producer(dev, buffer) {
/* input - we need to copy data from audio_stream (as source)
* to ring_buffer (as sink)
*/
struct comp_buffer *buffer =
container_of(blist, struct comp_buffer, sink_list);
err = audio_buffer_sync_secondary_buffer(&buffer->audio_buffer, UINT_MAX);

if (err) {
Expand All @@ -930,7 +919,7 @@ static int module_adapter_copy_ring_buffers(struct comp_dev *dev)
if (mod->dp_startup_delay)
return 0;

list_for_item(blist, &dev->bsink_list) {
comp_dev_for_each_consumer(dev, buffer) {
/* output - we need to copy data from ring_buffer (as source)
* to audio_stream (as sink)
*
Expand All @@ -943,8 +932,6 @@ static int module_adapter_copy_ring_buffers(struct comp_dev *dev)
*
* FIX: copy only the following module's IBS in each LL cycle
*/
struct comp_buffer *buffer =
container_of(blist, struct comp_buffer, source_list);
struct sof_source *following_mod_data_source =
audio_buffer_get_source(&buffer->audio_buffer);

Expand Down Expand Up @@ -1021,14 +1008,12 @@ static int module_adapter_raw_data_type_copy(struct comp_dev *dev)
}

/* copy source samples into input buffer */
list_for_item(blist, &dev->bsource_list) {
comp_dev_for_each_producer(dev, source) {
uint32_t bytes_to_process;
int frames, source_frame_bytes;

source = container_of(blist, struct comp_buffer, sink_list);

/* check if the source dev is in the same state as the dev */
if (!source->source || source->source->state != dev->state)
if (comp_buffer_get_source_state(source) != dev->state)
continue;

frames = MIN(min_free_frames,
Expand Down Expand Up @@ -1061,10 +1046,7 @@ static int module_adapter_raw_data_type_copy(struct comp_dev *dev)

i = 0;
/* consume from all input buffers */
list_for_item(blist, &dev->bsource_list) {

source = container_of(blist, struct comp_buffer, sink_list);

comp_dev_for_each_producer(dev, source) {
comp_update_buffer_consume(source, mod->input_buffers[i].consumed);

bzero((__sparse_force void *)mod->input_buffers[i].data, size);
Expand Down
25 changes: 8 additions & 17 deletions src/audio/module_adapter/module_adapter_ipc3.c
Original file line number Diff line number Diff line change
Expand Up @@ -121,8 +121,7 @@ void module_adapter_check_data(struct processing_module *mod, struct comp_dev *d
*/
if (IS_PROCESSING_MODE_AUDIO_STREAM(mod) && mod->num_of_sources == 1 &&
mod->num_of_sinks == 1) {
mod->source_comp_buffer = list_first_item(&dev->bsource_list,
struct comp_buffer, sink_list);
mod->source_comp_buffer = comp_dev_get_first_data_producer(dev);
mod->sink_comp_buffer = sink;
mod->stream_copy_single_to_single = true;
}
Expand All @@ -134,24 +133,20 @@ void module_adapter_set_params(struct processing_module *mod, struct sof_ipc_str

static int module_source_state_count(struct comp_dev *dev, uint32_t state)
{
struct list_item *blist;
int count = 0;
struct comp_buffer *source;

/* count source with state == status */
list_for_item(blist, &dev->bsource_list) {
comp_dev_for_each_producer(dev, source)
/*
* FIXME: this is racy, state can be changed by another core.
* This is implicitly protected by serialised IPCs. Even when
* IPCs are processed in the pipeline thread, the next IPC will
* not be sent until the thread has processed and replied to the
* current one.
*/
struct comp_buffer *source = container_of(blist, struct comp_buffer,
sink_list);

if (source->source && source->source->state == state)
if (comp_buffer_get_source_state(source) == state)
count++;
}

return count;
}
Expand Down Expand Up @@ -324,25 +319,21 @@ int module_adapter_cmd(struct comp_dev *dev, int cmd, void *data, int max_data_s
int module_adapter_sink_src_prepare(struct comp_dev *dev)
{
struct processing_module *mod = comp_mod(dev);
struct list_item *blist;
struct comp_buffer *sink_buffer;
struct comp_buffer *source_buffer;
int ret;
int i;

/* acquire all sink and source buffers, get handlers to sink/source API */
i = 0;
list_for_item(blist, &dev->bsink_list) {
struct comp_buffer *sink_buffer =
container_of(blist, struct comp_buffer, source_list);
comp_dev_for_each_consumer(dev, sink_buffer) {
mod->sinks[i] = audio_buffer_get_sink(&sink_buffer->audio_buffer);
i++;
}
mod->num_of_sinks = i;

i = 0;
list_for_item(blist, &dev->bsource_list) {
struct comp_buffer *source_buffer =
container_of(blist, struct comp_buffer, sink_list);

comp_dev_for_each_producer(dev, source_buffer) {
mod->sources[i] = audio_buffer_get_source(&source_buffer->audio_buffer);
i++;
}
Expand Down
17 changes: 6 additions & 11 deletions src/audio/module_adapter/module_adapter_ipc4.c
Original file line number Diff line number Diff line change
Expand Up @@ -187,24 +187,20 @@ EXPORT_SYMBOL(module_adapter_get_attribute);
static bool module_adapter_multi_sink_source_prepare(struct comp_dev *dev)
{
struct processing_module *mod = comp_mod(dev);
struct list_item *blist;
struct comp_buffer *sink_buffer;
struct comp_buffer *source_buffer;
int i;

/* acquire all sink and source buffers, get handlers to sink/source API */
i = 0;
list_for_item(blist, &dev->bsink_list) {
struct comp_buffer *sink_buffer =
container_of(blist, struct comp_buffer, source_list);
comp_dev_for_each_consumer(dev, sink_buffer) {
mod->sinks[i] = audio_buffer_get_sink(&sink_buffer->audio_buffer);
i++;
}
mod->num_of_sinks = i;

i = 0;
list_for_item(blist, &dev->bsource_list) {
struct comp_buffer *source_buffer =
container_of(blist, struct comp_buffer, sink_list);

comp_dev_for_each_producer(dev, source_buffer) {
mod->sources[i] = audio_buffer_get_source(&source_buffer->audio_buffer);
i++;
}
Expand All @@ -216,9 +212,8 @@ static bool module_adapter_multi_sink_source_prepare(struct comp_dev *dev)
return true;

/* re-assign the source/sink modules */
mod->sink_comp_buffer = list_first_item(&dev->bsink_list, struct comp_buffer, source_list);
mod->source_comp_buffer = list_first_item(&dev->bsource_list,
struct comp_buffer, sink_list);
mod->sink_comp_buffer = comp_dev_get_first_data_consumer(dev);
mod->source_comp_buffer = comp_dev_get_first_data_producer(dev);

return false;
}
Expand Down
4 changes: 2 additions & 2 deletions src/audio/pipeline/pipeline-graph.c
Original file line number Diff line number Diff line change
Expand Up @@ -167,9 +167,9 @@ static void buffer_set_comp(struct comp_buffer *buffer, struct comp_dev *comp,
int dir)
{
if (dir == PPL_CONN_DIR_COMP_TO_BUFFER)
buffer->source = comp;
comp_buffer_set_source_component(buffer, comp);
else
buffer->sink = comp;
comp_buffer_set_sink_component(buffer, comp);
}

int pipeline_connect(struct comp_dev *comp, struct comp_buffer *buffer,
Expand Down
54 changes: 26 additions & 28 deletions src/ipc/ipc-helper.c
Original file line number Diff line number Diff line change
Expand Up @@ -115,10 +115,8 @@ static void comp_update_params(uint32_t flag,
int comp_verify_params(struct comp_dev *dev, uint32_t flag,
struct sof_ipc_stream_params *params)
{
struct list_item *buffer_list;
struct list_item *source_list;
struct list_item *sink_list;
struct list_item *clist;
struct comp_buffer *sinkb;
struct comp_buffer *buf;
int dir = dev->direction;
Expand All @@ -136,13 +134,9 @@ int comp_verify_params(struct comp_dev *dev, uint32_t flag,
*/
if (list_is_empty(source_list) != list_is_empty(sink_list)) {
if (list_is_empty(sink_list))
buf = list_first_item(source_list,
struct comp_buffer,
sink_list);
buf = comp_dev_get_first_data_producer(dev);
else
buf = list_first_item(sink_list,
struct comp_buffer,
source_list);
buf = comp_dev_get_first_data_consumer(dev);

/* update specific pcm parameter with buffer parameter if
* specific flag is set.
Expand All @@ -160,18 +154,22 @@ int comp_verify_params(struct comp_dev *dev, uint32_t flag,
/* for other components we iterate over all downstream buffers
* (for playback) or upstream buffers (for capture).
*/
buffer_list = comp_buffer_list(dev, dir);

list_for_item(clist, buffer_list) {
buf = buffer_from_list(clist, dir);
comp_update_params(flag, params, buf);
buffer_set_params(buf, params, BUFFER_UPDATE_FORCE);
if (dir == PPL_DIR_DOWNSTREAM) {
comp_dev_for_each_consumer(dev, buf) {
comp_update_params(flag, params, buf);
buffer_set_params(buf, params,
BUFFER_UPDATE_FORCE);
}
} else {
comp_dev_for_each_producer(dev, buf) {
comp_update_params(flag, params, buf);
buffer_set_params(buf, params,
BUFFER_UPDATE_FORCE);
}
}

/* fetch sink buffer in order to calculate period frames */
sinkb = list_first_item(&dev->bsink_list, struct comp_buffer,
source_list);

sinkb = comp_dev_get_first_data_consumer(dev);
component_set_nearest_period_frames(dev, audio_stream_get_rate(&sinkb->stream));
}

Expand Down Expand Up @@ -263,7 +261,8 @@ int ipc_pipeline_complete(struct ipc *ipc, uint32_t comp_id)
int ipc_comp_free(struct ipc *ipc, uint32_t comp_id)
{
struct ipc_comp_dev *icd;
struct list_item *clist, *tmp;
struct comp_buffer *buffer;
struct comp_buffer *safe;
uint32_t flags;

/* check whether component exists */
Expand Down Expand Up @@ -305,21 +304,20 @@ int ipc_comp_free(struct ipc *ipc, uint32_t comp_id)
}

irq_local_disable(flags);
list_for_item_safe(clist, tmp, &icd->cd->bsource_list) {
struct comp_buffer *buffer = container_of(clist, struct comp_buffer, sink_list);

buffer->sink = NULL;
comp_dev_for_each_producer_safe(icd->cd, buffer, safe)
{
comp_buffer_set_sink_component(buffer, NULL);
/* This breaks the list, but we anyway delete all buffers */
list_init(clist);
comp_buffer_reset_sink_list(buffer);
}

list_for_item_safe(clist, tmp, &icd->cd->bsink_list) {
struct comp_buffer *buffer = container_of(clist, struct comp_buffer, source_list);

buffer->source = NULL;
comp_dev_for_each_consumer_safe(icd->cd, buffer, safe)
{
comp_buffer_set_source_component(buffer, NULL);
/* This breaks the list, but we anyway delete all buffers */
list_init(clist);
comp_buffer_reset_source_list(buffer);
}

irq_local_enable(flags);

/* free component and remove from list */
Expand Down
Loading

0 comments on commit 91a562f

Please sign in to comment.