Repository navigation
Fix handling of the mixer-module adapter combo on IPC3 platforms #7357
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
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 |
|---|---|---|
|
|
@@ -82,11 +82,12 @@ static int mixer_process(struct processing_module *mod, | |
| struct mixer_data *md = module_get_private_data(mod); | ||
| struct comp_dev *dev = mod->dev; | ||
| const struct audio_stream __sparse_cache *sources_stream[PLATFORM_MAX_STREAMS]; | ||
| int32_t i = 0; | ||
| int32_t i = 0, j = 0; | ||
| uint32_t frames = INT32_MAX; | ||
| /* Redundant, but helps the compiler */ | ||
| uint32_t source_bytes = 0; | ||
| uint32_t sink_bytes; | ||
| int active_input_buffers = 0; | ||
|
|
||
| comp_dbg(dev, "mixer_process() %d", num_input_buffers); | ||
|
|
||
|
|
@@ -105,10 +106,11 @@ static int mixer_process(struct processing_module *mod, | |
| if (avail_frames == 0) | ||
| continue; | ||
|
|
||
| active_input_buffers++; | ||
| frames = MIN(frames, avail_frames); | ||
| } | ||
|
|
||
| if (!num_input_buffers || (frames == 0 && md->sources_inactive)) { | ||
| if (!active_input_buffers) { | ||
| /* | ||
| * Generate silence when sources are inactive. When | ||
| * sources change to active, additionally keep | ||
|
|
@@ -119,33 +121,37 @@ static int mixer_process(struct processing_module *mod, | |
| if (!audio_stream_set_zero(mod->output_buffers[0].data, sink_bytes)) | ||
| mod->output_buffers[0].size = sink_bytes; | ||
|
|
||
| md->sources_inactive = true; | ||
|
|
||
| return 0; | ||
| } | ||
|
|
||
| /* Every source has the same format, so calculate bytes based on the first one */ | ||
| source_bytes = frames * audio_stream_frame_bytes(mod->input_buffers[0].data); | ||
|
|
||
| if (md->sources_inactive) { | ||
| md->sources_inactive = false; | ||
| comp_dbg(dev, "mixer_copy exit sources_inactive state"); | ||
| } | ||
|
|
||
| sink_bytes = frames * audio_stream_frame_bytes(mod->output_buffers[0].data); | ||
|
|
||
| comp_dbg(dev, "mixer_process(), source_bytes = 0x%x, sink_bytes = 0x%x", | ||
| source_bytes, sink_bytes); | ||
|
|
||
| /* mix streams */ | ||
| for (i = 0; i < num_input_buffers; i++) | ||
| sources_stream[i] = mod->input_buffers[i].data; | ||
| for (i = 0; i < num_input_buffers; i++) { | ||
| uint32_t avail_frames; | ||
|
|
||
| avail_frames = audio_stream_avail_frames_aligned(mod->input_buffers[i].data, | ||
| mod->output_buffers[0].data); | ||
|
|
||
| /* if one source is inactive, skip it */ | ||
| if (avail_frames == 0) | ||
| continue; | ||
|
|
||
| sources_stream[j++] = mod->input_buffers[i].data; | ||
| } | ||
|
|
||
| md->mix_func(dev, mod->output_buffers[0].data, sources_stream, num_input_buffers, frames); | ||
| if (j) | ||
| md->mix_func(dev, mod->output_buffers[0].data, sources_stream, j, frames); | ||
|
Collaborator
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. Perhaps I should use active_input_buffers here and below?
Contributor
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. You need j anyway to have the exact active buffers, so you can continue using j here and below
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. Hmm, wouldn't j==active_input_buffers ? If j can be differnent, then I think it deserves a longer more descriptive name as it's used across this long function (i.e. not just a loop index variable anymore).
Collaborator
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. They can differ if there's a race changing which buffers are active between the first check and this loop. I can write an assert stating that they don't differ I suppose. |
||
| mod->output_buffers[0].size = sink_bytes; | ||
|
|
||
| /* update source buffer consumed bytes */ | ||
| for (i = 0; i < num_input_buffers; i++) | ||
| for (i = 0; i < j; i++) | ||
| mod->input_buffers[i].consumed = source_bytes; | ||
|
|
||
| return 0; | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -167,21 +167,16 @@ int module_adapter_prepare(struct comp_dev *dev) | |
|
|
||
| comp_dbg(dev, "module_adapter_prepare() start"); | ||
|
|
||
| /* | ||
| * check if the component is already active. This could happen in the case of mixer when | ||
| * one of the sources is already active | ||
| */ | ||
| if (dev->state == COMP_STATE_ACTIVE) | ||
| return 0; | ||
| /* Prepare module */ | ||
| ret = module_prepare(mod); | ||
| if (ret) { | ||
| if (ret == PPL_STATUS_PATH_STOP) | ||
| return ret; | ||
|
|
||
| /* Are we already prepared? */ | ||
| ret = comp_set_state(dev, COMP_TRIGGER_PREPARE); | ||
| if (ret < 0) | ||
| return ret; | ||
| comp_err(dev, "module_adapter_prepare() error %x: module prepare failed", | ||
| ret); | ||
|
|
||
| if (ret == COMP_STATUS_STATE_ALREADY_SET) { | ||
| comp_warn(dev, "module_adapter_prepare(): module has already been prepared"); | ||
| return PPL_STATUS_PATH_STOP; | ||
| return -EIO; | ||
|
paulstelian97 marked this conversation as resolved.
|
||
| } | ||
|
|
||
| /* Get period_bytes first on prepare(). At this point it is guaranteed that the stream | ||
|
|
@@ -195,16 +190,21 @@ int module_adapter_prepare(struct comp_dev *dev) | |
|
|
||
| buffer_release(sink_c); | ||
|
|
||
| /* Prepare module */ | ||
| ret = module_prepare(mod); | ||
|
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. are we sure, that no module is currently relying on |
||
| if (ret) { | ||
| if (ret == PPL_STATUS_PATH_STOP) | ||
| return ret; | ||
| /* | ||
| * check if the component is already active. This could happen in the case of mixer when | ||
| * one of the sources is already active | ||
| */ | ||
| if (dev->state == COMP_STATE_ACTIVE) | ||
| return PPL_STATUS_PATH_STOP; | ||
|
|
||
| comp_err(dev, "module_adapter_prepare() error %x: module prepare failed", | ||
| ret); | ||
| /* Are we already prepared? */ | ||
| ret = comp_set_state(dev, COMP_TRIGGER_PREPARE); | ||
| if (ret < 0) | ||
| return ret; | ||
|
|
||
| return -EIO; | ||
| if (ret == COMP_STATUS_STATE_ALREADY_SET) { | ||
| comp_warn(dev, "module_adapter_prepare(): module has already been prepared"); | ||
| return PPL_STATUS_PATH_STOP; | ||
| } | ||
|
|
||
| mod->deep_buff_bytes = 0; | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.