summaryrefslogtreecommitdiff
path: root/android/a2dp.c
diff options
context:
space:
mode:
authorAndrzej Kaczmarek <andrzej.kaczmarek@tieto.com>2014-05-26 15:16:48 +0200
committerLuiz Augusto von Dentz <luiz.von.dentz@intel.com>2014-05-30 14:54:57 +0300
commit171aac2ead554510b24c67bf5c42b4f14c6f0c09 (patch)
treecfef5dd93199a04e5ebe771181cf94011e5deaaf /android/a2dp.c
parente1c7dddd0dd2f5e23e4d4cf98a9dde713fe6dd53 (diff)
downloadbluez-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.c72
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;
}