Merge "Abstract the adjustment of A2DP codec parameters"
diff --git a/bta/av/bta_av_aact.cc b/bta/av/bta_av_aact.cc
index ffcefab..6041908 100644
--- a/bta/av/bta_av_aact.cc
+++ b/bta/av/bta_av_aact.cc
@@ -66,9 +66,6 @@
static void bta_av_st_rc_timer(tBTA_AV_SCB *p_scb, tBTA_AV_DATA *p_data);
-static const size_t SBC_MAX_BITPOOL_OFFSET = 6;
-static const size_t SBC_MAX_BITPOOL = 53;
-
/* state machine states */
enum
{
@@ -1930,13 +1927,8 @@
&av_sink_codec_info);
}
- if ((uuid_int == UUID_SERVCLASS_AUDIO_SOURCE) &&
- (cfg.codec_info[SBC_MAX_BITPOOL_OFFSET] > SBC_MAX_BITPOOL))
- {
- APPL_TRACE_WARNING("%s: max bitpool length received for SBC is out of range."
- "Clamping the codec bitpool configuration from %d to %d.", __func__,
- cfg.codec_info[SBC_MAX_BITPOOL_OFFSET], SBC_MAX_BITPOOL);
- cfg.codec_info[SBC_MAX_BITPOOL_OFFSET] = SBC_MAX_BITPOOL;
+ if (uuid_int == UUID_SERVCLASS_AUDIO_SOURCE) {
+ A2DP_AdjustCodec(cfg.codec_info);
}
/* open the stream */
diff --git a/stack/a2dp/a2dp_api.cc b/stack/a2dp/a2dp_api.cc
index 71fff68..a360fd9 100644
--- a/stack/a2dp/a2dp_api.cc
+++ b/stack/a2dp/a2dp_api.cc
@@ -968,3 +968,19 @@
LOG_ERROR(LOG_TAG, "%s: unsupported codec type 0x%x", __func__, codec_type);
return NULL;
}
+
+bool A2DP_AdjustCodec(uint8_t* p_codec_info) {
+ tA2DP_CODEC_TYPE codec_type = A2DP_GetCodecType(p_codec_info);
+
+ switch (codec_type) {
+ case A2DP_MEDIA_CT_SBC:
+ return A2DP_AdjustCodecSbc(p_codec_info);
+ case A2DP_MEDIA_CT_NON_A2DP:
+ return A2DP_VendorAdjustCodec(p_codec_info);
+ default:
+ break;
+ }
+
+ LOG_ERROR(LOG_TAG, "%s: unsupported codec type 0x%x", __func__, codec_type);
+ return false;
+}
diff --git a/stack/a2dp/a2dp_sbc.cc b/stack/a2dp/a2dp_sbc.cc
index e091841..cf0c5c0 100644
--- a/stack/a2dp/a2dp_sbc.cc
+++ b/stack/a2dp/a2dp_sbc.cc
@@ -1149,3 +1149,20 @@
return &a2dp_encoder_interface_sbc;
}
+
+bool A2DP_AdjustCodecSbc(uint8_t* p_codec_info) {
+ tA2DP_SBC_CIE cfg_cie;
+
+ if (A2DP_ParsSbcInfo(&cfg_cie, p_codec_info, false) != A2DP_SUCCESS)
+ return false;
+
+ // Updated the max bitpool
+ if (cfg_cie.max_bitpool > A2DP_SBC_MAX_BITPOOL) {
+ LOG_WARN(LOG_TAG, "Updated the SBC codec max bitpool from %d to %d",
+ cfg_cie.max_bitpool, A2DP_SBC_MAX_BITPOOL);
+ cfg_cie.max_bitpool = A2DP_SBC_MAX_BITPOOL;
+ }
+
+ return (A2DP_BldSbcInfo(AVDT_MEDIA_TYPE_AUDIO, &cfg_cie,
+ p_codec_info) == A2DP_SUCCESS);
+}
diff --git a/stack/a2dp/a2dp_vendor.cc b/stack/a2dp/a2dp_vendor.cc
index 4ab6abc..04c6126 100644
--- a/stack/a2dp/a2dp_vendor.cc
+++ b/stack/a2dp/a2dp_vendor.cc
@@ -364,3 +364,12 @@
return NULL;
}
+
+bool A2DP_VendorAdjustCodec(uint8_t* p_codec_info) {
+ // uint32_t vendor_id = A2DP_VendorCodecGetVendorId(p_codec_info);
+ // uint16_t codec_id = A2DP_VendorCodecGetCodecId(p_codec_info);
+
+ // Add checks based on <vendor_id, codec_id>
+
+ return false;
+}
diff --git a/stack/include/a2dp_api.h b/stack/include/a2dp_api.h
index bb12646..e714b1a 100644
--- a/stack/include/a2dp_api.h
+++ b/stack/include/a2dp_api.h
@@ -608,6 +608,11 @@
const tA2DP_ENCODER_INTERFACE* A2DP_GetEncoderInterface(
const uint8_t* p_codec_info);
+// Adjusts the A2DP codec, based on local support and Bluetooth specification.
+// |p_codec_info| contains the codec information to adjust.
+// Returns true if |p_codec_info| is valid and supported, otherwise false.
+bool A2DP_AdjustCodec(uint8_t* p_codec_info);
+
#ifdef __cplusplus
}
#endif
diff --git a/stack/include/a2dp_sbc.h b/stack/include/a2dp_sbc.h
index 98a3206..efb9a8a 100644
--- a/stack/include/a2dp_sbc.h
+++ b/stack/include/a2dp_sbc.h
@@ -325,6 +325,12 @@
const tA2DP_ENCODER_INTERFACE* A2DP_GetEncoderInterfaceSbc(
const uint8_t* p_codec_info);
+// Adjusts the A2DP SBC codec, based on local support and Bluetooth
+// specification.
+// |p_codec_info| contains the codec information to adjust.
+// Returns true if |p_codec_info| is valid and supported, otherwise false.
+bool A2DP_AdjustCodecSbc(uint8_t* p_codec_info);
+
#ifdef __cplusplus
}
#endif
diff --git a/stack/include/a2dp_vendor.h b/stack/include/a2dp_vendor.h
index 9de2432..6693ae0 100644
--- a/stack/include/a2dp_vendor.h
+++ b/stack/include/a2dp_vendor.h
@@ -255,6 +255,12 @@
const tA2DP_ENCODER_INTERFACE* A2DP_VendorGetEncoderInterface(
const uint8_t* p_codec_info);
+// Adjusts the A2DP vendor-specific codec, based on local support and Bluetooth
+// specification.
+// |p_codec_info| contains the codec information to adjust.
+// Returns true if |p_codec_info| is valid and supported, otherwise false.
+bool A2DP_VendorAdjustCodec(uint8_t* p_codec_info);
+
#ifdef __cplusplus
}
#endif
diff --git a/stack/test/stack_a2dp_test.cc b/stack/test/stack_a2dp_test.cc
index ce37a54..1ce89b0 100644
--- a/stack/test/stack_a2dp_test.cc
+++ b/stack/test/stack_a2dp_test.cc
@@ -33,7 +33,7 @@
// Subbands: A2DP_SBC_IE_SUBBAND_8 |
// Allocation Method: A2DP_SBC_IE_ALLOC_MD_L
2, // MinimumBitpool Value: A2DP_SBC_IE_MIN_BITPOOL
- 53, // Maxium Bitpool Value: A2DP_SBC_MAX_BITPOOL
+ 53, // Maximum Bitpool Value: A2DP_SBC_MAX_BITPOOL
7, // Dummy
8, // Dummy
9 // Dummy
@@ -58,7 +58,7 @@
0x02 | 0x01, // Allocation Method: A2DP_SBC_IE_ALLOC_MD_S |
// A2DP_SBC_IE_ALLOC_MD_L
2, // MinimumBitpool Value: A2DP_SBC_IE_MIN_BITPOOL
- 250, // Maxium Bitpool Value: A2DP_SBC_IE_MAX_BITPOOL
+ 250, // Maximum Bitpool Value: A2DP_SBC_IE_MAX_BITPOOL
7, // Dummy
8, // Dummy
9 // Dummy
@@ -546,3 +546,35 @@
EXPECT_FALSE(A2DP_BuildCodecHeader(codec_info_non_a2dp, p_buf,
FRAMES_PER_PACKET));
}
+
+TEST(StackA2dpTest, test_a2dp_adjust_codec) {
+ uint8_t codec_info_sbc_test[AVDT_CODEC_SIZE];
+ uint8_t codec_info_non_a2dp_test[AVDT_CODEC_SIZE];
+
+ // Test updating a valid SBC codec that doesn't need adjustment
+ memset(codec_info_sbc_test, 0xAB, sizeof(codec_info_sbc_test));
+ memcpy(codec_info_sbc_test, codec_info_sbc, sizeof(codec_info_sbc));
+ EXPECT_TRUE(A2DP_AdjustCodec(codec_info_sbc_test));
+ EXPECT_TRUE(memcmp(codec_info_sbc_test, codec_info_sbc,
+ sizeof(codec_info_sbc)) == 0);
+
+ // Test updating a valid SBC codec that needs adjustment
+ memset(codec_info_sbc_test, 0xAB, sizeof(codec_info_sbc_test));
+ memcpy(codec_info_sbc_test, codec_info_sbc, sizeof(codec_info_sbc));
+ codec_info_sbc_test[6] = 54; // A2DP_SBC_MAX_BITPOOL + 1
+ EXPECT_TRUE(A2DP_AdjustCodec(codec_info_sbc_test));
+ EXPECT_TRUE(memcmp(codec_info_sbc_test, codec_info_sbc,
+ sizeof(codec_info_sbc)) == 0);
+
+ // Test updating an invalid SBC codec
+ memset(codec_info_sbc_test, 0xAB, sizeof(codec_info_sbc_test));
+ memcpy(codec_info_sbc_test, codec_info_sbc, sizeof(codec_info_sbc));
+ codec_info_sbc_test[6] = 255; // Invalid MAX_BITPOOL
+ EXPECT_FALSE(A2DP_AdjustCodec(codec_info_sbc_test));
+
+ // Test updating a non-A2DP codec that is not recognized
+ memset(codec_info_non_a2dp_test, 0xAB, sizeof(codec_info_non_a2dp_test));
+ memcpy(codec_info_non_a2dp_test, codec_info_non_a2dp,
+ sizeof(codec_info_non_a2dp));
+ EXPECT_FALSE(A2DP_AdjustCodec(codec_info_non_a2dp_test));
+}