diff --git a/src/audio/asrc/asrc.c b/src/audio/asrc/asrc.c index 8300a52250c8..055fdab8dfa1 100644 --- a/src/audio/asrc/asrc.c +++ b/src/audio/asrc/asrc.c @@ -452,7 +452,7 @@ static int asrc_dai_find(struct comp_dev *dev, struct comp_data *cd) do { sinkb = comp_dev_get_first_data_consumer(dev); - dev = sinkb->sink; + dev = comp_buffer_get_sink_component(sinkb); if (!dev) { comp_err(asrc_dev, "At end, no DAI found."); @@ -470,7 +470,7 @@ static int asrc_dai_find(struct comp_dev *dev, struct comp_data *cd) do { sourceb = comp_dev_get_first_data_producer(dev); - dev = sourceb->source; + dev = comp_buffer_get_source_component(sourceb); if (!dev) { comp_err(asrc_dev, "At beginning, no DAI found."); diff --git a/src/audio/buffers/comp_buffer.c b/src/audio/buffers/comp_buffer.c index 7aa6c158124c..e2f9c33ed043 100644 --- a/src/audio/buffers/comp_buffer.c +++ b/src/audio/buffers/comp_buffer.c @@ -480,11 +480,14 @@ void comp_update_buffer_produce(struct comp_buffer *buffer, uint32_t bytes) /* return if no bytes */ if (!bytes) { #if CONFIG_SOF_LOG_DBG_BUFFER + struct comp_dev *src_component = comp_buffer_get_source_component(buffer); + struct comp_dev *sink_component = comp_buffer_get_sink_component(buffer); + buf_dbg(buffer, "comp_update_buffer_produce(), no bytes to produce, source->comp.id = %u, source->comp.type = %u, sink->comp.id = %u, sink->comp.type = %u", - buffer->source ? dev_comp_id(buffer->source) : (unsigned int)UINT32_MAX, - buffer->source ? dev_comp_type(buffer->source) : (unsigned int)UINT32_MAX, - buffer->sink ? dev_comp_id(buffer->sink) : (unsigned int)UINT32_MAX, - buffer->sink ? dev_comp_type(buffer->sink) : (unsigned int)UINT32_MAX); + src_component ? dev_comp_id(src_component) : (unsigned int)UINT32_MAX, + src_component ? dev_comp_type(src_component) : (unsigned int)UINT32_MAX, + sink_component ? dev_comp_id(sink_component) : (unsigned int)UINT32_MAX, + sink_component ? dev_comp_type(sink_component) : (unsigned int)UINT32_MAX); #endif return; } @@ -520,11 +523,14 @@ void comp_update_buffer_consume(struct comp_buffer *buffer, uint32_t bytes) /* return if no bytes */ if (!bytes) { #if CONFIG_SOF_LOG_DBG_BUFFER + struct comp_dev *src_component = comp_buffer_get_source_component(buffer); + struct comp_dev *sink_component = comp_buffer_get_sink_component(buffer); + buf_dbg(buffer, "comp_update_buffer_consume(), no bytes to consume, source->comp.id = %u, source->comp.type = %u, sink->comp.id = %u, sink->comp.type = %u", - buffer->source ? dev_comp_id(buffer->source) : (unsigned int)UINT32_MAX, - buffer->source ? dev_comp_type(buffer->source) : (unsigned int)UINT32_MAX, - buffer->sink ? dev_comp_id(buffer->sink) : (unsigned int)UINT32_MAX, - buffer->sink ? dev_comp_type(buffer->sink) : (unsigned int)UINT32_MAX); + src_component ? dev_comp_id(src_component) : (unsigned int)UINT32_MAX, + src_component ? dev_comp_type(src_component) : (unsigned int)UINT32_MAX, + sink_component ? dev_comp_id(sink_component) : (unsigned int)UINT32_MAX, + sink_component ? dev_comp_type(sink_component) : (unsigned int)UINT32_MAX); #endif return; } diff --git a/src/audio/copier/copier.c b/src/audio/copier/copier.c index 31f62eb9d115..c9f81a213d70 100644 --- a/src/audio/copier/copier.c +++ b/src/audio/copier/copier.c @@ -463,7 +463,7 @@ static int copier_copy_to_sinks(struct copier_data *cd, struct comp_dev *dev, comp_dev_for_each_consumer(dev, sink) { struct comp_dev *sink_dev; - sink_dev = sink->sink; + sink_dev = comp_buffer_get_sink_component(sink); processed_data->sink_bytes = 0; if (sink_dev->state == COMP_STATE_ACTIVE) { ret = do_conversion_copy(dev, cd, src_c, sink, processed_data); @@ -508,7 +508,7 @@ static int copier_module_copy(struct processing_module *mod, struct comp_dev *sink_dev; sink_c = container_of(output_buffers[i].data, struct comp_buffer, stream); - sink_dev = sink_c->sink; + sink_dev = comp_buffer_get_sink_component(sink_c); processed_data.sink_bytes = 0; if (sink_dev->state == COMP_STATE_ACTIVE) { uint32_t source_samples; diff --git a/src/audio/crossover/crossover.c b/src/audio/crossover/crossover.c index 5878dd67c43c..914168aa395f 100644 --- a/src/audio/crossover/crossover.c +++ b/src/audio/crossover/crossover.c @@ -108,7 +108,7 @@ static int crossover_assign_sinks(struct processing_module *mod, unsigned int sink_id, state; sink_id = crossover_get_sink_id(cd, buffer_pipeline_id(sink), j); - state = sink->sink->state; + state = comp_buffer_get_sink_state(sink); if (state != dev->state) { j++; continue; diff --git a/src/audio/dai-zephyr.c b/src/audio/dai-zephyr.c index 5e6708437992..421757423392 100644 --- a/src/audio/dai-zephyr.c +++ b/src/audio/dai-zephyr.c @@ -284,7 +284,7 @@ dai_dma_cb(struct dai_data *dd, struct comp_dev *dev, uint32_t bytes, if (sink == dd->dma_buffer) continue; - sink_dev = sink->sink; + sink_dev = comp_buffer_get_sink_component(sink); j = IPC4_SRC_QUEUE_ID(buf_get_id(sink)); @@ -335,7 +335,7 @@ dai_dma_cb(struct dai_data *dd, struct comp_dev *dev, uint32_t bytes, if (sink == dd->local_buffer) continue; - sink_dev = sink->sink; + sink_dev = comp_buffer_get_sink_component(sink); j = IPC4_SINK_QUEUE_ID(buf_get_id(sink)); @@ -1648,7 +1648,7 @@ int dai_common_copy(struct dai_data *dd, struct comp_dev *dev, pcm_converter_fun comp_dev_for_each_consumer(dev, sink) { struct comp_dev *sink_dev; - sink_dev = sink->sink; + sink_dev = comp_buffer_get_sink_component(sink); if (sink_dev && sink_dev->state == COMP_STATE_ACTIVE && audio_buffer_hw_params_configured(&sink->audio_buffer)) { @@ -1678,7 +1678,7 @@ int dai_common_copy(struct dai_data *dd, struct comp_dev *dev, pcm_converter_fun comp_dev_for_each_consumer(dev, sink) { struct comp_dev *sink_dev; - sink_dev = sink->sink; + sink_dev = comp_buffer_get_sink_component(sink); if (sink_dev && sink_dev->state == COMP_STATE_ACTIVE && audio_buffer_hw_params_configured(&sink->audio_buffer)) { diff --git a/src/audio/google/google_rtc_audio_processing.c b/src/audio/google/google_rtc_audio_processing.c index 151bcee9fa92..0fb3bf344b42 100644 --- a/src/audio/google/google_rtc_audio_processing.c +++ b/src/audio/google/google_rtc_audio_processing.c @@ -787,8 +787,7 @@ static inline void execute_aec(struct google_rtc_audio_processing_comp_data *cd) static bool ref_stream_active(struct google_rtc_audio_processing_comp_data *cd) { #ifdef CONFIG_IPC_MAJOR_3 - return cd->ref_comp_buffer->source && - cd->ref_comp_buffer->source->state == COMP_STATE_ACTIVE; + return (comp_buffer_get_source_state(cd->ref_comp_buffer) == COMP_STATE_ACTIVE); #else return true; #endif diff --git a/src/audio/kpb.c b/src/audio/kpb.c index 6e83747831eb..e5b8827d4ec0 100644 --- a/src/audio/kpb.c +++ b/src/audio/kpb.c @@ -347,7 +347,7 @@ static int kpb_bind(struct comp_dev *dev, void *data) comp_dev_for_each_consumer(dev, sink) { int sink_buf_id; - if (!sink->sink) { + if (!comp_buffer_get_sink_component(sink)) { ret = -EINVAL; break; } @@ -862,11 +862,11 @@ static int kpb_prepare(struct comp_dev *dev) comp_dev_for_each_consumer(dev, sink) { enum sof_comp_type type; - if (!sink->sink) { + if (!comp_buffer_get_sink_component(sink)) { ret = -EINVAL; break; } - type = dev_comp_type(sink->sink); + type = dev_comp_type(comp_buffer_get_sink_component(sink)); switch (type) { case SOF_COMP_SELECTOR: @@ -1562,7 +1562,7 @@ static int kpb_register_client(struct comp_data *kpb, struct kpb_client *cli) static void kpb_init_draining(struct comp_dev *dev, struct kpb_client *cli) { struct comp_data *kpb = comp_get_drvdata(dev); - bool is_sink_ready = (kpb->host_sink->sink->state == COMP_STATE_ACTIVE); + bool is_sink_ready = (comp_buffer_get_sink_state(kpb->host_sink) == COMP_STATE_ACTIVE); size_t sample_width = kpb->config.sampling_width; size_t drain_req = cli->drain_req * kpb->config.channels * (kpb->config.sampling_freq / 1000) * @@ -1691,15 +1691,15 @@ static void kpb_init_draining(struct comp_dev *dev, struct kpb_client *cli) kpb->draining_task_data.sync_mode_on = kpb->sync_draining_mode; /* save current sink copy type */ - comp_get_attribute(kpb->host_sink->sink, COMP_ATTR_COPY_TYPE, - &kpb->draining_task_data.copy_type); + comp_get_attribute(comp_buffer_get_sink_component(kpb->host_sink), + COMP_ATTR_COPY_TYPE, &kpb->draining_task_data.copy_type); if (kpb->force_copy_type != COMP_COPY_INVALID) - comp_set_attribute(kpb->host_sink->sink, COMP_ATTR_COPY_TYPE, - &kpb->force_copy_type); + comp_set_attribute(comp_buffer_get_sink_component(kpb->host_sink), + COMP_ATTR_COPY_TYPE, &kpb->force_copy_type); /* Pause selector copy. */ - kpb->sel_sink->sink->state = COMP_STATE_PAUSED; + comp_buffer_get_sink_component(kpb->sel_sink)->state = COMP_STATE_PAUSED; /* Schedule draining task */ schedule_task(&kpb->draining_task, 0, 0); @@ -1827,13 +1827,13 @@ static enum task_state kpb_draining_task(void *arg) if (size_to_copy) { comp_update_buffer_produce(sink, size_to_copy); - comp_copy(sink->sink); + comp_copy(comp_buffer_get_sink_component(sink)); } else if (!audio_stream_get_free_bytes(&sink->stream)) { /* There is no free space in sink buffer. * Call .copy() on sink component so it can * process its data further. */ - comp_copy(sink->sink); + comp_copy(comp_buffer_get_sink_component(sink)); } if (sync_mode_on && period_bytes >= period_bytes_limit) { @@ -1870,7 +1870,7 @@ static enum task_state kpb_draining_task(void *arg) draining_time_end = sof_cycle_get_64(); /* Reset host-sink copy mode back to its pre-draining value */ - comp_set_attribute(kpb->host_sink->sink, COMP_ATTR_COPY_TYPE, + comp_set_attribute(comp_buffer_get_sink_component(kpb->host_sink), COMP_ATTR_COPY_TYPE, &kpb->draining_task_data.copy_type); draining_time_ms = k_cyc_to_ms_near64(draining_time_end - draining_time_start); diff --git a/src/audio/mixer/mixer.c b/src/audio/mixer/mixer.c index c04bc7dff395..2ed75b1e9e0b 100644 --- a/src/audio/mixer/mixer.c +++ b/src/audio/mixer/mixer.c @@ -174,7 +174,7 @@ static int mixer_reset(struct processing_module *mod) /* FIXME: this is racy and implicitly protected by serialised IPCs */ bool stop = false; - if (source->source && source->source->state > COMP_STATE_READY) + if (comp_buffer_get_source_state(source) > COMP_STATE_READY) stop = true; /* only mix the sources with the same state with mixer */ @@ -233,8 +233,8 @@ static int mixer_prepare(struct processing_module *mod, * done. */ mixer_set_frame_alignment(&source->stream); - stop = source->source && (source->source->state == COMP_STATE_PAUSED || - source->source->state == COMP_STATE_ACTIVE); + stop = comp_buffer_get_source_state(source) == COMP_STATE_PAUSED || + comp_buffer_get_source_state(source) == COMP_STATE_ACTIVE; /* only prepare downstream if we have no active sources */ if (stop) diff --git a/src/audio/mixin_mixout/mixin_mixout.c b/src/audio/mixin_mixout/mixin_mixout.c index 4ae3707d5d17..fe2c424efdb1 100644 --- a/src/audio/mixin_mixout/mixin_mixout.c +++ b/src/audio/mixin_mixout/mixin_mixout.c @@ -300,7 +300,7 @@ static int mixin_process(struct processing_module *mod, */ /* unused buffer between mixin and mixout */ unused_in_between_buf = comp_buffer_get_from_sink(sinks[i]); - mixout = unused_in_between_buf->sink; + mixout = comp_buffer_get_sink_component(unused_in_between_buf); /* Skip non-active mixout like it is not connected so it does not * block other possibly connected mixouts. In addition, non-active @@ -485,7 +485,7 @@ static int mixout_process(struct processing_module *mod, * sof_source implementation. */ unused_in_between_buf = comp_buffer_get_from_source(sources[i]); - mixin = unused_in_between_buf->source; + mixin = comp_buffer_get_source_component(unused_in_between_buf); pending_frames = get_mixin_pending_frames(md, mixin); if (!pending_frames) @@ -501,7 +501,7 @@ static int mixout_process(struct processing_module *mod, struct comp_dev *mixin; unused_in_between_buf = comp_buffer_get_from_source(sources[i]); - mixin = unused_in_between_buf->source; + mixin = comp_buffer_get_source_component(unused_in_between_buf); pending_frames = get_mixin_pending_frames(md, mixin); if (!pending_frames) @@ -569,8 +569,9 @@ static int mixout_reset(struct processing_module *mod) * sof_source implementation. */ source_buf = comp_buffer_get_from_source(mod->sources[i]); - stop = (dev->pipeline == source_buf->source->pipeline && - source_buf->source->state > COMP_STATE_PAUSED); + stop = (dev->pipeline == + comp_buffer_get_source_component(source_buf)->pipeline && + comp_buffer_get_source_state(source_buf) > COMP_STATE_PAUSED); if (stop) /* should not reset the downstream components */ diff --git a/src/audio/mux/mux.c b/src/audio/mux/mux.c index 2b8f6c4710f5..1215a0f6c33f 100644 --- a/src/audio/mux/mux.c +++ b/src/audio/mux/mux.c @@ -243,7 +243,7 @@ static int demux_process(struct processing_module *mod, /* align sink streams with their respective configurations */ comp_dev_for_each_consumer(dev, sink) { - if (sink->sink->state == dev->state) { + if (comp_buffer_get_sink_state(sink) == dev->state) { i = get_stream_index(dev, cd, buffer_pipeline_id(sink)); /* return if index wrong */ if (i < 0) { @@ -298,7 +298,7 @@ static int mux_process(struct processing_module *mod, /* align source streams with their respective configurations */ j = 0; comp_dev_for_each_producer(dev, source) { - if (source->source->state == dev->state) { + if (comp_buffer_get_source_state(source) == dev->state) { if (frames) frames = MIN(frames, input_buffers[j].size); else @@ -329,7 +329,7 @@ static int mux_process(struct processing_module *mod, /* Update consumed and produced */ j = 0; comp_dev_for_each_producer(dev, source) { - if (source->source->state == dev->state) + if (comp_buffer_get_source_state(source) == dev->state) mod->input_buffers[j].consumed = source_bytes; j++; } @@ -348,7 +348,7 @@ static int mux_reset(struct processing_module *mod) if (dir == SOF_IPC_STREAM_PLAYBACK) { comp_dev_for_each_producer(dev, source) { - int state = source->source->state; + int state = comp_buffer_get_source_state(source); /* only mux the sources with the same state with mux */ if (state > COMP_STATE_READY) @@ -439,7 +439,7 @@ static int demux_trigger(struct processing_module *mod, int cmd) struct comp_buffer *b; comp_dev_for_each_producer(mod->dev, b) { - if (b->sink->pipeline != mod->dev->pipeline) + if (comp_buffer_get_sink_component(b)->pipeline != mod->dev->pipeline) audio_stream_set_overrun(&b->stream, true); } diff --git a/src/audio/selector/selector.c b/src/audio/selector/selector.c index fc36d5a9a830..a386dc5c1a63 100644 --- a/src/audio/selector/selector.c +++ b/src/audio/selector/selector.c @@ -351,7 +351,7 @@ static int selector_trigger(struct comp_dev *dev, int cmd) * kpb_init_draining() and kpb_draining_task() are interrupted by * new pipeline_task() */ - type = dev_comp_type(sourceb->source); + type = dev_comp_type(comp_buffer_get_source_component(sourceb)); return type == SOF_COMP_KPB ? PPL_STATUS_PATH_TERMINATE : ret; } diff --git a/src/audio/smart_amp/smart_amp.c b/src/audio/smart_amp/smart_amp.c index e55d9cdb26b6..1b72ef4a65f8 100644 --- a/src/audio/smart_amp/smart_amp.c +++ b/src/audio/smart_amp/smart_amp.c @@ -607,7 +607,7 @@ static int smart_amp_copy(struct comp_dev *dev) if (sad->feedback_buf) { struct comp_buffer *feedback_buf = sad->feedback_buf; - if (comp_get_state(dev, feedback_buf->source) == dev->state) { + if (comp_get_state(feedback_buf->source) == dev->state) { /* feedback */ avail_feedback_frames = audio_stream_get_avail_frames(&feedback_buf->stream); diff --git a/src/include/sof/audio/buffer.h b/src/include/sof/audio/buffer.h index 5805fe0f420d..55e01b624ff9 100644 --- a/src/include/sof/audio/buffer.h +++ b/src/include/sof/audio/buffer.h @@ -143,6 +143,22 @@ struct comp_buffer { struct list_item sink_list; /* list in comp buffers */ }; +/* + * get a component providing data to the buffer + */ +static inline struct comp_dev *comp_buffer_get_source_component(const struct comp_buffer *buffer) +{ + return buffer->source; +} + +/* + * get a component consuming data from the buffer + */ +static inline struct comp_dev *comp_buffer_get_sink_component(const struct comp_buffer *buffer) +{ + return buffer->sink; +} + /* Only to be used for synchronous same-core notifications! */ struct buffer_cb_transact { struct comp_buffer *buffer; @@ -252,7 +268,9 @@ void buffer_detach(struct comp_buffer *buffer, struct list_item *head, int dir); static inline struct comp_dev *buffer_get_comp(struct comp_buffer *buffer, int dir) { - struct comp_dev *comp = dir == PPL_DIR_DOWNSTREAM ? buffer->sink : buffer->source; + struct comp_dev *comp = (dir == PPL_DIR_DOWNSTREAM) ? + comp_buffer_get_sink_component(buffer) : + comp_buffer_get_source_component(buffer); return comp; } diff --git a/src/include/sof/audio/component.h b/src/include/sof/audio/component.h index 692c55572ad4..54c640702c63 100644 --- a/src/include/sof/audio/component.h +++ b/src/include/sof/audio/component.h @@ -46,13 +46,14 @@ struct dai_ts_data; /** \name Audio Component States * @{ */ -#define COMP_STATE_INIT 0 /**< Component being initialised */ -#define COMP_STATE_READY 1 /**< Component inactive, but ready */ -#define COMP_STATE_SUSPEND 2 /**< Component suspended */ -#define COMP_STATE_PREPARE 3 /**< Component prepared */ -#define COMP_STATE_PAUSED 4 /**< Component paused */ -#define COMP_STATE_ACTIVE 5 /**< Component active */ -#define COMP_STATE_PRE_ACTIVE 6 /**< Component after early initialisation */ +#define COMP_STATE_NOT_EXIST 0 /**< Component does not exist */ +#define COMP_STATE_INIT 1 /**< Component being initialised */ +#define COMP_STATE_READY 2 /**< Component inactive, but ready */ +#define COMP_STATE_SUSPEND 3 /**< Component suspended */ +#define COMP_STATE_PREPARE 4 /**< Component prepared */ +#define COMP_STATE_PAUSED 5 /**< Component paused */ +#define COMP_STATE_ACTIVE 6 /**< Component active */ +#define COMP_STATE_PRE_ACTIVE 7 /**< Component after early initialisation */ /** @}*/ /** \name Standard Component Stream Commands @@ -986,14 +987,44 @@ void comp_get_copy_limits_frame_aligned(const struct comp_buffer *source, /** * Get component state. * - * @param req_dev Requesting component * @param dev Component from which user wants to read status. + * + * @retval COMP_STATE_NOT_EXIST if there's no connected component + * @return state of the component */ -static inline int comp_get_state(struct comp_dev *req_dev, struct comp_dev *dev) +static inline int comp_get_state(const struct comp_dev *dev) { + if (!dev) + return COMP_STATE_NOT_EXIST; return dev->state; } +/** + * @brief helper, provide state of a component connected to a buffer as a data provider + * + * @param buffer a buffer to be checked + * + * @retval COMP_STATE_NOT_EXIST if there's no connected component + * @return state of the component + */ +static inline int comp_buffer_get_source_state(const struct comp_buffer *buffer) +{ + return comp_get_state(comp_buffer_get_source_component(buffer)); +} + +/** + * @brief helper, provide state of a component connected to a buffer as a data consumer + * + * @param buffer a buffer to be checked + * + * @retval COMP_STATE_NOT_EXIST if there's no connected component + * @return state of the component + */ +static inline int comp_buffer_get_sink_state(const struct comp_buffer *buffer) +{ + return comp_get_state(comp_buffer_get_sink_component(buffer)); +} + /** * Warning: duplicate declaration in topology.h * diff --git a/src/samples/audio/smart_amp_test_ipc3.c b/src/samples/audio/smart_amp_test_ipc3.c index c69805a9d0bf..289b8a36e126 100644 --- a/src/samples/audio/smart_amp_test_ipc3.c +++ b/src/samples/audio/smart_amp_test_ipc3.c @@ -429,7 +429,7 @@ static int smart_amp_copy(struct comp_dev *dev) if (sad->feedback_buf) { struct comp_buffer *buf = sad->feedback_buf; - if (buf->source && comp_get_state(dev, buf->source) == dev->state) { + if (comp_buffer_get_source_state(buf) == dev->state) { /* feedback */ avail_feedback_frames = audio_stream_get_avail_frames(&buf->stream); @@ -501,7 +501,8 @@ static int smart_amp_prepare(struct comp_dev *dev) /* searching for stream and feedback source buffers */ comp_dev_for_each_producer(dev, source_buffer) { /* FIXME: how often can this loop be run? */ - if (source_buffer->source->ipc_config.type == SOF_COMP_DEMUX) + if (comp_buffer_get_source_component(source_buffer)->ipc_config.type == + SOF_COMP_DEMUX) sad->feedback_buf = source_buffer; else sad->source_buf = source_buffer;