[alsa-devel] [RFC - AAF PCM plugin 5/5] aaf: Implement Capture mode support
Takashi Sakamoto
o-takashi at sakamocchi.jp
Tue Aug 21 07:17:48 CEST 2018
Hi,
On Aug 21 2018 10:06, Andre Guedes wrote:
> This patch implements the capture mode support from the AAF plugin.
> Simply put, this mode works as follows: AVTP packets are received from
> the network, the PCM samples are retrieved and presented to the alsa-lib
> layer at the presentation time. In summary, the capture mode implements
> a typical AVTP Listener.
>
> Once the AAF device is put in running state, packet reception is
> started. Every time an AVTP packet is received the plugin checks if it
> is valid (according to the stream configuration provided by the user)
> and copies the PCM samples to the audio buffer. Note that at this
> moment, the samples are not presented to the alsa-lib layer (i.e.
> hw_ptr is not updated).
>
> When the first AVTP packet is received, the media clock is set to start
> at the presentation time from that packet. At every tick from the media
> clock, PCM samples are presented to the alsa-lib layer.
>
> Signed-off-by: Andre Guedes <andre.guedes at intel.com>
> ---
> aaf/pcm_aaf.c | 358 ++++++++++++++++++++++++++++++++++++++++++++++++++++++----
> 1 file changed, 338 insertions(+), 20 deletions(-)
>
> diff --git a/aaf/pcm_aaf.c b/aaf/pcm_aaf.c
> index e098247..b5bee57 100644
> --- a/aaf/pcm_aaf.c
> +++ b/aaf/pcm_aaf.c
> ...
> @@ -561,6 +819,42 @@ static int aaf_mclk_timeout_playback(snd_pcm_aaf_t *aaf)
> return 0;
> }
>
> +static int aaf_mclk_timeout_capture(snd_pcm_aaf_t *aaf)
> +{
> + ssize_t n;
> + uint64_t expirations;
> +
> + n = read(aaf->timer_fd, &expirations, sizeof(uint64_t));
> + if (n < 0) {
> + SNDERR("Failed to read() timer");
> + return -errno;
> + }
> +
> + if (expirations != 1)
> + pr_debug("Missed %llu presentation time(s) ", expirations - 1);
> +
> + while (expirations--) {
> + snd_pcm_sframes_t len;
> +
> + aaf_inc_ptr(&aaf->hw_ptr, aaf->frames_per_pkt, aaf->boundary);
> +
> + len = aaf->hw_virt_ptr - aaf->hw_ptr;
> + if (len < 0)
> + len += aaf->boundary;
> + if (len > aaf->buffer_size) {
> + /* If the distance between hw virtual pointer and hw
> + * pointer is greater than the buffer size, it means we
> + * had an overrun error so -EPIPE is returned.
> + */
> + return -EPIPE;
> + }
> +
> + aaf->mclk_ticks++;
> + }
> +
> + return 0;
> +}
In your code, -EPIPE can be returned in a call of
'snd_pcm_poll_revents()'. In this case, typical applications follow
recovery process below:
->snd_pcm_poll_revents()
->snd_pcm_prepare()
->snd_pcm_start()
In this case, status of corresponding PCM substream is reset (see
'snd_pcm_ioplug_prepare()'). In my opinion, in this case, backend is
expected to stop data streaming, then initialize hardware and restart
data streaming. In your driver, timer_fd/sk_fd is leaked. It's better to
release them by checking status of PCM substream in .prepare callback.
Regards
Takashi Sakamoto
More information about the Alsa-devel
mailing list