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