Skip to content

Commit 364e497

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 097907a commit 364e497

7 files changed

Lines changed: 409 additions & 271 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: 135 additions & 83 deletions
Original file line numberDiff line numberDiff line change
@@ -156,10 +156,10 @@ static int get_stream_index(struct comp_dev *dev, struct comp_data *cd, uint32_t
156156
}
157157

158158
static void mux_prepare_active_look_up(struct comp_data *cd,
159-
struct audio_stream *sink,
160-
const struct audio_stream **sources)
159+
struct sof_sink *sink,
160+
struct sof_source **sources)
161161
{
162-
const struct audio_stream *source;
162+
struct sof_source *source;
163163
int elem;
164164
int active_elem = 0;
165165

@@ -169,8 +169,8 @@ static void mux_prepare_active_look_up(struct comp_data *cd,
169169
if (!source)
170170
continue;
171171

172-
if (cd->lookup[0].copy_elem[elem].in_ch >= audio_stream_get_channels(source) ||
173-
cd->lookup[0].copy_elem[elem].out_ch >= audio_stream_get_channels(sink))
172+
if (cd->lookup[0].copy_elem[elem].in_ch >= source_get_channels(source) ||
173+
cd->lookup[0].copy_elem[elem].out_ch >= sink_get_channels(sink))
174174
continue;
175175

176176
cd->active_lookup.copy_elem[active_elem] = cd->lookup[0].copy_elem[elem];
@@ -203,17 +203,17 @@ static struct mux_look_up *get_lookup_table(struct comp_dev *dev, struct comp_da
203203
}
204204

205205
static void demux_prepare_active_look_up(struct comp_data *cd,
206-
struct audio_stream *sink,
207-
const struct audio_stream *source,
206+
struct sof_sink *sink,
207+
struct sof_source *source,
208208
struct mux_look_up *look_up)
209209
{
210210
int elem;
211211
int active_elem = 0;
212212

213213
/* init pointers */
214214
for (elem = 0; elem < look_up->num_elems; elem++) {
215-
if (look_up->copy_elem[elem].in_ch >= audio_stream_get_channels(source) ||
216-
look_up->copy_elem[elem].out_ch >= audio_stream_get_channels(sink))
215+
if (look_up->copy_elem[elem].in_ch >= source_get_channels(source) ||
216+
look_up->copy_elem[elem].out_ch >= sink_get_channels(sink))
217217
continue;
218218

219219
cd->active_lookup.copy_elem[active_elem] = look_up->copy_elem[elem];
@@ -225,56 +225,78 @@ static void demux_prepare_active_look_up(struct comp_data *cd,
225225

226226
/* process and copy stream data from source to sink buffers */
227227
static int demux_process(struct processing_module *mod,
228-
struct input_stream_buffer *input_buffers, int num_input_buffers,
229-
struct output_stream_buffer *output_buffers, int num_output_buffers)
228+
struct sof_source **sources, int num_of_sources,
229+
struct sof_sink **sinks, int num_of_sinks)
230230
{
231231
struct comp_data *cd = module_get_private_data(mod);
232232
struct comp_dev *dev = mod->dev;
233-
struct comp_buffer *sink;
234-
struct audio_stream *sinks_stream[MUX_MAX_STREAMS] = { NULL };
235-
struct mux_look_up *look_ups[MUX_MAX_STREAMS] = { NULL };
236-
int frames;
237-
int sink_bytes;
238-
int source_bytes;
233+
struct sof_source *source = sources[0];
234+
const void *source_data;
235+
const void *source_start;
236+
size_t source_size;
237+
size_t source_bytes;
238+
uint32_t frames;
239+
int ret;
239240
int i;
240241

241242
comp_dbg(dev, "entry");
242243

243-
/* align sink streams with their respective configurations */
244-
comp_dev_for_each_consumer(dev, sink) {
245-
if (comp_buffer_get_sink_state(sink) == dev->state) {
246-
i = get_stream_index(dev, cd, buffer_pipeline_id(sink));
247-
/* return if index wrong */
248-
if (i < 0) {
249-
return i;
250-
}
244+
/* if there are no sinks active, then there is nothing to do */
245+
if (num_of_sinks == 0)
246+
return 0;
251247

252-
look_ups[i] = get_lookup_table(dev, cd, buffer_pipeline_id(sink));
253-
sinks_stream[i] = &sink->stream;
254-
}
248+
/* the same number of frames is distributed to every sink, so it is
249+
* limited by both the source availability and every active sink's free
250+
* space
251+
*/
252+
frames = source_get_data_frames_available(source);
253+
for (i = 0; i < num_of_sinks; i++) {
254+
if (sink_get_state(sinks[i]) != dev->state)
255+
continue;
256+
257+
frames = MIN(frames, sink_get_free_frames(sinks[i]));
255258
}
256259

257-
/* if there are no sinks active, then sinks[] is also empty */
258-
if (num_output_buffers == 0)
260+
if (!frames)
259261
return 0;
260262

261-
frames = input_buffers[0].size;
262-
source_bytes = frames * audio_stream_frame_bytes(mod->input_buffers[0].data);
263-
sink_bytes = frames * audio_stream_frame_bytes(mod->output_buffers[0].data);
263+
/* the source is read-only and shared by all sinks, so it is obtained
264+
* once here and released once after all sinks have been served
265+
*/
266+
source_bytes = frames * source_get_frame_bytes(source);
267+
ret = source_get_data(source, source_bytes, &source_data, &source_start,
268+
&source_size);
269+
if (ret)
270+
return ret;
264271

265272
/* produce output, one sink at a time */
266-
for (i = 0; i < num_output_buffers; i++) {
267-
if (sinks_stream[i]) {
268-
demux_prepare_active_look_up(cd, sinks_stream[i],
269-
input_buffers[0].data, look_ups[i]);
270-
cd->demux(dev, sinks_stream[i], input_buffers[0].data,
271-
frames, &cd->active_lookup);
273+
for (i = 0; i < num_of_sinks; i++) {
274+
struct sof_sink *sink = sinks[i];
275+
uint32_t pipeline_id = sink_get_pipeline_id(sink);
276+
struct mux_look_up *look_up;
277+
278+
/* skip sinks that are not in the same state as the component */
279+
if (sink_get_state(sink) != dev->state)
280+
continue;
281+
282+
/* return if configuration for this pipeline is missing */
283+
if (get_stream_index(dev, cd, pipeline_id) < 0) {
284+
source_release_data(source, 0);
285+
return -EINVAL;
286+
}
287+
288+
look_up = get_lookup_table(dev, cd, pipeline_id);
289+
demux_prepare_active_look_up(cd, sink, source, look_up);
290+
ret = cd->demux(dev, sink, source, source_data, source_start,
291+
source_size, frames, &cd->active_lookup);
292+
if (ret) {
293+
source_release_data(source, 0);
294+
return ret;
272295
}
273-
mod->output_buffers[i].size = sink_bytes;
274296
}
275297

276-
/* Update consumed */
277-
mod->input_buffers[0].consumed = source_bytes;
298+
/* consume the processed data from the source */
299+
source_release_data(source, source_bytes);
278300
return 0;
279301
}
280302

@@ -305,58 +327,88 @@ static int demux_trigger(struct processing_module *mod, int cmd)
305327

306328
/* process and copy stream data from source to sink buffers */
307329
static int mux_process(struct processing_module *mod,
308-
struct input_stream_buffer *input_buffers, int num_input_buffers,
309-
struct output_stream_buffer *output_buffers, int num_output_buffers)
330+
struct sof_source **sources, int num_of_sources,
331+
struct sof_sink **sinks, int num_of_sinks)
310332
{
311333
struct comp_data *cd = module_get_private_data(mod);
312334
struct comp_dev *dev = mod->dev;
313-
struct comp_buffer *source;
314-
const struct audio_stream *sources_stream[MUX_MAX_STREAMS] = { NULL };
315-
int frames = 0;
316-
int sink_bytes;
317-
int i, j;
335+
struct sof_sink *sink = sinks[0];
336+
struct sof_source *active_sources[MUX_MAX_STREAMS] = { NULL };
337+
struct cir_buf_source source_bufs[MUX_MAX_STREAMS] = { 0 };
338+
size_t source_bytes[MUX_MAX_STREAMS] = { 0 };
339+
struct cir_buf_sink sink_buf;
340+
size_t sink_bytes, size;
341+
uint32_t frames;
342+
int i, idx, ret;
318343

319344
comp_dbg(dev, "entry");
320345

321-
/* align source streams with their respective configurations */
322-
j = 0;
323-
comp_dev_for_each_producer(dev, source) {
324-
if (comp_buffer_get_source_state(source) == dev->state) {
325-
if (frames)
326-
frames = MIN(frames, input_buffers[j].size);
327-
else
328-
frames = input_buffers[j].size;
329-
330-
i = get_stream_index(dev, cd, buffer_pipeline_id(source));
331-
/* return if index wrong */
332-
if (i < 0) {
333-
return i;
334-
}
346+
/* if there are no sources or sinks active, then there is nothing to do */
347+
if (num_of_sinks == 0 || num_of_sources == 0)
348+
return 0;
335349

336-
sources_stream[i] = &source->stream;
337-
}
338-
j++;
350+
/* the same number of frames is taken from every active source and
351+
* written to the single sink, so it is limited by both the sink free
352+
* space and every active source's availability
353+
*/
354+
frames = sink_get_free_frames(sink);
355+
for (i = 0; i < num_of_sources; i++) {
356+
struct sof_source *source = sources[i];
357+
358+
/* skip sources that are not in the same state as the component */
359+
if (source_get_comp_state(source) != dev->state)
360+
continue;
361+
362+
/* map the source to its configured stream index */
363+
idx = get_stream_index(dev, cd, source_get_pipeline_id(source));
364+
if (idx < 0)
365+
return idx;
366+
367+
active_sources[idx] = source;
368+
frames = MIN(frames, source_get_data_frames_available(source));
339369
}
340370

341-
/* check if there are any sources active */
342-
if (num_input_buffers == 0)
371+
if (!frames)
343372
return 0;
344373

345-
sink_bytes = frames * audio_stream_frame_bytes(mod->output_buffers[0].data);
346-
mux_prepare_active_look_up(cd, output_buffers[0].data, &sources_stream[0]);
374+
/* build the active routing table for the current connections */
375+
mux_prepare_active_look_up(cd, sink, active_sources);
347376

348-
/* produce output */
349-
cd->mux(dev, output_buffers[0].data, &sources_stream[0], frames, &cd->active_lookup);
350-
351-
/* Update consumed per source using each source's own frame size */
352-
j = 0;
353-
comp_dev_for_each_producer(dev, source) {
354-
if (comp_buffer_get_source_state(source) == dev->state)
355-
mod->input_buffers[j].consumed =
356-
frames * audio_stream_frame_bytes(mod->input_buffers[j].data);
357-
j++;
377+
/* acquire the single sink circular buffer for the whole period */
378+
sink_bytes = frames * sink_get_frame_bytes(sink);
379+
ret = sink_get_buffer(sink, sink_bytes, &sink_buf.ptr, &sink_buf.buf_start, &size);
380+
if (ret)
381+
return ret;
382+
sink_buf.buf_end = (char *)sink_buf.buf_start + size;
383+
384+
/* acquire every active source circular buffer */
385+
for (i = 0; i < MUX_MAX_STREAMS; i++) {
386+
if (!active_sources[i])
387+
continue;
388+
389+
source_bytes[i] = frames * source_get_frame_bytes(active_sources[i]);
390+
ret = source_get_data(active_sources[i], source_bytes[i], &source_bufs[i].ptr,
391+
&source_bufs[i].buf_start, &size);
392+
if (ret) {
393+
/* release the sources acquired so far and the sink */
394+
for (--i; i >= 0; i--)
395+
if (active_sources[i])
396+
source_release_data(active_sources[i], 0);
397+
sink_commit_buffer(sink, 0);
398+
return ret;
399+
}
400+
source_bufs[i].buf_end = (const char *)source_bufs[i].buf_start + size;
358401
}
359-
mod->output_buffers[0].size = sink_bytes;
402+
403+
/* produce output */
404+
cd->mux(dev, sink, &sink_buf, active_sources, source_bufs, frames, &cd->active_lookup);
405+
406+
/* commit the produced data and consume from every active source */
407+
sink_commit_buffer(sink, sink_bytes);
408+
for (i = 0; i < MUX_MAX_STREAMS; i++)
409+
if (active_sources[i])
410+
source_release_data(active_sources[i], source_bytes[i]);
411+
360412
return 0;
361413
}
362414

@@ -443,7 +495,7 @@ static const struct module_interface mux_interface = {
443495
.set_configuration = mux_set_config,
444496
.get_configuration = mux_get_config,
445497
.prepare = mux_prepare,
446-
.process_audio_stream = mux_process,
498+
.process = mux_process,
447499
.reset = mux_reset,
448500
.free = mux_free,
449501
};
@@ -454,7 +506,7 @@ static const struct module_interface demux_interface = {
454506
.set_configuration = mux_set_config,
455507
.get_configuration = mux_get_config,
456508
.prepare = mux_prepare,
457-
.process_audio_stream = demux_process,
509+
.process = demux_process,
458510
.trigger = demux_trigger,
459511
.reset = mux_reset,
460512
.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)