-
Notifications
You must be signed in to change notification settings - Fork 349
copier: pipeline period recalculation #7626
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 |
|---|---|---|
|
|
@@ -40,6 +40,7 @@ | |
| #include <sof/audio/dai_copier.h> | ||
| #include <sof/audio/ipcgtw_copier.h> | ||
| #include <sof/audio/module_adapter/module/generic.h> | ||
| #include <sof/schedule/ll_schedule_domain.h> | ||
|
|
||
| #if CONFIG_ZEPHYR_NATIVE_DRIVERS | ||
| #include <zephyr/drivers/dai.h> | ||
|
|
@@ -92,6 +93,41 @@ static int copier_init(struct processing_module *mod) | |
| } | ||
|
|
||
| dev->pipeline = ipc_pipe->pipeline; | ||
| /* Calculation of the period in which the component should be scheduled based on | ||
| * the input buffer size. | ||
| */ | ||
| if (copier->gtw_cfg.dma_buffer_size > 0 && dev->pipeline->deep_buffering) { | ||
| /* Size of the single frame in bytes. */ | ||
| uint32_t frame_size = copier->base.audio_fmt.channels_count * | ||
| (copier->base.audio_fmt.depth >> 3); | ||
| /* Size of the one second of audio data in bytes. */ | ||
| uint32_t one_s = frame_size * copier->base.audio_fmt.sampling_frequency; | ||
| /* Size of the ten millisecond of audio data in bytes. */ | ||
| uint32_t ten_ms = DIV_ROUND_UP(one_s, 100); | ||
| /* The number of ten milliseconds chunks of data that will fit into the buffer. */ | ||
| uint32_t chunk_count = copier->gtw_cfg.dma_buffer_size / ten_ms; | ||
|
|
||
| /* If buffer can fit at more than ten milliseconds of data we can try to schedule | ||
| * pipe on periods bigger than one millisecond. | ||
| */ | ||
| if (chunk_count) { | ||
|
||
| dev->deep_buffering = true; | ||
|
||
| if (chunk_count == 1) | ||
| dev->period = (5 * LL_TIMER_PERIOD_US); | ||
| else | ||
| dev->period = (10 * LL_TIMER_PERIOD_US); | ||
|
|
||
|
||
| /* If a component that may run on bigger periods has already been added to | ||
| * the pipeline, the pipe must run at the lowest possible value. | ||
| */ | ||
| if (!dev->pipeline->period || dev->pipeline->period < dev->period) { | ||
| dev->pipeline->period = dev->period; | ||
| comp_cl_warn(&comp_copier, | ||
| "changing the period for the pipe (new value %u)", | ||
| dev->pipeline->period); | ||
| } | ||
tmleman marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| } | ||
| } | ||
|
|
||
| node_id = copier->gtw_cfg.node_id; | ||
| /* copier is linked to gateway */ | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -18,7 +18,6 @@ | |
| #include <sof/lib/mailbox.h> | ||
| #include <sof/list.h> | ||
| #include <sof/platform.h> | ||
| #include <sof/schedule/ll_schedule_domain.h> | ||
| #include <rtos/wait.h> | ||
|
|
||
| /* TODO: Remove platform-specific code, see https://github.com/thesofproject/sof/issues/7549 */ | ||
|
|
@@ -206,7 +205,8 @@ static int ipc4_create_pipeline(struct ipc4_pipeline_create *pipe_desc) | |
| } | ||
|
|
||
| pipe->time_domain = SOF_TIME_DOMAIN_TIMER; | ||
| pipe->period = LL_TIMER_PERIOD_US; | ||
| pipe->period = 0; | ||
| pipe->deep_buffering = true; | ||
|
|
||
| /* sched_id is set in FW so initialize it to a invalid value */ | ||
| pipe->sched_id = 0xFFFFFFFF; | ||
|
|
@@ -869,6 +869,23 @@ int ipc4_add_comp_dev(struct comp_dev *dev) | |
| /* add new component to the list */ | ||
| list_item_append(&icd->list, &ipc->comp_list); | ||
|
|
||
| /* If new component added to the pipeline is not fitted for deep buffering we need to | ||
| * inform pipeline it cannot work on long periods. | ||
| */ | ||
| if (!dev->deep_buffering) { | ||
| if (!dev->pipeline) { | ||
| const uint32_t pipe_id = dev->ipc_config.pipeline_id; | ||
| struct ipc_comp_dev *ipc_comp = | ||
| ipc_get_comp_by_ppl_id(ipc, | ||
| COMP_TYPE_PIPELINE, | ||
| pipe_id); | ||
|
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. are we sure, that |
||
|
|
||
| dev->pipeline = ipc_comp->pipeline; | ||
| } | ||
|
|
||
| dev->pipeline->deep_buffering = false; | ||
| } | ||
|
|
||
| return IPC4_SUCCESS; | ||
| }; | ||
|
|
||
|
|
||
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.
just as an example to clarify why this won't quite calculate correct results and why you need to round up line 114:
that will tell you, that you can fit 100 10ms long chunks in the buffer, so you could conclude that a full second of audio fits into the buffer, whereas it doesn't - 90 bytes don't fit. Whereas if you round up the first division in line 114, you get
so you conclude, that 980ms of audio will fit into the buffer, which is correct - they will fit there and will occupy 0.98*8090 < 7983 < 8000 bytes.
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.
may need enumerate all the possible freqs and then divide can be avoided by look up table.
like is only support 44100 and 48000 input, then two divide can be avoided.
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.
I assumed that rounding is not needed because none of the formats we use will result in a value that is not divisible by 100. I added rounding anyway.
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.
Yeah, I dont think there are any rates that are not multiples of 100.
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.
so we will not support 11.025 khz and 22.05 khz ?
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.
oh, good point @RanderWang - these are rare but in IPC4 and ALSA.
@tmleman looks like we need a switch here to deal with the non divisible corner cases.