Skip to content

Commit f9f0ce3

Browse files
ranj063marcinszkudlinski
authored andcommitted
module: Add support for saving and retrieving the base config extension
Modules are bound with one another with a buffer in between. Today, this buffer's size is based on the source module's base config obs and sink module's base config ibs. But this is incorrect because this assumes that the connection is always from output pin 0 of the source module and input pin 0 of the sink module. To determine the buffer size correctly, the buffer size should be based on the pin-based obs/ibs of the source/sink module. To allow this, save the base config extension for the module during init so that it can be retrieved during module binding to get the obs/ibs based on the source/sink pin ID. Modify the google rtc and smart amp modules to save the base config extension during their init. Signed-off-by: Ranjani Sridharan <ranjani.sridharan@linux.intel.com> Marcin: google AEC merge Signed-off-by: Marcin Szkudlinski <marcin.szkudlinski@intel.com>
1 parent b102f09 commit f9f0ce3

8 files changed

Lines changed: 187 additions & 40 deletions

File tree

src/audio/google/google_rtc_audio_processing.c

Lines changed: 26 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -324,19 +324,36 @@ static int google_rtc_audio_processing_init(struct processing_module *mod)
324324
struct module_config *cfg = &md->cfg;
325325
const struct ipc4_base_module_extended_cfg *base_cfg = md->cfg.init_data;
326326
struct ipc4_input_pin_format reference_fmt, output_fmt;
327-
const size_t size = sizeof(struct ipc4_input_pin_format);
327+
size_t in_fmt_size = sizeof(struct ipc4_input_pin_format);
328+
size_t out_fmt_size = sizeof(struct ipc4_output_pin_format);
329+
size_t size;
328330

329331
cd->config.base_cfg = base_cfg->base_cfg;
330332

331333
/* Copy the reference format from input pin 1 format */
332-
memcpy_s(&reference_fmt, size,
333-
&base_cfg->base_cfg_ext.pin_formats[size], size);
334-
memcpy_s(&output_fmt, size,
335-
&base_cfg->base_cfg_ext.pin_formats[size * GOOGLE_RTC_NUM_INPUT_PINS], size);
334+
memcpy_s(&reference_fmt, in_fmt_size,
335+
&base_cfg->base_cfg_ext.pin_formats[in_fmt_size], in_fmt_size);
336+
memcpy_s(&output_fmt, in_fmt_size,
337+
&base_cfg->base_cfg_ext.pin_formats[in_fmt_size * GOOGLE_RTC_NUM_INPUT_PINS],
338+
in_fmt_size);
336339

337340
cd->config.reference_fmt = reference_fmt.audio_fmt;
338341
cd->config.output_fmt = output_fmt.audio_fmt;
339-
cd->config = *(const struct sof_ipc4_aec_config *)cfg->init_data;
342+
343+
/* save the base config extension */
344+
size = base_cfg->base_cfg_ext.nb_input_pins * in_fmt_size +
345+
base_cfg->base_cfg_ext.nb_output_pins * out_fmt_size;
346+
347+
md->cfg.basecfg_ext = rzalloc(SOF_MEM_ZONE_RUNTIME, 0, SOF_MEM_CAPS_RAM,
348+
sizeof(struct ipc4_base_module_cfg_ext) + size);
349+
if (!md->cfg.basecfg_ext) {
350+
ret = -ENOMEM;
351+
goto fail;
352+
}
353+
354+
memcpy_s(md->cfg.basecfg_ext, size + sizeof(struct ipc4_base_module_cfg_ext),
355+
&base_cfg->base_cfg_ext,
356+
size + sizeof(struct ipc4_base_module_cfg_ext));
340357

