Skip to content

Commit 48b21a9

Browse files
module: mux: rework module to use sink/source api
Rework the mux module to only use the sink/source api to prepare the SOF for the full transition to pipeline 2.0. Signed-off-by: Piotr Hoppe <piotr.hoppe@intel.com>
1 parent de024fe commit 48b21a9

5 files changed

Lines changed: 379 additions & 193 deletions

File tree

src/audio/buffers/comp_buffer.c

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,20 @@ static int comp_buffer_commit_buffer(struct sof_sink *sink, size_t commit_size)
100100
return 0;
101101
}
102102

103+
static int comp_buffer_sink_get_state(struct sof_sink *sink)
104+
{
105+
struct comp_buffer *buffer = comp_buffer_get_from_sink(sink);
106+
107+
return comp_get_state(comp_buffer_get_sink_component(buffer));
108+
}
109+
110+
static int comp_buffer_source_get_state(struct sof_source *source)
111+
{
112+
struct comp_buffer *buffer = comp_buffer_get_from_source(source);
113+
114+
return comp_get_state(comp_buffer_get_source_component(buffer));
115+
}
116+
103117
static int comp_buffer_set_ipc_params(struct sof_audio_buffer *audio_buffer,
104118
struct sof_ipc_stream_params *params,
105119
bool force_update)
@@ -179,6 +193,7 @@ APP_TASK_DATA static const struct source_ops comp_buffer_source_ops = {
179193
.audio_set_ipc_params = audio_buffer_source_set_ipc_params,
180194
.on_audio_format_set = audio_buffer_source_on_audio_format_set,
181195
.set_alignment_constants = audio_buffer_source_set_alignment_constants,
196+
.get_state = comp_buffer_source_get_state,
182197
};
183198

