alsa: add set_format for iec958 formats

This commit is contained in:
Wim Taymans 2021-08-12 15:16:27 +02:00
parent 5feb88575c
commit 437275460c
2 changed files with 70 additions and 6 deletions

View file

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

View file

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