• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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