-
Notifications
You must be signed in to change notification settings - Fork 349
Bunch of fixes to DP processing #8467
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -168,6 +168,9 @@ static int module_adapter_dp_queue_prepare(struct comp_dev *dev) | |
| * first, set all parameters by calling "module prepare" with pointers to | ||
| * "main" audio_stream buffers | ||
| */ | ||
| list_init(&mod->dp_queue_ll_to_dp_list); | ||
| list_init(&mod->dp_queue_dp_to_ll_list); | ||
|
|
||
| ret = module_adapter_sink_src_prepare(dev); | ||
| if (ret) | ||
| return ret; | ||
|
|
@@ -177,7 +180,6 @@ static int module_adapter_dp_queue_prepare(struct comp_dev *dev) | |
| * and copy stream parameters to shadow buffers | ||
| */ | ||
| i = 0; | ||
| list_init(&mod->dp_queue_ll_to_dp_list); | ||
| list_for_item(blist, &dev->bsource_list) { | ||
| struct comp_buffer *source_buffer = | ||
| container_of(blist, struct comp_buffer, sink_list); | ||
|
|
@@ -211,7 +213,6 @@ static int module_adapter_dp_queue_prepare(struct comp_dev *dev) | |
| unsigned int period = UINT32_MAX; | ||
|
|
||
| i = 0; | ||
| list_init(&mod->dp_queue_dp_to_ll_list); | ||
| list_for_item(blist, &dev->bsink_list) { | ||
| struct comp_buffer *sink_buffer = | ||
| container_of(blist, struct comp_buffer, source_list); | ||
|
|
@@ -1068,18 +1069,28 @@ static int module_adapter_copy_dp_queues(struct comp_dev *dev) | |
| dp_queue = dp_queue_get_next_item(dp_queue); | ||
| } | ||
|
|
||
| if (mod->dp_startup_delay) | ||
| return 0; | ||
|
|
||
| dp_queue = dp_queue_get_first_item(&mod->dp_queue_dp_to_ll_list); | ||
| list_for_item(blist, &dev->bsink_list) { | ||
| /* output - we need to copy data from dp_queue (as source) | ||
| * to audio_stream (as sink) | ||
| */ | ||
| /* output - we need to copy data from dp_queue (as source) | ||
| * to audio_stream (as sink) | ||
| */ | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't think we should drop this comment (from first patch in the series). The logic to not feed more than on LL is still in place, right, and should be explained. |
||
| 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), | ||
| source_get_data_available(data_src)); | ||
| size_t dp_data_available = source_get_data_available(data_src); | ||
|
|
||
| if (!dp_data_available) | ||
| comp_err(dev, "!!!! no data available from DP"); | ||
|
|
||
| uint32_t to_copy = MIN(source_get_min_available(following_mod_data_source), | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. shouldn't we fix offending LL modules one by one - as soon as you generate respective topologies?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. absolutely we do
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ok, since this is a temp WA, we probably want to create an issue to track and link it to the comments here. We can then check all the other modules as we build topologies and remove the WA.
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is at least in dp_copy_queues() function, so specific to DP-LL interface and the comment explains what is done here, so could be worse.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @lgirdwood I don't think it is neccessary Once all modules use sink/src and communication between them is in pipeline 2.0 manner (I'm preparng an RFC for this), dp_copy_queues will be removed in whole (well, hopefully together with module adapter)
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @marcinszkudlinski ok, and we should be able to track this in RFC GH issue. i.e. we can mention all the PRs - sound like we target v2.9 for this too. |
||
| dp_data_available); | ||
|
|
||
| err = source_to_sink_copy(data_src, data_sink, true, to_copy); | ||
| if (err) | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -225,6 +225,35 @@ struct processing_module { | |
| /* module-specific flags for comp_verify_params() */ | ||
| uint32_t verify_params_flags; | ||
|
|
||
| /* indicates that this DP module did not yet reach its first deadline and | ||
| * no data should be passed yet to next LL module | ||
| * | ||
| * why: lets assume DP with 10ms period (a.k.a a deadline). It starts and finishes | ||
| * Earlier, i.e. in 2ms providing 10ms of data. LL starts consuming data in 1ms chunks and | ||
| * will drain 10ms buffer in 10ms, expecting a new portion of data on 11th ms | ||
| * BUT - the DP module deadline is still 10ms, regardless if it had finished earlier | ||
| * and it is completely fine that processing in next cycle takes full 10ms - as long as it | ||
| * fits into the deadline. | ||
| * It may lead to underruns: | ||
| * | ||
| * LL1 (1ms) ---> DP (10ms) -->LL2 (1ms) | ||
| * | ||
| * ticks 0..9 -> LL1 is producing 1ms data portions, DP is waiting, LL2 is waiting | ||
| * tick 10 - DP has enough data to run, it starts processing | ||
| * tick 12 - DP finishes earlier, LL2 starts consuming, LL1 is producing data | ||
| * ticks 13-19 LL1 is producing data, LL2 is consuming data (both in 1ms chunks) | ||
| * tick 20 - DP starts processing a new portion of 10ms data, having 10ms to finish | ||
| * !!!! but LL2 has already consumed 8ms !!!! | ||
| * tick 22 - LL2 is consuming the last 1ms data chunk | ||
| * tick 23 - DP is still processing, LL2 has no data to process | ||
| * !!! UNDERRUN !!!! | ||
| * tick 19 - DP finishes properly in a deadline time | ||
| * | ||
| * Solution: even if DP finishes before its deadline, the data must be held till | ||
| * deadline time, so LL2 may start processing no earlier than tick 20 | ||
| */ | ||
| bool dp_startup_delay; | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. thinking aloud - would this be better as a int i.e. a counter and could be set to any delay value needed and decremented on each LL tick ? |
||
|
|
||
| /* flag to indicate module does not pause */ | ||
| bool no_pause; | ||
|
|
||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We can merge this one straight away if WA patch alignment takes long time.