[PATCH 0/4] Enable timestamp support for SOF compress driver
From: Daniel Baluta daniel.baluta@nxp.com
This patchseries computes pcm_io_frames from the DAI position reported by SOF firmware.
Using pcm_io_frames userspace applications can later compute timestamps for compressed stream.
Daniel Baluta (2): ASoC: SOF: compress: Remove byte offset computation ASoC: SOF: compress: Introduce sof_compr_stream
Laurentiu Mihalcea (2): ASoC: SOF: compress: Save channel count and sample bytes ASoC: SOF: compress: Add support for computing timestamps
sound/soc/sof/compress.c | 54 ++++++++++++++++++++++++---------------- sound/soc/sof/sof-priv.h | 7 ++++++ 2 files changed, 40 insertions(+), 21 deletions(-)
From: Daniel Baluta daniel.baluta@nxp.com
Byte offset is the offset in the ring buffer to the DSP while posn_offset is an offset inside the stream_box where we keep position information.
Reviewed-by: Paul Olaru paul.olaru@oss.nxp.com Reviewed-by: Pierre-Louis Bossart pierre-louis.bossart@linux.intel.com Signed-off-by: Daniel Baluta daniel.baluta@nxp.com --- sound/soc/sof/compress.c | 1 - 1 file changed, 1 deletion(-)
diff --git a/sound/soc/sof/compress.c b/sound/soc/sof/compress.c index 67139e15f862..760d6a4a5253 100644 --- a/sound/soc/sof/compress.c +++ b/sound/soc/sof/compress.c @@ -237,7 +237,6 @@ static int sof_compr_set_params(struct snd_soc_component *component, goto out; }
- tstamp->byte_offset = sdev->stream_box.offset + ipc_params_reply.posn_offset; tstamp->sampling_rate = params->codec.sample_rate;
spcm->prepared[cstream->direction] = true;
From: Daniel Baluta daniel.baluta@nxp.com
This will keep SOF compress stream private data. So far we used snd_compr_tstamp to hold the private data but this is no longer enough as we need to hold other info like number of channels or sample bytes.
Reviewed-by: Paul Olaru paul.olaru@oss.nxp.com Reviewed-by: Pierre-Louis Bossart pierre-louis.bossart@linux.intel.com Signed-off-by: Daniel Baluta daniel.baluta@nxp.com --- sound/soc/sof/compress.c | 40 ++++++++++++++++++++-------------------- sound/soc/sof/sof-priv.h | 5 +++++ 2 files changed, 25 insertions(+), 20 deletions(-)
diff --git a/sound/soc/sof/compress.c b/sound/soc/sof/compress.c index 760d6a4a5253..e990fa093bb5 100644 --- a/sound/soc/sof/compress.c +++ b/sound/soc/sof/compress.c @@ -11,20 +11,20 @@ #include "sof-priv.h" #include "sof-utils.h"
-static void sof_set_transferred_bytes(struct snd_compr_tstamp *tstamp, +static void sof_set_transferred_bytes(struct sof_compr_stream *sstream, u64 host_pos, u64 buffer_size) { u64 prev_pos; unsigned int copied;
- div64_u64_rem(tstamp->copied_total, buffer_size, &prev_pos); + div64_u64_rem(sstream->copied_total, buffer_size, &prev_pos);
if (host_pos < prev_pos) copied = (buffer_size - prev_pos) + host_pos; else copied = host_pos - prev_pos;
- tstamp->copied_total += copied; + sstream->copied_total += copied; }
static void snd_sof_compr_fragment_elapsed_work(struct work_struct *work) @@ -49,7 +49,7 @@ void snd_sof_compr_fragment_elapsed(struct snd_compr_stream *cstream) struct snd_soc_pcm_runtime *rtd; struct snd_compr_runtime *crtd; struct snd_soc_component *component; - struct snd_compr_tstamp *tstamp; + struct sof_compr_stream *sstream; struct snd_sof_pcm *spcm;
if (!cstream) @@ -57,7 +57,7 @@ void snd_sof_compr_fragment_elapsed(struct snd_compr_stream *cstream)
rtd = cstream->private_data; crtd = cstream->runtime; - tstamp = crtd->private_data; + sstream = crtd->private_data; component = snd_soc_rtdcom_lookup(rtd, SOF_AUDIO_PCM_DRV_NAME);
spcm = snd_sof_find_spcm_dai(component, rtd); @@ -67,7 +67,7 @@ void snd_sof_compr_fragment_elapsed(struct snd_compr_stream *cstream) return; }
- sof_set_transferred_bytes(tstamp, spcm->stream[cstream->direction].posn.host_posn, + sof_set_transferred_bytes(sstream, spcm->stream[cstream->direction].posn.host_posn, crtd->buffer_size);
/* use the same workqueue-based solution as for PCM, cf. snd_sof_pcm_elapsed */ @@ -96,24 +96,24 @@ static int sof_compr_open(struct snd_soc_component *component, { struct snd_soc_pcm_runtime *rtd = cstream->private_data; struct snd_compr_runtime *crtd = cstream->runtime; - struct snd_compr_tstamp *tstamp; + struct sof_compr_stream *sstream; struct snd_sof_pcm *spcm; int dir;
- tstamp = kzalloc(sizeof(*tstamp), GFP_KERNEL); - if (!tstamp) + sstream = kzalloc(sizeof(*sstream), GFP_KERNEL); + if (!sstream) return -ENOMEM;
spcm = snd_sof_find_spcm_dai(component, rtd); if (!spcm) { - kfree(tstamp); + kfree(sstream); return -EINVAL; }
dir = cstream->direction;
if (spcm->stream[dir].cstream) { - kfree(tstamp); + kfree(sstream); return -EBUSY; }
@@ -122,7 +122,7 @@ static int sof_compr_open(struct snd_soc_component *component, spcm->stream[dir].posn.dai_posn = 0; spcm->prepared[dir] = false;
- crtd->private_data = tstamp; + crtd->private_data = sstream;
return 0; } @@ -131,7 +131,7 @@ static int sof_compr_free(struct snd_soc_component *component, struct snd_compr_stream *cstream) { struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(component); - struct snd_compr_tstamp *tstamp = cstream->runtime->private_data; + struct sof_compr_stream *sstream = cstream->runtime->private_data; struct snd_soc_pcm_runtime *rtd = cstream->private_data; struct sof_ipc_stream stream; struct sof_ipc_reply reply; @@ -155,7 +155,7 @@ static int sof_compr_free(struct snd_soc_component *component,
cancel_work_sync(&spcm->stream[cstream->direction].period_elapsed_work); spcm->stream[cstream->direction].cstream = NULL; - kfree(tstamp); + kfree(sstream);
return ret; } @@ -169,7 +169,7 @@ static int sof_compr_set_params(struct snd_soc_component *component, struct sof_ipc_pcm_params_reply ipc_params_reply; struct sof_ipc_fw_ready *ready = &sdev->fw_ready; struct sof_ipc_fw_version *v = &ready->version; - struct snd_compr_tstamp *tstamp; + struct sof_compr_stream *sstream; struct sof_ipc_pcm_params *pcm; struct snd_sof_pcm *spcm; size_t ext_data_size; @@ -184,7 +184,7 @@ static int sof_compr_set_params(struct snd_soc_component *component, return -EINVAL; }
- tstamp = crtd->private_data; + sstream = crtd->private_data;
spcm = snd_sof_find_spcm_dai(component, rtd);
@@ -237,7 +237,7 @@ static int sof_compr_set_params(struct snd_soc_component *component, goto out; }
- tstamp->sampling_rate = params->codec.sample_rate; + sstream->sampling_rate = params->codec.sample_rate;
spcm->prepared[cstream->direction] = true;
@@ -325,10 +325,10 @@ static int sof_compr_pointer(struct snd_soc_component *component, struct snd_compr_stream *cstream, struct snd_compr_tstamp *tstamp) { - struct snd_compr_tstamp *pstamp = cstream->runtime->private_data; + struct sof_compr_stream *sstream = cstream->runtime->private_data;
- tstamp->sampling_rate = pstamp->sampling_rate; - tstamp->copied_total = pstamp->copied_total; + tstamp->sampling_rate = sstream->sampling_rate; + tstamp->copied_total = sstream->copied_total;
return 0; } diff --git a/sound/soc/sof/sof-priv.h b/sound/soc/sof/sof-priv.h index 823583086279..42f112030fb8 100644 --- a/sound/soc/sof/sof-priv.h +++ b/sound/soc/sof/sof-priv.h @@ -105,6 +105,11 @@ enum sof_debugfs_access_type { SOF_DEBUGFS_ACCESS_D0_ONLY, };
+struct sof_compr_stream { + u64 copied_total; + u32 sampling_rate; +}; + struct snd_sof_dev; struct snd_sof_ipc_msg; struct snd_sof_ipc;
From: Laurentiu Mihalcea laurentiu.mihalcea@nxp.com
The purpose of this change is to enable the saving of the channel count and sample container bytes format parameters for later use to compute the timestamps.
This is done when setting the compress stream parameters (in sof_compr_set_params).
Reviewed-by: Paul Olaru paul.olaru@oss.nxp.com Reviewed-by: Pierre-Louis Bossart pierre-louis.bossart@linux.intel.com Signed-off-by: Laurentiu Mihalcea laurentiu.mihalcea@nxp.com Signed-off-by: Daniel Baluta daniel.baluta@nxp.com --- sound/soc/sof/compress.c | 2 ++ sound/soc/sof/sof-priv.h | 2 ++ 2 files changed, 4 insertions(+)
diff --git a/sound/soc/sof/compress.c b/sound/soc/sof/compress.c index e990fa093bb5..ac79b46ce3b9 100644 --- a/sound/soc/sof/compress.c +++ b/sound/soc/sof/compress.c @@ -238,6 +238,8 @@ static int sof_compr_set_params(struct snd_soc_component *component, }
sstream->sampling_rate = params->codec.sample_rate; + sstream->channels = params->codec.ch_out; + sstream->sample_container_bytes = pcm->params.sample_container_bytes;
spcm->prepared[cstream->direction] = true;
diff --git a/sound/soc/sof/sof-priv.h b/sound/soc/sof/sof-priv.h index 42f112030fb8..33165299a20f 100644 --- a/sound/soc/sof/sof-priv.h +++ b/sound/soc/sof/sof-priv.h @@ -108,6 +108,8 @@ enum sof_debugfs_access_type { struct sof_compr_stream { u64 copied_total; u32 sampling_rate; + u16 channels; + u16 sample_container_bytes; };
struct snd_sof_dev;
From: Laurentiu Mihalcea laurentiu.mihalcea@nxp.com
We compute the number of pcm_io_frames by dividing the dai position to size of a frame (channels * sample size).
Reviewed-by: Paul Olaru paul.olaru@oss.nxp.com Reviewed-by: Pierre-Louis Bossart pierre-louis.bossart@linux.intel.com Signed-off-by: Laurentiu Mihalcea laurentiu.mihalcea@nxp.com Signed-off-by: Daniel Baluta daniel.baluta@nxp.com --- sound/soc/sof/compress.c | 11 +++++++++++ 1 file changed, 11 insertions(+)
diff --git a/sound/soc/sof/compress.c b/sound/soc/sof/compress.c index ac79b46ce3b9..174b3d8e67dd 100644 --- a/sound/soc/sof/compress.c +++ b/sound/soc/sof/compress.c @@ -327,10 +327,21 @@ static int sof_compr_pointer(struct snd_soc_component *component, struct snd_compr_stream *cstream, struct snd_compr_tstamp *tstamp) { + u64 dai_posn; + struct snd_sof_pcm *spcm; + struct snd_soc_pcm_runtime *rtd = cstream->private_data; struct sof_compr_stream *sstream = cstream->runtime->private_data;
+ spcm = snd_sof_find_spcm_dai(component, rtd); + if (!spcm) + return -EINVAL; + + dai_posn = spcm->stream[cstream->direction].posn.dai_posn; + tstamp->sampling_rate = sstream->sampling_rate; tstamp->copied_total = sstream->copied_total; + tstamp->pcm_io_frames = div_u64(spcm->stream[cstream->direction].posn.dai_posn, + sstream->channels * sstream->sample_container_bytes);
return 0; }
On Wed, 17 Aug 2022 11:05:25 +0300, Daniel Baluta wrote:
From: Daniel Baluta daniel.baluta@nxp.com
This patchseries computes pcm_io_frames from the DAI position reported by SOF firmware.
Using pcm_io_frames userspace applications can later compute timestamps for compressed stream.
[...]
Applied to
https://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git for-next
Thanks!
[1/4] ASoC: SOF: compress: Remove byte offset computation commit: bab10ec9fd9dc1537b705d0dd3862dd5982b921f [2/4] ASoC: SOF: compress: Introduce sof_compr_stream commit: e3091f0a3f563ad1c9b60c290752e1190b67ea97 [3/4] ASoC: SOF: compress: Save channel count and sample bytes commit: 3ccbe6887747679d15e5c9524b23754281a24d9e [4/4] ASoC: SOF: compress: Add support for computing timestamps commit: c1a731c71359407eae4fd0a5fd675ef25a582764
All being well this means that it will be integrated into the linux-next tree (usually sometime in the next 24 hours) and sent to Linus during the next merge window (or sooner if it is a bug fix), however if problems are discovered then the patch may be dropped or reverted.
You may get further e-mails resulting from automated or manual testing and review of the tree, please engage with people reporting problems and send followup patches addressing any issues that are reported if needed.
If any updates are required or you are submitting further changes they should be sent as incremental updates against current git, existing patches will not be replaced.
Please add any relevant lists and maintainers to the CCs when replying to this mail.
Thanks, Mark
participants (2)
-
Daniel Baluta
-
Mark Brown