Skip to content

Commit 482bf31

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 19d7a58 commit 482bf31

5 files changed

Lines changed: 367 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: 141 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,84 @@ 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;
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 (sources == NULL && sources[0] == NULL) {
245+
return 0;
246+
}
247+
source = sources[0];
251248

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

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

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);
269+
/* the source is read-only and shared by all sinks, so it is obtained
270+
* once here and released once after all sinks have been served
271+
*/
272+
source_bytes = frames * source_get_frame_bytes(source);
273+
ret = source_get_data(source, source_bytes, &source_data, &source_start,
274+
&source_size);
275+
if (ret)
276+
return ret;
264277

265278
/* 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);
279+
for (i = 0; i < num_of_sinks; i++) {
280+
struct sof_sink *sink = sinks[i];
281+
uint32_t pipeline_id = sink_get_pipeline_id(sink);
282+
struct mux_look_up *look_up;
283+
284+
/* skip sinks that are not in the same state as the component */
285+
if (sink_get_state(sink) != dev->state)
286+
continue;
287+
288+
/* return if configuration for this pipeline is missing */
289+
if (get_stream_index(dev, cd, pipeline_id) < 0) {
290+
source_release_data(source, 0);
291+
return -EINVAL;
292+
}
293+
294+
look_up = get_lookup_table(dev, cd, pipeline_id);
295+
demux_prepare_active_look_up(cd, sink, source, look_up);
296+
ret = cd->demux(dev, sink, source, source_data, source_start,
297+
source_size, frames, &cd->active_lookup);
298+
if (ret) {
299+
source_release_data(source, 0);
300+
return ret;
272301
}
273-
mod->output_buffers[i].size = sink_bytes;
274302
}
275303

276-
/* Update consumed */
277-
mod->input_buffers[0].consumed = source_bytes;
304+
/* consume the processed data from the source */
305+
source_release_data(source, source_bytes);
278306
return 0;
279307
}
280308

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

306334
/* process and copy stream data from source to sink buffers */
307335
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)
336+
struct sof_source **sources, int num_of_sources,
337+
struct sof_sink **sinks, int num_of_sinks)
310338
{
311339
struct comp_data *cd = module_get_private_data(mod);
312340
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;
341+
struct sof_sink *sink = sinks[0];
342+
struct sof_source *active_sources[MUX_MAX_STREAMS] = { NULL };
343+
struct cir_buf_source source_bufs[MUX_MAX_STREAMS] = { 0 };
344+
size_t source_bytes[MUX_MAX_STREAMS] = { 0 };
345+
struct cir_buf_sink sink_buf;
346+
size_t sink_bytes, size;
347+
uint32_t frames;
348+
int i, idx, ret;
318349

319350
comp_dbg(dev, "entry");
320351

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-
}
352+
/* if there are no sources or sinks active, then there is nothing to do */
353+
if (num_of_sinks == 0 || num_of_sources == 0)
354+
return 0;
335355

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

341-
/* check if there are any sources active */
342-
if (num_input_buffers == 0)
377+
if (!frames)
343378
return 0;
344379

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]);
380+
/* build the active routing table for the current connections */
381+
mux_prepare_active_look_up(cd, sink, active_sources);
347382

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++;
383+
/* acquire the single sink circular buffer for the whole period */
384+
sink_bytes = frames * sink_get_frame_bytes(sink);
385+
ret = sink_get_buffer(sink, sink_bytes, &sink_buf.ptr, &sink_buf.buf_start, &size);
386+
if (ret)
387+
return ret;
388+
sink_buf.buf_end = (char *)sink_buf.buf_start + size;
389+
390+
/* acquire every active source circular buffer */
391+
for (i = 0; i < MUX_MAX_STREAMS; i++) {
392+
if (!active_sources[i])
393+
continue;
394+
395+
source_bytes[i] = frames * source_get_frame_bytes(active_sources[i]);
396+
ret = source_get_data(active_sources[i], source_bytes[i], &source_bufs[i].ptr,
397+
&source_bufs[i].buf_start, &size);
398+
if (ret) {
399+
/* release the sources acquired so far and the sink */
400+
for (--i; i >= 0; i--)
401+
if (active_sources[i])
402+
source_release_data(active_sources[i], 0);
403+
sink_commit_buffer(sink, 0);
404+
return ret;
405+
}
406+
source_bufs[i].buf_end = (const char *)source_bufs[i].buf_start + size;
358407
}
359-
mod->output_buffers[0].size = sink_bytes;
408+
409+
/* produce output */
410+
cd->mux(dev, sink, &sink_buf, active_sources, source_bufs, frames, &cd->active_lookup);
411+
412+
/* commit the produced data and consume from every active source */
413+
sink_commit_buffer(sink, sink_bytes);
414+
for (i = 0; i < MUX_MAX_STREAMS; i++)
415+
if (active_sources[i])
416+
source_release_data(active_sources[i], source_bytes[i]);
417+
360418
return 0;
361419
}
362420

@@ -443,7 +501,7 @@ static const struct module_interface mux_interface = {
443501
.set_configuration = mux_set_config,
444502
.get_configuration = mux_get_config,
445503
.prepare = mux_prepare,
446-
.process_audio_stream = mux_process,
504+
.process = mux_process,
447505
.reset = mux_reset,
448506
.free = mux_free,
449507
};
@@ -454,7 +512,7 @@ static const struct module_interface demux_interface = {
454512
.set_configuration = mux_set_config,
455513
.get_configuration = mux_get_config,
456514
.prepare = mux_prepare,
457-
.process_audio_stream = demux_process,
515+
.process = demux_process,
458516
.trigger = demux_trigger,
459517
.reset = mux_reset,
460518
.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)