184199
APP_TASK_DATA static const struct sink_ops comp_buffer_sink_ops = {
@@ -189,6 +204,7 @@ APP_TASK_DATA static const struct sink_ops comp_buffer_sink_ops = {
189204
.on_audio_format_set = audio_buffer_sink_on_audio_format_set,
190205
.set_alignment_constants = audio_buffer_sink_set_alignment_constants,
191206
.get_lft = audio_buffer_sink_get_lft,
207+
.get_state = comp_buffer_sink_get_state,
192208
};
193209

194210
static const struct audio_buffer_ops audio_buffer_ops = {

src/audio/mux/mux.c

Lines changed: 154 additions & 81 deletions
Original file line numberDiff line numberDiff line change
@@ -158,10 +158,10 @@ static int get_stream_index(struct comp_dev *dev, struct comp_data *cd, uint32_t
158158
}
159159

160160
static void mux_prepare_active_look_up(struct comp_data *cd,
161-
struct audio_stream *sink,
162-
const struct audio_stream **sources)
161+
struct sof_sink *sink,
162+
struct sof_source **sources)
163163
{
164-
const struct audio_stream *source;
164+
struct sof_source *source;
165165
int elem;
166166
int active_elem = 0;
167167

@@ -171,9 +171,10 @@ static void mux_prepare_active_look_up(struct comp_data *cd,
171171
if (!source)
172172
continue;
173173

174-
if (cd->lookup[0].copy_elem[elem].in_ch >= audio_stream_get_channels(source) ||
175-
cd->lookup[0].copy_elem[elem].out_ch >= audio_stream_get_channels(sink))
174+
if (cd->lookup[0].copy_elem[elem].in_ch >= source_get_channels(source) ||
175+
cd->lookup[0].copy_elem[elem].out_ch >= sink_get_channels(sink)) {
176176
continue;
177+
}
177178

178179
cd->active_lookup.copy_elem[active_elem] = cd->lookup[0].copy_elem[elem];
179180
active_elem++;
@@ -205,18 +206,19 @@ static struct mux_look_up *get_lookup_table(struct comp_dev *dev, struct comp_da
205206
}
206207

207208
static void demux_prepare_active_look_up(struct comp_data *cd,
208-
struct audio_stream *sink,
209-
const struct audio_stream *source,
209+
struct sof_sink *sink,
210+
struct sof_source *source,
210211
struct mux_look_up *look_up)
211212
{
212213
int elem;
213214
int active_elem = 0;
214215

215216
/* init pointers */
216217
for (elem = 0; elem < look_up->num_elems; elem++) {
217-
if (look_up->copy_elem[elem].in_ch >= audio_stream_get_channels(source) ||
218-
look_up->copy_elem[elem].out_ch >= audio_stream_get_channels(sink))
218+
if (look_up->copy_elem[elem].in_ch >= source_get_channels(source) ||
219+
look_up->copy_elem[elem].out_ch >= sink_get_channels(sink)) {
219220
continue;
221+
}
220222

221223
cd->active_lookup.copy_elem[active_elem] = look_up->copy_elem[elem];
222224
active_elem++;
@@ -227,56 +229,89 @@ static void demux_prepare_active_look_up(struct comp_data *cd,
227229

228230
/* process and copy stream data from source to sink buffers */
229231
static int demux_process(struct processing_module *mod,
230-
struct input_stream_buffer *input_buffers, int num_input_buffers,
231-
struct output_stream_buffer *output_buffers, int num_output_buffers)
232+
struct sof_source **sources, int num_of_sources,
233+
struct sof_sink **sinks, int num_of_sinks)
232234
{
233235
struct comp_data *cd = module_get_private_data(mod);
234236
struct comp_dev *dev = mod->dev;
235-
struct comp_buffer *sink;
236-
struct audio_stream *sinks_stream[MUX_MAX_STREAMS] = { NULL };
237-
struct mux_look_up *look_ups[MUX_MAX_STREAMS] = { NULL };
238-
int frames;
239-
int sink_bytes;
240-
int source_bytes;
237+
struct sof_source *source;
238+
const void *source_data;
239+
const void *source_start;
240+
size_t source_size;
241+
size_t source_bytes;
242+
uint32_t frames;
243+
int ret;
241244
int i;
242245

243246
comp_dbg(dev, "entry");
244247

245-
/* align sink streams with their respective configurations */
246-
comp_dev_for_each_consumer(dev, sink) {
247-
if (comp_buffer_get_sink_state(sink) == dev->state) {
248-
i = get_stream_index(dev, cd, buffer_pipeline_id(sink));
249-
/* return if index wrong */
250-
if (i < 0) {
251-
return i;
252-
}
248+
if (sources == NULL && sources[0] == NULL) {
249+
return 0;
250+
}
251+
source = sources[0];
253252

254-
look_ups[i] = get_lookup_table(dev, cd, buffer_pipeline_id(sink));
255-
sinks_stream[i] = &sink->stream;
253+
/* if there are no sinks active, then there is nothing to do */
254+
if (num_of_sinks == 0) {
255+
return 0;
256+
}
257+
258+
/* the same number of frames is distributed to every sink, so it is
259+
* limited by both the source availability and every active sink's free
260+
* space
261+
*/
262+
frames = source_get_data_frames_available(source);
263+
for (i = 0; i < num_of_sinks; i++) {
264+
if (sink_get_state(sinks[i]) != dev->state) {
265+
comp_warn(dev, "the sink %d has diffrent state, culd not process", i);
266+
continue;
256267
}
268+
269+
frames = MIN(frames, sink_get_free_frames(sinks[i]));
257270
}
258271

259-
/* if there are no sinks active, then sinks[] is also empty */
260-
if (num_output_buffers == 0)
272+
if (!frames) {
261273
return 0;
274+
}
262275

263-
frames = input_buffers[0].size;
264-
source_bytes = frames * audio_stream_frame_bytes(mod->input_buffers[0].data);
265-
sink_bytes = frames * audio_stream_frame_bytes(mod->output_buffers[0].data);
276+
/* the source is read-only and shared by all sinks, so it is obtained
277+
* once here and released once after all sinks have been served
278+
*/
279+
source_bytes = frames * source_get_frame_bytes(source);
280+
ret = source_get_data(source, source_bytes, &source_data, &source_start,
281+
&source_size);
282+
if (ret) {
283+
return ret;
284+
}
266285

267286
/* produce output, one sink at a time */
268-
for (i = 0; i < num_output_buffers; i++) {
269-
if (sinks_stream[i]) {
270-
demux_prepare_active_look_up(cd, sinks_stream[i],
271-
input_buffers[0].data, look_ups[i]);
272-
cd->demux(dev, sinks_stream[i], input_buffers[0].data,
273-
frames, &cd->active_lookup);
287+
for (i = 0; i < num_of_sinks; i++) {
288+
struct sof_sink *sink = sinks[i];
289+
uint32_t pipeline_id = sink_get_pipeline_id(sink);
290+
struct mux_look_up *look_up;
291+
292+
/* skip sinks that are not in the same state as the component */
293+
if (sink_get_state(sink) != dev->state) {
294+
continue;
295+
}
296+
297+
/* return if configuration for this pipeline is missing */
298+
if (get_stream_index(dev, cd, pipeline_id) < 0) {
299+
source_release_data(source, 0);
300+
return -EINVAL;
301+
}
302+
303+
look_up = get_lookup_table(dev, cd, pipeline_id);
304+
demux_prepare_active_look_up(cd, sink, source, look_up);
305+
ret = cd->demux(dev, sink, source, source_data, source_start,
306+
source_size, frames, &cd->active_lookup);
307+
if (ret) {
308+
source_release_data(source, 0);
309+
return ret;
274310
}
275-
mod->output_buffers[i].size = sink_bytes;
276311
}
277312

278-
/* Update consumed */
279-
mod->input_buffers[0].consumed = source_bytes;
313+
/* consume the processed data from the source */
314+
source_release_data(source, source_bytes);
280315
return 0;
281316
}
282317

@@ -307,58 +342,96 @@ static int demux_trigger(struct processing_module *mod, int cmd)
307342

308343
/* process and copy stream data from source to sink buffers */
309344
static int mux_process(struct processing_module *mod,
310-
struct input_stream_buffer *input_buffers, int num_input_buffers,
311-
struct output_stream_buffer *output_buffers, int num_output_buffers)
345+
struct sof_source **sources, int num_of_sources,
346+
struct sof_sink **sinks, int num_of_sinks)
312347
{
313348
struct comp_data *cd = module_get_private_data(mod);
314349
struct comp_dev *dev = mod->dev;
315-
struct comp_buffer *source;
316-
const struct audio_stream *sources_stream[MUX_MAX_STREAMS] = { NULL };
317-
int frames = 0;
318-
int sink_bytes;
319-
int i, j;
350+
struct sof_sink *sink = sinks[0];
351+
struct sof_source *active_sources[MUX_MAX_STREAMS] = { NULL };
352+
struct cir_buf_source source_bufs[MUX_MAX_STREAMS] = { 0 };
353+
size_t source_bytes[MUX_MAX_STREAMS] = { 0 };
354+
struct cir_buf_sink sink_buf;
355+
size_t sink_bytes, size;
356+
uint32_t frames;
357+
int i, idx, ret;
320358

321359
comp_dbg(dev, "entry");
322360

323-
/* align source streams with their respective configurations */
324-
j = 0;
325-
comp_dev_for_each_producer(dev, source) {
326-
if (comp_buffer_get_source_state(source) == dev->state) {
327-
if (frames)
328-
frames = MIN(frames, input_buffers[j].size);
329-
else
330-
frames = input_buffers[j].size;
331-
332-
i = get_stream_index(dev, cd, buffer_pipeline_id(source));
333-
/* return if index wrong */
334-
if (i < 0) {
335-
return i;
336-
}
361+
/* if there are no sources or sinks active, then there is nothing to do */
362+
if (num_of_sinks == 0 || num_of_sources == 0) {
363+
return 0;
364+
}
365+
366+
/* the same number of frames is taken from every active source and
367+
* written to the single sink, so it is limited by both the sink free
368+
* space and every active source's availability
369+
*/
370+
frames = sink_get_free_frames(sink);
371+
for (i = 0; i < num_of_sources; i++) {
372+
struct sof_source *source = sources[i];
337373

338-
sources_stream[i] = &source->stream;
374+
/* skip sources that are not in the same state as the component */
375+
if (source_get_comp_state(source) != dev->state) {
376+
continue;
339377
}
340-
j++;
378+
379+
/* map the source to its configured stream index */
380+
idx = get_stream_index(dev, cd, source_get_pipeline_id(source));
381+
if (idx < 0) {
382+
return idx;
383+
}
384+
385+
active_sources[idx] = source;
386+
frames = MIN(frames, source_get_data_frames_available(source));
341387
}
342388

343-
/* check if there are any sources active */
344-
if (num_input_buffers == 0)
389+
if (!frames) {
345390
return 0;
391+
}
346392

347-
sink_bytes = frames * audio_stream_frame_bytes(mod->output_buffers[0].data);
348-
mux_prepare_active_look_up(cd, output_buffers[0].data, &sources_stream[0]);
393+
/* build the active routing table for the current connections */
394+
mux_prepare_active_look_up(cd, sink, active_sources);
349395

350-
/* produce output */
351-
cd->mux(dev, output_buffers[0].data, &sources_stream[0], frames, &cd->active_lookup);
352-
353-
/* Update consumed per source using each source's own frame size */
354-
j = 0;
355-
comp_dev_for_each_producer(dev, source) {
356-
if (comp_buffer_get_source_state(source) == dev->state)
357-
mod->input_buffers[j].consumed =
358-
frames * audio_stream_frame_bytes(mod->input_buffers[j].data);
359-
j++;
396+
/* acquire the single sink circular buffer for the whole period */
397+
sink_bytes = frames * sink_get_frame_bytes(sink);
398+
ret = sink_get_buffer(sink, sink_bytes, &sink_buf.ptr, &sink_buf.buf_start, &size);
399+
if (ret) {
400+
return ret;
360401
}
361-
mod->output_buffers[0].size = sink_bytes;
402+
sink_buf.buf_end = (char *)sink_buf.buf_start + size;
403+
404+
/* acquire every active source circular buffer */
405+
for (i = 0; i < MUX_MAX_STREAMS; i++) {
406+
if (!active_sources[i]) {
407+
continue;
408+
}
409+
410+
source_bytes[i] = frames * source_get_frame_bytes(active_sources[i]);
411+
ret = source_get_data(active_sources[i], source_bytes[i], &source_bufs[i].ptr,
412+
&source_bufs[i].buf_start, &size);
413+
if (ret) {
414+
/* release the sources acquired so far and the sink */
415+
for (--i; i >= 0; i--)
416+
if (active_sources[i]) {
417+
source_release_data(active_sources[i], 0);
418+
}
419+
sink_commit_buffer(sink, 0);
420+
return ret;
421+
}
422+
source_bufs[i].buf_end = (const char *)source_bufs[i].buf_start + size;
423+
}
424+
425+
/* produce output */
426+
cd->mux(dev, sink, &sink_buf, active_sources, source_bufs, frames, &cd->active_lookup);
427+
428+
/* commit the produced data and consume from every active source */
429+
sink_commit_buffer(sink, sink_bytes);
430+
for (i = 0; i < MUX_MAX_STREAMS; i++)
431+
if (active_sources[i]) {
432+
source_release_data(active_sources[i], source_bytes[i]);
433+
}
434+
362435
return 0;
363436
}
364437

@@ -445,7 +518,7 @@ static const struct module_interface mux_interface = {
445518
.set_configuration = mux_set_config,
446519
.get_configuration = mux_get_config,
447520
.prepare = mux_prepare,
448-
.process_audio_stream = mux_process,
521+
.process = mux_process,
449522
.reset = mux_reset,
450523
.free = mux_free,
451524
};
@@ -456,7 +529,7 @@ static const struct module_interface demux_interface = {
456529
.set_configuration = mux_set_config,
457530
.get_configuration = mux_get_config,
458531
.prepare = mux_prepare,
459-
.process_audio_stream = demux_process,
532+
.process = demux_process,
460533
.trigger = demux_trigger,
461534
.reset = mux_reset,
462535
.free = mux_free,

src/audio/mux/mux.h

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,10 @@
2828
#endif
2929
struct comp_buffer;
3030
struct comp_dev;
31+
struct sof_source;
32+
struct sof_sink;
33+
struct cir_buf_source;
34+
struct cir_buf_sink;
3135

3236
/** \brief Supported streams count. */
3337
#if CONFIG_IPC_MAJOR_3
@@ -66,11 +70,13 @@ struct mux_stream_data {
6670
uint8_t reserved2[3]; // padding to ensure proper alignment of following instances
6771
} __attribute__((packed, aligned(4)));
6872

69-
typedef void(*demux_func)(struct comp_dev *dev, struct audio_stream *sink,
70-
const struct audio_stream *source, uint32_t frames,
71-
struct mux_look_up *look_up);
72-
typedef void(*mux_func)(struct comp_dev *dev, struct audio_stream *sink,
73-
const struct audio_stream **sources, uint32_t frames,
73+
typedef int(*demux_func)(struct comp_dev *dev, struct sof_sink *sink,
74+
struct sof_source *source, const void *source_data,
75+
const void *source_start, size_t source_size,
76+
uint32_t frames, struct mux_look_up *look_up);
77+
typedef void(*mux_func)(struct comp_dev *dev, struct sof_sink *sink,
78+
struct cir_buf_sink *sink_buf, struct sof_source **sources,
79+
struct cir_buf_source *source_bufs, uint32_t frames,
7480
struct mux_look_up *look_up);
7581

7682
/**

0 commit comments

Comments
 (0)