[alsa-devel] [RFC - AAF PCM plugin 3/5] aaf: Implement Playback mode support

Takashi Sakamoto o-takashi at sakamocchi.jp
Tue Aug 21 06:31:43 CEST 2018


Hi,

On Aug 21 2018 10:06, Andre Guedes wrote:
> This patch implements the playback mode support from the AAF plugin.
> Simply put, this mode works as follows: PCM samples provided by alsa-lib
> layer are encapsulated into AVTP packets and transmitted through the
> network. In summary, the playback mode implements a typical AVTP Talker.
> 
> When the AAF device is put in running state, its media clock is started.
> At every tick from the media clock, audio frames are consumed from the
> audio buffer, encapsulated into an AVTP packet, and transmitted to the
> network. The presentation time from each AVTP packet is calculated
> taking in consideration the maximum transit time and time uncertainty
> values configured by the user.
> 
> Below follows some discussion about implementation details:
> 
> Even though only one file descriptor is used to implement the playback
> mode, this patch doesn't leverage ioplug->poll_fd but defines poll
> callbacks instead. The reason is these callbacks will be required to
> support capture mode (to be implemented by upcoming patch).
> 
> The TSN data plane interface is the AF_PACKET socket family so the
> plugin uses an AF_PACKET socket to send/receive AVTP packets. Linux
> requires CAP_NET_RAW capability in order to open an AF_PACKET socket so
> the application that instantiates the plugin must have it. For further
> info about AF_PACKET socket family see packet(7).
> 
> Signed-off-by: Andre Guedes <andre.guedes at intel.com>
> ---
>   aaf/pcm_aaf.c | 611 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
>   doc/aaf.txt   |  40 ++++
>   2 files changed, 651 insertions(+)
> 
> diff --git a/aaf/pcm_aaf.c b/aaf/pcm_aaf.c
> index 4c6f031..72f6652 100644
> --- a/aaf/pcm_aaf.c
> +++ b/aaf/pcm_aaf.c
> ...
> +static int aaf_hw_params(snd_pcm_ioplug_t *io,
> +			 snd_pcm_hw_params_t *params ATTRIBUTE_UNUSED)
> +{
> +	int res;
> +	snd_pcm_aaf_t *aaf = io->private_data;
> +
> +	if (io->access != SND_PCM_ACCESS_RW_INTERLEAVED)
> +		return -ENOTSUP;
> +
> +	if (io->buffer_size > LONG_MAX)
> +		return -EINVAL;
> +
> +	/* XXX: We might want to support Little Endian format in future. To
> +	 * achieve that, we need to convert LE samples to BE before
> +	 * transmitting them.
> +	 */
> +	switch (io->format) {
> +	case SND_PCM_FORMAT_S16_BE:
> +	case SND_PCM_FORMAT_S24_3BE:
> +	case SND_PCM_FORMAT_S32_BE:
> +	case SND_PCM_FORMAT_FLOAT_BE:
> +		break;
> +	default:
> +		return -ENOTSUP;
> +	}
> +
> +	switch (io->rate) {
> +	case 8000:
> +	case 16000:
> +	case 24000:
> +	case 32000:
> +	case 44100:
> +	case 48000:
> +	case 88200:
> +	case 96000:
> +	case 176400:
> +	case 192000:
> +		break;
> +	default:
> +		return -ENOTSUP;
> +	}
> +
> +	aaf->buffer_size = io->buffer_size;
> +
> +	res = aaf_init_pdu(aaf);
> +	if (res < 0)
> +		return res;
> +
> +	res = aaf_init_audio_buffer(aaf);
> +	if (res < 0)
> +		goto err_free_pdu;
> +
> +	res = aaf_init_areas(aaf);
> +	if (res < 0)
> +		goto err_free_audiobuf;
> +
> +	return 0;
> +
> +err_free_audiobuf:
> +	free(aaf->audiobuf);
> +err_free_pdu:
> +	free(aaf->pdu);
> +	return res;
> +}
> ...
>   SND_PCM_PLUGIN_DEFINE_FUNC(aaf)
> @@ -186,12 +787,21 @@ SND_PCM_PLUGIN_DEFINE_FUNC(aaf)
>   	snd_pcm_aaf_t *aaf;
>   	int res;
>   
> +	/* For now the plugin only supports Playback mode i.e. AAF Talker
> +	 * functionality.
> +	 */
> +	if (stream != SND_PCM_STREAM_PLAYBACK)
> +		return -EINVAL;
> +
>   	aaf = calloc(1, sizeof(*aaf));
>   	if (!aaf) {
>   		SNDERR("Failed to allocate memory");
>   		return -ENOMEM;
>   	}
>   
> +	aaf->sk_fd = -1;
> +	aaf->timer_fd = -1;
> +
>   	res = aaf_load_config(aaf, conf);
>   	if (res < 0)
>   		goto err;
> @@ -200,6 +810,7 @@ SND_PCM_PLUGIN_DEFINE_FUNC(aaf)
>   	aaf->io.name = "AVTP Audio Format (AAF) Plugin";
>   	aaf->io.callback = &aaf_callback;
>   	aaf->io.private_data = aaf;
> +	aaf->io.flags = SND_PCM_IOPLUG_FLAG_BOUNDARY_WA;
>   	res = snd_pcm_ioplug_create(&aaf->io, name, stream, mode);
>   	if (res < 0) {
>   		SNDERR("Failed to create ioplug instance");

In a design of ALSA external plugin SDK[1], you can apply constrains to 
available hw_params/sw_params by a call of 
'snd_pcm_ioplug_set_param_minmax()' and 
'snd_pcm_ioplug_set_param_list()' at entry point. If you program error 
path at .hw_params callback for unexpected parameters, it's better to 
apply constants in advance.

Do you have any reason not to do it? Is it difficult to retrieve 
capabilities of target AVTP end station in the entry point?

[1] http://www.alsa-project.org/alsa-doc/alsa-lib/pcm_external_plugins.html


Regards

Takashi Sakamoto


More information about the Alsa-devel mailing list