Skip to content

Commit 8da9ef7

Browse files
committed
component: Add eos support in components copy function
Add eos support in the function that calls the module's data processing function. If the end of the stream in the source buffer is detected, pass it to the output buffer. For DP modules, generate silence on the input after end of the stream to allow them to process the remaining data. Signed-off-by: Adrian Warecki <adrian.warecki@intel.com>
1 parent 5772920 commit 8da9ef7

File tree

1 file changed

+60
-0
lines changed

1 file changed

+60
-0
lines changed

src/audio/component.c

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
// Author: Liam Girdwood <liam.r.girdwood@linux.intel.com>
66

77
#include <sof/audio/component_ext.h>
8+
#include <sof/audio/sink_source_utils.h>
89
#include <sof/common.h>
910
#include <sof/debug/telemetry/performance_monitor.h>
1011
#include <rtos/panic.h>
@@ -496,6 +497,62 @@ void audio_stream_copy_to_linear(const struct audio_stream *source, int ioffset,
496497
}
497498
}
498499

500+
static bool comp_check_eos(struct comp_dev *dev)
501+
{
502+
enum sof_audio_buffer_state sink_state = AUDIOBUF_STATE_INITIAL;
503+
struct comp_buffer *buffer;
504+
505+
if (!dev->pipeline->expect_eos)
506+
return false;
507+
508+
comp_dev_for_each_producer(dev, buffer) {
509+
struct sof_source *source = audio_buffer_get_source(&buffer->audio_buffer);
510+
enum sof_audio_buffer_state state = source_get_state(source);
511+
512+
if (source_get_pipeline_id(source) != dev->pipeline->pipeline_id)
513+
continue;
514+
515+
if (state == AUDIOBUF_STATE_END_OF_STREAM_FLUSH) {
516+
/* Earlier in the pipeline, there is a DP module that has reached
517+
* the EOS state. However, silence is generated to flush its internal
518+
* buffers, so pass this state to the output buffers.
519+
*/
520+
comp_dbg(dev, "comp_check_eos() - EOS flush detected");
521+
sink_state = AUDIOBUF_STATE_END_OF_STREAM_FLUSH;
522+
break;
523+
} else if (state == AUDIOBUF_STATE_END_OF_STREAM) {
524+
/* EOS is detected, so we need to set the sink state to AUDIOBUF_STATE_EOS. */
525+
size_t min_avail = source_get_min_available(source);
526+
527+
if (source_get_data_available(source) < min_avail) {
528+
comp_dbg(dev, "comp_check_eos() - EOS detected");
529+
if (dev->ipc_config.proc_domain == COMP_PROCESSING_DOMAIN_DP) {
530+
/* For DP modules, fill missing input data with silence to
531+
* allow it to process the remaining data.
532+
*/
533+
struct sof_sink *previous_mod_data_sink =
534+
audio_buffer_get_sink(&buffer->audio_buffer);
535+
sink_fill_with_silence(previous_mod_data_sink, min_avail);
536+
sink_state = AUDIOBUF_STATE_END_OF_STREAM_FLUSH;
537+
} else {
538+
sink_state = AUDIOBUF_STATE_END_OF_STREAM;
539+
break;
540+
}
541+
}
542+
}
543+
}
544+
545+
if (sink_state != AUDIOBUF_STATE_INITIAL) {
546+
comp_dev_for_each_consumer(dev, buffer)
547+
audio_buffer_set_state(&buffer->audio_buffer, sink_state);
548+
549+
/* For AUDIOBUF_STATE_END_OF_STREAM_FLUSH process data normally. */
550+
return sink_state != AUDIOBUF_STATE_END_OF_STREAM_FLUSH;
551+
}
552+
553+
return false;
554+
}
555+
499556
/** See comp_ops::copy */
500557
int comp_copy(struct comp_dev *dev)
501558
{
@@ -530,6 +587,9 @@ int comp_copy(struct comp_dev *dev)
530587
const uint32_t begin_stamp = (uint32_t)telemetry_timestamp();
531588
#endif
532589

590+
if (comp_check_eos(dev))
591+
return 0;
592+
533593
ret = dev->drv->ops.copy(dev);
534594

535595
#ifdef CONFIG_SOF_TELEMETRY_PERFORMANCE_MEASUREMENTS

0 commit comments

Comments
 (0)