341358
cd->tuning_handler = comp_data_blob_handler_new(dev);
342359
if (!cd->tuning_handler) {
@@ -434,6 +451,7 @@ static int google_rtc_audio_processing_init(struct processing_module *mod)
434451
}
435452
GoogleRtcAudioProcessingDetachMemoryBuffer();
436453
rfree(cd->memory_buffer);
454+
rfree(md->cfg.basecfg_ext);
437455
rfree(cd->process_buffer);
438456
comp_data_blob_handler_free(cd->tuning_handler);
439457
rfree(cd);
@@ -445,6 +463,7 @@ static int google_rtc_audio_processing_init(struct processing_module *mod)
445463
static int google_rtc_audio_processing_free(struct processing_module *mod)
446464
{
447465
struct google_rtc_audio_processing_comp_data *cd = module_get_private_data(mod);
466+
struct module_data *md = &mod->priv;
448467

449468
comp_dbg(mod->dev, "google_rtc_audio_processing_free()");
450469

@@ -455,6 +474,7 @@ static int google_rtc_audio_processing_free(struct processing_module *mod)
455474
rfree(cd->memory_buffer);
456475
rfree(cd->process_buffer);
457476
comp_data_blob_handler_free(cd->tuning_handler);
477+
rfree(md->cfg.basecfg_ext);
458478
rfree(cd);
459479
return 0;
460480
}

src/audio/module_adapter/module_adapter_ipc4.c

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,22 @@ int module_adapter_get_attribute(struct comp_dev *dev, uint32_t type, void *valu
147147
memcpy_s(value, sizeof(struct ipc4_base_module_cfg),
148148
&mod->priv.cfg.base_cfg, sizeof(mod->priv.cfg.base_cfg));
149149
break;
150+
case COMP_ATTR_BASE_CONFIG_EXT:
151+
{
152+
struct ipc4_base_module_cfg_ext *basecfg_ext = mod->priv.cfg.basecfg_ext;
153+
size_t size;
154+
155+
if (!basecfg_ext) {
156+
comp_err(mod->dev, "No base config extn set for module");
157+
return -EINVAL;
158+
}
159+
160+
size = basecfg_ext->nb_input_pins * sizeof(struct ipc4_input_pin_format) +
161+
basecfg_ext->nb_output_pins * sizeof(struct ipc4_output_pin_format);
162+
memcpy_s(value, sizeof(*basecfg_ext) + size,
163+
basecfg_ext, sizeof(*basecfg_ext) + size);
164+
break;
165+
}
150166
default:
151167
return -EINVAL;
152168
}

src/include/module/module/base.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ struct module_config {
3030
const void *init_data; /**< Initial IPC configuration. */
3131
#if CONFIG_IPC_MAJOR_4
3232
struct ipc4_base_module_cfg base_cfg;
33+
struct ipc4_base_module_cfg_ext *basecfg_ext;
3334
#endif
3435
};
3536

