Skip to content

Commit

Permalink
demux: Support inactive cross-pipeline sinks
Browse files Browse the repository at this point in the history
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 <[email protected]>
  • Loading branch information
andyross committed Dec 13, 2023
1 parent ded7ed8 commit cb9c47c
Showing 1 changed file with 32 additions and 3 deletions.
35 changes: 32 additions & 3 deletions src/audio/mux/mux.c
Original file line number Diff line number Diff line change
Expand Up @@ -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++) {
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);
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);
}
mod->output_buffers[i].size = sink_bytes;
}

Expand Down Expand Up @@ -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,
Expand All @@ -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,
};
Expand Down

0 comments on commit cb9c47c

Please sign in to comment.