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