1 /*
2 * Copyright 2016 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 /**
18 * A2DP Codecs Configuration
19 */
20
21 #define LOG_TAG "bluetooth-a2dp"
22
23 #include <bluetooth/log.h>
24 #include <stdio.h>
25
26 #include <cstddef>
27 #include <cstdint>
28 #include <cstring>
29 #include <ios>
30 #include <mutex>
31 #include <optional>
32 #include <sstream>
33 #include <string>
34 #include <utility>
35 #include <vector>
36
37 #include "a2dp_aac.h"
38 #include "a2dp_codec_api.h"
39 #include "a2dp_constants.h"
40 #include "a2dp_ext.h"
41 #include "a2dp_sbc.h"
42 #include "a2dp_vendor.h"
43 #include "a2dp_vendor_aptx_constants.h"
44 #include "a2dp_vendor_aptx_hd_constants.h"
45 #include "a2dp_vendor_ldac_constants.h"
46 #include "avdt_api.h"
47 #include "device/include/device_iot_conf_defs.h"
48 #include "hardware/bt_av.h"
49
50 #if !defined(EXCLUDE_NONSTANDARD_CODECS)
51 #include "a2dp_vendor_aptx.h"
52 #include "a2dp_vendor_aptx_hd.h"
53 #include "a2dp_vendor_ldac.h"
54 #include "a2dp_vendor_opus.h"
55 #endif
56
57 #include "audio_hal_interface/a2dp_encoding.h"
58 #include "bta/av/bta_av_int.h"
59 #include "osi/include/properties.h"
60 #include "stack/include/bt_hdr.h"
61
62 /* The Media Type offset within the codec info byte array */
63 #define A2DP_MEDIA_TYPE_OFFSET 1
64
65 namespace bluetooth::a2dp {
66
ParseCodecId(uint8_t const media_codec_capabilities[])67 std::optional<CodecId> ParseCodecId(uint8_t const media_codec_capabilities[]) {
68 uint8_t length_of_service_capability = media_codec_capabilities[0];
69 // The Media Codec Capabilities contain the Media Codec Type and
70 // Media Type on 16-bits.
71 if (length_of_service_capability < 2) {
72 return {};
73 }
74 tA2DP_CODEC_TYPE codec_type = A2DP_GetCodecType(media_codec_capabilities);
75 switch (codec_type) {
76 case A2DP_MEDIA_CT_SBC:
77 return CodecId::SBC;
78 case A2DP_MEDIA_CT_AAC:
79 return CodecId::AAC;
80 case A2DP_MEDIA_CT_NON_A2DP: {
81 // The Vendor Codec Specific Information Elements contain
82 // a 32-bit Vendor ID and 16-bit Vendor Specific Codec ID.
83 if (length_of_service_capability < 8) {
84 return {};
85 }
86 uint32_t vendor_id = A2DP_VendorCodecGetVendorId(media_codec_capabilities);
87 uint16_t codec_id = A2DP_VendorCodecGetCodecId(media_codec_capabilities);
88 // The lower 16 bits of the 32-bit Vendor ID shall contain a valid,
89 // nonreserved 16-bit Company ID as defined in Bluetooth Assigned Numbers.
90 // The upper 16 bits of the 32-bit Vendor ID shall be set to zero.
91 if (vendor_id > UINT16_MAX) {
92 return {};
93 }
94 return static_cast<CodecId>(VendorCodecId(static_cast<uint16_t>(vendor_id), codec_id));
95 }
96 default:
97 return {};
98 }
99 }
100
101 } // namespace bluetooth::a2dp
102
103 using namespace bluetooth;
104
105 // Initializes the codec config.
106 // |codec_config| is the codec config to initialize.
107 // |codec_index| and |codec_priority| are the codec type and priority to use
108 // for the initialization.
init_btav_a2dp_codec_config(btav_a2dp_codec_config_t * codec_config,btav_a2dp_codec_index_t codec_index,btav_a2dp_codec_priority_t codec_priority)109 static void init_btav_a2dp_codec_config(btav_a2dp_codec_config_t* codec_config,
110 btav_a2dp_codec_index_t codec_index,
111 btav_a2dp_codec_priority_t codec_priority) {
112 memset(codec_config, 0, sizeof(btav_a2dp_codec_config_t));
113 codec_config->codec_type = codec_index;
114 codec_config->codec_priority = codec_priority;
115 }
116
A2dpCodecConfig(btav_a2dp_codec_index_t codec_index,a2dp::CodecId codec_id,const std::string & name,btav_a2dp_codec_priority_t codec_priority)117 A2dpCodecConfig::A2dpCodecConfig(btav_a2dp_codec_index_t codec_index, a2dp::CodecId codec_id,
118 const std::string& name, btav_a2dp_codec_priority_t codec_priority)
119 : codec_index_(codec_index),
120 codec_id_(codec_id),
121 name_(name),
122 default_codec_priority_(codec_priority) {
123 setCodecPriority(codec_priority);
124
125 init_btav_a2dp_codec_config(&codec_config_, codec_index_, codecPriority());
126 init_btav_a2dp_codec_config(&codec_capability_, codec_index_, codecPriority());
127 init_btav_a2dp_codec_config(&codec_local_capability_, codec_index_, codecPriority());
128 init_btav_a2dp_codec_config(&codec_selectable_capability_, codec_index_, codecPriority());
129 init_btav_a2dp_codec_config(&codec_user_config_, codec_index_, BTAV_A2DP_CODEC_PRIORITY_DEFAULT);
130 init_btav_a2dp_codec_config(&codec_audio_config_, codec_index_, BTAV_A2DP_CODEC_PRIORITY_DEFAULT);
131
132 memset(ota_codec_config_, 0, sizeof(ota_codec_config_));
133 memset(ota_codec_peer_capability_, 0, sizeof(ota_codec_peer_capability_));
134 memset(ota_codec_peer_config_, 0, sizeof(ota_codec_peer_config_));
135 }
136
~A2dpCodecConfig()137 A2dpCodecConfig::~A2dpCodecConfig() {}
138
setCodecPriority(btav_a2dp_codec_priority_t codec_priority)139 void A2dpCodecConfig::setCodecPriority(btav_a2dp_codec_priority_t codec_priority) {
140 if (codec_priority == BTAV_A2DP_CODEC_PRIORITY_DEFAULT) {
141 // Compute the default codec priority
142 setDefaultCodecPriority();
143 } else {
144 codec_priority_ = codec_priority;
145 }
146 codec_config_.codec_priority = codec_priority_;
147 }
148
setDefaultCodecPriority()149 void A2dpCodecConfig::setDefaultCodecPriority() {
150 if (default_codec_priority_ != BTAV_A2DP_CODEC_PRIORITY_DEFAULT) {
151 codec_priority_ = default_codec_priority_;
152 } else {
153 // Compute the default codec priority
154 uint32_t priority = 1000 * (codec_index_ + 1) + 1;
155 codec_priority_ = static_cast<btav_a2dp_codec_priority_t>(priority);
156 }
157 codec_config_.codec_priority = codec_priority_;
158 }
159
createCodec(btav_a2dp_codec_index_t codec_index,btav_a2dp_codec_priority_t codec_priority)160 A2dpCodecConfig* A2dpCodecConfig::createCodec(btav_a2dp_codec_index_t codec_index,
161 btav_a2dp_codec_priority_t codec_priority) {
162 log::info("{}", A2DP_CodecIndexStr(codec_index));
163
164 // Hardware offload codec extensibility:
165 // management of the codec is moved under the ProviderInfo
166 // class of the aidl audio HAL client.
167 if (::bluetooth::audio::a2dp::provider::supports_codec(codec_index)) {
168 return new A2dpCodecConfigExt(codec_index, true);
169 }
170
171 A2dpCodecConfig* codec_config = nullptr;
172 switch (codec_index) {
173 case BTAV_A2DP_CODEC_INDEX_SOURCE_SBC:
174 codec_config = new A2dpCodecConfigSbcSource(codec_priority);
175 break;
176 case BTAV_A2DP_CODEC_INDEX_SINK_SBC:
177 codec_config = new A2dpCodecConfigSbcSink(codec_priority);
178 break;
179 #if !defined(EXCLUDE_NONSTANDARD_CODECS)
180 case BTAV_A2DP_CODEC_INDEX_SOURCE_AAC:
181 codec_config = new A2dpCodecConfigAacSource(codec_priority);
182 break;
183 case BTAV_A2DP_CODEC_INDEX_SINK_AAC:
184 codec_config = new A2dpCodecConfigAacSink(codec_priority);
185 break;
186 case BTAV_A2DP_CODEC_INDEX_SOURCE_APTX:
187 codec_config = new A2dpCodecConfigAptx(codec_priority);
188 break;
189 case BTAV_A2DP_CODEC_INDEX_SOURCE_APTX_HD:
190 codec_config = new A2dpCodecConfigAptxHd(codec_priority);
191 break;
192 case BTAV_A2DP_CODEC_INDEX_SOURCE_LDAC:
193 codec_config = new A2dpCodecConfigLdacSource(codec_priority);
194 break;
195 case BTAV_A2DP_CODEC_INDEX_SINK_LDAC:
196 codec_config = new A2dpCodecConfigLdacSink(codec_priority);
197 break;
198 case BTAV_A2DP_CODEC_INDEX_SOURCE_OPUS:
199 codec_config = new A2dpCodecConfigOpusSource(codec_priority);
200 break;
201 case BTAV_A2DP_CODEC_INDEX_SINK_OPUS:
202 codec_config = new A2dpCodecConfigOpusSink(codec_priority);
203 break;
204 #endif
205 case BTAV_A2DP_CODEC_INDEX_MAX:
206 default:
207 break;
208 }
209
210 if (codec_config != nullptr) {
211 if (!codec_config->init()) {
212 delete codec_config;
213 codec_config = nullptr;
214 }
215 }
216
217 return codec_config;
218 }
219
getTrackBitRate() const220 int A2dpCodecConfig::getTrackBitRate() const {
221 uint8_t p_codec_info[AVDT_CODEC_SIZE];
222 memcpy(p_codec_info, ota_codec_config_, sizeof(ota_codec_config_));
223 tA2DP_CODEC_TYPE codec_type = A2DP_GetCodecType(p_codec_info);
224
225 switch (codec_type) {
226 case A2DP_MEDIA_CT_SBC:
227 return A2DP_GetBitrateSbc();
228 #if !defined(EXCLUDE_NONSTANDARD_CODECS)
229 case A2DP_MEDIA_CT_AAC:
230 return A2DP_GetBitRateAac(p_codec_info);
231 case A2DP_MEDIA_CT_NON_A2DP:
232 return A2DP_VendorGetBitRate(p_codec_info);
233 #endif
234 default:
235 break;
236 }
237
238 log::error("unsupported codec type 0x{:x}", codec_type);
239 return -1;
240 }
241
getCodecSpecificConfig(tBT_A2DP_OFFLOAD * p_a2dp_offload)242 bool A2dpCodecConfig::getCodecSpecificConfig(tBT_A2DP_OFFLOAD* p_a2dp_offload) {
243 std::lock_guard<std::recursive_mutex> lock(codec_mutex_);
244
245 uint8_t codec_config[AVDT_CODEC_SIZE];
246 uint32_t vendor_id;
247 uint16_t codec_id;
248
249 memset(p_a2dp_offload->codec_info, 0, sizeof(p_a2dp_offload->codec_info));
250
251 if (!A2DP_IsSourceCodecValid(ota_codec_config_)) {
252 return false;
253 }
254
255 memcpy(codec_config, ota_codec_config_, sizeof(ota_codec_config_));
256 tA2DP_CODEC_TYPE codec_type = A2DP_GetCodecType(codec_config);
257 switch (codec_type) {
258 case A2DP_MEDIA_CT_SBC:
259 p_a2dp_offload->codec_info[0] = codec_config[4]; // blk_len | subbands | Alloc Method
260 p_a2dp_offload->codec_info[1] = codec_config[5]; // Min bit pool
261 p_a2dp_offload->codec_info[2] = codec_config[6]; // Max bit pool
262 p_a2dp_offload->codec_info[3] = codec_config[3]; // Sample freq | channel mode
263 break;
264 #if !defined(EXCLUDE_NONSTANDARD_CODECS)
265 case A2DP_MEDIA_CT_AAC:
266 p_a2dp_offload->codec_info[0] = codec_config[3]; // object type
267 p_a2dp_offload->codec_info[1] = codec_config[6]; // VBR | BR
268 break;
269 case A2DP_MEDIA_CT_NON_A2DP:
270 vendor_id = A2DP_VendorCodecGetVendorId(codec_config);
271 codec_id = A2DP_VendorCodecGetCodecId(codec_config);
272 p_a2dp_offload->codec_info[0] = (vendor_id & 0x000000FF);
273 p_a2dp_offload->codec_info[1] = (vendor_id & 0x0000FF00) >> 8;
274 p_a2dp_offload->codec_info[2] = (vendor_id & 0x00FF0000) >> 16;
275 p_a2dp_offload->codec_info[3] = (vendor_id & 0xFF000000) >> 24;
276 p_a2dp_offload->codec_info[4] = (codec_id & 0x000000FF);
277 p_a2dp_offload->codec_info[5] = (codec_id & 0x0000FF00) >> 8;
278 if (vendor_id == A2DP_LDAC_VENDOR_ID && codec_id == A2DP_LDAC_CODEC_ID) {
279 if (codec_config_.codec_specific_1 == 0) { // default is 0, ABR
280 p_a2dp_offload->codec_info[6] = A2DP_LDAC_QUALITY_ABR_OFFLOAD; // ABR in offload
281 } else {
282 switch (codec_config_.codec_specific_1 % 10) {
283 case 0:
284 p_a2dp_offload->codec_info[6] = A2DP_LDAC_QUALITY_HIGH; // High bitrate
285 break;
286 case 1:
287 p_a2dp_offload->codec_info[6] = A2DP_LDAC_QUALITY_MID; // Mid birate
288 break;
289 case 2:
290 p_a2dp_offload->codec_info[6] = A2DP_LDAC_QUALITY_LOW; // Low birate
291 break;
292 case 3:
293 FALLTHROUGH_INTENDED; /* FALLTHROUGH */
294 default:
295 p_a2dp_offload->codec_info[6] = A2DP_LDAC_QUALITY_ABR_OFFLOAD; // ABR in offload
296 break;
297 }
298 }
299 p_a2dp_offload->codec_info[7] = codec_config[10]; // LDAC specific channel mode
300 log::verbose("Ldac specific channelmode ={}", p_a2dp_offload->codec_info[7]);
301 }
302 break;
303 #endif
304 default:
305 break;
306 }
307 return true;
308 }
309
copyOutOtaCodecConfig(uint8_t * p_codec_info)310 bool A2dpCodecConfig::copyOutOtaCodecConfig(uint8_t* p_codec_info) {
311 std::lock_guard<std::recursive_mutex> lock(codec_mutex_);
312
313 // TODO: We should use a mechanism to verify codec config,
314 // not codec capability.
315 if (!A2DP_IsSourceCodecValid(ota_codec_config_)) {
316 return false;
317 }
318 memcpy(p_codec_info, ota_codec_config_, sizeof(ota_codec_config_));
319 return true;
320 }
321
getCodecConfig()322 btav_a2dp_codec_config_t A2dpCodecConfig::getCodecConfig() {
323 std::lock_guard<std::recursive_mutex> lock(codec_mutex_);
324
325 // TODO: We should check whether the codec config is valid
326 return codec_config_;
327 }
328
getCodecCapability()329 btav_a2dp_codec_config_t A2dpCodecConfig::getCodecCapability() {
330 std::lock_guard<std::recursive_mutex> lock(codec_mutex_);
331
332 // TODO: We should check whether the codec capability is valid
333 return codec_capability_;
334 }
335
getCodecLocalCapability()336 btav_a2dp_codec_config_t A2dpCodecConfig::getCodecLocalCapability() {
337 std::lock_guard<std::recursive_mutex> lock(codec_mutex_);
338
339 // TODO: We should check whether the codec capability is valid
340 return codec_local_capability_;
341 }
342
getCodecSelectableCapability()343 btav_a2dp_codec_config_t A2dpCodecConfig::getCodecSelectableCapability() {
344 std::lock_guard<std::recursive_mutex> lock(codec_mutex_);
345
346 // TODO: We should check whether the codec capability is valid
347 return codec_selectable_capability_;
348 }
349
getCodecUserConfig()350 btav_a2dp_codec_config_t A2dpCodecConfig::getCodecUserConfig() {
351 std::lock_guard<std::recursive_mutex> lock(codec_mutex_);
352
353 return codec_user_config_;
354 }
355
getCodecAudioConfig()356 btav_a2dp_codec_config_t A2dpCodecConfig::getCodecAudioConfig() {
357 std::lock_guard<std::recursive_mutex> lock(codec_mutex_);
358
359 return codec_audio_config_;
360 }
361
getAudioBitsPerSample()362 uint8_t A2dpCodecConfig::getAudioBitsPerSample() {
363 std::lock_guard<std::recursive_mutex> lock(codec_mutex_);
364
365 switch (codec_config_.bits_per_sample) {
366 case BTAV_A2DP_CODEC_BITS_PER_SAMPLE_16:
367 return 16;
368 case BTAV_A2DP_CODEC_BITS_PER_SAMPLE_24:
369 return 24;
370 case BTAV_A2DP_CODEC_BITS_PER_SAMPLE_32:
371 return 32;
372 case BTAV_A2DP_CODEC_BITS_PER_SAMPLE_NONE:
373 break;
374 }
375 return 0;
376 }
377
isCodecConfigEmpty(const btav_a2dp_codec_config_t & codec_config)378 bool A2dpCodecConfig::isCodecConfigEmpty(const btav_a2dp_codec_config_t& codec_config) {
379 return (codec_config.codec_priority == BTAV_A2DP_CODEC_PRIORITY_DEFAULT) &&
380 (codec_config.sample_rate == BTAV_A2DP_CODEC_SAMPLE_RATE_NONE) &&
381 (codec_config.bits_per_sample == BTAV_A2DP_CODEC_BITS_PER_SAMPLE_NONE) &&
382 (codec_config.channel_mode == BTAV_A2DP_CODEC_CHANNEL_MODE_NONE) &&
383 (codec_config.codec_specific_1 == 0) && (codec_config.codec_specific_2 == 0) &&
384 (codec_config.codec_specific_3 == 0) && (codec_config.codec_specific_4 == 0);
385 }
386
setCodecUserConfig(const btav_a2dp_codec_config_t & codec_user_config,const btav_a2dp_codec_config_t & codec_audio_config,const tA2DP_ENCODER_INIT_PEER_PARAMS *,const uint8_t * p_peer_codec_info,bool is_capability,uint8_t * p_result_codec_config,bool * p_restart_input,bool * p_restart_output,bool * p_config_updated)387 tA2DP_STATUS A2dpCodecConfig::setCodecUserConfig(
388 const btav_a2dp_codec_config_t& codec_user_config,
389 const btav_a2dp_codec_config_t& codec_audio_config,
390 const tA2DP_ENCODER_INIT_PEER_PARAMS* /* p_peer_params */, const uint8_t* p_peer_codec_info,
391 bool is_capability, uint8_t* p_result_codec_config, bool* p_restart_input,
392 bool* p_restart_output, bool* p_config_updated) {
393 std::lock_guard<std::recursive_mutex> lock(codec_mutex_);
394 *p_restart_input = false;
395 *p_restart_output = false;
396 *p_config_updated = false;
397
398 // Save copies of the current codec config, and the OTA codec config, so they
399 // can be compared for changes.
400 btav_a2dp_codec_config_t saved_codec_config = getCodecConfig();
401 uint8_t saved_ota_codec_config[AVDT_CODEC_SIZE];
402 memcpy(saved_ota_codec_config, ota_codec_config_, sizeof(ota_codec_config_));
403
404 btav_a2dp_codec_config_t saved_codec_user_config = codec_user_config_;
405 codec_user_config_ = codec_user_config;
406 btav_a2dp_codec_config_t saved_codec_audio_config = codec_audio_config_;
407 codec_audio_config_ = codec_audio_config;
408 auto status = setCodecConfig(p_peer_codec_info, is_capability, p_result_codec_config);
409 if (status != A2DP_SUCCESS) {
410 // Restore the local copy of the user and audio config
411 codec_user_config_ = saved_codec_user_config;
412 codec_audio_config_ = saved_codec_audio_config;
413 return status;
414 }
415
416 //
417 // The input (audio data) should be restarted if the audio format has changed
418 //
419 btav_a2dp_codec_config_t new_codec_config = getCodecConfig();
420 if ((saved_codec_config.sample_rate != new_codec_config.sample_rate) ||
421 (saved_codec_config.bits_per_sample != new_codec_config.bits_per_sample) ||
422 (saved_codec_config.channel_mode != new_codec_config.channel_mode)) {
423 *p_restart_input = true;
424 }
425
426 //
427 // The output (the connection) should be restarted if OTA codec config
428 // has changed.
429 //
430 if (!A2DP_CodecEquals(saved_ota_codec_config, p_result_codec_config)) {
431 *p_restart_output = true;
432 }
433
434 if (*p_restart_input || *p_restart_output) {
435 *p_config_updated = true;
436 }
437
438 return A2DP_SUCCESS;
439 }
440
codecConfigIsValid(const btav_a2dp_codec_config_t & codec_config)441 bool A2dpCodecConfig::codecConfigIsValid(const btav_a2dp_codec_config_t& codec_config) {
442 return (codec_config.codec_type < BTAV_A2DP_CODEC_INDEX_MAX) &&
443 (codec_config.sample_rate != BTAV_A2DP_CODEC_SAMPLE_RATE_NONE) &&
444 (codec_config.bits_per_sample != BTAV_A2DP_CODEC_BITS_PER_SAMPLE_NONE) &&
445 (codec_config.channel_mode != BTAV_A2DP_CODEC_CHANNEL_MODE_NONE);
446 }
447
codecConfig2Str(const btav_a2dp_codec_config_t & codec_config)448 std::string A2dpCodecConfig::codecConfig2Str(const btav_a2dp_codec_config_t& codec_config) {
449 std::string result;
450
451 if (!codecConfigIsValid(codec_config)) {
452 return "Invalid";
453 }
454
455 result.append("Rate=");
456 result.append(codecSampleRate2Str(codec_config.sample_rate));
457 result.append(" Bits=");
458 result.append(codecBitsPerSample2Str(codec_config.bits_per_sample));
459 result.append(" Mode=");
460 result.append(codecChannelMode2Str(codec_config.channel_mode));
461
462 return result;
463 }
464
codecSampleRate2Str(btav_a2dp_codec_sample_rate_t codec_sample_rate)465 std::string A2dpCodecConfig::codecSampleRate2Str(btav_a2dp_codec_sample_rate_t codec_sample_rate) {
466 std::string result;
467
468 if (codec_sample_rate & BTAV_A2DP_CODEC_SAMPLE_RATE_44100) {
469 if (!result.empty()) {
470 result += "|";
471 }
472 result += "44100";
473 }
474 if (codec_sample_rate & BTAV_A2DP_CODEC_SAMPLE_RATE_48000) {
475 if (!result.empty()) {
476 result += "|";
477 }
478 result += "48000";
479 }
480 if (codec_sample_rate & BTAV_A2DP_CODEC_SAMPLE_RATE_88200) {
481 if (!result.empty()) {
482 result += "|";
483 }
484 result += "88200";
485 }
486 if (codec_sample_rate & BTAV_A2DP_CODEC_SAMPLE_RATE_96000) {
487 if (!result.empty()) {
488 result += "|";
489 }
490 result += "96000";
491 }
492 if (codec_sample_rate & BTAV_A2DP_CODEC_SAMPLE_RATE_176400) {
493 if (!result.empty()) {
494 result += "|";
495 }
496 result += "176400";
497 }
498 if (codec_sample_rate & BTAV_A2DP_CODEC_SAMPLE_RATE_192000) {
499 if (!result.empty()) {
500 result += "|";
501 }
502 result += "192000";
503 }
504 if (result.empty()) {
505 std::stringstream ss;
506 ss << "UnknownSampleRate(0x" << std::hex << codec_sample_rate << ")";
507 ss >> result;
508 }
509
510 return result;
511 }
512
codecBitsPerSample2Str(btav_a2dp_codec_bits_per_sample_t codec_bits_per_sample)513 std::string A2dpCodecConfig::codecBitsPerSample2Str(
514 btav_a2dp_codec_bits_per_sample_t codec_bits_per_sample) {
515 std::string result;
516
517 if (codec_bits_per_sample & BTAV_A2DP_CODEC_BITS_PER_SAMPLE_16) {
518 if (!result.empty()) {
519 result += "|";
520 }
521 result += "16";
522 }
523 if (codec_bits_per_sample & BTAV_A2DP_CODEC_BITS_PER_SAMPLE_24) {
524 if (!result.empty()) {
525 result += "|";
526 }
527 result += "24";
528 }
529 if (codec_bits_per_sample & BTAV_A2DP_CODEC_BITS_PER_SAMPLE_32) {
530 if (!result.empty()) {
531 result += "|";
532 }
533 result += "32";
534 }
535 if (result.empty()) {
536 std::stringstream ss;
537 ss << "UnknownBitsPerSample(0x" << std::hex << codec_bits_per_sample << ")";
538 ss >> result;
539 }
540
541 return result;
542 }
543
codecChannelMode2Str(btav_a2dp_codec_channel_mode_t codec_channel_mode)544 std::string A2dpCodecConfig::codecChannelMode2Str(
545 btav_a2dp_codec_channel_mode_t codec_channel_mode) {
546 std::string result;
547
548 if (codec_channel_mode & BTAV_A2DP_CODEC_CHANNEL_MODE_MONO) {
549 if (!result.empty()) {
550 result += "|";
551 }
552 result += "MONO";
553 }
554 if (codec_channel_mode & BTAV_A2DP_CODEC_CHANNEL_MODE_STEREO) {
555 if (!result.empty()) {
556 result += "|";
557 }
558 result += "STEREO";
559 }
560 if (result.empty()) {
561 std::stringstream ss;
562 ss << "UnknownChannelMode(0x" << std::hex << codec_channel_mode << ")";
563 ss >> result;
564 }
565
566 return result;
567 }
568
debug_codec_dump(int fd)569 void A2dpCodecConfig::debug_codec_dump(int fd) {
570 std::string result;
571 dprintf(fd, "\nA2DP %s State:\n", name().c_str());
572 dprintf(fd, " Priority: %d\n", codecPriority());
573
574 result = codecConfig2Str(getCodecConfig());
575 dprintf(fd, " Config: %s\n", result.c_str());
576
577 result = codecConfig2Str(getCodecSelectableCapability());
578 dprintf(fd, " Selectable: %s\n", result.c_str());
579
580 result = codecConfig2Str(getCodecLocalCapability());
581 dprintf(fd, " Local capability: %s\n", result.c_str());
582 }
583
A2DP_IotGetPeerSinkCodecType(const uint8_t * p_codec_info)584 int A2DP_IotGetPeerSinkCodecType(const uint8_t* p_codec_info) {
585 int peer_codec_type = 0;
586 tA2DP_CODEC_TYPE codec_type = A2DP_GetCodecType(p_codec_info);
587 log::verbose("codec_type = 0x{:x}", codec_type);
588 switch (codec_type) {
589 case A2DP_MEDIA_CT_SBC:
590 peer_codec_type = IOT_CONF_VAL_A2DP_CODECTYPE_SBC;
591 break;
592 #if !defined(EXCLUDE_NONSTANDARD_CODECS)
593 case A2DP_MEDIA_CT_NON_A2DP: {
594 uint16_t codec_id = A2DP_VendorCodecGetCodecId(p_codec_info);
595 uint32_t vendor_id = A2DP_VendorCodecGetVendorId(p_codec_info);
596
597 log::verbose("codec_id = {}", codec_id);
598 log::verbose("vendor_id = {:x}", vendor_id);
599
600 if (codec_id == A2DP_APTX_CODEC_ID_BLUETOOTH && vendor_id == A2DP_APTX_VENDOR_ID) {
601 peer_codec_type = IOT_CONF_VAL_A2DP_CODECTYPE_APTX;
602 } else if (codec_id == A2DP_APTX_HD_CODEC_ID_BLUETOOTH &&
603 vendor_id == A2DP_APTX_HD_VENDOR_ID) {
604 peer_codec_type = IOT_CONF_VAL_A2DP_CODECTYPE_APTXHD;
605 } else if (codec_id == A2DP_LDAC_CODEC_ID && vendor_id == A2DP_LDAC_VENDOR_ID) {
606 peer_codec_type = IOT_CONF_VAL_A2DP_CODECTYPE_LDAC;
607 }
608 break;
609 }
610 case A2DP_MEDIA_CT_AAC:
611 peer_codec_type = IOT_CONF_VAL_A2DP_CODECTYPE_AAC;
612 break;
613 #endif
614 default:
615 break;
616 }
617 return peer_codec_type;
618 }
619
620 //
621 // Compares two codecs |lhs| and |rhs| based on their priority.
622 // Returns true if |lhs| has higher priority (larger priority value).
623 // If |lhs| and |rhs| have same priority, the unique codec index is used
624 // as a tie-breaker: larger codec index value means higher priority.
625 //
compare_codec_priority(const A2dpCodecConfig * lhs,const A2dpCodecConfig * rhs)626 static bool compare_codec_priority(const A2dpCodecConfig* lhs, const A2dpCodecConfig* rhs) {
627 if (lhs->codecPriority() > rhs->codecPriority()) {
628 return true;
629 }
630 if (lhs->codecPriority() < rhs->codecPriority()) {
631 return false;
632 }
633 return lhs->codecIndex() > rhs->codecIndex();
634 }
635
A2dpCodecs(const std::vector<btav_a2dp_codec_config_t> & codec_priorities)636 A2dpCodecs::A2dpCodecs(const std::vector<btav_a2dp_codec_config_t>& codec_priorities)
637 : current_codec_config_(nullptr) {
638 for (auto config : codec_priorities) {
639 codec_priorities_.insert(std::make_pair(config.codec_type, config.codec_priority));
640 }
641 }
642
~A2dpCodecs()643 A2dpCodecs::~A2dpCodecs() {
644 std::unique_lock<std::recursive_mutex> lock(codec_mutex_);
645 for (const auto& iter : indexed_codecs_) {
646 delete iter.second;
647 }
648 for (const auto& iter : disabled_codecs_) {
649 delete iter.second;
650 }
651 lock.unlock();
652 }
653
init()654 bool A2dpCodecs::init() {
655 log::info("");
656 std::lock_guard<std::recursive_mutex> lock(codec_mutex_);
657
658 bool opus_enabled = osi_property_get_bool("persist.bluetooth.opus.enabled", false);
659
660 for (int i = BTAV_A2DP_CODEC_INDEX_MIN; i < BTAV_A2DP_CODEC_INDEX_MAX; i++) {
661 btav_a2dp_codec_index_t codec_index = static_cast<btav_a2dp_codec_index_t>(i);
662
663 // Select the codec priority if explicitly configured
664 btav_a2dp_codec_priority_t codec_priority = BTAV_A2DP_CODEC_PRIORITY_DEFAULT;
665 auto cp_iter = codec_priorities_.find(codec_index);
666 if (cp_iter != codec_priorities_.end()) {
667 codec_priority = cp_iter->second;
668 }
669
670 #if !defined(UNIT_TESTS)
671 if (codec_index == BTAV_A2DP_CODEC_INDEX_SOURCE_OPUS) {
672 if (!bluetooth::audio::a2dp::is_opus_supported()) {
673 // We are using HIDL HAL which does not support OPUS codec
674 // Mark OPUS as disabled
675 opus_enabled = false;
676 }
677 }
678 #endif
679
680 // If OPUS is not supported it is disabled
681 if (codec_index == BTAV_A2DP_CODEC_INDEX_SOURCE_OPUS && !opus_enabled) {
682 codec_priority = BTAV_A2DP_CODEC_PRIORITY_DISABLED;
683 log::info("OPUS codec disabled, updated priority to {}", codec_priority);
684 }
685
686 A2dpCodecConfig* codec_config = A2dpCodecConfig::createCodec(codec_index, codec_priority);
687 if (codec_config == nullptr) {
688 continue;
689 }
690
691 if (codec_priority != BTAV_A2DP_CODEC_PRIORITY_DEFAULT) {
692 log::info("updated {} codec priority to {}", codec_config->name(), codec_priority);
693 }
694
695 // Test if the codec is disabled
696 if (codec_config->codecPriority() == BTAV_A2DP_CODEC_PRIORITY_DISABLED) {
697 disabled_codecs_.insert(std::make_pair(codec_index, codec_config));
698 continue;
699 }
700
701 indexed_codecs_.insert(std::make_pair(codec_index, codec_config));
702
703 if (codec_index < BTAV_A2DP_CODEC_INDEX_SOURCE_MAX) {
704 ordered_source_codecs_.push_back(codec_config);
705 ordered_source_codecs_.sort(compare_codec_priority);
706 } else {
707 ordered_sink_codecs_.push_back(codec_config);
708 ordered_sink_codecs_.sort(compare_codec_priority);
709 }
710 }
711
712 if (ordered_source_codecs_.empty()) {
713 log::error("no Source codecs were initialized");
714 } else {
715 for (auto iter : ordered_source_codecs_) {
716 log::info("initialized Source codec {}, idx {}", iter->name(), iter->codecIndex());
717 }
718 }
719 if (ordered_sink_codecs_.empty()) {
720 log::error("no Sink codecs were initialized");
721 } else {
722 for (auto iter : ordered_sink_codecs_) {
723 log::info("initialized Sink codec {}, idx {}", iter->name(), iter->codecIndex());
724 }
725 }
726
727 return !ordered_source_codecs_.empty() && !ordered_sink_codecs_.empty();
728 }
729
findSourceCodecConfig(const uint8_t * p_codec_info)730 A2dpCodecConfig* A2dpCodecs::findSourceCodecConfig(const uint8_t* p_codec_info) {
731 std::lock_guard<std::recursive_mutex> lock(codec_mutex_);
732 btav_a2dp_codec_index_t codec_index = A2DP_SourceCodecIndex(p_codec_info);
733 if (codec_index == BTAV_A2DP_CODEC_INDEX_MAX) {
734 return nullptr;
735 }
736
737 auto iter = indexed_codecs_.find(codec_index);
738 if (iter == indexed_codecs_.end()) {
739 return nullptr;
740 }
741 return iter->second;
742 }
743
findSourceCodecConfig(btav_a2dp_codec_index_t codec_index)744 A2dpCodecConfig* A2dpCodecs::findSourceCodecConfig(btav_a2dp_codec_index_t codec_index) {
745 std::lock_guard<std::recursive_mutex> lock(codec_mutex_);
746
747 auto iter = indexed_codecs_.find(codec_index);
748 if (iter == indexed_codecs_.end()) {
749 return nullptr;
750 }
751 return iter->second;
752 }
753
findSinkCodecConfig(const uint8_t * p_codec_info)754 A2dpCodecConfig* A2dpCodecs::findSinkCodecConfig(const uint8_t* p_codec_info) {
755 std::lock_guard<std::recursive_mutex> lock(codec_mutex_);
756 btav_a2dp_codec_index_t codec_index = A2DP_SinkCodecIndex(p_codec_info);
757 if (codec_index == BTAV_A2DP_CODEC_INDEX_MAX) {
758 return nullptr;
759 }
760
761 auto iter = indexed_codecs_.find(codec_index);
762 if (iter == indexed_codecs_.end()) {
763 return nullptr;
764 }
765 return iter->second;
766 }
767
isSupportedCodec(btav_a2dp_codec_index_t codec_index)768 bool A2dpCodecs::isSupportedCodec(btav_a2dp_codec_index_t codec_index) {
769 std::lock_guard<std::recursive_mutex> lock(codec_mutex_);
770 return indexed_codecs_.find(codec_index) != indexed_codecs_.end();
771 }
772
setCodecConfig(const uint8_t * p_peer_codec_info,bool is_capability,uint8_t * p_result_codec_config,bool select_current_codec)773 bool A2dpCodecs::setCodecConfig(const uint8_t* p_peer_codec_info, bool is_capability,
774 uint8_t* p_result_codec_config, bool select_current_codec) {
775 std::lock_guard<std::recursive_mutex> lock(codec_mutex_);
776 A2dpCodecConfig* a2dp_codec_config = findSourceCodecConfig(p_peer_codec_info);
777 if (a2dp_codec_config == nullptr) {
778 return false;
779 }
780 if (a2dp_codec_config->setCodecConfig(p_peer_codec_info, is_capability, p_result_codec_config) !=
781 A2DP_SUCCESS) {
782 return false;
783 }
784 if (select_current_codec) {
785 current_codec_config_ = a2dp_codec_config;
786 }
787 return true;
788 }
789
setSinkCodecConfig(const uint8_t * p_peer_codec_info,bool is_capability,uint8_t * p_result_codec_config,bool select_current_codec)790 bool A2dpCodecs::setSinkCodecConfig(const uint8_t* p_peer_codec_info, bool is_capability,
791 uint8_t* p_result_codec_config, bool select_current_codec) {
792 std::lock_guard<std::recursive_mutex> lock(codec_mutex_);
793 A2dpCodecConfig* a2dp_codec_config = findSinkCodecConfig(p_peer_codec_info);
794 if (a2dp_codec_config == nullptr) {
795 return false;
796 }
797 if (a2dp_codec_config->setCodecConfig(p_peer_codec_info, is_capability, p_result_codec_config) !=
798 A2DP_SUCCESS) {
799 return false;
800 }
801 if (select_current_codec) {
802 current_codec_config_ = a2dp_codec_config;
803 }
804 return true;
805 }
806
setCodecUserConfig(const btav_a2dp_codec_config_t & codec_user_config,const tA2DP_ENCODER_INIT_PEER_PARAMS * p_peer_params,const uint8_t * p_peer_sink_capabilities,uint8_t * p_result_codec_config,bool * p_restart_input,bool * p_restart_output,bool * p_config_updated)807 bool A2dpCodecs::setCodecUserConfig(const btav_a2dp_codec_config_t& codec_user_config,
808 const tA2DP_ENCODER_INIT_PEER_PARAMS* p_peer_params,
809 const uint8_t* p_peer_sink_capabilities,
810 uint8_t* p_result_codec_config, bool* p_restart_input,
811 bool* p_restart_output, bool* p_config_updated) {
812 std::lock_guard<std::recursive_mutex> lock(codec_mutex_);
813 btav_a2dp_codec_config_t codec_audio_config;
814 A2dpCodecConfig* a2dp_codec_config = nullptr;
815 A2dpCodecConfig* last_codec_config = current_codec_config_;
816 *p_restart_input = false;
817 *p_restart_output = false;
818 *p_config_updated = false;
819
820 log::info("Configuring: {}", codec_user_config.ToString());
821
822 if (codec_user_config.codec_type < BTAV_A2DP_CODEC_INDEX_MAX) {
823 auto iter = indexed_codecs_.find(codec_user_config.codec_type);
824 if (iter == indexed_codecs_.end()) {
825 goto fail;
826 }
827 a2dp_codec_config = iter->second;
828 } else {
829 // Update the default codec
830 a2dp_codec_config = current_codec_config_;
831 }
832 if (a2dp_codec_config == nullptr) {
833 goto fail;
834 }
835
836 // Reuse the existing codec audio config
837 codec_audio_config = a2dp_codec_config->getCodecAudioConfig();
838 if (a2dp_codec_config->setCodecUserConfig(codec_user_config, codec_audio_config, p_peer_params,
839 p_peer_sink_capabilities, true, p_result_codec_config,
840 p_restart_input, p_restart_output,
841 p_config_updated) != A2DP_SUCCESS) {
842 goto fail;
843 }
844
845 // Update the codec priorities, and eventually restart the connection
846 // if a new codec needs to be selected.
847 do {
848 // Update the codec priority
849 btav_a2dp_codec_priority_t old_priority = a2dp_codec_config->codecPriority();
850 btav_a2dp_codec_priority_t new_priority = codec_user_config.codec_priority;
851 a2dp_codec_config->setCodecPriority(new_priority);
852 // Get the actual (recomputed) priority
853 new_priority = a2dp_codec_config->codecPriority();
854
855 // Check if there was no previous codec
856 if (last_codec_config == nullptr) {
857 current_codec_config_ = a2dp_codec_config;
858 *p_restart_input = true;
859 *p_restart_output = true;
860 break;
861 }
862
863 // Check if the priority of the current codec was updated
864 if (a2dp_codec_config == last_codec_config) {
865 if (old_priority == new_priority) {
866 break; // No change in priority
867 }
868
869 *p_config_updated = true;
870 if (new_priority < old_priority) {
871 // The priority has become lower - restart the connection to
872 // select a new codec.
873 *p_restart_output = true;
874 }
875 break;
876 }
877
878 if (new_priority <= old_priority) {
879 // No change in priority, or the priority has become lower.
880 // This wasn't the current codec, so we shouldn't select a new codec.
881 if (*p_restart_input || *p_restart_output || (old_priority != new_priority)) {
882 *p_config_updated = true;
883 }
884 *p_restart_input = false;
885 *p_restart_output = false;
886 break;
887 }
888
889 *p_config_updated = true;
890 if (new_priority >= last_codec_config->codecPriority()) {
891 // The new priority is higher than the current codec. Restart the
892 // connection to select a new codec.
893 current_codec_config_ = a2dp_codec_config;
894 last_codec_config->setDefaultCodecPriority();
895 *p_restart_input = true;
896 *p_restart_output = true;
897 }
898 } while (false);
899 ordered_source_codecs_.sort(compare_codec_priority);
900
901 if (*p_restart_input || *p_restart_output) {
902 *p_config_updated = true;
903 }
904
905 log::info("Configured: restart_input = {} restart_output = {} config_updated = {}",
906 *p_restart_input, *p_restart_output, *p_config_updated);
907
908 return true;
909
910 fail:
911 current_codec_config_ = last_codec_config;
912 return false;
913 }
914
setCodecAudioConfig(const btav_a2dp_codec_config_t & codec_audio_config,const tA2DP_ENCODER_INIT_PEER_PARAMS * p_peer_params,const uint8_t * p_peer_sink_capabilities,uint8_t * p_result_codec_config,bool * p_restart_output,bool * p_config_updated)915 bool A2dpCodecs::setCodecAudioConfig(const btav_a2dp_codec_config_t& codec_audio_config,
916 const tA2DP_ENCODER_INIT_PEER_PARAMS* p_peer_params,
917 const uint8_t* p_peer_sink_capabilities,
918 uint8_t* p_result_codec_config, bool* p_restart_output,
919 bool* p_config_updated) {
920 std::lock_guard<std::recursive_mutex> lock(codec_mutex_);
921 btav_a2dp_codec_config_t codec_user_config;
922 A2dpCodecConfig* a2dp_codec_config = current_codec_config_;
923 *p_restart_output = false;
924 *p_config_updated = false;
925
926 if (a2dp_codec_config == nullptr) {
927 return false;
928 }
929
930 // Reuse the existing codec user config
931 codec_user_config = a2dp_codec_config->getCodecUserConfig();
932 bool restart_input = false; // Flag ignored - input was just restarted
933 if (a2dp_codec_config->setCodecUserConfig(codec_user_config, codec_audio_config, p_peer_params,
934 p_peer_sink_capabilities, true, p_result_codec_config,
935 &restart_input, p_restart_output,
936 p_config_updated) != A2DP_SUCCESS) {
937 return false;
938 }
939
940 return true;
941 }
942
setCodecOtaConfig(const uint8_t * p_ota_codec_config,const tA2DP_ENCODER_INIT_PEER_PARAMS * p_peer_params,uint8_t * p_result_codec_config,bool * p_restart_input,bool * p_restart_output,bool * p_config_updated)943 tA2DP_STATUS A2dpCodecs::setCodecOtaConfig(const uint8_t* p_ota_codec_config,
944 const tA2DP_ENCODER_INIT_PEER_PARAMS* p_peer_params,
945 uint8_t* p_result_codec_config, bool* p_restart_input,
946 bool* p_restart_output, bool* p_config_updated) {
947 std::lock_guard<std::recursive_mutex> lock(codec_mutex_);
948 btav_a2dp_codec_index_t codec_type;
949 btav_a2dp_codec_config_t codec_user_config;
950 btav_a2dp_codec_config_t codec_audio_config;
951 A2dpCodecConfig* a2dp_codec_config = nullptr;
952 A2dpCodecConfig* last_codec_config = current_codec_config_;
953 *p_restart_input = false;
954 *p_restart_output = false;
955 *p_config_updated = false;
956 tA2DP_STATUS status = AVDTP_UNSUPPORTED_CONFIGURATION;
957
958 // Check whether the current codec config is explicitly configured by
959 // user configuration. If yes, then the OTA codec configuration is ignored.
960 if (current_codec_config_ != nullptr) {
961 codec_user_config = current_codec_config_->getCodecUserConfig();
962 if (!A2dpCodecConfig::isCodecConfigEmpty(codec_user_config)) {
963 log::warn(
964 "ignoring peer OTA configuration for codec {}: existing user "
965 "configuration for current codec {}",
966 A2DP_CodecName(p_ota_codec_config), current_codec_config_->name());
967 goto fail;
968 }
969 }
970
971 // Check whether the codec config for the same codec is explicitly configured
972 // by user configuration. If yes, then the OTA codec configuration is
973 // ignored.
974 codec_type = A2DP_SourceCodecIndex(p_ota_codec_config);
975 if (codec_type == BTAV_A2DP_CODEC_INDEX_MAX) {
976 log::warn("ignoring peer OTA codec configuration: invalid codec");
977 goto fail; // Invalid codec
978 } else {
979 auto iter = indexed_codecs_.find(codec_type);
980 if (iter == indexed_codecs_.end()) {
981 log::warn("cannot find codec configuration for peer OTA codec {}",
982 A2DP_CodecName(p_ota_codec_config));
983 status = A2DP_NOT_SUPPORTED_CODEC_TYPE;
984 goto fail;
985 }
986 a2dp_codec_config = iter->second;
987 }
988 if (a2dp_codec_config == nullptr) {
989 status = A2DP_NOT_SUPPORTED_CODEC_TYPE;
990 goto fail;
991 }
992 codec_user_config = a2dp_codec_config->getCodecUserConfig();
993 if (!A2dpCodecConfig::isCodecConfigEmpty(codec_user_config)) {
994 log::warn(
995 "ignoring peer OTA configuration for codec {}: existing user "
996 "configuration for same codec",
997 A2DP_CodecName(p_ota_codec_config));
998 status = AVDTP_UNSUPPORTED_CONFIGURATION;
999 goto fail;
1000 }
1001 current_codec_config_ = a2dp_codec_config;
1002
1003 // Reuse the existing codec user config and codec audio config
1004 codec_audio_config = a2dp_codec_config->getCodecAudioConfig();
1005 status = a2dp_codec_config->setCodecUserConfig(
1006 codec_user_config, codec_audio_config, p_peer_params, p_ota_codec_config, false,
1007 p_result_codec_config, p_restart_input, p_restart_output, p_config_updated);
1008 if (status != A2DP_SUCCESS) {
1009 log::warn("cannot set codec configuration for peer OTA codec {}",
1010 A2DP_CodecName(p_ota_codec_config));
1011 goto fail;
1012 }
1013
1014 log::assert_that(current_codec_config_ != nullptr,
1015 "assert failed: current_codec_config_ != nullptr");
1016
1017 if (*p_restart_input || *p_restart_output) {
1018 *p_config_updated = true;
1019 }
1020
1021 return A2DP_SUCCESS;
1022
1023 fail:
1024 current_codec_config_ = last_codec_config;
1025 return status;
1026 }
1027
setPeerSinkCodecCapabilities(const uint8_t * p_peer_codec_capabilities)1028 bool A2dpCodecs::setPeerSinkCodecCapabilities(const uint8_t* p_peer_codec_capabilities) {
1029 std::lock_guard<std::recursive_mutex> lock(codec_mutex_);
1030
1031 A2dpCodecConfig* a2dp_codec_config = findSourceCodecConfig(p_peer_codec_capabilities);
1032 if (a2dp_codec_config == nullptr) {
1033 return false;
1034 }
1035
1036 // Bypass the validation for codecs that are offloaded:
1037 // the stack does not need to know about the peer capabilities,
1038 // since the validation and selection will be performed by the
1039 // bluetooth audio HAL for offloaded codecs.
1040 if (!::bluetooth::audio::a2dp::provider::supports_codec(a2dp_codec_config->codecIndex()) &&
1041 !A2DP_IsPeerSinkCodecValid(p_peer_codec_capabilities)) {
1042 return false;
1043 }
1044
1045 return a2dp_codec_config->setPeerCodecCapabilities(p_peer_codec_capabilities);
1046 }
1047
setPeerSourceCodecCapabilities(const uint8_t * p_peer_codec_capabilities)1048 bool A2dpCodecs::setPeerSourceCodecCapabilities(const uint8_t* p_peer_codec_capabilities) {
1049 std::lock_guard<std::recursive_mutex> lock(codec_mutex_);
1050
1051 if (!A2DP_IsPeerSourceCodecValid(p_peer_codec_capabilities)) {
1052 return false;
1053 }
1054 A2dpCodecConfig* a2dp_codec_config = findSinkCodecConfig(p_peer_codec_capabilities);
1055 if (a2dp_codec_config == nullptr) {
1056 return false;
1057 }
1058 return a2dp_codec_config->setPeerCodecCapabilities(p_peer_codec_capabilities);
1059 }
1060
getCodecConfigAndCapabilities(btav_a2dp_codec_config_t * p_codec_config,std::vector<btav_a2dp_codec_config_t> * p_codecs_local_capabilities,std::vector<btav_a2dp_codec_config_t> * p_codecs_selectable_capabilities)1061 bool A2dpCodecs::getCodecConfigAndCapabilities(
1062 btav_a2dp_codec_config_t* p_codec_config,
1063 std::vector<btav_a2dp_codec_config_t>* p_codecs_local_capabilities,
1064 std::vector<btav_a2dp_codec_config_t>* p_codecs_selectable_capabilities) {
1065 std::lock_guard<std::recursive_mutex> lock(codec_mutex_);
1066
1067 if (current_codec_config_ != nullptr) {
1068 *p_codec_config = current_codec_config_->getCodecConfig();
1069 } else {
1070 btav_a2dp_codec_config_t codec_config;
1071 memset(&codec_config, 0, sizeof(codec_config));
1072 *p_codec_config = codec_config;
1073 }
1074
1075 std::vector<btav_a2dp_codec_config_t> codecs_capabilities;
1076 for (auto codec : orderedSourceCodecs()) {
1077 codecs_capabilities.push_back(codec->getCodecLocalCapability());
1078 }
1079 *p_codecs_local_capabilities = codecs_capabilities;
1080
1081 codecs_capabilities.clear();
1082 for (auto codec : orderedSourceCodecs()) {
1083 btav_a2dp_codec_config_t codec_capability = codec->getCodecSelectableCapability();
1084 // Don't add entries that cannot be used
1085 if ((codec_capability.sample_rate == BTAV_A2DP_CODEC_SAMPLE_RATE_NONE) ||
1086 (codec_capability.bits_per_sample == BTAV_A2DP_CODEC_BITS_PER_SAMPLE_NONE) ||
1087 (codec_capability.channel_mode == BTAV_A2DP_CODEC_CHANNEL_MODE_NONE)) {
1088 continue;
1089 }
1090 codecs_capabilities.push_back(codec_capability);
1091 }
1092 *p_codecs_selectable_capabilities = codecs_capabilities;
1093
1094 return true;
1095 }
1096
debug_codec_dump(int fd)1097 void A2dpCodecs::debug_codec_dump(int fd) {
1098 std::lock_guard<std::recursive_mutex> lock(codec_mutex_);
1099 dprintf(fd, "\nA2DP Codecs State:\n");
1100
1101 // Print the current codec name
1102 if (current_codec_config_ != nullptr) {
1103 dprintf(fd, " Current Codec: %s\n", current_codec_config_->name().c_str());
1104 } else {
1105 dprintf(fd, " Current Codec: None\n");
1106 }
1107
1108 // Print the codec-specific state
1109 for (auto codec_config : ordered_source_codecs_) {
1110 codec_config->debug_codec_dump(fd);
1111 }
1112 }
1113
A2DP_GetCodecType(const uint8_t * p_codec_info)1114 tA2DP_CODEC_TYPE A2DP_GetCodecType(const uint8_t* p_codec_info) {
1115 return (tA2DP_CODEC_TYPE)(p_codec_info[AVDT_CODEC_TYPE_INDEX]);
1116 }
1117
A2DP_IsCodecTypeValid(tA2DP_CODEC_TYPE codec_type)1118 bool A2DP_IsCodecTypeValid(tA2DP_CODEC_TYPE codec_type) {
1119 switch (codec_type) {
1120 case A2DP_MEDIA_CT_SBC:
1121 case A2DP_MEDIA_CT_MPEG_AUDIO:
1122 case A2DP_MEDIA_CT_AAC:
1123 case A2DP_MEDIA_CT_MPEG_USAC:
1124 case A2DP_MEDIA_CT_ATRAC:
1125 case A2DP_MEDIA_CT_NON_A2DP:
1126 return true;
1127 default:
1128 break;
1129 }
1130 return false;
1131 }
1132
A2DP_IsSourceCodecValid(const uint8_t * p_codec_info)1133 bool A2DP_IsSourceCodecValid(const uint8_t* p_codec_info) {
1134 tA2DP_CODEC_TYPE codec_type = A2DP_GetCodecType(p_codec_info);
1135
1136 switch (codec_type) {
1137 case A2DP_MEDIA_CT_SBC:
1138 return A2DP_IsCodecValidSbc(p_codec_info);
1139 #if !defined(EXCLUDE_NONSTANDARD_CODECS)
1140 case A2DP_MEDIA_CT_AAC:
1141 return A2DP_IsCodecValidAac(p_codec_info);
1142 case A2DP_MEDIA_CT_NON_A2DP:
1143 return A2DP_IsVendorSourceCodecValid(p_codec_info);
1144 #endif
1145 default:
1146 break;
1147 }
1148
1149 return false;
1150 }
1151
A2DP_IsPeerSourceCodecValid(const uint8_t * p_codec_info)1152 bool A2DP_IsPeerSourceCodecValid(const uint8_t* p_codec_info) {
1153 tA2DP_CODEC_TYPE codec_type = A2DP_GetCodecType(p_codec_info);
1154
1155 switch (codec_type) {
1156 case A2DP_MEDIA_CT_SBC:
1157 return A2DP_IsCodecValidSbc(p_codec_info);
1158 #if !defined(EXCLUDE_NONSTANDARD_CODECS)
1159 case A2DP_MEDIA_CT_AAC:
1160 return A2DP_IsCodecValidAac(p_codec_info);
1161 case A2DP_MEDIA_CT_NON_A2DP:
1162 return A2DP_IsVendorPeerSourceCodecValid(p_codec_info);
1163 #endif
1164 default:
1165 break;
1166 }
1167
1168 return false;
1169 }
1170
A2DP_IsPeerSinkCodecValid(const uint8_t * p_codec_info)1171 bool A2DP_IsPeerSinkCodecValid(const uint8_t* p_codec_info) {
1172 tA2DP_CODEC_TYPE codec_type = A2DP_GetCodecType(p_codec_info);
1173
1174 switch (codec_type) {
1175 case A2DP_MEDIA_CT_SBC:
1176 return A2DP_IsCodecValidSbc(p_codec_info);
1177 #if !defined(EXCLUDE_NONSTANDARD_CODECS)
1178 case A2DP_MEDIA_CT_AAC:
1179 return A2DP_IsCodecValidAac(p_codec_info);
1180 case A2DP_MEDIA_CT_NON_A2DP:
1181 return A2DP_IsVendorPeerSinkCodecValid(p_codec_info);
1182 #endif
1183 default:
1184 break;
1185 }
1186
1187 return false;
1188 }
1189
A2DP_IsSinkCodecSupported(const uint8_t * p_codec_info)1190 tA2DP_STATUS A2DP_IsSinkCodecSupported(const uint8_t* p_codec_info) {
1191 tA2DP_CODEC_TYPE codec_type = A2DP_GetCodecType(p_codec_info);
1192
1193 switch (codec_type) {
1194 case A2DP_MEDIA_CT_SBC:
1195 return A2DP_IsSinkCodecSupportedSbc(p_codec_info);
1196 #if !defined(EXCLUDE_NONSTANDARD_CODECS)
1197 case A2DP_MEDIA_CT_AAC:
1198 return A2DP_IsSinkCodecSupportedAac(p_codec_info);
1199 case A2DP_MEDIA_CT_NON_A2DP:
1200 return A2DP_IsVendorSinkCodecSupported(p_codec_info);
1201 #endif
1202 default:
1203 break;
1204 }
1205
1206 return A2DP_NOT_SUPPORTED_CODEC_TYPE;
1207 }
1208
A2DP_InitDefaultCodec(uint8_t * p_codec_info)1209 void A2DP_InitDefaultCodec(uint8_t* p_codec_info) { A2DP_InitDefaultCodecSbc(p_codec_info); }
1210
A2DP_UsesRtpHeader(bool content_protection_enabled,const uint8_t * p_codec_info)1211 bool A2DP_UsesRtpHeader(bool content_protection_enabled, const uint8_t* p_codec_info) {
1212 tA2DP_CODEC_TYPE codec_type = A2DP_GetCodecType(p_codec_info);
1213
1214 if (codec_type != A2DP_MEDIA_CT_NON_A2DP) {
1215 return true;
1216 }
1217
1218 #if !defined(EXCLUDE_NONSTANDARD_CODECS)
1219 return A2DP_VendorUsesRtpHeader(content_protection_enabled, p_codec_info);
1220 #else
1221 return true;
1222 #endif
1223 }
1224
A2DP_GetMediaType(const uint8_t * p_codec_info)1225 uint8_t A2DP_GetMediaType(const uint8_t* p_codec_info) {
1226 uint8_t media_type = (p_codec_info[A2DP_MEDIA_TYPE_OFFSET] >> 4) & 0x0f;
1227 return media_type;
1228 }
1229
A2DP_CodecName(const uint8_t * p_codec_info)1230 const char* A2DP_CodecName(const uint8_t* p_codec_info) {
1231 tA2DP_CODEC_TYPE codec_type = A2DP_GetCodecType(p_codec_info);
1232
1233 switch (codec_type) {
1234 case A2DP_MEDIA_CT_SBC:
1235 return A2DP_CodecNameSbc(p_codec_info);
1236 #if !defined(EXCLUDE_NONSTANDARD_CODECS)
1237 case A2DP_MEDIA_CT_AAC:
1238 return A2DP_CodecNameAac(p_codec_info);
1239 case A2DP_MEDIA_CT_NON_A2DP:
1240 return A2DP_VendorCodecName(p_codec_info);
1241 #endif
1242 default:
1243 break;
1244 }
1245
1246 log::error("unsupported codec type 0x{:x}", codec_type);
1247 return "UNKNOWN CODEC";
1248 }
1249
A2DP_CodecTypeEquals(const uint8_t * p_codec_info_a,const uint8_t * p_codec_info_b)1250 bool A2DP_CodecTypeEquals(const uint8_t* p_codec_info_a, const uint8_t* p_codec_info_b) {
1251 tA2DP_CODEC_TYPE codec_type_a = A2DP_GetCodecType(p_codec_info_a);
1252 tA2DP_CODEC_TYPE codec_type_b = A2DP_GetCodecType(p_codec_info_b);
1253
1254 if (codec_type_a != codec_type_b) {
1255 return false;
1256 }
1257
1258 switch (codec_type_a) {
1259 case A2DP_MEDIA_CT_SBC:
1260 return A2DP_CodecTypeEqualsSbc(p_codec_info_a, p_codec_info_b);
1261 #if !defined(EXCLUDE_NONSTANDARD_CODECS)
1262 case A2DP_MEDIA_CT_AAC:
1263 return A2DP_CodecTypeEqualsAac(p_codec_info_a, p_codec_info_b);
1264 case A2DP_MEDIA_CT_NON_A2DP:
1265 return A2DP_VendorCodecTypeEquals(p_codec_info_a, p_codec_info_b);
1266 #endif
1267 default:
1268 break;
1269 }
1270
1271 log::error("unsupported codec type 0x{:x}", codec_type_a);
1272 return false;
1273 }
1274
A2DP_CodecEquals(const uint8_t * p_codec_info_a,const uint8_t * p_codec_info_b)1275 bool A2DP_CodecEquals(const uint8_t* p_codec_info_a, const uint8_t* p_codec_info_b) {
1276 auto codec_id_a = bluetooth::a2dp::ParseCodecId(p_codec_info_a);
1277 auto codec_id_b = bluetooth::a2dp::ParseCodecId(p_codec_info_b);
1278
1279 if (!codec_id_a.has_value() || !codec_id_b.has_value() || codec_id_a != codec_id_b) {
1280 return false;
1281 }
1282
1283 switch (codec_id_a.value()) {
1284 case bluetooth::a2dp::CodecId::SBC:
1285 return A2DP_CodecEqualsSbc(p_codec_info_a, p_codec_info_b);
1286 #if !defined(EXCLUDE_NONSTANDARD_CODECS)
1287 case bluetooth::a2dp::CodecId::AAC:
1288 return A2DP_CodecEqualsAac(p_codec_info_a, p_codec_info_b);
1289 case bluetooth::a2dp::CodecId::APTX:
1290 return A2DP_VendorCodecEqualsAptx(p_codec_info_a, p_codec_info_b);
1291 case bluetooth::a2dp::CodecId::APTX_HD:
1292 return A2DP_VendorCodecEqualsAptxHd(p_codec_info_a, p_codec_info_b);
1293 case bluetooth::a2dp::CodecId::LDAC:
1294 return A2DP_VendorCodecEqualsLdac(p_codec_info_a, p_codec_info_b);
1295 case bluetooth::a2dp::CodecId::OPUS:
1296 return A2DP_VendorCodecEqualsOpus(p_codec_info_a, p_codec_info_b);
1297 #endif
1298 default:
1299 break;
1300 }
1301
1302 log::error("unsupported codec id 0x{:x}", codec_id_a.value());
1303 return false;
1304 }
1305
A2DP_GetTrackSampleRate(const uint8_t * p_codec_info)1306 int A2DP_GetTrackSampleRate(const uint8_t* p_codec_info) {
1307 auto codec_id = bluetooth::a2dp::ParseCodecId(p_codec_info);
1308
1309 if (!codec_id.has_value()) {
1310 return -1;
1311 }
1312
1313 switch (codec_id.value()) {
1314 case bluetooth::a2dp::CodecId::SBC:
1315 return A2DP_GetTrackSampleRateSbc(p_codec_info);
1316 #if !defined(EXCLUDE_NONSTANDARD_CODECS)
1317 case bluetooth::a2dp::CodecId::AAC:
1318 return A2DP_GetTrackSampleRateAac(p_codec_info);
1319 case bluetooth::a2dp::CodecId::APTX:
1320 return A2DP_VendorGetTrackSampleRateAptx(p_codec_info);
1321 case bluetooth::a2dp::CodecId::APTX_HD:
1322 return A2DP_VendorGetTrackSampleRateAptxHd(p_codec_info);
1323 case bluetooth::a2dp::CodecId::LDAC:
1324 return A2DP_VendorGetTrackSampleRateLdac(p_codec_info);
1325 case bluetooth::a2dp::CodecId::OPUS:
1326 return A2DP_VendorGetTrackSampleRateOpus(p_codec_info);
1327 #endif
1328 default:
1329 break;
1330 }
1331
1332 log::error("unsupported codec id 0x{:x}", codec_id.value());
1333 return -1;
1334 }
1335
A2DP_GetTrackBitsPerSample(const uint8_t * p_codec_info)1336 int A2DP_GetTrackBitsPerSample(const uint8_t* p_codec_info) {
1337 auto codec_id = bluetooth::a2dp::ParseCodecId(p_codec_info);
1338
1339 if (!codec_id.has_value()) {
1340 return -1;
1341 }
1342
1343 switch (codec_id.value()) {
1344 case bluetooth::a2dp::CodecId::SBC:
1345 return A2DP_GetTrackBitsPerSampleSbc(p_codec_info);
1346 #if !defined(EXCLUDE_NONSTANDARD_CODECS)
1347 case bluetooth::a2dp::CodecId::AAC:
1348 return A2DP_GetTrackBitsPerSampleAac(p_codec_info);
1349 case bluetooth::a2dp::CodecId::APTX:
1350 return A2DP_VendorGetTrackBitsPerSampleAptx(p_codec_info);
1351 case bluetooth::a2dp::CodecId::APTX_HD:
1352 return A2DP_VendorGetTrackBitsPerSampleAptxHd(p_codec_info);
1353 case bluetooth::a2dp::CodecId::LDAC:
1354 return A2DP_VendorGetTrackBitsPerSampleLdac(p_codec_info);
1355 case bluetooth::a2dp::CodecId::OPUS:
1356 return A2DP_VendorGetTrackBitsPerSampleOpus(p_codec_info);
1357 #endif
1358 default:
1359 break;
1360 }
1361
1362 log::error("unsupported codec id 0x{:x}", codec_id.value());
1363 return -1;
1364 }
1365
A2DP_GetTrackChannelCount(const uint8_t * p_codec_info)1366 int A2DP_GetTrackChannelCount(const uint8_t* p_codec_info) {
1367 auto codec_id = bluetooth::a2dp::ParseCodecId(p_codec_info);
1368
1369 if (!codec_id.has_value()) {
1370 return -1;
1371 }
1372
1373 switch (codec_id.value()) {
1374 case bluetooth::a2dp::CodecId::SBC:
1375 return A2DP_GetTrackChannelCountSbc(p_codec_info);
1376 #if !defined(EXCLUDE_NONSTANDARD_CODECS)
1377 case bluetooth::a2dp::CodecId::AAC:
1378 return A2DP_GetTrackChannelCountAac(p_codec_info);
1379 case bluetooth::a2dp::CodecId::APTX:
1380 return A2DP_VendorGetTrackChannelCountAptx(p_codec_info);
1381 case bluetooth::a2dp::CodecId::APTX_HD:
1382 return A2DP_VendorGetTrackChannelCountAptxHd(p_codec_info);
1383 case bluetooth::a2dp::CodecId::LDAC:
1384 return A2DP_VendorGetTrackChannelCountLdac(p_codec_info);
1385 case bluetooth::a2dp::CodecId::OPUS:
1386 return A2DP_VendorGetTrackChannelCountOpus(p_codec_info);
1387 #endif
1388 default:
1389 break;
1390 }
1391
1392 log::error("unsupported codec id 0x{:x}", codec_id.value());
1393 return -1;
1394 }
1395
A2DP_GetSinkTrackChannelType(const uint8_t * p_codec_info)1396 int A2DP_GetSinkTrackChannelType(const uint8_t* p_codec_info) {
1397 tA2DP_CODEC_TYPE codec_type = A2DP_GetCodecType(p_codec_info);
1398
1399 switch (codec_type) {
1400 case A2DP_MEDIA_CT_SBC:
1401 return A2DP_GetSinkTrackChannelTypeSbc(p_codec_info);
1402 #if !defined(EXCLUDE_NONSTANDARD_CODECS)
1403 case A2DP_MEDIA_CT_AAC:
1404 return A2DP_GetSinkTrackChannelTypeAac(p_codec_info);
1405 case A2DP_MEDIA_CT_NON_A2DP:
1406 return A2DP_VendorGetSinkTrackChannelType(p_codec_info);
1407 #endif
1408 default:
1409 break;
1410 }
1411
1412 log::error("unsupported codec type 0x{:x}", codec_type);
1413 return -1;
1414 }
1415
A2DP_GetPacketTimestamp(const uint8_t * p_codec_info,const uint8_t * p_data,uint32_t * p_timestamp)1416 bool A2DP_GetPacketTimestamp(const uint8_t* p_codec_info, const uint8_t* p_data,
1417 uint32_t* p_timestamp) {
1418 auto codec_id = bluetooth::a2dp::ParseCodecId(p_codec_info);
1419
1420 if (!codec_id.has_value()) {
1421 return false;
1422 }
1423
1424 switch (codec_id.value()) {
1425 case bluetooth::a2dp::CodecId::SBC:
1426 return A2DP_GetPacketTimestampSbc(p_codec_info, p_data, p_timestamp);
1427 #if !defined(EXCLUDE_NONSTANDARD_CODECS)
1428 case bluetooth::a2dp::CodecId::AAC:
1429 return A2DP_GetPacketTimestampAac(p_codec_info, p_data, p_timestamp);
1430 case bluetooth::a2dp::CodecId::APTX:
1431 return A2DP_VendorGetPacketTimestampAptx(p_codec_info, p_data, p_timestamp);
1432 case bluetooth::a2dp::CodecId::APTX_HD:
1433 return A2DP_VendorGetPacketTimestampAptxHd(p_codec_info, p_data, p_timestamp);
1434 case bluetooth::a2dp::CodecId::LDAC:
1435 return A2DP_VendorGetPacketTimestampLdac(p_codec_info, p_data, p_timestamp);
1436 case bluetooth::a2dp::CodecId::OPUS:
1437 return A2DP_VendorGetPacketTimestampOpus(p_codec_info, p_data, p_timestamp);
1438 #endif
1439 default:
1440 break;
1441 }
1442
1443 log::error("unsupported codec id 0x{:x}", codec_id.value());
1444 return false;
1445 }
1446
A2DP_BuildCodecHeader(const uint8_t * p_codec_info,BT_HDR * p_buf,uint16_t frames_per_packet)1447 bool A2DP_BuildCodecHeader(const uint8_t* p_codec_info, BT_HDR* p_buf, uint16_t frames_per_packet) {
1448 tA2DP_CODEC_TYPE codec_type = A2DP_GetCodecType(p_codec_info);
1449
1450 switch (codec_type) {
1451 case A2DP_MEDIA_CT_SBC:
1452 return A2DP_BuildCodecHeaderSbc(p_codec_info, p_buf, frames_per_packet);
1453 #if !defined(EXCLUDE_NONSTANDARD_CODECS)
1454 case A2DP_MEDIA_CT_AAC:
1455 return A2DP_BuildCodecHeaderAac(p_codec_info, p_buf, frames_per_packet);
1456 case A2DP_MEDIA_CT_NON_A2DP:
1457 return A2DP_VendorBuildCodecHeader(p_codec_info, p_buf, frames_per_packet);
1458 #endif
1459 default:
1460 break;
1461 }
1462
1463 log::error("unsupported codec type 0x{:x}", codec_type);
1464 return false;
1465 }
1466
A2DP_GetEncoderInterface(const uint8_t * p_codec_info)1467 const tA2DP_ENCODER_INTERFACE* A2DP_GetEncoderInterface(const uint8_t* p_codec_info) {
1468 tA2DP_CODEC_TYPE codec_type = A2DP_GetCodecType(p_codec_info);
1469
1470 if (::bluetooth::audio::a2dp::provider::supports_codec(A2DP_SourceCodecIndex(p_codec_info))) {
1471 return A2DP_GetEncoderInterfaceExt(p_codec_info);
1472 }
1473
1474 switch (codec_type) {
1475 case A2DP_MEDIA_CT_SBC:
1476 return A2DP_GetEncoderInterfaceSbc(p_codec_info);
1477 #if !defined(EXCLUDE_NONSTANDARD_CODECS)
1478 case A2DP_MEDIA_CT_AAC:
1479 return A2DP_GetEncoderInterfaceAac(p_codec_info);
1480 case A2DP_MEDIA_CT_NON_A2DP:
1481 return A2DP_VendorGetEncoderInterface(p_codec_info);
1482 #endif
1483 default:
1484 break;
1485 }
1486
1487 log::error("unsupported codec type 0x{:x}", codec_type);
1488 return NULL;
1489 }
1490
A2DP_GetDecoderInterface(const uint8_t * p_codec_info)1491 const tA2DP_DECODER_INTERFACE* A2DP_GetDecoderInterface(const uint8_t* p_codec_info) {
1492 tA2DP_CODEC_TYPE codec_type = A2DP_GetCodecType(p_codec_info);
1493
1494 switch (codec_type) {
1495 case A2DP_MEDIA_CT_SBC:
1496 return A2DP_GetDecoderInterfaceSbc(p_codec_info);
1497 #if !defined(EXCLUDE_NONSTANDARD_CODECS)
1498 case A2DP_MEDIA_CT_AAC:
1499 return A2DP_GetDecoderInterfaceAac(p_codec_info);
1500 case A2DP_MEDIA_CT_NON_A2DP:
1501 return A2DP_VendorGetDecoderInterface(p_codec_info);
1502 #endif
1503 default:
1504 break;
1505 }
1506
1507 log::error("unsupported codec type 0x{:x}", codec_type);
1508 return NULL;
1509 }
1510
A2DP_AdjustCodec(uint8_t * p_codec_info)1511 bool A2DP_AdjustCodec(uint8_t* p_codec_info) {
1512 tA2DP_CODEC_TYPE codec_type = A2DP_GetCodecType(p_codec_info);
1513
1514 switch (codec_type) {
1515 case A2DP_MEDIA_CT_SBC:
1516 return A2DP_AdjustCodecSbc(p_codec_info);
1517 #if !defined(EXCLUDE_NONSTANDARD_CODECS)
1518 case A2DP_MEDIA_CT_AAC:
1519 return A2DP_AdjustCodecAac(p_codec_info);
1520 case A2DP_MEDIA_CT_NON_A2DP:
1521 return A2DP_VendorAdjustCodec(p_codec_info);
1522 #endif
1523 default:
1524 break;
1525 }
1526
1527 log::error("unsupported codec type 0x{:x}", codec_type);
1528 return false;
1529 }
1530
A2DP_SourceCodecIndex(const uint8_t * p_codec_info)1531 btav_a2dp_codec_index_t A2DP_SourceCodecIndex(const uint8_t* p_codec_info) {
1532 tA2DP_CODEC_TYPE codec_type = A2DP_GetCodecType(p_codec_info);
1533
1534 auto ext_codec_index = bluetooth::audio::a2dp::provider::source_codec_index(p_codec_info);
1535 if (ext_codec_index.has_value()) {
1536 return ext_codec_index.value();
1537 }
1538
1539 switch (codec_type) {
1540 case A2DP_MEDIA_CT_SBC:
1541 return A2DP_SourceCodecIndexSbc(p_codec_info);
1542 #if !defined(EXCLUDE_NONSTANDARD_CODECS)
1543 case A2DP_MEDIA_CT_AAC:
1544 return A2DP_SourceCodecIndexAac(p_codec_info);
1545 case A2DP_MEDIA_CT_NON_A2DP:
1546 return A2DP_VendorSourceCodecIndex(p_codec_info);
1547 #endif
1548 default:
1549 break;
1550 }
1551
1552 log::error("unsupported codec type 0x{:x}", codec_type);
1553 return BTAV_A2DP_CODEC_INDEX_MAX;
1554 }
1555
A2DP_SinkCodecIndex(const uint8_t * p_codec_info)1556 btav_a2dp_codec_index_t A2DP_SinkCodecIndex(const uint8_t* p_codec_info) {
1557 tA2DP_CODEC_TYPE codec_type = A2DP_GetCodecType(p_codec_info);
1558
1559 auto ext_codec_index = bluetooth::audio::a2dp::provider::sink_codec_index(p_codec_info);
1560 if (ext_codec_index.has_value()) {
1561 return ext_codec_index.value();
1562 }
1563
1564 switch (codec_type) {
1565 case A2DP_MEDIA_CT_SBC:
1566 return A2DP_SinkCodecIndexSbc(p_codec_info);
1567 #if !defined(EXCLUDE_NONSTANDARD_CODECS)
1568 case A2DP_MEDIA_CT_AAC:
1569 return A2DP_SinkCodecIndexAac(p_codec_info);
1570 case A2DP_MEDIA_CT_NON_A2DP:
1571 return A2DP_VendorSinkCodecIndex(p_codec_info);
1572 #endif
1573 default:
1574 break;
1575 }
1576
1577 log::error("unsupported codec type 0x{:x}", codec_type);
1578 return BTAV_A2DP_CODEC_INDEX_MAX;
1579 }
1580
A2DP_CodecIndexStr(btav_a2dp_codec_index_t codec_index)1581 const char* A2DP_CodecIndexStr(btav_a2dp_codec_index_t codec_index) {
1582 if ((codec_index >= BTAV_A2DP_CODEC_INDEX_SOURCE_EXT_MIN &&
1583 codec_index < BTAV_A2DP_CODEC_INDEX_SOURCE_EXT_MAX) ||
1584 (codec_index >= BTAV_A2DP_CODEC_INDEX_SINK_EXT_MIN &&
1585 codec_index < BTAV_A2DP_CODEC_INDEX_SINK_EXT_MAX)) {
1586 auto codec_index_str = bluetooth::audio::a2dp::provider::codec_index_str(codec_index);
1587 if (codec_index_str.has_value()) {
1588 return codec_index_str.value();
1589 }
1590 }
1591
1592 switch (codec_index) {
1593 case BTAV_A2DP_CODEC_INDEX_SOURCE_SBC:
1594 return A2DP_CodecIndexStrSbc();
1595 case BTAV_A2DP_CODEC_INDEX_SINK_SBC:
1596 return A2DP_CodecIndexStrSbcSink();
1597 #if !defined(EXCLUDE_NONSTANDARD_CODECS)
1598 case BTAV_A2DP_CODEC_INDEX_SOURCE_AAC:
1599 return A2DP_CodecIndexStrAac();
1600 case BTAV_A2DP_CODEC_INDEX_SINK_AAC:
1601 return A2DP_CodecIndexStrAacSink();
1602 #endif
1603 default:
1604 break;
1605 }
1606
1607 #if !defined(EXCLUDE_NONSTANDARD_CODECS)
1608 if (codec_index < BTAV_A2DP_CODEC_INDEX_MAX) {
1609 return A2DP_VendorCodecIndexStr(codec_index);
1610 }
1611 #endif
1612
1613 return "UNKNOWN CODEC INDEX";
1614 }
1615
A2DP_InitCodecConfig(btav_a2dp_codec_index_t codec_index,AvdtpSepConfig * p_cfg)1616 bool A2DP_InitCodecConfig(btav_a2dp_codec_index_t codec_index, AvdtpSepConfig* p_cfg) {
1617 log::verbose("codec {}", A2DP_CodecIndexStr(codec_index));
1618
1619 /* Default: no content protection info */
1620 p_cfg->num_protect = 0;
1621 p_cfg->protect_info[0] = 0;
1622
1623 if (::bluetooth::audio::a2dp::provider::supports_codec(codec_index)) {
1624 return ::bluetooth::audio::a2dp::provider::codec_info(codec_index, nullptr, p_cfg->codec_info,
1625 nullptr);
1626 }
1627
1628 switch (codec_index) {
1629 case BTAV_A2DP_CODEC_INDEX_SOURCE_SBC:
1630 return A2DP_InitCodecConfigSbc(p_cfg);
1631 case BTAV_A2DP_CODEC_INDEX_SINK_SBC:
1632 return A2DP_InitCodecConfigSbcSink(p_cfg);
1633 #if !defined(EXCLUDE_NONSTANDARD_CODECS)
1634 case BTAV_A2DP_CODEC_INDEX_SOURCE_AAC:
1635 return A2DP_InitCodecConfigAac(p_cfg);
1636 case BTAV_A2DP_CODEC_INDEX_SINK_AAC:
1637 return A2DP_InitCodecConfigAacSink(p_cfg);
1638 #endif
1639 default:
1640 break;
1641 }
1642
1643 #if !defined(EXCLUDE_NONSTANDARD_CODECS)
1644 if (codec_index < BTAV_A2DP_CODEC_INDEX_MAX) {
1645 return A2DP_VendorInitCodecConfig(codec_index, p_cfg);
1646 }
1647 #endif
1648
1649 return false;
1650 }
1651
A2DP_CodecInfoString(const uint8_t * p_codec_info)1652 std::string A2DP_CodecInfoString(const uint8_t* p_codec_info) {
1653 tA2DP_CODEC_TYPE codec_type = A2DP_GetCodecType(p_codec_info);
1654
1655 switch (codec_type) {
1656 case A2DP_MEDIA_CT_SBC:
1657 return A2DP_CodecInfoStringSbc(p_codec_info);
1658 #if !defined(EXCLUDE_NONSTANDARD_CODECS)
1659 case A2DP_MEDIA_CT_AAC:
1660 return A2DP_CodecInfoStringAac(p_codec_info);
1661 case A2DP_MEDIA_CT_NON_A2DP:
1662 return A2DP_VendorCodecInfoString(p_codec_info);
1663 #endif
1664 default:
1665 break;
1666 }
1667
1668 return std::format("Unsupported codec type: {:x}", codec_type);
1669 }
1670
A2DP_GetEecoderEffectiveFrameSize(const uint8_t * p_codec_info)1671 int A2DP_GetEecoderEffectiveFrameSize(const uint8_t* p_codec_info) {
1672 const tA2DP_ENCODER_INTERFACE* a2dp_encoder_interface = A2DP_GetEncoderInterface(p_codec_info);
1673 return a2dp_encoder_interface ? a2dp_encoder_interface->get_effective_frame_size() : 0;
1674 }
1675
A2DP_VendorCodecGetVendorId(const uint8_t * p_codec_info)1676 uint32_t A2DP_VendorCodecGetVendorId(const uint8_t* p_codec_info) {
1677 const uint8_t* p = &p_codec_info[A2DP_VENDOR_CODEC_VENDOR_ID_START_IDX];
1678
1679 uint32_t vendor_id = (p[0] & 0x000000ff) | ((p[1] << 8) & 0x0000ff00) |
1680 ((p[2] << 16) & 0x00ff0000) | ((p[3] << 24) & 0xff000000);
1681
1682 return vendor_id;
1683 }
1684
A2DP_VendorCodecGetCodecId(const uint8_t * p_codec_info)1685 uint16_t A2DP_VendorCodecGetCodecId(const uint8_t* p_codec_info) {
1686 const uint8_t* p = &p_codec_info[A2DP_VENDOR_CODEC_CODEC_ID_START_IDX];
1687
1688 uint16_t codec_id = (p[0] & 0x00ff) | ((p[1] << 8) & 0xff00);
1689
1690 return codec_id;
1691 }
1692