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