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