alsa: only enable PCM iec958 codec when configured

Rework the codec enumeration a little and don't automatically enable PCM
as the code unless requested by the user.
This commit is contained in:
Wim Taymans 2021-08-23 17:01:36 +02:00
parent 454a9bd55f
commit b0a9945ed0

View file

@ -25,7 +25,6 @@ int spa_alsa_init(struct state *state)
if (state->stream == SND_PCM_STREAM_PLAYBACK) { if (state->stream == SND_PCM_STREAM_PLAYBACK) {
state->is_iec958 = spa_strstartswith(state->props.device, "iec958"); state->is_iec958 = spa_strstartswith(state->props.device, "iec958");
state->is_hdmi = spa_strstartswith(state->props.device, "hdmi"); state->is_hdmi = spa_strstartswith(state->props.device, "hdmi");
state->iec958_codecs |= 1ULL << SPA_AUDIO_IEC958_CODEC_PCM;
} }
if (state->open_ucm) { if (state->open_ucm) {
@ -538,6 +537,30 @@ skip_channels:
return 1; return 1;
} }
static bool codec_supported(uint32_t codec, unsigned int chmax, unsigned int rmax)
{
switch (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:
if (chmax >= 2)
return true;
break;
case SPA_AUDIO_IEC958_CODEC_EAC3:
if (rmax >= 48000 * 4 && chmax >= 2)
return true;
break;
case SPA_AUDIO_IEC958_CODEC_TRUEHD:
case SPA_AUDIO_IEC958_CODEC_DTSHD:
if (chmax >= 8)
return true;
break;
}
return false;
}
static int enum_iec958_formats(struct state *state, uint32_t index, uint32_t *next, static int enum_iec958_formats(struct state *state, uint32_t index, uint32_t *next,
struct spa_pod **result, struct spa_pod_builder *b) struct spa_pod **result, struct spa_pod_builder *b)
{ {
@ -548,6 +571,7 @@ static int enum_iec958_formats(struct state *state, uint32_t index, uint32_t *ne
struct spa_pod_choice *choice; struct spa_pod_choice *choice;
unsigned int rmin, rmax; unsigned int rmin, rmax;
unsigned int chmin, chmax; unsigned int chmin, chmax;
uint32_t i, c, codecs[16], n_codecs;
if ((index & 0xffff) > 0) if ((index & 0xffff) > 0)
return 0; return 0;
@ -586,28 +610,14 @@ static int enum_iec958_formats(struct state *state, uint32_t index, uint32_t *ne
spa_pod_builder_prop(b, SPA_FORMAT_AUDIO_iec958Codec, 0); spa_pod_builder_prop(b, SPA_FORMAT_AUDIO_iec958Codec, 0);
spa_pod_builder_push_choice(b, &f[1], SPA_CHOICE_Enum, 0); spa_pod_builder_push_choice(b, &f[1], SPA_CHOICE_Enum, 0);
if (chmax >= 2) {
spa_pod_builder_id(b, SPA_AUDIO_IEC958_CODEC_PCM);
spa_pod_builder_id(b, SPA_AUDIO_IEC958_CODEC_PCM);
if (state->iec958_codecs & (1ULL << SPA_AUDIO_IEC958_CODEC_DTS)) n_codecs = spa_alsa_get_iec958_codecs(state, codecs, SPA_N_ELEMENTS(codecs));
spa_pod_builder_id(b, SPA_AUDIO_IEC958_CODEC_DTS); for (i = 0, c = 0; i < n_codecs; i++) {
if (state->iec958_codecs & (1ULL << SPA_AUDIO_IEC958_CODEC_AC3)) if (!codec_supported(codecs[i], chmax, rmax))
spa_pod_builder_id(b, SPA_AUDIO_IEC958_CODEC_AC3); continue;
if (state->iec958_codecs & (1ULL << SPA_AUDIO_IEC958_CODEC_MPEG)) if (c++ == 0)
spa_pod_builder_id(b, SPA_AUDIO_IEC958_CODEC_MPEG); spa_pod_builder_id(b, codecs[i]);
if (state->iec958_codecs & (1ULL << SPA_AUDIO_IEC958_CODEC_MPEG2_AAC)) spa_pod_builder_id(b, codecs[i]);
spa_pod_builder_id(b, SPA_AUDIO_IEC958_CODEC_MPEG2_AAC);
if (rmax >= 48000 * 4 &&
(state->iec958_codecs & (1ULL << SPA_AUDIO_IEC958_CODEC_EAC3)))
spa_pod_builder_id(b, SPA_AUDIO_IEC958_CODEC_EAC3);
}
if (chmax >= 8) {
if (state->iec958_codecs & (1ULL << SPA_AUDIO_IEC958_CODEC_TRUEHD))
spa_pod_builder_id(b, SPA_AUDIO_IEC958_CODEC_TRUEHD);
if (state->iec958_codecs & (1ULL << SPA_AUDIO_IEC958_CODEC_DTSHD))
spa_pod_builder_id(b, SPA_AUDIO_IEC958_CODEC_DTSHD);
} }
spa_pod_builder_pop(b, &f[1]); spa_pod_builder_pop(b, &f[1]);