mirror of https://github.com/thesofproject/sof.git
demux: Support inactive cross-pipeline sinks
It may happen that a demux is configured to write to a buffer in a stopped pipeline (consider echo cancellation when the mic is not in use: the output reference stream has nowhere to go). This doesn't work in the tree currently; the general pipeline design is to try to turn on pipes that are required, but that's incomplete for the case (again, echo cancellation) where the pipelines are oriented in different directions and in any case is undesirable as a microphone stream shouldn't be required to be active for playback to work. Instead, detect the situation at PRE_START time, configure the output buffers overrun_permitted (as there may not be a reader), and drop the unconfigured streams dynamically at process() time, as the target pipeline may be started up at arbitrary moments. When it starts, we'll begin emitting output at the first process callback as desired. Signed-off-by: Andy Ross <andyross@google.com>
This commit is contained in:
parent
ddf70fa033
commit
33ef5f6a7d
|
@ -270,9 +270,12 @@ static int demux_process(struct processing_module *mod,
|
|||
|
||||
/* produce output, one sink at a time */
|
||||
for (i = 0; i < num_output_buffers; i++) {
|
||||
if (sinks_stream[i]) {
|
||||
demux_prepare_active_look_up(cd, sinks_stream[i],
|
||||
input_buffers[0].data, look_ups[i]);
|
||||
cd->demux(dev, sinks_stream[i], input_buffers[0].data, frames, &cd->active_lookup);
|
||||
cd->demux(dev, sinks_stream[i], input_buffers[0].data,
|
||||
frames, &cd->active_lookup);
|
||||
}
|
||||
mod->output_buffers[i].size = sink_bytes;
|
||||
}
|
||||
|
||||
|
@ -453,6 +456,31 @@ static int mux_set_config(struct processing_module *mod, uint32_t config_id,
|
|||
fragment, fragment_size);
|
||||
}
|
||||
|
||||
static int demux_trigger(struct processing_module *mod, int cmd)
|
||||
{
|
||||
struct list_item *li;
|
||||
struct comp_buffer *b;
|
||||
|
||||
/* Check for cross-pipeline sinks: in general foreign
|
||||
* pipelines won't be started synchronously with ours (it's
|
||||
* under control of host software), so output can't be
|
||||
* guaranteed not to overflow. Always set the
|
||||
* overrun_permitted flag. These sink components are assumed
|
||||
* responsible for flushing/synchronizing the stream
|
||||
* themselves.
|
||||
*/
|
||||
if (cmd == COMP_TRIGGER_PRE_START) {
|
||||
list_for_item(li, &mod->dev->bsink_list) {
|
||||
b = container_of(li, struct comp_buffer, source_list);
|
||||
if (b->sink->pipeline != mod->dev->pipeline)
|
||||
audio_stream_set_overrun(&b->stream, true);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return module_adapter_set_state(mod, mod->dev, cmd);
|
||||
}
|
||||
|
||||
static const struct module_interface mux_interface = {
|
||||
.init = mux_init,
|
||||
.set_configuration = mux_set_config,
|
||||
|
@ -472,6 +500,7 @@ static const struct module_interface demux_interface = {
|
|||
.get_configuration = mux_get_config,
|
||||
.prepare = mux_prepare,
|
||||
.process_audio_stream = demux_process,
|
||||
.trigger = demux_trigger,
|
||||
.reset = mux_reset,
|
||||
.free = mux_free,
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue