summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBhakthavatsala Raghavendra <braghave@codeaurora.org>2016-07-29 19:11:28 -0700
committerBhakthavatsala Raghavendra <braghave@codeaurora.org>2016-09-16 12:31:13 -0700
commit79f4e57290c78f087718dce8fcd2999267a79a3c (patch)
tree51f48291276044b9fa5a5d177d2e1de053e37c26
parent4f46530ce740f606cb5fcc0d549a1b82b2c818db (diff)
downloadandroid_system_bt-79f4e57290c78f087718dce8fcd2999267a79a3c.tar.gz
android_system_bt-79f4e57290c78f087718dce8fcd2999267a79a3c.tar.bz2
android_system_bt-79f4e57290c78f087718dce8fcd2999267a79a3c.zip
Bluetooth: Add AAC codec Support in Split-a2dp mode
Add AAC codec support in split-a2dp mode Change-Id: I174b0c44cdef8b5d174a2e39fa34fefc55d4807b
-rw-r--r--audio_a2dp_hw/bthost_ipc.c104
-rw-r--r--audio_a2dp_hw/bthost_ipc.h14
-rw-r--r--bta/Android.mk1
-rw-r--r--bta/av/bta_av_aac.c83
-rw-r--r--bta/include/bta_av_aac.h57
-rw-r--r--bta/include/bta_av_api.h4
-rw-r--r--bta/include/bta_av_co.h3
-rw-r--r--btif/co/bta_av_co.c258
-rw-r--r--btif/include/btif_av_api.h2
-rw-r--r--btif/include/btif_av_co.h15
-rw-r--r--btif/include/btif_media.h6
-rw-r--r--btif/src/btif_media_task.c76
-rw-r--r--include/bt_target.h13
-rw-r--r--stack/Android.mk1
-rw-r--r--stack/a2dp/a2d_aac.c175
-rw-r--r--stack/include/a2d_aac.h149
16 files changed, 950 insertions, 11 deletions
diff --git a/audio_a2dp_hw/bthost_ipc.c b/audio_a2dp_hw/bthost_ipc.c
index 08d9a264e..fc0e91483 100644
--- a/audio_a2dp_hw/bthost_ipc.c
+++ b/audio_a2dp_hw/bthost_ipc.c
@@ -89,6 +89,7 @@ struct a2dp_stream_common audio_stream;
audio_sbc_encoder_config sbc_codec;
audio_aptx_encoder_config aptx_codec;
+audio_aac_encoder_config aac_codec;
/*****************************************************************************
** Externs
******************************************************************************/
@@ -269,8 +270,105 @@ static void* a2dp_codec_parser(uint8_t *codec_cfg, audio_format_t *codec_type)
sbc_codec.bitrate |= (*p_cfg++ << 16);
sbc_codec.bitrate |= (*p_cfg++ << 24);
*codec_type = AUDIO_FORMAT_SBC;
- INFO("Done copying full codec config");
+ INFO("SBC: Done copying full codec config");
return ((void *)(&sbc_codec));
+ } else if (codec_cfg[CODEC_OFFSET] == CODEC_TYPE_AAC)
+ {
+ uint16_t aac_samp_freq = 0;
+ uint32_t aac_bit_rate = 0;
+ memset(&aac_codec,0,sizeof(audio_aac_encoder_config));
+ p_cfg++;//skip dev idx
+ len = *p_cfg++;
+ p_cfg++;//skip media type
+ len--;
+ p_cfg++;//skip codec type
+ len--;
+ byte = *p_cfg++;
+ len--;
+ switch (byte & A2D_AAC_IE_OBJ_TYPE_MSK)
+ {
+ case A2D_AAC_IE_OBJ_TYPE_MPEG_2_AAC_LC:
+ aac_codec.enc_mode = AUDIO_FORMAT_AAC_SUB_LC;
+ break;
+ case A2D_AAC_IE_OBJ_TYPE_MPEG_4_AAC_LC:
+ aac_codec.enc_mode = AUDIO_FORMAT_AAC_SUB_LC;
+ break;
+ case A2D_AAC_IE_OBJ_TYPE_MPEG_4_AAC_LTP:
+ aac_codec.enc_mode = AUDIO_FORMAT_AAC_SUB_LTP;
+ break;
+ case A2D_AAC_IE_OBJ_TYPE_MPEG_4_AAC_SCA:
+ aac_codec.enc_mode = AUDIO_FORMAT_AAC_SUB_SCALABLE;
+ break;
+ default:
+ ERROR("Unknown encoder mode");
+ }
+ //USE 0 (AAC_LC) as hardcoded value till Audio
+ //define constants
+ aac_codec.enc_mode = 0;
+ //USE LOAS(1) or LATM(4) hardcoded values till
+ //Audio define proper constants
+ aac_codec.format_flag = 4;
+ byte = *p_cfg++;
+ len--;
+ aac_samp_freq = byte << 8; //1st byte of sample_freq
+ byte = *p_cfg++;
+ len--;
+ aac_samp_freq |= byte & 0x00F0; //1st nibble of second byte of samp_freq
+
+ switch (aac_samp_freq) {
+ case 0x8000: aac_codec.sampling_rate = 8000; break;
+ case 0x4000: aac_codec.sampling_rate = 11025; break;
+ case 0x2000: aac_codec.sampling_rate = 12000; break;
+ case 0x1000: aac_codec.sampling_rate = 16000; break;
+ case 0x0800: aac_codec.sampling_rate = 22050; break;
+ case 0x0400: aac_codec.sampling_rate = 24000; break;
+ case 0x0200: aac_codec.sampling_rate = 32000; break;
+ case 0x0100: aac_codec.sampling_rate = 44100; break;
+ case 0x0080: aac_codec.sampling_rate = 48000; break;
+ case 0x0040: aac_codec.sampling_rate = 64000; break;
+ case 0x0020: aac_codec.sampling_rate = 88200; break;
+ case 0x0010: aac_codec.sampling_rate = 96000; break;
+ default:
+ ERROR("Invalid sample_freq: %x", aac_samp_freq);
+ }
+
+ switch (byte & A2D_AAC_IE_CHANNELS_MSK)
+ {
+ case A2D_AAC_IE_CHANNELS_1:
+ aac_codec.channels = 1;
+ break;
+ case A2D_AAC_IE_CHANNELS_2:
+ aac_codec.channels = 2;
+ break;
+ default:
+ ERROR("Unknow channel mode");
+ }
+ byte = *p_cfg++; //Move to VBR byte
+ len--;
+ switch (byte & A2D_AAC_IE_VBR_MSK)
+ {
+ case A2D_AAC_IE_VBR:
+ break;
+ default:
+ ERROR("VBR not supported");
+ }
+ aac_bit_rate = 0x7F&byte;
+ //Move it 2nd byte of 32 bit word. leaving the VBR bit
+ aac_bit_rate = aac_bit_rate << 16;
+ byte = *p_cfg++; //Move to 2nd byteof bitrate
+ len--;
+
+ //Move it to 3rd byte of 32bit word
+ aac_bit_rate |= 0x0000FF00 & (((uint32_t)byte)<<8);
+ byte = *p_cfg++; //Move to 3rd byte of bitrate
+ len--;
+
+ aac_bit_rate |= 0x000000FF & (((uint32_t)byte));
+ aac_codec.bitrate = aac_bit_rate;
+
+ *codec_type = AUDIO_FORMAT_AAC;
+ INFO("AAC: Done copying full codec config");
+ return ((void *)(&aac_codec));
}
else if (codec_cfg[CODEC_OFFSET] == NON_A2DP_CODEC_TYPE)
{
@@ -332,6 +430,8 @@ static void* a2dp_codec_parser(uint8_t *codec_cfg, audio_format_t *codec_type)
aptx_codec.bitrate |= (*p_cfg++ << 8);
aptx_codec.bitrate |= (*p_cfg++ << 16);
aptx_codec.bitrate |= (*p_cfg++ << 24);
+
+ INFO("APTx: Done copying full codec config");
return ((void *)&aptx_codec);
}
return NULL;
@@ -933,7 +1033,7 @@ int audio_stop_stream()
return 0;
}
audio_stream.state = AUDIO_A2DP_STATE_STOPPED;
- return -1;
+ return -1;
}
int audio_suspend_stream()
diff --git a/audio_a2dp_hw/bthost_ipc.h b/audio_a2dp_hw/bthost_ipc.h
index d30dfdc88..14ab882d7 100644
--- a/audio_a2dp_hw/bthost_ipc.h
+++ b/audio_a2dp_hw/bthost_ipc.h
@@ -101,6 +101,20 @@ codec specific definitions
#define A2D_APTX_CHAN_STEREO 0x02
#define A2D_APTX_CHAN_MONO 0x01
+
+#define A2D_AAC_IE_OBJ_TYPE_MSK 0xF0 /* b7-b4 Object Type */
+#define A2D_AAC_IE_OBJ_TYPE_MPEG_2_AAC_LC 0x80 /* b7:MPEG-2 AAC LC */
+#define A2D_AAC_IE_OBJ_TYPE_MPEG_4_AAC_LC 0x40 /* b7:MPEG-4 AAC LC */
+#define A2D_AAC_IE_OBJ_TYPE_MPEG_4_AAC_LTP 0x20 /* b7:MPEG-4 AAC LTP */
+#define A2D_AAC_IE_OBJ_TYPE_MPEG_4_AAC_SCA 0x10 /* b7:MPEG-4 AAC SCALABLE */
+
+#define A2D_AAC_IE_CHANNELS_MSK 0x0C
+#define A2D_AAC_IE_CHANNELS_1 0x08 /* Channel 1 */
+#define A2D_AAC_IE_CHANNELS_2 0x04 /* Channel 2 */
+
+#define A2D_AAC_IE_VBR_MSK 0x80
+#define A2D_AAC_IE_VBR 0x80 /* supported */
+
typedef struct {
uint8_t codec_type;
uint8_t dev_idx;
diff --git a/bta/Android.mk b/bta/Android.mk
index bd1b19db8..ba6e68f53 100644
--- a/bta/Android.mk
+++ b/bta/Android.mk
@@ -57,6 +57,7 @@ LOCAL_SRC_FILES:= \
./av/bta_av_cfg.c \
./av/bta_av_ssm.c \
./av/bta_av_sbc.c \
+ ./av/bta_av_aac.c \
./ar/bta_ar.c \
./hl/bta_hl_act.c \
./hl/bta_hl_api.c \
diff --git a/bta/av/bta_av_aac.c b/bta/av/bta_av_aac.c
new file mode 100644
index 000000000..3ef088538
--- /dev/null
+++ b/bta/av/bta_av_aac.c
@@ -0,0 +1,83 @@
+/******************************************************************************
+ *
+ * Copyright (c) 2016, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of The Linux Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ ******************************************************************************/
+
+#include "a2d_api.h"
+#include "a2d_aac.h"
+#include "bta_av_aac.h"
+#include "utl.h"
+
+/*******************************************************************************
+**
+** Function bta_av_aac_cfg_in_cap
+**
+** Description Checks if AAC codec config is allowed for given caps.
+** codec config bits are also checked for sanity
+**
+** Returns 0 if ok, nonzero if error.
+**
+*******************************************************************************/
+UINT8 bta_av_aac_cfg_in_cap(UINT8 *p_cfg, tA2D_AAC_CIE *p_cap)
+{
+ UINT8 status = 0;
+ tA2D_AAC_CIE cfg_cie;
+
+ /* parse configuration */
+ if ((status = A2D_ParsAacInfo(&cfg_cie, p_cfg, FALSE)) != 0)
+ {
+ APPL_TRACE_DEBUG("bta_av_aac_cfg_in_cap can't parse %d", status);
+ return status;
+ }
+
+
+ /* object type */
+ if ((cfg_cie.object_type & p_cap->object_type) == 0)
+ {
+ status = A2D_NS_OBJ_TYPE;
+ }
+ /* frequency */
+ else if ((cfg_cie.samp_freq & p_cap->samp_freq) == 0)
+ {
+ status = A2D_NS_SAMP_FREQ;
+ }
+ /* channels */
+ else if ((cfg_cie.channels & p_cap->channels) == 0)
+ {
+ status = A2D_NS_CHANNEL;
+ }
+ /* block length */
+ else if ((cfg_cie.bit_rate & p_cap->bit_rate) == 0)
+ {
+ status = A2D_NS_BIT_RATE;
+ }
+ APPL_TRACE_DEBUG("bta_av_aac_cfg_in_cap return %d", status);
+ return status;
+}
+
diff --git a/bta/include/bta_av_aac.h b/bta/include/bta_av_aac.h
new file mode 100644
index 000000000..310cbfa23
--- /dev/null
+++ b/bta/include/bta_av_aac.h
@@ -0,0 +1,57 @@
+/******************************************************************************
+ *
+ * Copyright (c) 2016, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of The Linux Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ * Interface to utility functions for AAC codec
+ *
+ ******************************************************************************/
+#ifndef BTA_AV_AAC_H
+#define BTA_AV_AAC_H
+
+
+/* AAC packet header size */
+#define BTA_AV_AAC_HDR_SIZE A2D_AAC_MPL_HDR_LEN
+
+/*******************************************************************************
+**
+** Function bta_av_aac_cfg_in_cap
+**
+** Description Checks if AAC codec config is allowed for given caps.
+** codec config bits are also checked for sanity
+**
+** Returns 0 if ok, nonzero if error.
+**
+*******************************************************************************/
+extern UINT8 bta_av_aac_cfg_in_cap(UINT8 *p_cfg, tA2D_AAC_CIE *p_cap);
+
+#endif /* BTA_AV_AAC_H */
+
diff --git a/bta/include/bta_av_api.h b/bta/include/bta_av_api.h
index d9974e43b..891535587 100644
--- a/bta/include/bta_av_api.h
+++ b/bta/include/bta_av_api.h
@@ -109,8 +109,12 @@ typedef UINT8 tBTA_AV_HNDL;
#endif
#ifndef BTA_AV_MAX_SEPS
+#if defined(AAC_ENCODER_INCLUDED) && (AAC_ENCODER_INCLUDED == TRUE)
+#define BTA_AV_MAX_SEPS 3
+#else
#define BTA_AV_MAX_SEPS 2
#endif
+#endif
#ifndef BTA_AV_MAX_A2DP_MTU
/*#define BTA_AV_MAX_A2DP_MTU 668 //224 (DM5) * 3 - 4(L2CAP header) */
diff --git a/bta/include/bta_av_co.h b/bta/include/bta_av_co.h
index 2510968f7..00fc5ade6 100644
--- a/bta/include/bta_av_co.h
+++ b/bta/include/bta_av_co.h
@@ -63,6 +63,9 @@ enum
{
BTIF_SV_AV_AA_SBC_INDEX = 0,
BTIF_SV_AV_AA_APTX_INDEX,
+#if defined(AAC_ENCODER_INCLUDED) && (AAC_ENCODER_INCLUDED == TRUE)
+ BTIF_SV_AV_AA_AAC_INDEX,
+#endif
BTIF_SV_AV_AA_SRC_SEP_INDEX /* Last index */
};
diff --git a/btif/co/bta_av_co.c b/btif/co/bta_av_co.c
index d0a40ca7d..ae042e3fc 100644
--- a/btif/co/bta_av_co.c
+++ b/btif/co/bta_av_co.c
@@ -45,6 +45,10 @@
#include "bt_utils.h"
#include "a2d_aptx.h"
+#if defined(AAC_ENCODER_INCLUDED) && (AAC_ENCODER_INCLUDED == TRUE)
+#include "a2d_aac.h"
+#include "bta_av_aac.h"
+#endif
/*****************************************************************************
** Constants
@@ -160,6 +164,36 @@ const tA2D_APTX_CIE btif_av_aptx_default_config =
A2D_APTX_FUTURE_2
};
+#if defined(AAC_ENCODER_INCLUDED) && (AAC_ENCODER_INCLUDED == TRUE)
+const tA2D_AAC_CIE bta_av_co_aac_caps =
+{
+ (A2D_AAC_IE_OBJ_TYPE_MPEG_2_AAC_LC|A2D_AAC_IE_OBJ_TYPE_MPEG_4_AAC_LC), /* obj type */
+#ifndef BTA_AV_SPLIT_A2DP_DEF_FREQ_48KHZ
+ (A2D_AAC_IE_SAMP_FREQ_44100),
+#else
+ (A2D_AAC_IE_SAMP_FREQ_44100 | A2D_AAC_IE_SAMP_FREQ_48000),
+#endif
+ (A2D_AAC_IE_CHANNELS_1 | A2D_AAC_IE_CHANNELS_2 ), /* channels */
+ A2D_AAC_IE_BIT_RATE, /* BIT RATE */
+ A2D_AAC_IE_VBR_NOT_SUPP /* variable bit rate */
+};
+
+/* Default AAC codec configuration */
+const tA2D_AAC_CIE btif_av_aac_default_config =
+{
+ A2D_AAC_IE_OBJ_TYPE_MPEG_2_AAC_LC, /* obj type */
+#ifndef BTA_AV_SPLIT_A2DP_DEF_FREQ_48KHZ
+ A2D_AAC_IE_SAMP_FREQ_44100, /* samp_freq */
+#else
+ A2D_AAC_IE_SAMP_FREQ_48000, /* samp_freq */
+#endif
+ A2D_AAC_IE_CHANNELS_2, /* channels */
+ BTIF_AAC_DEFAULT_BIT_RATE, /* bit rate */
+ A2D_AAC_IE_VBR_NOT_SUPP
+};
+#endif
+
+
/*****************************************************************************
** Local data
*****************************************************************************/
@@ -216,6 +250,10 @@ typedef struct
tBTIF_AV_CODEC_INFO codec_cfg_sbc_setconfig; /* remote peer setconfig preference (SBC) */
tBTIF_AV_CODEC_INFO codec_cfg_aptx;
tBTIF_AV_CODEC_INFO codec_cfg_aptx_setconfig; /* remote peer setconfig preference (aptX)*/
+#if defined(AAC_ENCODER_INCLUDED) && (AAC_ENCODER_INCLUDED == TRUE)
+ tBTIF_AV_CODEC_INFO codec_cfg_aac;
+ tBTIF_AV_CODEC_INFO codec_cfg_aac_setconfig; /* remote peer setconfig preference (AAC)*/
+#endif
tBTA_AV_CO_CP cp;
} tBTA_AV_CO_CB;
@@ -380,7 +418,13 @@ BOOLEAN bta_av_co_audio_init(UINT8 *p_codec_type, UINT8 *p_codec_info, UINT8 *p_
*p_codec_type = A2D_NON_A2DP_MEDIA_CT;
A2D_BldAptxInfo(AVDT_MEDIA_AUDIO, (tA2D_APTX_CIE *) &bta_av_co_aptx_caps, p_codec_info);
return TRUE;
-
+#if defined(AAC_ENCODER_INCLUDED) && (AAC_ENCODER_INCLUDED == TRUE)
+ case BTIF_SV_AV_AA_AAC_INDEX:
+ APPL_TRACE_DEBUG("%s AAC", __func__);
+ *p_codec_type = BTA_AV_CODEC_M24;
+ A2D_BldAacInfo(AVDT_MEDIA_AUDIO, (tA2D_AAC_CIE *) &bta_av_co_aac_caps ,p_codec_info);
+ return TRUE;
+#endif
#if (BTA_AV_SINK_INCLUDED == TRUE)
case BTIF_SV_AV_AA_SBC_SINK_INDEX:
*p_codec_type = BTA_AV_CODEC_SBC;
@@ -707,6 +751,12 @@ UINT8 bta_av_co_audio_getconfig(tBTA_AV_HNDL hndl, tBTA_AV_CODEC codec_type,
}
break;
}
+#if defined(AAC_ENCODER_INCLUDED) && (AAC_ENCODER_INCLUDED == TRUE)
+ case BTA_AV_CODEC_M24:
+ APPL_TRACE_DEBUG("%s: AAC is supported", __func__);
+ supported = TRUE;
+ break;
+#endif
default:
break;
}
@@ -977,7 +1027,17 @@ void bta_av_co_audio_setconfig(tBTA_AV_HNDL hndl, tBTA_AV_CODEC codec_type,
}
break;
}
+#if defined(AAC_ENCODER_INCLUDED) && (AAC_ENCODER_INCLUDED == TRUE)
+ case BTA_AV_CODEC_M24:
+ {
+ APPL_TRACE_DEBUG("%s AAC", __func__);
+ bta_av_co_cb.codec_cfg_aac_setconfig.id = BTIF_AV_CODEC_M24;
+ memcpy(bta_av_co_cb.codec_cfg_aac_setconfig.info, p_codec_info, AVDT_CODEC_SIZE);
+ bta_av_co_cb.codec_cfg_setconfig = &bta_av_co_cb.codec_cfg_aac_setconfig;
+ APPL_TRACE_DEBUG("%s codec_type = %x", __func__, codec_type);
+ } break;
+#endif
default:
APPL_TRACE_ERROR("bta_av_co_audio_setconfig unsupported cid %d", bta_av_co_cb.codec_cfg->id);
recfg_needed = TRUE;
@@ -1259,7 +1319,14 @@ static BOOLEAN bta_av_co_audio_codec_build_config(const UINT8 *p_codec_caps, UIN
p_codec_cfg[BTA_AV_CO_SBC_MIN_BITPOOL_OFF],
p_codec_caps[BTA_AV_CO_SBC_MAX_BITPOOL_OFF]);
break;
-
+#if defined(AAC_ENCODER_INCLUDED) && (AAC_ENCODER_INCLUDED == TRUE)
+ case BTIF_AV_CODEC_M24:
+ /* only copy the relevant portions for this codec to avoid issues when
+ comparing codec configs covering larger codec sets than SBC (7 bytes) */
+ memcpy(p_codec_cfg, bta_av_co_cb.codec_cfg->info, A2D_AAC_INFO_LEN+1);
+ APPL_TRACE_DEBUG("%s AAC", __func__);
+ break;
+#endif
case A2D_NON_A2DP_MEDIA_CT:
{
UINT16 codecId;
@@ -1317,6 +1384,37 @@ static BOOLEAN bta_av_co_audio_codec_cfg_matches_caps(UINT8 codec_id, const UINT
return FALSE;
}
break;
+#if defined(AAC_ENCODER_INCLUDED) && (AAC_ENCODER_INCLUDED == TRUE)
+ /* in case of Sink we have to match if Src Cap is a subset of ours */
+ case BTA_AV_CODEC_M24:
+ {
+ tBTIF_AV_CODEC_INFO *p_local_aac_cfg = (tBTIF_AV_CODEC_INFO*)p_codec_cfg;
+ tA2D_AAC_CIE p_local_aac_caps;
+ tA2D_AAC_CIE p_snk_aac_caps;
+
+ if (A2D_ParsAacInfo(&p_local_aac_caps, (UINT8*)p_local_aac_cfg, FALSE) != A2D_SUCCESS) {
+ APPL_TRACE_ERROR("%s: A2D_BldAacInfo: LOCAL failed", __func__);
+ }
+ if (A2D_ParsAacInfo(&p_snk_aac_caps, (UINT8*)p_codec_cfg, FALSE) != A2D_SUCCESS) {
+ APPL_TRACE_ERROR("%s: A2D_BldAacInfo: SNK failed", __func__);
+ }
+
+ APPL_TRACE_EVENT("AAC obj_type: snk %x local %x",
+ p_snk_aac_caps.object_type, p_local_aac_caps.object_type);
+ APPL_TRACE_EVENT("AAC samp_freq: snk %x local %x",
+ p_snk_aac_caps.samp_freq, p_local_aac_caps.samp_freq);
+ APPL_TRACE_EVENT("AAC channels: snk %x local %x",
+ p_snk_aac_caps.channels, p_local_aac_caps.channels);
+ APPL_TRACE_EVENT("AAC bit_rate: snk %x local %x",
+ p_snk_aac_caps.bit_rate, p_local_aac_caps.bit_rate);
+ APPL_TRACE_EVENT("AAC vbr: snk %x local %x",
+ p_snk_aac_caps.vbr, p_local_aac_caps.vbr);
+ return (((p_snk_aac_caps.object_type)&(p_local_aac_caps.object_type))&&
+ ((p_snk_aac_caps.samp_freq)&(p_local_aac_caps.samp_freq))&&
+ ((p_snk_aac_caps.channels)&(p_local_aac_caps.channels)));
+ }
+ break;
+#endif
case A2D_NON_A2DP_MEDIA_CT:
{
UINT16 codecId;
@@ -1379,6 +1477,11 @@ static BOOLEAN bta_av_co_audio_codec_match(const UINT8 *p_codec_caps, UINT8 code
case BTIF_AV_CODEC_SBC:
return bta_av_co_audio_codec_cfg_matches_caps(bta_av_co_cb.codec_cfg_sbc.id, p_codec_caps, bta_av_co_cb.codec_cfg_sbc.info);
break;
+#if defined(AAC_ENCODER_INCLUDED) && (AAC_ENCODER_INCLUDED == TRUE)
+ case BTIF_AV_CODEC_M24:
+ return bta_av_co_audio_codec_cfg_matches_caps(bta_av_co_cb.codec_cfg_aac.id, p_codec_caps, bta_av_co_cb.codec_cfg_aac.info);
+ break;
+#endif
case A2D_NON_A2DP_MEDIA_CT:
{
UINT16 codecId;
@@ -1582,6 +1685,46 @@ static BOOLEAN bta_av_co_audio_peer_supports_codec(tBTA_AV_CO_PEER *p_peer, UINT
} else
APPL_TRACE_DEBUG("%s aptX is disabled", __func__);
+#if defined(AAC_ENCODER_INCLUDED) && (AAC_ENCODER_INCLUDED == TRUE)
+ if (bt_split_a2dp_enabled && btif_av_is_codec_offload_supported(AAC)) {
+ for (index = 0; index < p_peer->num_sup_snks; index++)
+ {
+ APPL_TRACE_DEBUG("%s AAC: index: %d, codec_type: %d", __func__, index, p_peer->snks[index].codec_type);
+
+ if (p_peer->snks[index].codec_type == bta_av_co_cb.codec_cfg_aac.id)
+ {
+ switch (p_peer->snks[index].codec_type)
+ {
+ case BTIF_AV_CODEC_M24:
+ if (p_snk_index) *p_snk_index = index;
+ APPL_TRACE_DEBUG("%s AAC", __func__);
+ if (bta_av_co_audio_codec_match(p_peer->snks[index].codec_caps, BTIF_AV_CODEC_M24))
+ {
+#if defined(BTA_AV_CO_CP_SCMS_T) && (BTA_AV_CO_CP_SCMS_T == TRUE)
+ if (bta_av_co_audio_sink_has_scmst(&p_peer->snks[index]))
+#endif
+ {
+ bta_av_co_cb.current_codec_id = bta_av_co_cb.codec_cfg_aac.id;
+ bta_av_co_cb.codec_cfg = &bta_av_co_cb.codec_cfg_aac;
+
+ APPL_TRACE_DEBUG("%s AAC matched", __func__);
+ return TRUE;
+ }
+ }
+ break;
+
+ default:
+ APPL_TRACE_ERROR("AAC: bta_av_co_audio_peer_supports_codec: unsupported codec id %d", bta_av_co_cb.codec_cfg->id);
+ //Fall thru for further SBC check
+ break;
+ }
+ }
+ }
+ } else
+ APPL_TRACE_DEBUG("%s aptX is disabled", __func__);
+#endif
+
+
for (index = 0; index < p_peer->num_sup_snks; index++)
{
if (p_peer->snks[index].codec_type == codec_type ||
@@ -1720,6 +1863,15 @@ static BOOLEAN bta_av_co_audio_media_supports_config(UINT8 codec_type, const UIN
return FALSE;
}
break;
+#if defined(AAC_ENCODER_INCLUDED) && (AAC_ENCODER_INCLUDED == TRUE)
+ case BTA_AV_CODEC_M24:
+ if (bta_av_aac_cfg_in_cap((UINT8 *)p_codec_cfg, (tA2D_AAC_CIE *)&bta_av_co_aac_caps))
+ {
+ APPL_TRACE_DEBUG("%s AAC ",__func__);
+ return FALSE;
+ }
+ break;
+#endif
case A2D_NON_A2DP_MEDIA_CT:
aptx_capabilities = &(((tBTA_AV_CO_SINK*)p_codec_cfg)->codec_caps[0]);
codecId = ((tA2D_APTX_CIE*)(aptx_capabilities))->codecId;
@@ -1876,7 +2028,15 @@ void bta_av_co_audio_codec_reset(void)
APPL_TRACE_ERROR("bta_av_co_audio_codec_reset A2D_BldSbcInfo failed");
} else
bta_av_co_cb.codec_cfg = &(bta_av_co_cb.codec_cfg_sbc);
-
+#if defined(AAC_ENCODER_INCLUDED) && (AAC_ENCODER_INCLUDED == TRUE)
+ /* Reset the current configuration to AAC */
+ bta_av_co_cb.codec_cfg_aac.id = BTIF_AV_CODEC_M24;
+ if (A2D_BldAacInfo(A2D_MEDIA_TYPE_AUDIO, (tA2D_AAC_CIE *)&btif_av_aac_default_config, bta_av_co_cb.codec_cfg_aac.info) != A2D_SUCCESS)
+ {
+ APPL_TRACE_ERROR("bta_av_co_audio_codec_reset A2D_BldAacInfo failed");
+ } else
+ bta_av_co_cb.codec_cfg = &(bta_av_co_cb.codec_cfg_sbc);
+#endif
/* Reset the Current configuration to aptX */
bta_av_co_cb.codec_cfg_aptx.id = A2D_NON_A2DP_MEDIA_CT;
if (A2D_BldAptxInfo(A2D_MEDIA_TYPE_AUDIO, (tA2D_APTX_CIE *)&btif_av_aptx_default_config, bta_av_co_cb.codec_cfg_aptx.info) != A2D_SUCCESS)
@@ -1902,6 +2062,10 @@ BOOLEAN bta_av_co_audio_set_codec(const tBTIF_AV_MEDIA_FEEDINGS *p_feeding, tBTI
tBTIF_AV_CODEC_INFO new_cfg_sbc;
tA2D_APTX_CIE aptx_config;
tBTIF_AV_CODEC_INFO new_cfg_aptx;
+#if defined(AAC_ENCODER_INCLUDED) && (AAC_ENCODER_INCLUDED == TRUE)
+ tA2D_AAC_CIE aac_config;
+ tBTIF_AV_CODEC_INFO new_cfg_aac;
+#endif
FUNC_TRACE();
/* Check AV feeding is supported */
@@ -1930,6 +2094,10 @@ BOOLEAN bta_av_co_audio_set_codec(const tBTIF_AV_MEDIA_FEEDINGS *p_feeding, tBTI
}
new_cfg_aptx.id = A2D_NON_A2DP_MEDIA_CT;
aptx_config = btif_av_aptx_default_config;
+#if defined(AAC_ENCODER_INCLUDED) && (AAC_ENCODER_INCLUDED == TRUE)
+ new_cfg_aac.id = BTIF_AV_CODEC_M24;
+ aac_config = btif_av_aac_default_config;
+#endif
switch (p_feeding->cfg.pcm.sampling_freq)
{
case 8000:
@@ -1940,6 +2108,9 @@ BOOLEAN bta_av_co_audio_set_codec(const tBTIF_AV_MEDIA_FEEDINGS *p_feeding, tBTI
case 48000:
sbc_config.samp_freq = A2D_SBC_IE_SAMP_FREQ_48;
aptx_config.sampleRate = A2D_APTX_SAMPLERATE_48000;
+#if defined(AAC_ENCODER_INCLUDED) && (AAC_ENCODER_INCLUDED == TRUE)
+ aac_config.samp_freq = A2D_AAC_IE_SAMP_FREQ_48000;
+#endif
break;
case 11025:
@@ -1947,6 +2118,9 @@ BOOLEAN bta_av_co_audio_set_codec(const tBTIF_AV_MEDIA_FEEDINGS *p_feeding, tBTI
case 44100:
sbc_config.samp_freq = A2D_SBC_IE_SAMP_FREQ_44;
aptx_config.sampleRate = A2D_APTX_SAMPLERATE_44100;
+#if defined(AAC_ENCODER_INCLUDED) && (AAC_ENCODER_INCLUDED == TRUE)
+ aac_config.samp_freq = A2D_AAC_IE_SAMP_FREQ_44100;
+#endif
break;
default:
APPL_TRACE_ERROR("bta_av_co_audio_set_codec PCM sampling frequency unsupported");
@@ -1964,6 +2138,13 @@ BOOLEAN bta_av_co_audio_set_codec(const tBTIF_AV_MEDIA_FEEDINGS *p_feeding, tBTI
APPL_TRACE_ERROR("%s A2D_BldAptxInfo failed", __func__);
return FALSE;
}
+#if defined(AAC_ENCODER_INCLUDED) && (AAC_ENCODER_INCLUDED == TRUE)
+ if (A2D_BldAacInfo(A2D_MEDIA_TYPE_AUDIO, &aac_config, new_cfg_aac.info) != A2D_SUCCESS)
+ {
+ APPL_TRACE_ERROR("%s A2D_BldAacInfo failed", __func__);
+ return FALSE;
+ }
+#endif
break;
@@ -1977,6 +2158,9 @@ BOOLEAN bta_av_co_audio_set_codec(const tBTIF_AV_MEDIA_FEEDINGS *p_feeding, tBTI
bta_av_co_cb.codec_cfg_sbc = new_cfg_sbc;
bta_av_co_cb.codec_cfg = &bta_av_co_cb.codec_cfg_sbc;
bta_av_co_cb.codec_cfg_aptx= new_cfg_aptx;
+#if defined(AAC_ENCODER_INCLUDED) && (AAC_ENCODER_INCLUDED == TRUE)
+ bta_av_co_cb.codec_cfg_aac = new_cfg_aac;
+#endif
/* Check all devices support it */
*p_status = BTIF_SUCCESS;
@@ -2042,6 +2226,9 @@ BOOLEAN bta_av_co_audio_get_codec_config(UINT8 *p_config, UINT16 *p_minmtu, UINT
tBTA_AV_CO_PEER *p_peer;
tBTA_AV_CO_SINK *p_sink;
tA2D_SBC_CIE *sbc_config;
+#if defined(AAC_ENCODER_INCLUDED) && (AAC_ENCODER_INCLUDED == TRUE)
+ tA2D_AAC_CIE *aac_config;
+#endif
APPL_TRACE_EVENT("%s codec 0x%x", __func__, bta_av_co_cb.codec_cfg->id);
@@ -2069,6 +2256,17 @@ BOOLEAN bta_av_co_audio_get_codec_config(UINT8 *p_config, UINT16 *p_minmtu, UINT
} else {
APPL_TRACE_DEBUG("%s vendorId: %d codecId: %d\n", __func__, ((tA2D_APTX_CIE *)p_config)->vendorId, ((tA2D_APTX_CIE *)p_config)->codecId);
}
+#if defined(AAC_ENCODER_INCLUDED) && (AAC_ENCODER_INCLUDED == TRUE)
+ if (type == BTIF_AV_CODEC_M24)
+ {
+ APPL_TRACE_DEBUG("%s AAC", __func__);
+ aac_config = (tA2D_AAC_CIE *)p_config;
+ if (A2D_ParsAacInfo(aac_config, bta_av_co_cb.codec_cfg_aac.info, FALSE) == A2D_SUCCESS)
+ result = TRUE;
+ else
+ memcpy((tA2D_AAC_CIE *) p_config, &btif_av_aac_default_config, sizeof(tA2D_AAC_CIE));
+ }
+#endif
for (index = 0; index < BTA_AV_CO_NUM_ELEMENTS(bta_av_co_cb.peers); index++)
{
p_peer = &bta_av_co_cb.peers[index];
@@ -2172,6 +2370,60 @@ BOOLEAN bta_av_co_audio_get_sbc_config(tA2D_SBC_CIE *p_sbc_config, UINT16 *p_min
return result;
}
+#if defined(AAC_ENCODER_INCLUDED) && (AAC_ENCODER_INCLUDED == TRUE)
+/*******************************************************************************
+ **
+ ** Function bta_av_co_audio_get_aac_config
+ **
+ ** Description Retrieves the AAC codec configuration. If the codec in use
+ ** is not AAC, return the default AAC codec configuration.
+ **
+ ** Returns TRUE if codec is AAC, FALSE otherwise
+ **
+ *******************************************************************************/
+BOOLEAN bta_av_co_audio_get_aac_config(tA2D_AAC_CIE *p_aac_config, UINT16 *p_minmtu)
+{
+ BOOLEAN result = FALSE;
+ UINT8 index;
+ tBTA_AV_CO_PEER *p_peer;
+
+ APPL_TRACE_EVENT("bta_av_co_cb.codec_cfg->id : codec 0x%x", bta_av_co_cb.codec_cfg->id);
+
+ /* Minimum MTU is by default very large */
+ *p_minmtu = 0xFFFF;
+
+ mutex_global_lock();
+ if (bta_av_co_cb.codec_cfg->id == BTIF_AV_CODEC_M24)
+ {
+ if (A2D_ParsAacInfo(p_aac_config, bta_av_co_cb.codec_cfg->info, FALSE) == A2D_SUCCESS)
+ {
+ for (index = 0; index < BTA_AV_CO_NUM_ELEMENTS(bta_av_co_cb.peers); index++)
+ {
+ p_peer = &bta_av_co_cb.peers[index];
+ if (p_peer->opened)
+ {
+ APPL_TRACE_EVENT("%s on index= %d", __func__, index);
+ if (p_peer->mtu < *p_minmtu)
+ {
+ *p_minmtu = p_peer->mtu;
+ }
+ }
+ }
+ result = TRUE;
+ }
+ }
+
+ if (!result)
+ {
+ /* Not AAC, still return the default values */
+ APPL_TRACE_EVENT("%s Not SBC, still return the default values", __func__);
+ *p_aac_config = btif_av_aac_default_config;
+ }
+ mutex_global_unlock();
+
+ return result;
+}
+#endif
/*******************************************************************************
**
diff --git a/btif/include/btif_av_api.h b/btif/include/btif_av_api.h
index 99c492395..857fed21c 100644
--- a/btif/include/btif_av_api.h
+++ b/btif/include/btif_av_api.h
@@ -51,7 +51,7 @@
/* Codec type */
#define BTIF_AV_CODEC_NONE 0xF1
#define BTIF_AV_CODEC_SBC A2D_MEDIA_CT_SBC /* SBC media codec type */
-
+#define BTIF_AV_CODEC_M24 A2D_MEDIA_CT_M24 /* AAC media codec type */
#define BTIF_AV_CODEC_PCM 0x5 /* Raw PCM */
typedef UINT8 tBTIF_AV_CODEC_ID;
diff --git a/btif/include/btif_av_co.h b/btif/include/btif_av_co.h
index 2d2bbc9d4..167e1a5d7 100644
--- a/btif/include/btif_av_co.h
+++ b/btif/include/btif_av_co.h
@@ -30,7 +30,6 @@
/*******************************************************************************
** Constants & Macros
********************************************************************************/
-
/*******************************************************************************
** Functions
********************************************************************************/
@@ -154,6 +153,20 @@ BOOLEAN bta_av_co_audio_get_codec_config(UINT8 *p_sbc_config, UINT16 *p_minmtu,
**
*******************************************************************************/
BOOLEAN bta_av_co_audio_get_sbc_config(tA2D_SBC_CIE *p_sbc_config, UINT16 *p_minmtu);
+#if defined(AAC_ENCODER_INCLUDED) && (AAC_ENCODER_INCLUDED == TRUE)
+/*******************************************************************************
+ **
+ ** Function bta_av_co_audio_get_aac_config
+ **
+ ** Description Retrieves the AAC codec configuration. If the codec in use
+ ** is not AAC, return the default SBC codec configuration.
+ **
+ ** Returns TRUE if codec is AAC, FALSE otherwise
+ **
+ *******************************************************************************/
+BOOLEAN bta_av_co_audio_get_aac_config(tA2D_AAC_CIE *p_aac_config, UINT16 *p_minmtu);
+#endif
+
/*******************************************************************************
**
diff --git a/btif/include/btif_media.h b/btif/include/btif_media.h
index c7e10fe1c..f9ef11e7d 100644
--- a/btif/include/btif_media.h
+++ b/btif/include/btif_media.h
@@ -39,6 +39,7 @@
#include "bt_common.h"
#include "btif_av_api.h"
#include "audio_a2dp_hw.h"
+#include "a2d_aac.h"
/*******************************************************************************
** Constants
@@ -83,6 +84,11 @@ typedef struct
UINT8 CodecType; /* SBC or Non-A2DP */
UINT8 BluetoothVendorID; /* Bluetooth Vendor ID */
UINT8 BluetoothCodecID; /* Bluetooth Codec ID */
+#if defined(AAC_ENCODER_INCLUDED) && (AAC_ENCODER_INCLUDED == TRUE)
+ UINT8 ObjectType;
+ UINT32 bit_rate;
+ UINT8 vbr;
+#endif
} tBTIF_MEDIA_INIT_AUDIO;
#if (BTA_AV_INCLUDED == TRUE)
diff --git a/btif/src/btif_media_task.c b/btif/src/btif_media_task.c
index d1d2f25e5..6180852f9 100644
--- a/btif/src/btif_media_task.c
+++ b/btif/src/btif_media_task.c
@@ -61,12 +61,14 @@
#include "a2d_int.h"
#include "a2d_sbc.h"
#include "a2d_aptx.h"
+#include "a2d_aac.h"
#include "audio_a2dp_hw.h"
#include "bt_target.h"
#include "bta_api.h"
#include "bta_av_api.h"
#include "bta_av_ci.h"
#include "bta_av_sbc.h"
+#include "bta_av_aac.h"
#include "bta_sys.h"
#include "bta_sys_int.h"
#include "btif_av.h"
@@ -184,6 +186,12 @@ enum {
#endif
#if (BTA_AV_CO_CP_SCMS_T == TRUE)
+#define BTIF_MEDIA_AA_AAC_OFFSET (AVDT_MEDIA_OFFSET + BTA_AV_AAC_HDR_SIZE + 1)
+#else
+#define BTIF_MEDIA_AA_AAC_OFFSET (AVDT_MEDIA_OFFSET + BTA_AV_AAC_HDR_SIZE)
+#endif
+
+#if (BTA_AV_CO_CP_SCMS_T == TRUE)
#define BTIF_MEDIA_AA_APTX_OFFSET (AVDT_MEDIA_OFFSET + 1)
#else
#define BTIF_MEDIA_AA_APTX_OFFSET (AVDT_MEDIA_OFFSET - AVDT_MEDIA_HDR_SIZE) //no RTP header for aptX classic
@@ -899,6 +907,14 @@ static void btif_recv_ctrl_data(void)
A2D_BldSbcInfo(AVDT_MEDIA_AUDIO,&codec_cfg,&param[1]);
bitrate = btif_media_cb.encoder.u16BitRate * 1000;
}
+#if defined(AAC_ENCODER_INCLUDED) && (AAC_ENCODER_INCLUDED == TRUE)
+ else if (codec_id == BTIF_AV_CODEC_M24) {
+ tA2D_AAC_CIE aac_cfg;
+ bta_av_co_audio_get_aac_config(&aac_cfg, &min_mtu);
+ A2D_BldAacInfo(AVDT_MEDIA_AUDIO,&aac_cfg,&param[1]);
+ bitrate = btif_media_cb.encoder.u16BitRate * 1000;
+ }
+#endif
else if (codec_id == A2D_NON_A2DP_MEDIA_CT) //this is changed to non-a2dp VS codec
{
//ADD APTX support
@@ -913,7 +929,7 @@ static void btif_recv_ctrl_data(void)
{
tA2D_APTX_CIE* codecInfo = 0;
codecInfo = (tA2D_APTX_CIE*) &ptr[3];
- if (codecInfo && codecInfo->vendorId == A2D_APTX_VENDOR_ID
+ if (codecInfo && codecInfo->vendorId == A2D_APTX_VENDOR_ID
&& codecInfo->codecId == A2D_APTX_CODEC_ID_BLUETOOTH)
{
tA2D_APTX_CIE aptx_config;
@@ -1116,7 +1132,9 @@ static void btif_a2dp_encoder_init(tBTA_AV_HNDL hdl)
tBTIF_MEDIA_INIT_AUDIO msg;
tA2D_SBC_CIE sbc_config;
tA2D_APTX_CIE* codecInfo = 0;
-
+#if defined(AAC_ENCODER_INCLUDED) && (AAC_ENCODER_INCLUDED == TRUE)
+ tA2D_AAC_CIE aac_config;
+#endif
/* lookup table for converting channel mode */
UINT16 codec_mode_tbl[5] = { SBC_JOINT_STEREO, SBC_STEREO, SBC_DUAL, 0, SBC_MONO };
@@ -1169,6 +1187,22 @@ static void btif_a2dp_encoder_init(tBTA_AV_HNDL hdl)
}
}/* if ( A2D_NON_A2DP_MEDIA_CT == codectype) */
+
+#if defined(AAC_ENCODER_INCLUDED) && (AAC_ENCODER_INCLUDED == TRUE)
+ if (BTIF_AV_CODEC_M24 == codectype) {
+ ALOGI("%s Selected Codec AAC", __func__);
+ bta_av_co_audio_get_codec_config ((UINT8*)&aac_config, &minmtu, BTIF_AV_CODEC_M24);
+ msg.ObjectType = aac_config.object_type;
+ msg.ChannelMode = (aac_config.channels == A2D_AAC_IE_CHANNELS_2) ? SBC_STEREO : SBC_MONO;
+ msg.SamplingFreq = freq_block_tbl[aac_config.samp_freq >> 5];
+ msg.MtuSize = minmtu;
+ msg.CodecType = BTIF_AV_CODEC_M24;
+ msg.bit_rate = aac_config.bit_rate;
+ btif_media_task_enc_init_req(&msg);
+ return;
+ }
+#endif
+
ALOGI("%s Selected Codec SBC", __func__);
/* Retrieve the current SBC configuration (default if currently not used) */
@@ -1191,6 +1225,9 @@ static void btif_a2dp_encoder_update(void)
{
UINT16 minmtu = 0;
tA2D_SBC_CIE sbc_config;
+#if defined(AAC_ENCODER_INCLUDED) && (AAC_ENCODER_INCLUDED == TRUE)
+ tA2D_AAC_CIE aac_config;
+#endif
tBTIF_MEDIA_UPDATE_AUDIO msg;
UINT8 pref_min;
UINT8 pref_max;
@@ -1218,7 +1255,17 @@ static void btif_a2dp_encoder_update(void)
msg.BluetoothCodecID = aptx_config.codecId;
}
} /* if (ptr) */
- } else {
+ }
+#if defined(AAC_ENCODER_INCLUDED) && (AAC_ENCODER_INCLUDED == TRUE)
+ else if (codectype == BTIF_AV_CODEC_M24) {
+ bta_av_co_audio_get_aac_config(&aac_config, &minmtu);
+
+ APPL_TRACE_DEBUG("btif_a2dp_encoder_update: AAC object_type :%d channels :%d",
+ aac_config.object_type, aac_config.channels);
+ msg.CodecType = BTIF_AV_CODEC_M24;
+ }
+#endif
+ else {
/* Retrieve the current SBC configuration (default if currently not used) */
bta_av_co_audio_get_sbc_config(&sbc_config, &minmtu);
@@ -2464,7 +2511,16 @@ static void btif_media_task_enc_init(BT_HDR *p_msg)
/* do nothing, fall through to SBC */
}
}
-
+#if defined(AAC_ENCODER_INCLUDED) && (AAC_ENCODER_INCLUDED == TRUE)
+ else if (pInitAudio->CodecType == BTIF_AV_CODEC_M24) {
+ /*AAC is supported only in split mode, so only update the
+ required MTU size for AAC to send down to FW via VSC*/
+ btif_media_cb.TxAaMtuSize = ((BTIF_MEDIA_AA_BUF_SIZE-BTIF_MEDIA_AA_AAC_OFFSET-sizeof(BT_HDR))
+ < pInitAudio->MtuSize) ? (BTIF_MEDIA_AA_BUF_SIZE - BTIF_MEDIA_AA_AAC_OFFSET
+ - sizeof(BT_HDR)) : pInitAudio->MtuSize;
+ return;
+ }
+#endif
/* SBC encoder config (enforced even if not used) */
btif_media_cb.encoder.s16ChannelMode = pInitAudio->ChannelMode;
btif_media_cb.encoder.s16NumOfSubBands = pInitAudio->NumOfSubBands;
@@ -2541,6 +2597,17 @@ static void btif_media_task_enc_update(BT_HDR *p_msg)
/* do nothing, fall through to SBC */
}
}
+#if defined(AAC_ENCODER_INCLUDED) && (AAC_ENCODER_INCLUDED == TRUE)
+ else if (pUpdateAudio->CodecType == BTIF_AV_CODEC_M24) {
+ APPL_TRACE_EVENT("%s AAC" , __func__);
+ btif_media_cb.TxAaMtuSize = ((BTIF_MEDIA_AA_BUF_SIZE -
+ BTIF_MEDIA_AA_AAC_OFFSET - sizeof(BT_HDR))
+ < pUpdateAudio->MinMtuSize) ? (BTIF_MEDIA_AA_BUF_SIZE - BTIF_MEDIA_AA_AAC_OFFSET
+ - sizeof(BT_HDR)) : pUpdateAudio->MinMtuSize;
+ return;
+ }
+#endif
+ else
{
if (!pstrEncParams->s16NumOfSubBands)
{
@@ -2887,6 +2954,7 @@ static void btif_media_task_audio_feeding_init(BT_HDR *p_msg)
}
}
}
+
btif_media_cb.TxTranscoding = BTIF_MEDIA_TRSCD_PCM_2_SBC;
btif_media_task_pcm2sbc_init(p_feeding);
break;
diff --git a/include/bt_target.h b/include/bt_target.h
index 9e495553c..da845bf49 100644
--- a/include/bt_target.h
+++ b/include/bt_target.h
@@ -175,6 +175,11 @@
#define HL_INCLUDED TRUE
#endif
+#ifndef AAC_ENCODER_INCLUDED
+#define AAC_ENCODER_INCLUDED TRUE
+#endif
+
+
#ifndef AG_VOICE_SETTINGS
#define AG_VOICE_SETTINGS HCI_DEFAULT_VOICE_SETTINGS
#endif
@@ -1204,8 +1209,12 @@
* Audio*2 + Video*2 + 1 Additional
*/
#ifndef AVDT_NUM_SEPS
+#if defined(AAC_ENCODER_INCLUDED) && (AAC_ENCODER_INCLUDED == TRUE)
+#define AVDT_NUM_SEPS 7
+#else
#define AVDT_NUM_SEPS 5
#endif
+#endif
/* Number of transport channels setup by AVDT for all media streams */
#ifndef AVDT_NUM_TC_TBL
@@ -1405,6 +1414,10 @@
#define A2D_INCLUDED TRUE
#endif
+#ifndef A2D_M24_INCLUDED
+#define A2D_M24_INCLUDED A2D_INCLUDED
+#endif
+
/******************************************************************************
**
** AVCTP
diff --git a/stack/Android.mk b/stack/Android.mk
index 4eb9ce822..ace03dd0d 100644
--- a/stack/Android.mk
+++ b/stack/Android.mk
@@ -39,6 +39,7 @@ LOCAL_SRC_FILES:= \
./a2dp/a2d_api.c \
./a2dp/a2d_sbc.c \
./a2dp/a2d_aptx.c \
+ ./a2dp/a2d_aac.c \
./avrc/avrc_api.c \
./avrc/avrc_sdp.c \
./avrc/avrc_opt.c \
diff --git a/stack/a2dp/a2d_aac.c b/stack/a2dp/a2d_aac.c
new file mode 100644
index 000000000..d299e00cb
--- /dev/null
+++ b/stack/a2dp/a2d_aac.c
@@ -0,0 +1,175 @@
+/******************************************************************************
+ *
+ * Copyright (c) 2016, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of The Linux Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ ******************************************************************************/
+/******************************************************************************
+ *
+ * Utility functions to help build and parse AAC Codec Information
+ *
+ ******************************************************************************/
+
+#include "bt_target.h"
+#include <string.h>
+#include "a2d_api.h"
+#include "a2d_int.h"
+#include "a2d_aac.h"
+#include "bt_utils.h"
+
+#if (A2D_M24_INCLUDED == TRUE)
+static UINT8 A2D_UINT32_BitsSet(UINT32 num);
+/******************************************************************************
+**
+** Function A2D_BldAacInfo
+**
+** Description This function builds byte sequence for
+** Aac Codec Capabilities.
+** Input : media_type: Audio or MultiMedia.
+** p_ie: AAC Codec Information Element
+**
+** Output : p_result: codec info.
+**
+** Returns A2D_SUCCESS if successful.
+** Error otherwise.
+******************************************************************************/
+tA2D_STATUS A2D_BldAacInfo(UINT8 media_type, tA2D_AAC_CIE *p_ie, UINT8 *p_result)
+{
+ tA2D_STATUS status;
+ if( p_ie == NULL || p_result == NULL ||
+ (p_ie->object_type & ~A2D_AAC_IE_OBJ_TYPE_MSK) ||
+ (p_ie->samp_freq & ~A2D_AAC_IE_SAMP_FREQ_MSK) ||
+ (p_ie->channels & ~A2D_AAC_IE_CHANNELS_MSK) ||
+ (p_ie->bit_rate & ~A2D_AAC_IE_BIT_RATE_MSK) ||
+ (p_ie->vbr & ~A2D_AAC_IE_VBR_MSK) )
+ {
+ /* return invalid params if invalid bit is set */
+ status = A2D_INVALID_PARAMS;
+ }
+ else
+ {
+ status = A2D_SUCCESS;
+ *p_result++ = A2D_AAC_INFO_LEN;
+ *p_result++ = media_type;
+ *p_result++ = A2D_MEDIA_CT_M24;
+
+ /* Codec information */
+ *p_result++ = p_ie->object_type; // object type
+
+ *p_result++ = (UINT8)(p_ie->samp_freq >> 8);
+
+ *p_result++ = (p_ie->samp_freq & 0x00F0)|p_ie->channels;
+ *p_result++ = p_ie->vbr | ((p_ie->bit_rate >> 16)& 0x007F);
+ *p_result++ = (p_ie->bit_rate >> 8)& 0x00FF;
+ *p_result = p_ie->bit_rate & 0x000000FF;
+ }
+ return status;
+}
+
+/******************************************************************************
+**
+** Function A2D_ParsAacInfo
+**
+** Description This function parse byte sequence for
+** Aac Codec Capabilities.
+** Input : p_info: input byte sequence.
+** for_caps: True for getcap, false otherwise
+**
+** Output : p_ie: Aac codec information.
+**
+** Returns A2D_SUCCESS if successful.
+** Error otherwise.
+******************************************************************************/
+tA2D_STATUS A2D_ParsAacInfo(tA2D_AAC_CIE *p_ie, UINT8 *p_info, BOOLEAN for_caps)
+{
+ tA2D_STATUS status;
+ UINT8 losc;
+ UINT8 media_type;
+
+ if( p_ie == NULL || p_info == NULL)
+ status = A2D_INVALID_PARAMS;
+ else
+ {
+ losc = *p_info++;
+ media_type = *p_info++;
+ /* Check for wrong length, media type */
+ if(losc != A2D_AAC_INFO_LEN || *p_info != A2D_MEDIA_CT_M24)
+ status = A2D_WRONG_CODEC;
+ else
+ {
+ p_info++;
+ /* obj type */
+ p_ie->object_type = *p_info & A2D_AAC_IE_OBJ_TYPE_MSK; p_info++;
+ /* samping freq */
+ p_ie->samp_freq = *p_info; p_info++;
+ p_ie->samp_freq = p_ie->samp_freq << 8;
+ p_ie->samp_freq |= (*p_info & 0xF0);
+ /* channels */
+ p_ie->channels = *p_info & A2D_AAC_IE_CHANNELS_MSK; p_info++;
+ /* variable bit rate */
+ p_ie->vbr = *p_info & A2D_AAC_IE_VBR_MSK;
+ /* bit rate */
+ p_ie->bit_rate = *p_info & 0x7F;p_ie->bit_rate = p_ie->bit_rate << 8; p_info++;
+ p_ie->bit_rate |= *p_info;p_ie->bit_rate = p_ie->bit_rate << 8; p_info++;
+ p_ie->bit_rate |= *p_info;
+ status = A2D_SUCCESS;
+
+ if(for_caps == FALSE)
+ {
+ if(A2D_UINT32_BitsSet(p_ie->object_type) != A2D_SET_ONE_BIT)
+ status = A2D_BAD_OBJ_TYPE;
+ if(A2D_UINT32_BitsSet(p_ie->samp_freq) != A2D_SET_ONE_BIT)
+ status = A2D_BAD_SAMP_FREQ;
+ if(A2D_UINT32_BitsSet(p_ie->channels) != A2D_SET_ONE_BIT)
+ status = A2D_BAD_CHANNEL;
+ }
+ }
+ }
+ return status;
+}
+/******************************************************************************
+** Function A2D_UINT32_BitsSet
+**
+** Description Check the given number of 32bit for the number of bits set
+** Returns A2D_SET_ONE_BIT, if one and only one bit is set
+** A2D_SET_ZERO_BIT, if all bits clear
+** A2D_SET_MULTL_BIT, if multiple bits are set
+******************************************************************************/
+static UINT8 A2D_UINT32_BitsSet(UINT32 num)
+{
+ UINT8 count;
+ BOOLEAN res;
+ if(num == 0)
+ res = A2D_SET_ZERO_BIT;
+ else
+ {
+ count = (num & (num - 1));
+ res = ((count==0)?A2D_SET_ONE_BIT:A2D_SET_MULTL_BIT);
+ }
+ return res;
+}
+#endif /* A2D_M24_INCLUDED == TRUE */
diff --git a/stack/include/a2d_aac.h b/stack/include/a2d_aac.h
new file mode 100644
index 000000000..102de6787
--- /dev/null
+++ b/stack/include/a2d_aac.h
@@ -0,0 +1,149 @@
+/******************************************************************************
+ *
+ * Copyright (c) 2016, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of The Linux Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ ******************************************************************************/
+
+#ifndef A2D_AAC_H
+#define A2D_AAC_H
+
+/*****************************************************************************
+** Constants
+*****************************************************************************/
+
+#define A2D_AAC_MPL_HDR_LEN 1
+
+/* AAC media codec capabilitiy len*/
+#define A2D_AAC_INFO_LEN 8
+
+/* AAC Codec Specific */
+#define A2D_AAC_IE_OBJ_TYPE_MSK 0xF0 /* b7-b4 Object Type */
+#define A2D_AAC_IE_OBJ_TYPE_MPEG_2_AAC_LC 0x80 /* b7:MPEG-2 AAC LC */
+#define A2D_AAC_IE_OBJ_TYPE_MPEG_4_AAC_LC 0x40 /* b7:MPEG-4 AAC LC */
+#define A2D_AAC_IE_OBJ_TYPE_MPEG_4_AAC_LTP 0x20 /* b7:MPEG-4 AAC LTP */
+#define A2D_AAC_IE_OBJ_TYPE_MPEG_4_AAC_SCA 0x10 /* b7:MPEG-4 AAC SCALABLE */
+
+#define A2D_AAC_IE_SAMP_FREQ_MSK 0xFFF0 /* b15-b4 sampling frequency */
+#define A2D_AAC_IE_SAMP_FREQ_8000 0x8000 /* b15: 8000 */
+#define A2D_AAC_IE_SAMP_FREQ_11025 0x4000 /* b15: 11025 */
+#define A2D_AAC_IE_SAMP_FREQ_12000 0x2000 /* b15: 12000 */
+#define A2D_AAC_IE_SAMP_FREQ_16000 0x1000 /* b15: 16000 */
+#define A2D_AAC_IE_SAMP_FREQ_22050 0x0800 /* b15: 22050 */
+#define A2D_AAC_IE_SAMP_FREQ_24000 0x0400 /* b15: 24000 */
+#define A2D_AAC_IE_SAMP_FREQ_32000 0x0200 /* b15: 32000 */
+#define A2D_AAC_IE_SAMP_FREQ_44100 0x0100 /* b15: 441000 */
+#define A2D_AAC_IE_SAMP_FREQ_48000 0x0080 /* b15: 48000 */
+#define A2D_AAC_IE_SAMP_FREQ_64000 0x0040 /* b15: 64000 */
+#define A2D_AAC_IE_SAMP_FREQ_88200 0x0020 /* b15: 88200 */
+#define A2D_AAC_IE_SAMP_FREQ_96000 0x0010 /* b15: 96000 */
+
+
+#define A2D_AAC_IE_CHANNELS_MSK 0x0C /* b7-b6 channels supported */
+#define A2D_AAC_IE_CHANNELS_1 0x08 /* Channel 1 */
+#define A2D_AAC_IE_CHANNELS_2 0x04 /* Channel 2 */
+
+#define A2D_AAC_IE_VBR_MSK 0x80 /* b7 variable bit rate */
+#define A2D_AAC_IE_VBR_SUPP 0x80 /* supported */
+#define A2D_AAC_IE_VBR_NOT_SUPP 0x00 /* supported */
+
+#define A2D_AAC_IE_BIT_RATE_MSK 0x007FFFFF /* bit rate */
+#define A2D_AAC_IE_BIT_RATE 0x007FFFFF
+
+
+#define BTIF_AAC_DEFAULT_BIT_RATE 0x000409B6
+
+typedef struct {
+ INT16 s16SamplingFreq; /* 16k, 32k, 44.1k or 48k*/
+ INT16 s16ChannelMode; /* mono, dual, streo or joint streo*/
+ UINT16 u16BitRate;
+ UINT16 *ps16NextPcmBuffer;
+ UINT8 *pu8Packet;
+ UINT8 *pu8NextPacket;
+ UINT16 u16PacketLength;
+ void* encoder;
+} A2D_AAC_ENC_PARAMS;
+
+/*****************************************************************************
+** Type Definitions
+*****************************************************************************/
+
+/* AAC Codec Information data type */
+typedef struct
+{
+ UINT8 object_type; /* Object Type */
+ UINT16 samp_freq; /* Sampling Frequency */
+ UINT8 channels; /* Channels */
+ UINT32 bit_rate; /* bit_rate */
+ UINT8 vbr; /* variable bit rate */
+} tA2D_AAC_CIE;
+
+
+/*****************************************************************************
+** External Function Declarations
+*****************************************************************************/
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/******************************************************************************
+**
+** Function A2D_BldAacInfo
+**
+** Description This function builds byte sequence for
+** Aac Codec Capabilities.
+** Input : media_type: Audio or MultiMedia.
+** p_ie: AAC Codec Information Element
+**
+** Output : p_result: codec info.
+**
+** Returns A2D_SUCCESS if successful.
+** Error otherwise.
+******************************************************************************/
+extern tA2D_STATUS A2D_BldAacInfo(UINT8 media_type, tA2D_AAC_CIE *p_ie, UINT8 *p_result);
+
+/******************************************************************************
+**
+** Function A2D_ParsAacInfo
+**
+** Description This function parse byte sequence for
+** Aac Codec Capabilities.
+** Input : p_info: input byte sequence.
+** for_caps: True for getcap, false otherwise
+**
+** Output : p_ie: Aac codec information.
+**
+** Returns A2D_SUCCESS if successful.
+** Error otherwise.
+******************************************************************************/
+extern tA2D_STATUS A2D_ParsAacInfo(tA2D_AAC_CIE *p_ie, UINT8 *p_info, BOOLEAN for_caps);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* A2D_AAC_H */