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