From 437275460cda4e9f15de1bfb1d537d5c22d421a0 Mon Sep 17 00:00:00 2001 From: Wim Taymans Date: Thu, 12 Aug 2021 15:16:27 +0200 Subject: [PATCH] alsa: add set_format for iec958 formats --- spa/plugins/alsa/alsa-pcm-sink.c | 28 ++++++++++++++++--- spa/plugins/alsa/alsa-pcm.c | 48 ++++++++++++++++++++++++++++++-- 2 files changed, 70 insertions(+), 6 deletions(-) diff --git a/spa/plugins/alsa/alsa-pcm-sink.c b/spa/plugins/alsa/alsa-pcm-sink.c index fcdf16ba6..7f482bf3a 100644 --- a/spa/plugins/alsa/alsa-pcm-sink.c +++ b/spa/plugins/alsa/alsa-pcm-sink.c @@ -497,7 +497,18 @@ impl_node_port_enum_params(void *object, int seq, if (result.index > 0) return 0; - param = spa_format_audio_raw_build(&b, id, &this->current_format.info.raw); + switch (this->current_format.media_subtype) { + case SPA_MEDIA_SUBTYPE_raw: + param = spa_format_audio_raw_build(&b, id, + &this->current_format.info.raw); + break; + case SPA_MEDIA_SUBTYPE_iec958: + param = spa_format_audio_iec958_build(&b, id, + &this->current_format.info.iec958); + break; + default: + return -EIO; + } break; case SPA_PARAM_Buffers: @@ -612,12 +623,21 @@ static int port_set_format(void *object, if ((err = spa_format_parse(format, &info.media_type, &info.media_subtype)) < 0) return err; - if (info.media_type != SPA_MEDIA_TYPE_audio || - info.media_subtype != SPA_MEDIA_SUBTYPE_raw) + if (info.media_type != SPA_MEDIA_TYPE_audio) return -EINVAL; - if (spa_format_audio_raw_parse(format, &info.info.raw) < 0) + switch (info.media_subtype) { + case SPA_MEDIA_SUBTYPE_raw: + if (spa_format_audio_raw_parse(format, &info.info.raw) < 0) + return -EINVAL; + break; + case SPA_MEDIA_SUBTYPE_iec958: + if (spa_format_audio_iec958_parse(format, &info.info.iec958) < 0) + return -EINVAL; + break; + default: return -EINVAL; + } if ((err = spa_alsa_set_format(this, &info, flags)) < 0) return err; diff --git a/spa/plugins/alsa/alsa-pcm.c b/spa/plugins/alsa/alsa-pcm.c index 95f12bb0f..dec827d6d 100644 --- a/spa/plugins/alsa/alsa-pcm.c +++ b/spa/plugins/alsa/alsa-pcm.c @@ -682,7 +682,7 @@ spa_alsa_enum_format(struct state *state, int seq, uint32_t start, uint32_t num, return res; } -int spa_alsa_set_format(struct state *state, struct spa_audio_info *fmt, uint32_t flags) +static int set_pcm_format(struct state *state, struct spa_audio_info_raw *info, uint32_t flags) { unsigned int rrate, rchannels; snd_pcm_uframes_t period_size; @@ -690,7 +690,6 @@ int spa_alsa_set_format(struct state *state, struct spa_audio_info *fmt, uint32_ snd_pcm_hw_params_t *params; snd_pcm_format_t format; snd_pcm_access_mask_t *amask; - struct spa_audio_info_raw *info = &fmt->info.raw; snd_pcm_t *hndl; unsigned int periods; bool match = true, planar, is_batch; @@ -832,6 +831,51 @@ int spa_alsa_set_format(struct state *state, struct spa_audio_info *fmt, uint32_ return match ? 0 : 1; } +static int set_iec958_format(struct state *state, struct spa_audio_info_iec958 *info, uint32_t flags) +{ + struct spa_audio_info_raw fmt; + + fmt.format = SPA_AUDIO_FORMAT_S16_LE; + fmt.channels = 2; + fmt.rate = info->rate; + + switch (info->codec) { + case SPA_AUDIO_IEC958_CODEC_PCM: + case SPA_AUDIO_IEC958_CODEC_DTS: + case SPA_AUDIO_IEC958_CODEC_AC3: + case SPA_AUDIO_IEC958_CODEC_MPEG: + case SPA_AUDIO_IEC958_CODEC_MPEG2_AAC: + break; + case SPA_AUDIO_IEC958_CODEC_EAC3: + fmt.rate *= 4; + break; + case SPA_AUDIO_IEC958_CODEC_TRUEHD: + case SPA_AUDIO_IEC958_CODEC_DTSHD: + fmt.channels = 8; + break; + default: + return -ENOTSUP; + } + return set_pcm_format(state, &fmt, flags); +} + +int spa_alsa_set_format(struct state *state, struct spa_audio_info *fmt, uint32_t flags) +{ + int res; + + switch (fmt->media_subtype) { + case SPA_MEDIA_SUBTYPE_raw: + res = set_pcm_format(state, &fmt->info.raw, flags); + break; + case SPA_MEDIA_SUBTYPE_iec958: + res = set_iec958_format(state, &fmt->info.iec958, flags); + break; + default: + return -ENOTSUP; + } + return res; +} + static int set_swparams(struct state *state) { snd_pcm_t *hndl = state->hndl;