-
Notifications
You must be signed in to change notification settings - Fork 364
selector: re-validate configuration on control set #10912
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -231,16 +231,85 @@ static int selector_ctrl_set_data(struct comp_dev *dev, | |
| struct sof_ipc_ctrl_data *cdata) | ||
| { | ||
| struct comp_data *cd = comp_get_drvdata(dev); | ||
| struct comp_buffer *src; | ||
| struct sof_sel_config *cfg; | ||
| uint32_t src_channels; | ||
| int ret = 0; | ||
|
|
||
| switch (cdata->cmd) { | ||
| case SOF_CTRL_CMD_BINARY: | ||
| comp_dbg(dev, "SOF_CTRL_CMD_BINARY"); | ||
|
|
||
| if (cdata->data->size < sizeof(struct sof_sel_config)) { | ||
| comp_err(dev, "invalid config blob size %u", cdata->data->size); | ||
| return -EINVAL; | ||
| } | ||
|
|
||
| cfg = (struct sof_sel_config *) | ||
| ASSUME_ALIGNED(&cdata->data->data, 4); | ||
|
|
||
| /* | ||
| * The config validated at .params() time can be replaced here at | ||
| * runtime, so re-validate the new channel counts and selected | ||
| * channel before accepting them; otherwise an out-of-range value | ||
| * later indexes past the source channels in the copy routine. | ||
| */ | ||
| switch (cfg->in_channels_count) { | ||
| case 0: | ||
| case SEL_SOURCE_2CH: | ||
| case SEL_SOURCE_4CH: | ||
| break; | ||
| default: | ||
| comp_err(dev, "invalid in_channels_count %u", | ||
| cfg->in_channels_count); | ||
| return -EINVAL; | ||
| } | ||
|
|
||
| switch (cfg->out_channels_count) { | ||
| case 0: | ||
| case SEL_SINK_1CH: | ||
| case SEL_SINK_2CH: | ||
| case SEL_SINK_4CH: | ||
| break; | ||
| default: | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. also 5.1 and 7.1 sinks
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The accepted set here intentionally mirrors the existing |
||
| comp_err(dev, "invalid out_channels_count %u", | ||
| cfg->out_channels_count); | ||
| return -EINVAL; | ||
| } | ||
|
Comment on lines
+257
to
+278
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 0 isn't a "no change" sentinel here — it's a valid configuration meaning "derive the channel count from the stream at runtime". See
Comment on lines
+257
to
+278
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The two paths validate different things, which is why I didn't share code: |
||
|
|
||
| /* sel_channel indexes the source channels, so it must be below | ||
| * the source channel count, otherwise the copy routine reads | ||
| * past the end of each source frame. The copy routine strides by | ||
| * the live producer stream channel count, so when the source is | ||
| * already connected that live count is the authority for both the | ||
| * selected channel and any fixed input count; before connection | ||
| * fall back to the configured input count. Always cap by the | ||
| * maximum supported source width. | ||
| */ | ||
| src = comp_dev_get_first_data_producer(dev); | ||
| if (src) | ||
| src_channels = audio_stream_get_channels(&src->stream); | ||
| else | ||
| src_channels = cfg->in_channels_count; | ||
|
|
||
| /* A fixed (non-zero) input count must not exceed the live source | ||
| * width, otherwise sel_channel could be accepted below the | ||
| * requested count yet still index past the actual stream. | ||
| */ | ||
| if (src && cfg->in_channels_count && | ||
| cfg->in_channels_count > src_channels) { | ||
| comp_err(dev, "in_channels_count %u exceeds source channels %u", | ||
| cfg->in_channels_count, src_channels); | ||
| return -EINVAL; | ||
| } | ||
|
|
||
| if (cfg->sel_channel >= SEL_SOURCE_4CH || | ||
| (src_channels && cfg->sel_channel >= src_channels)) { | ||
| comp_err(dev, "invalid sel_channel %u (source channels %u)", | ||
| cfg->sel_channel, src_channels); | ||
| return -EINVAL; | ||
| } | ||
|
|
||
| /* Just set the configuration */ | ||
| cd->config.in_channels_count = cfg->in_channels_count; | ||
| cd->config.out_channels_count = cfg->out_channels_count; | ||
|
Comment on lines
313
to
315
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 0 isn't a "no change" sentinel here — it's a valid configuration meaning "derive the channel count from the stream at runtime". See |
||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We have also 5.1 and 7.1 down-mix supported. See https://github.com/thesofproject/sof/tree/main/tools/topology/topology2/include/components/micsel
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
and also 1CH input is supported