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