Skip to content

Commit f9101a7

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 f9101a7

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
@@ -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,9 +169,10 @@ 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;
175+
}
175176

176177
cd->active_lookup.copy_elem[active_elem] = cd->lookup[0].copy_elem[elem];
177178
active_elem++;
@@ -203,18 +204,19 @@ static struct mux_look_up *get_lookup_table(struct comp_dev *dev, struct comp_da
203204
}
204205

205206
static void demux_prepare_active_look_up(struct comp_data *cd,
206-
struct audio_stream *sink,
207-
const struct audio_stream *source,
207+
struct sof_sink *sink,
208+
struct sof_source *source,
208209
struct mux_look_up *look_up)
209210
{
210211
int elem;
211212
int active_elem = 0;
212213

213214
/* init pointers */
214215
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))
216+
if (look_up->copy_elem[elem].in_ch >= source_get_channels(source) ||
217+
look_up->copy_elem[elem].out_ch >= sink_get_channels(sink)) {
217218
continue;
219+
}
218220

219221
cd->active_lookup.copy_elem[active_elem] = look_up->copy_elem[elem];
220222
active_elem++;
@@ -225,56 +227,89 @@ static void demux_prepare_active_look_up(struct comp_data *cd,
225227

226228
/* process and copy stream data from source to sink buffers */
227229
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)
230+
struct sof_source **sources, int num_of_sources,
231+
struct sof_sink **sinks, int num_of_sinks)
230232
{
231233
struct comp_data *cd = module_get_private_data(mod);
232234
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;
235+
struct sof_source *source;
236+
const void *source_data;
237+
const void *source_start;
238+
size_t source_size;
239+
size_t source_bytes;
240+
uint32_t frames;
241+
int ret;
239242
int i;
240243

241244
comp_dbg(dev, "entry");
242245

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-
}
246+
if (sources == NULL && sources[0] == NULL) {
247+
return 0;
248+
}
249+
source = sources[0];
251250

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

257-
/* if there are no sinks active, then sinks[] is also empty */
258-
if (num_output_buffers == 0)
270+
if (!frames) {
259271
return 0;
272+
}
260273

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);
274+
/* the source is read-only and shared by all sinks, so it is obtained
275+
* once here and released once after all sinks have been served
276+
*/
277+
source_bytes = frames * source_get_frame_bytes(source);
278+
ret = source_get_data(source, source_bytes, &source_data, &source_start,
279+
&source_size);
280+
if (ret) {
281+
return ret;
282+
}
264283

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

276-
/* Update consumed */
277-
mod->input_buffers[0].consumed = source_bytes;
311+
/* consume the processed data from the source */
312+
source_release_data(source, source_bytes);
278313
return 0;
279314
}
280315

@@ -305,58 +340,96 @@ static int demux_trigger(struct processing_module *mod, int cmd)
305340

306341
/* process and copy stream data from source to sink buffers */
307342
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)
343+
struct sof_source **sources, int num_of_sources,
344+
struct sof_sink **sinks, int num_of_sinks)
310345
{
311346
struct comp_data *cd = module_get_private_data(mod);
312347
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;
348+
struct sof_sink *sink = sinks[0];
349+
struct sof_source *active_sources[MUX_MAX_STREAMS] = { NULL };
350+
struct cir_buf_source source_bufs[MUX_MAX_STREAMS] = { 0 };
351+
size_t source_bytes[MUX_MAX_STREAMS] = { 0 };
352+
struct cir_buf_sink sink_buf;
353+
size_t sink_bytes, size;
354+
uint32_t frames;
355+
int i, idx, ret;
318356

319357
comp_dbg(dev, "entry");
320358

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-
}
359+
/* if there are no sources or sinks active, then there is nothing to do */
360+
if (num_of_sinks == 0 || num_of_sources == 0) {
361+
return 0;
362+
}
363+
364+
/* the same number of frames is taken from every active source and
365+
* written to the single sink, so it is limited by both the sink free
366+
* space and every active source's availability
367+
*/
368+
frames = sink_get_free_frames(sink);
369+
for (i = 0; i < num_of_sources; i++) {
370+
struct sof_source *source = sources[i];
335371

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

341-
/* check if there are any sources active */
342-
if (num_input_buffers == 0)
387+
if (!frames) {
343388
return 0;
389+
}
344390

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

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++;
394+
/* acquire the single sink circular buffer for the whole period */
395+
sink_bytes = frames * sink_get_frame_bytes(sink);
396+
ret = sink_get_buffer(sink, sink_bytes, &sink_buf.ptr, &sink_buf.buf_start, &size);
397+
if (ret) {
398+
return ret;
358399
}
359-
mod->output_buffers[0].size = sink_bytes;
400+
sink_buf.buf_end = (char *)sink_buf.buf_start + size;
401+
402+
/* acquire every active source circular buffer */
403+
for (i = 0; i < MUX_MAX_STREAMS; i++) {
404+
if (!active_sources[i]) {
405+
continue;
406+
}
407+
408+
source_bytes[i] = frames * source_get_frame_bytes(active_sources[i]);
409+
ret = source_get_data(active_sources[i], source_bytes[i], &source_bufs[i].ptr,
410+
&source_bufs[i].buf_start, &size);
411+
if (ret) {
412+
/* release the sources acquired so far and the sink */
413+
for (--i; i >= 0; i--)
414+
if (active_sources[i]) {
415+
source_release_data(active_sources[i], 0);
416+
}
417+
sink_commit_buffer(sink, 0);
418+
return ret;
419+
}
420+
source_bufs[i].buf_end = (const char *)source_bufs[i].buf_start + size;
421+
}
422+
423+
/* produce output */
424+
cd->mux(dev, sink, &sink_buf, active_sources, source_bufs, frames, &cd->active_lookup);
425+
426+
/* commit the produced data and consume from every active source */
427+
sink_commit_buffer(sink, sink_bytes);
428+
for (i = 0; i < MUX_MAX_STREAMS; i++)
429+
if (active_sources[i]) {
430+
source_release_data(active_sources[i], source_bytes[i]);
431+
}
432+
360433
return 0;
361434
}
362435

@@ -443,7 +516,7 @@ static const struct module_interface mux_interface = {
443516
.set_configuration = mux_set_config,
444517
.get_configuration = mux_get_config,
445518
.prepare = mux_prepare,
446-
.process_audio_stream = mux_process,
519+
.process = mux_process,
447520
.reset = mux_reset,
448521
.free = mux_free,
449522
};
@@ -454,7 +527,7 @@ static const struct module_interface demux_interface = {
454527
.set_configuration = mux_set_config,
455528
.get_configuration = mux_get_config,
456529
.prepare = mux_prepare,
457-
.process_audio_stream = demux_process,
530+
.process = demux_process,
458531
.trigger = demux_trigger,
459532
.reset = mux_reset,
460533
.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)