src/include/sof/audio/component.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,7 @@ enum {
117117
#define COMP_ATTR_COPY_DIR 2 /**< Comp copy direction */
118118
#define COMP_ATTR_VDMA_INDEX 3 /**< Comp index of the virtual DMA at the gateway. */
119119
#define COMP_ATTR_BASE_CONFIG 4 /**< Component base config */
120+
#define COMP_ATTR_BASE_CONFIG_EXT 5 /**< Component base config extension */
120121
/** @}*/
121122

122123
/** \name Trace macros

src/include/sof/audio/component_ext.h

Lines changed: 41 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
#ifndef __SOF_AUDIO_COMPONENT_INT_H__
1717
#define __SOF_AUDIO_COMPONENT_INT_H__
1818

19+
#include <sof/audio/module_adapter/module/generic.h>
1920
#include <sof/audio/component.h>
2021
#include <ipc/topology.h>
2122

@@ -216,31 +217,59 @@ struct get_attribute_remote_payload {
216217
static inline int comp_ipc4_get_attribute_remote(struct comp_dev *dev, uint32_t type,
217218
void *value)
218219
{
220+
struct ipc4_base_module_cfg_ext *basecfg_ext;
219221
struct ipc4_base_module_cfg *base_cfg;
220222
struct get_attribute_remote_payload payload = {};
221223
struct idc_msg msg = { IDC_MSG_GET_ATTRIBUTE,
222224
IDC_EXTENSION(dev->ipc_config.id), dev->ipc_config.core,
223225
sizeof(payload), &payload};
226+
size_t size = MODULE_MAX_SINKS * sizeof(struct ipc4_output_pin_format) +
227+
MODULE_MAX_SOURCES * sizeof(struct ipc4_input_pin_format);
224228
int ret;
225229

226-
/* Only COMP_ATTR_BASE_CONFIG is supported for remote access */
227-
if (type != COMP_ATTR_BASE_CONFIG)
228-
return -EINVAL;
230+
payload.type = type;
229231

230-
base_cfg = rzalloc(SOF_MEM_ZONE_RUNTIME_SHARED, 0, SOF_MEM_CAPS_RAM, sizeof(*base_cfg));
231-
if (!base_cfg)
232-
return -ENOMEM;
232+
/*
233+
* Only COMP_ATTR_BASE_CONFIG and COMP_ATTR_BASE_CONFIG_EXT are supported for
234+
* remote access
235+
*/
236+
switch (type) {
237+
case COMP_ATTR_BASE_CONFIG:
238+
base_cfg = rzalloc(SOF_MEM_ZONE_RUNTIME_SHARED, 0, SOF_MEM_CAPS_RAM,
239+
sizeof(*base_cfg));
240+
if (!base_cfg)
241+
return -ENOMEM;
242+
243+
payload.value = base_cfg;
244+
break;
245+
case COMP_ATTR_BASE_CONFIG_EXT:
246+
basecfg_ext = rzalloc(SOF_MEM_ZONE_RUNTIME_SHARED, 0, SOF_MEM_CAPS_RAM,
247+
sizeof(*basecfg_ext) + size);
248+
if (!basecfg_ext)
249+
return -ENOMEM;
233250

234-
payload.type = type;
235-
payload.value = base_cfg;
251+
payload.value = basecfg_ext;
252+
break;
253+
default:
254+
return -EINVAL;
255+
}
236256

237257
ret = idc_send_msg(&msg, IDC_BLOCKING);
238258

239-
if (ret == 0)
240-
memcpy_s(value, sizeof(struct ipc4_base_module_cfg),
241-
base_cfg, sizeof(struct ipc4_base_module_cfg));
259+
if (!ret) {
260+
switch (type) {
261+
case COMP_ATTR_BASE_CONFIG:
262+
memcpy_s(value, sizeof(struct ipc4_base_module_cfg),
263+
base_cfg, sizeof(struct ipc4_base_module_cfg));
264+
rfree(base_cfg);
265+
break;
266+
case COMP_ATTR_BASE_CONFIG_EXT:
267+
memcpy_s(value, size, basecfg_ext, size);
268+
rfree(basecfg_ext);
269+
break;
270+
}
271+
}
242272

243-
rfree(base_cfg);
244273
return ret;
245274
}
246275
#endif /* CONFIG_IPC_MAJOR_4 */

src/include/sof/audio/module_adapter/module/generic.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131

3232
#define MAX_BLOB_SIZE 8192
3333
#define MODULE_MAX_SOURCES 8
34+
#define MODULE_MAX_SINKS 8
3435

