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@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