Skip to content

Commit

Permalink
mod: too quick draining buffer fix
Browse files Browse the repository at this point in the history
DP may produce a huge chunk of output data (i.e. 10 LL
cycles), and the following module should be able to
consume it in 1 cycle chunks, one by one

unfortunately some modules are not prepared to
work when there's more than 1 data portion available
in the buffer and are draining buffers with data loss

a workaround: copy only the following module's IBS in each LL cycle

required fix: all modules using sink/src interface must be aware to
process only data they need, not forcefully draining a buffer

Signed-off-by: Marcin Szkudlinski <[email protected]>
  • Loading branch information
marcinszkudlinski committed Nov 9, 2023
1 parent 3bd9991 commit c8f675d
Showing 1 changed file with 15 additions and 1 deletion.
16 changes: 15 additions & 1 deletion src/audio/module_adapter/module_adapter.c
Original file line number Diff line number Diff line change
Expand Up @@ -1072,13 +1072,27 @@ static int module_adapter_copy_dp_queues(struct comp_dev *dev)
list_for_item(blist, &dev->bsink_list) {
/* output - we need to copy data from dp_queue (as source)
* to audio_stream (as sink)
*
* a trick is needed there as a workaround
* DP may produce a huge chunk of output data (i.e. 10 LL
* cycles), and the following module should be able to consume it in 1 cycle chunks
*
* unfortunately some modules are not prepared to work when there's more than
* 1 data portion available in the buffer and are draining buffers with data loss
*
* a workaround: copy only the following module's IBS in each LL cycle
*
* required fix: all modules using sink/src interface must be aware to
* process only data they need, not forcefully draining a buffer
*/
assert(dp_queue);
struct comp_buffer *buffer =
container_of(blist, struct comp_buffer, source_list);
struct sof_sink *data_sink = audio_stream_get_sink(&buffer->stream);
struct sof_source *following_mod_data_source =
audio_stream_get_source(&buffer->stream);
struct sof_source *data_src = dp_queue_get_source(dp_queue);
uint32_t to_copy = MIN(sink_get_free_size(data_sink),
uint32_t to_copy = MIN(source_get_min_available(following_mod_data_source),
source_get_data_available(data_src));

err = source_to_sink_copy(data_src, data_sink, true, to_copy);
Expand Down

0 comments on commit c8f675d

Please sign in to comment.