3536
#define API_CALL(cd, cmd, sub_cmd, value, ret) \
3637
do { \

src/ipc/ipc4/helper.c

Lines changed: 84 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
#include <sof/audio/buffer.h>
99
#include <sof/audio/component.h>
1010
#include <sof/audio/component_ext.h>
11+
#include <sof/audio/module_adapter/module/generic.h>
1112
#include <sof/audio/pipeline.h>
1213
#include <sof/common.h>
1314
#include <rtos/interrupt.h>
@@ -424,15 +425,20 @@ static int ll_wait_finished_on_core(struct comp_dev *dev)
424425

425426
int ipc_comp_connect(struct ipc *ipc, ipc_pipe_comp_connect *_connect)
426427
{
428+
struct ipc4_base_module_cfg_ext *src_basecfg_ext, *sink_basecfg_ext;
427429
struct ipc4_module_bind_unbind *bu;
428430
struct comp_buffer *buffer;
429431
struct comp_dev *source;
430432
struct comp_dev *sink;
431433
struct ipc4_base_module_cfg source_src_cfg;
432434
struct ipc4_base_module_cfg sink_src_cfg;
433435
uint32_t flags;
436+
uint32_t ibs = 0;
437+
uint32_t obs = 0;
438+
uint32_t buf_size;
434439
int src_id, sink_id;
435440
int ret;
441+
size_t size;
436442

437443
bu = (struct ipc4_module_bind_unbind *)_connect;
438444
src_id = IPC4_COMP_ID(bu->primary.r.module_id, bu->primary.r.instance_id);
@@ -453,32 +459,88 @@ int ipc_comp_connect(struct ipc *ipc, ipc_pipe_comp_connect *_connect)
453459
if (!cpu_is_me(source->ipc_config.core) && !cross_core_bind)
454460
return ipc4_process_on_core(source->ipc_config.core, false);
455461

456-
/* these might call comp_ipc4_get_attribute_remote() if necessary */
457-
ret = comp_get_attribute(source, COMP_ATTR_BASE_CONFIG, &source_src_cfg);
458-
if (ret < 0) {
459-
tr_err(&ipc_tr, "failed to get base config for module %#x", dev_comp_id(source));
460-
return IPC4_FAILURE;
462+
size = MODULE_MAX_SINKS * sizeof(struct ipc4_output_pin_format) +
463+
MODULE_MAX_SOURCES * sizeof(struct ipc4_input_pin_format);
464+
465+
/* get obs from the base config extension if the src queue ID is non-zero */
466+
if (bu->extension.r.src_queue) {
467+
struct ipc4_output_pin_format *out_fmt;
468+
size_t output_fmt_offset;
469+
470+
src_basecfg_ext = rzalloc(SOF_MEM_ZONE_RUNTIME, 0, SOF_MEM_CAPS_RAM,
471+
sizeof(*src_basecfg_ext) + size);
472+
if (!src_basecfg_ext)
473+
return IPC4_OUT_OF_MEMORY;
474+
475+
ret = comp_get_attribute(source, COMP_ATTR_BASE_CONFIG_EXT, src_basecfg_ext);
476+
if (!ret) {
477+
size_t in_fmt_size = sizeof(struct ipc4_input_pin_format);
478+
size_t out_fmt_size = sizeof(struct ipc4_output_pin_format);
479+
480+
/*
481+
* offset of the format for the output pin with ID 'src_queue' within the
482+
* base config extension.
483+
*/
484+
output_fmt_offset =
485+
src_basecfg_ext->nb_input_pins * in_fmt_size +
486+
bu->extension.r.src_queue * out_fmt_size;
487+
out_fmt = (struct ipc4_output_pin_format *)&sink_basecfg_ext->pin_formats[output_fmt_offset];
488+
obs = out_fmt->obs;
489+
}
490+
rfree(src_basecfg_ext);
461491
}
462492

463-
ret = comp_get_attribute(sink, COMP_ATTR_BASE_CONFIG, &sink_src_cfg);
464-
if (ret < 0) {
465-
tr_err(&ipc_tr, "failed to get base config for module %#x", dev_comp_id(sink));
466-
return IPC4_FAILURE;
493+
/* get obs from base config if src queue ID is 0 or if base config extn is missing */
494+
if (!obs) {
495+
/* these might call comp_ipc4_get_attribute_remote() if necessary */
496+
ret = comp_get_attribute(source, COMP_ATTR_BASE_CONFIG, &source_src_cfg);
497+
498+
if (ret < 0) {
499+
tr_err(&ipc_tr, "failed to get base config for src module %#x",
500+
dev_comp_id(source));
501+
return IPC4_FAILURE;
502+
}
503+
obs = source_src_cfg.obs;
467504
}
468505

469-
/* create a buffer
470-
* in case of LL -> LL or LL->DP
471-
* size = 2*obs of source module (obs is single buffer size)
472-
* in case of DP -> LL
473-
* size = 2*ibs of destination (LL) module. DP queue will handle obs of DP module
474-
*/
475-
uint32_t buf_size;
506+
/* get ibs from the base config extension if the sink queue ID is non-zero */
507+
if (bu->extension.r.dst_queue) {
508+
struct ipc4_input_pin_format *in_fmt;
509+
size_t input_fmt_offset;
510+
511+
sink_basecfg_ext = rzalloc(SOF_MEM_ZONE_RUNTIME, 0, SOF_MEM_CAPS_RAM,
512+
sizeof(*sink_basecfg_ext) + size);
513+
if (!sink_basecfg_ext)
514+
return IPC4_OUT_OF_MEMORY;
515+
516+
ret = comp_get_attribute(sink, COMP_ATTR_BASE_CONFIG_EXT, sink_basecfg_ext);
517+
if (!ret) {
518+
/*
519+
* offset of the format for the input pin with ID 'dst_queue' within the
520+
* base config extension.
521+
*/
522+
input_fmt_offset =
523+
bu->extension.r.dst_queue * sizeof(struct ipc4_input_pin_format);
524+
in_fmt = (struct ipc4_input_pin_format *)&sink_basecfg_ext->pin_formats[input_fmt_offset];
525+
ibs = in_fmt->ibs;
526+
}
527+
rfree(sink_basecfg_ext);
528+
}
476529

477-
if (source->ipc_config.proc_domain == COMP_PROCESSING_DOMAIN_LL)
478-
buf_size = source_src_cfg.obs * 2;
479-
else
480-
buf_size = sink_src_cfg.ibs * 2;
530+
/* get ibs from base config if sink queue ID is 0 or if base config extn is missing */
531+
if (!ibs) {
532+
ret = comp_get_attribute(sink, COMP_ATTR_BASE_CONFIG, &sink_src_cfg);
533+
if (ret < 0) {
534+
tr_err(&ipc_tr, "failed to get base config for sink module %#x",
535+
dev_comp_id(sink));
536+
return IPC4_FAILURE;
537+
}
538+
539+
ibs = sink_src_cfg.ibs;
540+
}
481541

542+
/* allocate buffer with size large enough to fit ibs of the sink or obs of the source */
543+
buf_size = MAX(ibs * 2, obs * 2);
482544
buffer = ipc4_create_buffer(source, cross_core_bind, buf_size, bu->extension.r.src_queue,
483545
bu->extension.r.dst_queue);
484546
if (!buffer) {
@@ -496,8 +558,8 @@ int ipc_comp_connect(struct ipc *ipc, ipc_pipe_comp_connect *_connect)
496558
* sink_module needs to set its IBS (input buffer size)
497559
* as min_available in buffer's source ifc
498560
*/
499-
sink_set_min_free_space(audio_stream_get_sink(&buffer->stream), source_src_cfg.obs);
500-
source_set_min_available(audio_stream_get_source(&buffer->stream), sink_src_cfg.ibs);
561+
sink_set_min_free_space(audio_stream_get_sink(&buffer->stream), obs);
562+
source_set_min_available(audio_stream_get_source(&buffer->stream), ibs);
501563

502564
/*
503565
* Connect and bind the buffer to both source and sink components with LL processing been

src/samples/audio/smart_amp_test_ipc4.c

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,9 +66,13 @@ static struct smart_amp_data smart_amp_priv;
6666
static int smart_amp_init(struct processing_module *mod)
6767
{
6868
struct smart_amp_data *sad;
69+
struct comp_dev *dev = mod->dev;
6970
struct module_data *mod_data = &mod->priv;
71+
const size_t in_size = sizeof(struct ipc4_input_pin_format) * SMART_AMP_NUM_IN_PINS;
72+
const size_t out_size = sizeof(struct ipc4_output_pin_format) * SMART_AMP_NUM_OUT_PINS;
7073
int ret;
7174
const struct ipc4_base_module_extended_cfg *base_cfg = mod_data->cfg.init_data;
75+
size_t size;
7276

7377
LOG_DBG("smart_amp_init()");
7478

@@ -96,6 +100,16 @@ static int smart_amp_init(struct processing_module *mod)
96100
*(struct ipc4_output_pin_format *)(base_cfg->base_cfg_ext.pin_formats
97101
+ sizeof(sad->ipc4_cfg.input_pins));
98102

103+
/* save the base config extension */
104+
size = sizeof(struct ipc4_base_module_cfg_ext) + in_size + out_size;
105+
mod_data->cfg.basecfg_ext = rzalloc(SOF_MEM_ZONE_RUNTIME, 0, SOF_MEM_CAPS_RAM, size);
106+
if (!mod_data->cfg.basecfg_ext) {
107+
ret = -ENOMEM;
108+
goto sad_fail;
109+
}
110+
111+
memcpy_s(mod_data->cfg.basecfg_ext, size, &base_cfg->base_cfg_ext, size);
112+
99113
return 0;
100114

101115
sad_fail:
@@ -155,7 +169,10 @@ static int smart_amp_free(struct processing_module *mod)
155169

156170
#ifndef __SOF_MODULE_SERVICE_BUILD__
157171
struct smart_amp_data *sad = module_get_private_data(mod);
172+
struct module_data *mod_data = &mod->priv;
173+
struct comp_dev *dev = mod->dev;
158174

175+
rfree(mod_data->cfg.basecfg_ext);
159176
rfree(sad);
160177
#endif
161178

0 commit comments

Comments
 (0)