diff --git a/spa/plugins/bluez5/a2dp-codec-aac.c b/spa/plugins/bluez5/a2dp-codec-aac.c index 5e409d2f7..6ebcf6707 100644 --- a/spa/plugins/bluez5/a2dp-codec-aac.c +++ b/spa/plugins/bluez5/a2dp-codec-aac.c @@ -239,6 +239,50 @@ static int codec_enum_config(const struct a2dp_codec *codec, return *param == NULL ? -EIO : 1; } +static int codec_validate_config(const struct a2dp_codec *codec, uint32_t flags, + const void *caps, size_t caps_size, + struct spa_audio_info *info) +{ + a2dp_aac_t conf; + size_t j; + + if (caps == NULL || caps_size < sizeof(conf)) + return -EINVAL; + + memcpy(&conf, caps, sizeof(conf)); + + spa_zero(*info); + info->media_type = SPA_MEDIA_TYPE_audio; + info->media_subtype = SPA_MEDIA_SUBTYPE_raw; + info->info.raw.format = SPA_AUDIO_FORMAT_S16; + + if (conf.object_type != AAC_OBJECT_TYPE_MPEG2_AAC_LC && + conf.object_type != AAC_OBJECT_TYPE_MPEG4_AAC_LC) + return -EINVAL; + + for (j = 0; j < SPA_N_ELEMENTS(aac_frequencies); ++j) { + if (AAC_GET_FREQUENCY(conf) & aac_frequencies[j].config) { + info->info.raw.rate = aac_frequencies[j].value; + break; + } + } + if (j == SPA_N_ELEMENTS(aac_frequencies)) + return -EINVAL; + + if (conf.channels & AAC_CHANNELS_2) { + info->info.raw.channels = 2; + info->info.raw.position[0] = SPA_AUDIO_CHANNEL_FL; + info->info.raw.position[1] = SPA_AUDIO_CHANNEL_FR; + } else if (conf.channels & AAC_CHANNELS_1) { + info->info.raw.channels = 1; + info->info.raw.position[0] = SPA_AUDIO_CHANNEL_MONO; + } else { + return -EINVAL; + } + + return 0; +} + static void *codec_init_props(const struct a2dp_codec *codec, const struct spa_dict *settings) { struct props *p = calloc(1, sizeof(struct props)); @@ -495,6 +539,7 @@ const struct a2dp_codec a2dp_codec_aac = { .fill_caps = codec_fill_caps, .select_config = codec_select_config, .enum_config = codec_enum_config, + .validate_config = codec_validate_config, .init_props = codec_init_props, .clear_props = codec_clear_props, .init = codec_init,