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