codec_adapter: check if deep buffering is needed

This patch introduces deep buffering for codec adapter.
This is needed when codec input buffer is not a natural multiple
of pipeline buffer. In such situation codec adapter won't be able
to produce samples every n period. Hence we "deep buffer" samples
during startup (typically few periods, depending on the difference
between pipeline buff and codec buff) so once we gathered enough
samples to regularly produce output we start processing.

Signed-off-by: Marcin Rajwa <marcin.rajwa@linux.intel.com>
This commit is contained in:
Marcin Rajwa 2020-11-23 15:43:07 +01:00 committed by Liam Girdwood
parent 9c660ec6a6
commit 007e5a2560
2 changed files with 26 additions and 0 deletions

View File

@ -180,6 +180,8 @@ static int codec_adapter_prepare(struct comp_dev *dev)
{
int ret;
struct comp_data *cd = comp_get_drvdata(dev);
struct codec_data *codec = &cd->codec;
uint32_t buff_periods; /* number of deep buffering periods */
comp_info(dev, "codec_adapter_prepare() start");
@ -216,6 +218,29 @@ static int codec_adapter_prepare(struct comp_dev *dev)
return -EIO;
}
/* Codec is prepared, now we need to configure processing settings.
* If codec internal buffer is not equal to natural multiple of pipeline
* buffer we have a situation where CA have to deep buffer certain amount
* of samples on its start (typically few periods) in order to regularly
* generate output once started (same situation happens for compress streams
* as well).
*/
if (codec->cpd.in_buff_size != cd->period_bytes) {
if (codec->cpd.in_buff_size > cd->period_bytes) {
buff_periods = (codec->cpd.in_buff_size % cd->period_bytes) ?
(codec->cpd.in_buff_size / cd->period_bytes) + 2 :
(codec->cpd.in_buff_size / cd->period_bytes) + 1;
} else {
buff_periods = (cd->period_bytes % codec->cpd.in_buff_size) ?
(cd->period_bytes / codec->cpd.in_buff_size) + 2 :
(cd->period_bytes / codec->cpd.in_buff_size) + 1;
}
cd->deep_buff_bytes = cd->period_bytes * buff_periods;
} else {
cd->deep_buff_bytes = 0;
}
comp_info(dev, "codec_adapter_prepare() done");
cd->state = PP_STATE_PREPARED;

View File

@ -185,6 +185,7 @@ struct comp_data {
struct comp_buffer *ca_source;
struct sof_ipc_stream_params stream_params;
uint32_t period_bytes; /** pipeline period bytes */
uint32_t deep_buff_bytes; /**< copy start threshold */
};
/*****************************************************************************/