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