A2DP: Enable AAC VBR for A2DP source feature
This CL adds AAC variable bitrate to the source capabilities, and the
software encoder uses VBR mode 5 (vary high bitrate) by default.
Bug: 112325138
Test: atest net_test_stack / IOP test
Tag: #feature
Change-Id: I4271154248af5ea82c3de2c97bb39526e9f904ba
Merged-In: I4271154248af5ea82c3de2c97bb39526e9f904ba
diff --git a/stack/a2dp/a2dp_aac.cc b/stack/a2dp/a2dp_aac.cc
index a7b7218..96d84e2 100644
--- a/stack/a2dp/a2dp_aac.cc
+++ b/stack/a2dp/a2dp_aac.cc
@@ -35,6 +35,7 @@
#include "bt_utils.h"
#include "osi/include/log.h"
#include "osi/include/osi.h"
+#include "osi/include/properties.h"
#define A2DP_AAC_DEFAULT_BITRATE 320000 // 320 kbps
#define A2DP_AAC_MIN_BITRATE 64000 // 64 kbps
@@ -50,8 +51,11 @@
btav_a2dp_codec_bits_per_sample_t bits_per_sample;
} tA2DP_AAC_CIE;
+static bool aac_source_caps_configured = false;
+static tA2DP_AAC_CIE a2dp_aac_source_caps = {};
+
/* AAC Source codec capabilities */
-static const tA2DP_AAC_CIE a2dp_aac_source_caps = {
+static const tA2DP_AAC_CIE a2dp_aac_cbr_source_caps = {
// objectType
A2DP_AAC_OBJECT_TYPE_MPEG2_LC,
// sampleRate
@@ -66,6 +70,22 @@
// bits_per_sample
BTAV_A2DP_CODEC_BITS_PER_SAMPLE_16};
+/* AAC Source codec capabilities */
+static const tA2DP_AAC_CIE a2dp_aac_vbr_source_caps = {
+ // objectType
+ A2DP_AAC_OBJECT_TYPE_MPEG2_LC,
+ // sampleRate
+ // TODO: AAC 48.0kHz sampling rate should be added back - see b/62301376
+ A2DP_AAC_SAMPLING_FREQ_44100,
+ // channelMode
+ A2DP_AAC_CHANNEL_MODE_STEREO,
+ // variableBitRateSupport
+ A2DP_AAC_VARIABLE_BIT_RATE_ENABLED,
+ // bitRate
+ A2DP_AAC_DEFAULT_BITRATE,
+ // bits_per_sample
+ BTAV_A2DP_CODEC_BITS_PER_SAMPLE_16};
+
/* AAC Sink codec capabilities */
static const tA2DP_AAC_CIE a2dp_aac_sink_caps = {
// objectType
@@ -708,7 +728,19 @@
const char* A2DP_CodecIndexStrAacSink(void) { return "AAC SINK"; }
+void aac_source_caps_initialize() {
+ if (aac_source_caps_configured) {
+ return;
+ }
+ a2dp_aac_source_caps =
+ osi_property_get_bool("persist.bluetooth.a2dp_aac.vbr_supported", false)
+ ? a2dp_aac_vbr_source_caps
+ : a2dp_aac_cbr_source_caps;
+ aac_source_caps_configured = true;
+}
+
bool A2DP_InitCodecConfigAac(AvdtpSepConfig* p_cfg) {
+ aac_source_caps_initialize();
if (A2DP_BuildInfoAac(AVDT_MEDIA_TYPE_AUDIO, &a2dp_aac_source_caps,
p_cfg->codec_info) != A2DP_SUCCESS) {
return false;
@@ -754,6 +786,7 @@
btav_a2dp_codec_priority_t codec_priority)
: A2dpCodecConfigAacBase(BTAV_A2DP_CODEC_INDEX_SOURCE_AAC,
A2DP_CodecIndexStrAac(), codec_priority, true) {
+ aac_source_caps_initialize();
// Compute the local capability
if (a2dp_aac_source_caps.sampleRate & A2DP_AAC_SAMPLING_FREQ_44100) {
codec_local_capability_.sample_rate |= BTAV_A2DP_CODEC_SAMPLE_RATE_44100;