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