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