diff options
author | Andrzej Kaczmarek <andrzej.kaczmarek@tieto.com> | 2014-05-26 15:16:48 +0200 |
---|---|---|
committer | Luiz Augusto von Dentz <luiz.von.dentz@intel.com> | 2014-05-30 14:54:57 +0300 |
commit | 171aac2ead554510b24c67bf5c42b4f14c6f0c09 (patch) | |
tree | cfef5dd93199a04e5ebe771181cf94011e5deaaf /android/a2dp.c | |
parent | e1c7dddd0dd2f5e23e4d4cf98a9dde713fe6dd53 (diff) | |
download | bluez-171aac2ead554510b24c67bf5c42b4f14c6f0c09.tar.gz |
android/a2dp: Add support to check MPEG-2,4 AAC caps
Diffstat (limited to 'android/a2dp.c')
-rw-r--r-- | android/a2dp.c | 72 |
1 files changed, 72 insertions, 0 deletions
diff --git a/android/a2dp.c b/android/a2dp.c index c1938735f..58c949bc6 100644 --- a/android/a2dp.c +++ b/android/a2dp.c @@ -325,6 +325,52 @@ static int sbc_check_config(void *caps, uint8_t caps_len, void *conf, return 0; } +static int aac_check_config(void *caps, uint8_t caps_len, void *conf, + uint8_t conf_len) +{ + a2dp_aac_t *cap, *config; + + if (conf_len != caps_len || conf_len != sizeof(a2dp_aac_t)) { + error("AAC: Invalid configuration size (%u)", conf_len); + return -EINVAL; + } + + cap = caps; + config = conf; + + if (!(cap->object_type & config->object_type)) { + error("AAC: Unsupported object type (%u) by endpoint", + config->object_type); + return -EINVAL; + } + + if (!(AAC_GET_FREQUENCY(*cap) & AAC_GET_FREQUENCY(*config))) { + error("AAC: Unsupported frequency (%u) by endpoint", + AAC_GET_FREQUENCY(*config)); + return -EINVAL; + } + + if (!(cap->channels & config->channels)) { + error("AAC: Unsupported channels (%u) by endpoint", + config->channels); + return -EINVAL; + } + + /* VBR support in SNK is mandatory but let's make sure we don't try to + * have VBR on remote which for some reason does not support it + */ + if (!cap->vbr && config->vbr) { + error("AAC: Unsupported VBR (%u) by endpoint", + config->vbr); + return -EINVAL; + } + + if (AAC_GET_BITRATE(*cap) < AAC_GET_BITRATE(*config)) + return -ERANGE; + + return 0; +} + static int check_capabilities(struct a2dp_preset *preset, struct avdtp_media_codec_capability *codec, uint8_t codec_len) @@ -334,6 +380,9 @@ static int check_capabilities(struct a2dp_preset *preset, case A2DP_CODEC_SBC: return sbc_check_config(codec->data, codec_len, preset->data, preset->len); + case A2DP_CODEC_MPEG24: + return aac_check_config(codec->data, codec_len, preset->data, + preset->len); default: return -EINVAL; } @@ -358,6 +407,26 @@ static struct a2dp_preset *sbc_select_range(void *caps, uint8_t caps_len, return p; } +static struct a2dp_preset *aac_select_range(void *caps, uint8_t caps_len, + void *conf, uint8_t conf_len) +{ + struct a2dp_preset *p; + a2dp_aac_t *cap, *config; + uint32_t bitrate; + + cap = caps; + config = conf; + + bitrate = MIN(AAC_GET_BITRATE(*cap), AAC_GET_BITRATE(*config)); + AAC_SET_BITRATE(*config, bitrate); + + p = g_new0(struct a2dp_preset, 1); + p->len = conf_len; + p->data = g_memdup(conf, p->len); + + return p; +} + static struct a2dp_preset *select_preset_range(struct a2dp_preset *preset, struct avdtp_media_codec_capability *codec, uint8_t codec_len) @@ -367,6 +436,9 @@ static struct a2dp_preset *select_preset_range(struct a2dp_preset *preset, case A2DP_CODEC_SBC: return sbc_select_range(codec->data, codec_len, preset->data, preset->len); + case A2DP_CODEC_MPEG24: + return aac_select_range(codec->data, codec_len, preset->data, + preset->len); default: return NULL; } |