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  * Vendor Specific A2DP Codecs Support
     19  */
     20 
     21 #define LOG_TAG "a2dp_vendor"
     22 
     23 #include "a2dp_vendor.h"
     24 #include "a2dp_vendor_aptx.h"
     25 #include "a2dp_vendor_aptx_hd.h"
     26 #include "a2dp_vendor_ldac.h"
     27 #include "bt_target.h"
     28 #include "osi/include/log.h"
     29 #include "osi/include/osi.h"
     30 
     31 bool A2DP_IsVendorSourceCodecValid(const uint8_t* p_codec_info) {
     32   uint32_t vendor_id = A2DP_VendorCodecGetVendorId(p_codec_info);
     33   uint16_t codec_id = A2DP_VendorCodecGetCodecId(p_codec_info);
     34 
     35   // Check for aptX
     36   if (vendor_id == A2DP_APTX_VENDOR_ID &&
     37       codec_id == A2DP_APTX_CODEC_ID_BLUETOOTH) {
     38     return A2DP_IsVendorSourceCodecValidAptx(p_codec_info);
     39   }
     40 
     41   // Check for aptX-HD
     42   if (vendor_id == A2DP_APTX_HD_VENDOR_ID &&
     43       codec_id == A2DP_APTX_HD_CODEC_ID_BLUETOOTH) {
     44     return A2DP_IsVendorSourceCodecValidAptxHd(p_codec_info);
     45   }
     46 
     47   // Check for LDAC
     48   if (vendor_id == A2DP_LDAC_VENDOR_ID && codec_id == A2DP_LDAC_CODEC_ID) {
     49     return A2DP_IsVendorSourceCodecValidLdac(p_codec_info);
     50   }
     51 
     52   // Add checks based on <vendor_id, codec_id>
     53 
     54   return false;
     55 }
     56 
     57 bool A2DP_IsVendorSinkCodecValid(UNUSED_ATTR const uint8_t* p_codec_info) {
     58   // uint32_t vendor_id = A2DP_VendorCodecGetVendorId(p_codec_info);
     59   // uint16_t codec_id = A2DP_VendorCodecGetCodecId(p_codec_info);
     60 
     61   // Add checks based on <vendor_id, codec_id>
     62   // NOTE: Should be done only for local Sink codecs.
     63 
     64   return false;
     65 }
     66 
     67 bool A2DP_IsVendorPeerSourceCodecValid(
     68     UNUSED_ATTR const uint8_t* p_codec_info) {
     69   // uint32_t vendor_id = A2DP_VendorCodecGetVendorId(p_codec_info);
     70   // uint16_t codec_id = A2DP_VendorCodecGetCodecId(p_codec_info);
     71 
     72   // Add checks based on <vendor_id, codec_id>
     73   // NOTE: Should be done only for local Sink codecs.
     74 
     75   return false;
     76 }
     77 
     78 bool A2DP_IsVendorPeerSinkCodecValid(const uint8_t* p_codec_info) {
     79   uint32_t vendor_id = A2DP_VendorCodecGetVendorId(p_codec_info);
     80   uint16_t codec_id = A2DP_VendorCodecGetCodecId(p_codec_info);
     81 
     82   // Check for aptX
     83   if (vendor_id == A2DP_APTX_VENDOR_ID &&
     84       codec_id == A2DP_APTX_CODEC_ID_BLUETOOTH) {
     85     return A2DP_IsVendorPeerSinkCodecValidAptx(p_codec_info);
     86   }
     87 
     88   // Check for aptX-HD
     89   if (vendor_id == A2DP_APTX_HD_VENDOR_ID &&
     90       codec_id == A2DP_APTX_HD_CODEC_ID_BLUETOOTH) {
     91     return A2DP_IsVendorPeerSinkCodecValidAptxHd(p_codec_info);
     92   }
     93 
     94   // Check for LDAC
     95   if (vendor_id == A2DP_LDAC_VENDOR_ID && codec_id == A2DP_LDAC_CODEC_ID) {
     96     return A2DP_IsVendorPeerSinkCodecValidLdac(p_codec_info);
     97   }
     98 
     99   // Add checks based on <vendor_id, codec_id>
    100 
    101   return false;
    102 }
    103 
    104 bool A2DP_IsVendorSinkCodecSupported(UNUSED_ATTR const uint8_t* p_codec_info) {
    105   // uint32_t vendor_id = A2DP_VendorCodecGetVendorId(p_codec_info);
    106   // uint16_t codec_id = A2DP_VendorCodecGetCodecId(p_codec_info);
    107 
    108   // Add checks based on <vendor_id, codec_id>
    109   // NOTE: Should be done only for local Sink codecs.
    110 
    111   return false;
    112 }
    113 
    114 bool A2DP_IsVendorPeerSourceCodecSupported(
    115     UNUSED_ATTR const uint8_t* p_codec_info) {
    116   // uint32_t vendor_id = A2DP_VendorCodecGetVendorId(p_codec_info);
    117   // uint16_t codec_id = A2DP_VendorCodecGetCodecId(p_codec_info);
    118 
    119   // Add checks based on <vendor_id, codec_id> and peer codec capabilities
    120   // NOTE: Should be done only for local Sink codecs.
    121 
    122   return false;
    123 }
    124 
    125 tA2DP_STATUS A2DP_VendorBuildSrc2SinkConfig(
    126     UNUSED_ATTR const uint8_t* p_src_cap, UNUSED_ATTR uint8_t* p_pref_cfg) {
    127   // uint32_t vendor_id = A2DP_VendorCodecGetVendorId(p_codec_info);
    128   // uint16_t codec_id = A2DP_VendorCodecGetCodecId(p_codec_info);
    129 
    130   // Add checks based on <vendor_id, codec_id>
    131   // NOTE: Should be done only for local Sink codecs.
    132 
    133   return A2DP_NS_CODEC_TYPE;
    134 }
    135 
    136 uint32_t A2DP_VendorCodecGetVendorId(const uint8_t* p_codec_info) {
    137   const uint8_t* p = &p_codec_info[A2DP_VENDOR_CODEC_VENDOR_ID_START_IDX];
    138 
    139   uint32_t vendor_id = (p[0] & 0x000000ff) | ((p[1] << 8) & 0x0000ff00) |
    140                        ((p[2] << 16) & 0x00ff0000) |
    141                        ((p[3] << 24) & 0xff000000);
    142 
    143   return vendor_id;
    144 }
    145 
    146 uint16_t A2DP_VendorCodecGetCodecId(const uint8_t* p_codec_info) {
    147   const uint8_t* p = &p_codec_info[A2DP_VENDOR_CODEC_CODEC_ID_START_IDX];
    148 
    149   uint16_t codec_id = (p[0] & 0x00ff) | ((p[1] << 8) & 0xff00);
    150 
    151   return codec_id;
    152 }
    153 
    154 bool A2DP_VendorUsesRtpHeader(bool content_protection_enabled,
    155                               const uint8_t* p_codec_info) {
    156   uint32_t vendor_id = A2DP_VendorCodecGetVendorId(p_codec_info);
    157   uint16_t codec_id = A2DP_VendorCodecGetCodecId(p_codec_info);
    158 
    159   // Check for aptX
    160   if (vendor_id == A2DP_APTX_VENDOR_ID &&
    161       codec_id == A2DP_APTX_CODEC_ID_BLUETOOTH) {
    162     return A2DP_VendorUsesRtpHeaderAptx(content_protection_enabled,
    163                                         p_codec_info);
    164   }
    165 
    166   // Check for aptX-HD
    167   if (vendor_id == A2DP_APTX_HD_VENDOR_ID &&
    168       codec_id == A2DP_APTX_HD_CODEC_ID_BLUETOOTH) {
    169     return A2DP_VendorUsesRtpHeaderAptxHd(content_protection_enabled,
    170                                           p_codec_info);
    171   }
    172 
    173   // Check for LDAC
    174   if (vendor_id == A2DP_LDAC_VENDOR_ID && codec_id == A2DP_LDAC_CODEC_ID) {
    175     return A2DP_VendorUsesRtpHeaderLdac(content_protection_enabled,
    176                                         p_codec_info);
    177   }
    178 
    179   // Add checks based on <content_protection_enabled, vendor_id, codec_id>
    180 
    181   return true;
    182 }
    183 
    184 const char* A2DP_VendorCodecName(UNUSED_ATTR const uint8_t* p_codec_info) {
    185   uint32_t vendor_id = A2DP_VendorCodecGetVendorId(p_codec_info);
    186   uint16_t codec_id = A2DP_VendorCodecGetCodecId(p_codec_info);
    187 
    188   // Check for aptX
    189   if (vendor_id == A2DP_APTX_VENDOR_ID &&
    190       codec_id == A2DP_APTX_CODEC_ID_BLUETOOTH) {
    191     return A2DP_VendorCodecNameAptx(p_codec_info);
    192   }
    193 
    194   // Check for aptX-HD
    195   if (vendor_id == A2DP_APTX_HD_VENDOR_ID &&
    196       codec_id == A2DP_APTX_HD_CODEC_ID_BLUETOOTH) {
    197     return A2DP_VendorCodecNameAptxHd(p_codec_info);
    198   }
    199 
    200   // Check for LDAC
    201   if (vendor_id == A2DP_LDAC_VENDOR_ID && codec_id == A2DP_LDAC_CODEC_ID) {
    202     return A2DP_VendorCodecNameLdac(p_codec_info);
    203   }
    204 
    205   // Add checks based on <vendor_id, codec_id>
    206 
    207   return "UNKNOWN VENDOR CODEC";
    208 }
    209 
    210 bool A2DP_VendorCodecTypeEquals(const uint8_t* p_codec_info_a,
    211                                 const uint8_t* p_codec_info_b) {
    212   tA2DP_CODEC_TYPE codec_type_a = A2DP_GetCodecType(p_codec_info_a);
    213   tA2DP_CODEC_TYPE codec_type_b = A2DP_GetCodecType(p_codec_info_b);
    214 
    215   if ((codec_type_a != codec_type_b) ||
    216       (codec_type_a != A2DP_MEDIA_CT_NON_A2DP)) {
    217     return false;
    218   }
    219 
    220   uint32_t vendor_id_a = A2DP_VendorCodecGetVendorId(p_codec_info_a);
    221   uint16_t codec_id_a = A2DP_VendorCodecGetCodecId(p_codec_info_a);
    222   uint32_t vendor_id_b = A2DP_VendorCodecGetVendorId(p_codec_info_b);
    223   uint16_t codec_id_b = A2DP_VendorCodecGetCodecId(p_codec_info_b);
    224 
    225   if (vendor_id_a != vendor_id_b || codec_id_a != codec_id_b) return false;
    226 
    227   // Check for aptX
    228   if (vendor_id_a == A2DP_APTX_VENDOR_ID &&
    229       codec_id_a == A2DP_APTX_CODEC_ID_BLUETOOTH) {
    230     return A2DP_VendorCodecTypeEqualsAptx(p_codec_info_a, p_codec_info_b);
    231   }
    232 
    233   // Check for aptX-HD
    234   if (vendor_id_a == A2DP_APTX_HD_VENDOR_ID &&
    235       codec_id_a == A2DP_APTX_HD_CODEC_ID_BLUETOOTH) {
    236     return A2DP_VendorCodecTypeEqualsAptxHd(p_codec_info_a, p_codec_info_b);
    237   }
    238 
    239   // Check for LDAC
    240   if (vendor_id_a == A2DP_LDAC_VENDOR_ID && codec_id_a == A2DP_LDAC_CODEC_ID) {
    241     return A2DP_VendorCodecTypeEqualsLdac(p_codec_info_a, p_codec_info_b);
    242   }
    243 
    244   // OPTIONAL: Add extra vendor-specific checks based on the
    245   // vendor-specific data stored in "p_codec_info_a" and "p_codec_info_b".
    246 
    247   return true;
    248 }
    249 
    250 bool A2DP_VendorCodecEquals(const uint8_t* p_codec_info_a,
    251                             const uint8_t* p_codec_info_b) {
    252   tA2DP_CODEC_TYPE codec_type_a = A2DP_GetCodecType(p_codec_info_a);
    253   tA2DP_CODEC_TYPE codec_type_b = A2DP_GetCodecType(p_codec_info_b);
    254 
    255   if ((codec_type_a != codec_type_b) ||
    256       (codec_type_a != A2DP_MEDIA_CT_NON_A2DP)) {
    257     return false;
    258   }
    259 
    260   uint32_t vendor_id_a = A2DP_VendorCodecGetVendorId(p_codec_info_a);
    261   uint16_t codec_id_a = A2DP_VendorCodecGetCodecId(p_codec_info_a);
    262   uint32_t vendor_id_b = A2DP_VendorCodecGetVendorId(p_codec_info_b);
    263   uint16_t codec_id_b = A2DP_VendorCodecGetCodecId(p_codec_info_b);
    264 
    265   if ((vendor_id_a != vendor_id_b) || (codec_id_a != codec_id_b)) return false;
    266 
    267   // Check for aptX
    268   if (vendor_id_a == A2DP_APTX_VENDOR_ID &&
    269       codec_id_a == A2DP_APTX_CODEC_ID_BLUETOOTH) {
    270     return A2DP_VendorCodecEqualsAptx(p_codec_info_a, p_codec_info_b);
    271   }
    272 
    273   // Check for aptX-HD
    274   if (vendor_id_a == A2DP_APTX_HD_VENDOR_ID &&
    275       codec_id_a == A2DP_APTX_HD_CODEC_ID_BLUETOOTH) {
    276     return A2DP_VendorCodecEqualsAptxHd(p_codec_info_a, p_codec_info_b);
    277   }
    278 
    279   // Check for LDAC
    280   if (vendor_id_a == A2DP_LDAC_VENDOR_ID && codec_id_a == A2DP_LDAC_CODEC_ID) {
    281     return A2DP_VendorCodecEqualsLdac(p_codec_info_a, p_codec_info_b);
    282   }
    283 
    284   // Add extra vendor-specific checks based on the
    285   // vendor-specific data stored in "p_codec_info_a" and "p_codec_info_b".
    286 
    287   return false;
    288 }
    289 
    290 int A2DP_VendorGetTrackSampleRate(const uint8_t* p_codec_info) {
    291   uint32_t vendor_id = A2DP_VendorCodecGetVendorId(p_codec_info);
    292   uint16_t codec_id = A2DP_VendorCodecGetCodecId(p_codec_info);
    293 
    294   // Check for aptX
    295   if (vendor_id == A2DP_APTX_VENDOR_ID &&
    296       codec_id == A2DP_APTX_CODEC_ID_BLUETOOTH) {
    297     return A2DP_VendorGetTrackSampleRateAptx(p_codec_info);
    298   }
    299 
    300   // Check for aptX-HD
    301   if (vendor_id == A2DP_APTX_HD_VENDOR_ID &&
    302       codec_id == A2DP_APTX_HD_CODEC_ID_BLUETOOTH) {
    303     return A2DP_VendorGetTrackSampleRateAptxHd(p_codec_info);
    304   }
    305 
    306   // Check for LDAC
    307   if (vendor_id == A2DP_LDAC_VENDOR_ID && codec_id == A2DP_LDAC_CODEC_ID) {
    308     return A2DP_VendorGetTrackSampleRateLdac(p_codec_info);
    309   }
    310 
    311   // Add checks based on <vendor_id, codec_id>
    312 
    313   return -1;
    314 }
    315 
    316 int A2DP_VendorGetTrackBitsPerSample(const uint8_t* p_codec_info) {
    317   uint32_t vendor_id = A2DP_VendorCodecGetVendorId(p_codec_info);
    318   uint16_t codec_id = A2DP_VendorCodecGetCodecId(p_codec_info);
    319 
    320   // Check for aptX
    321   if (vendor_id == A2DP_APTX_VENDOR_ID &&
    322       codec_id == A2DP_APTX_CODEC_ID_BLUETOOTH) {
    323     return A2DP_VendorGetTrackBitsPerSampleAptx(p_codec_info);
    324   }
    325 
    326   // Check for aptX-HD
    327   if (vendor_id == A2DP_APTX_HD_VENDOR_ID &&
    328       codec_id == A2DP_APTX_HD_CODEC_ID_BLUETOOTH) {
    329     return A2DP_VendorGetTrackBitsPerSampleAptxHd(p_codec_info);
    330   }
    331 
    332   // Check for LDAC
    333   if (vendor_id == A2DP_LDAC_VENDOR_ID && codec_id == A2DP_LDAC_CODEC_ID) {
    334     return A2DP_VendorGetTrackBitsPerSampleLdac(p_codec_info);
    335   }
    336 
    337   // Add checks based on <vendor_id, codec_id>
    338 
    339   return -1;
    340 }
    341 
    342 int A2DP_VendorGetTrackChannelCount(const uint8_t* p_codec_info) {
    343   uint32_t vendor_id = A2DP_VendorCodecGetVendorId(p_codec_info);
    344   uint16_t codec_id = A2DP_VendorCodecGetCodecId(p_codec_info);
    345 
    346   // Check for aptX
    347   if (vendor_id == A2DP_APTX_VENDOR_ID &&
    348       codec_id == A2DP_APTX_CODEC_ID_BLUETOOTH) {
    349     return A2DP_VendorGetTrackChannelCountAptx(p_codec_info);
    350   }
    351 
    352   // Check for aptX-HD
    353   if (vendor_id == A2DP_APTX_HD_VENDOR_ID &&
    354       codec_id == A2DP_APTX_HD_CODEC_ID_BLUETOOTH) {
    355     return A2DP_VendorGetTrackChannelCountAptxHd(p_codec_info);
    356   }
    357 
    358   // Check for LDAC
    359   if (vendor_id == A2DP_LDAC_VENDOR_ID && codec_id == A2DP_LDAC_CODEC_ID) {
    360     return A2DP_VendorGetTrackChannelCountLdac(p_codec_info);
    361   }
    362 
    363   // Add checks based on <vendor_id, codec_id>
    364 
    365   return -1;
    366 }
    367 
    368 int A2DP_VendorGetSinkTrackChannelType(
    369     UNUSED_ATTR const uint8_t* p_codec_info) {
    370   // uint32_t vendor_id = A2DP_VendorCodecGetVendorId(p_codec_info);
    371   // uint16_t codec_id = A2DP_VendorCodecGetCodecId(p_codec_info);
    372 
    373   // Add checks based on <vendor_id, codec_id>
    374   // NOTE: Should be done only for local Sink codecs.
    375 
    376   return -1;
    377 }
    378 
    379 int A2DP_VendorGetSinkFramesCountToProcess(
    380     UNUSED_ATTR uint64_t time_interval_ms,
    381     UNUSED_ATTR const uint8_t* p_codec_info) {
    382   // uint32_t vendor_id = A2DP_VendorCodecGetVendorId(p_codec_info);
    383   // uint16_t codec_id = A2DP_VendorCodecGetCodecId(p_codec_info);
    384 
    385   // Add checks based on <vendor_id, codec_id>
    386   // NOTE: Should be done only for local Sink codecs.
    387 
    388   return -1;
    389 }
    390 
    391 bool A2DP_VendorGetPacketTimestamp(const uint8_t* p_codec_info,
    392                                    const uint8_t* p_data,
    393                                    uint32_t* p_timestamp) {
    394   uint32_t vendor_id = A2DP_VendorCodecGetVendorId(p_codec_info);
    395   uint16_t codec_id = A2DP_VendorCodecGetCodecId(p_codec_info);
    396 
    397   // Check for aptX
    398   if (vendor_id == A2DP_APTX_VENDOR_ID &&
    399       codec_id == A2DP_APTX_CODEC_ID_BLUETOOTH) {
    400     return A2DP_VendorGetPacketTimestampAptx(p_codec_info, p_data, p_timestamp);
    401   }
    402 
    403   // Check for aptX-HD
    404   if (vendor_id == A2DP_APTX_HD_VENDOR_ID &&
    405       codec_id == A2DP_APTX_HD_CODEC_ID_BLUETOOTH) {
    406     return A2DP_VendorGetPacketTimestampAptxHd(p_codec_info, p_data,
    407                                                p_timestamp);
    408   }
    409 
    410   // Check for LDAC
    411   if (vendor_id == A2DP_LDAC_VENDOR_ID && codec_id == A2DP_LDAC_CODEC_ID) {
    412     return A2DP_VendorGetPacketTimestampLdac(p_codec_info, p_data, p_timestamp);
    413   }
    414 
    415   // Add checks based on <vendor_id, codec_id>
    416 
    417   return false;
    418 }
    419 
    420 bool A2DP_VendorBuildCodecHeader(const uint8_t* p_codec_info, BT_HDR* p_buf,
    421                                  uint16_t frames_per_packet) {
    422   uint32_t vendor_id = A2DP_VendorCodecGetVendorId(p_codec_info);
    423   uint16_t codec_id = A2DP_VendorCodecGetCodecId(p_codec_info);
    424 
    425   // Check for aptX
    426   if (vendor_id == A2DP_APTX_VENDOR_ID &&
    427       codec_id == A2DP_APTX_CODEC_ID_BLUETOOTH) {
    428     return A2DP_VendorBuildCodecHeaderAptx(p_codec_info, p_buf,
    429                                            frames_per_packet);
    430   }
    431 
    432   // Check for aptX-HD
    433   if (vendor_id == A2DP_APTX_HD_VENDOR_ID &&
    434       codec_id == A2DP_APTX_HD_CODEC_ID_BLUETOOTH) {
    435     return A2DP_VendorBuildCodecHeaderAptxHd(p_codec_info, p_buf,
    436                                              frames_per_packet);
    437   }
    438 
    439   // Check for LDAC
    440   if (vendor_id == A2DP_LDAC_VENDOR_ID && codec_id == A2DP_LDAC_CODEC_ID) {
    441     return A2DP_VendorBuildCodecHeaderLdac(p_codec_info, p_buf,
    442                                            frames_per_packet);
    443   }
    444 
    445   // Add checks based on <vendor_id, codec_id>
    446 
    447   return false;
    448 }
    449 
    450 const tA2DP_ENCODER_INTERFACE* A2DP_VendorGetEncoderInterface(
    451     const uint8_t* p_codec_info) {
    452   uint32_t vendor_id = A2DP_VendorCodecGetVendorId(p_codec_info);
    453   uint16_t codec_id = A2DP_VendorCodecGetCodecId(p_codec_info);
    454 
    455   // Check for aptX
    456   if (vendor_id == A2DP_APTX_VENDOR_ID &&
    457       codec_id == A2DP_APTX_CODEC_ID_BLUETOOTH) {
    458     return A2DP_VendorGetEncoderInterfaceAptx(p_codec_info);
    459   }
    460 
    461   // Check for aptX-HD
    462   if (vendor_id == A2DP_APTX_HD_VENDOR_ID &&
    463       codec_id == A2DP_APTX_HD_CODEC_ID_BLUETOOTH) {
    464     return A2DP_VendorGetEncoderInterfaceAptxHd(p_codec_info);
    465   }
    466 
    467   // Check for LDAC
    468   if (vendor_id == A2DP_LDAC_VENDOR_ID && codec_id == A2DP_LDAC_CODEC_ID) {
    469     return A2DP_VendorGetEncoderInterfaceLdac(p_codec_info);
    470   }
    471 
    472   // Add checks based on <vendor_id, codec_id>
    473 
    474   return NULL;
    475 }
    476 
    477 bool A2DP_VendorAdjustCodec(uint8_t* p_codec_info) {
    478   uint32_t vendor_id = A2DP_VendorCodecGetVendorId(p_codec_info);
    479   uint16_t codec_id = A2DP_VendorCodecGetCodecId(p_codec_info);
    480 
    481   // Check for aptX
    482   if (vendor_id == A2DP_APTX_VENDOR_ID &&
    483       codec_id == A2DP_APTX_CODEC_ID_BLUETOOTH) {
    484     return A2DP_VendorAdjustCodecAptx(p_codec_info);
    485   }
    486 
    487   // Check for aptX-HD
    488   if (vendor_id == A2DP_APTX_HD_VENDOR_ID &&
    489       codec_id == A2DP_APTX_HD_CODEC_ID_BLUETOOTH) {
    490     return A2DP_VendorAdjustCodecAptxHd(p_codec_info);
    491   }
    492 
    493   // Check for LDAC
    494   if (vendor_id == A2DP_LDAC_VENDOR_ID && codec_id == A2DP_LDAC_CODEC_ID) {
    495     return A2DP_VendorAdjustCodecLdac(p_codec_info);
    496   }
    497 
    498   // Add checks based on <vendor_id, codec_id>
    499 
    500   return false;
    501 }
    502 
    503 btav_a2dp_codec_index_t A2DP_VendorSourceCodecIndex(
    504     const uint8_t* p_codec_info) {
    505   uint32_t vendor_id = A2DP_VendorCodecGetVendorId(p_codec_info);
    506   uint16_t codec_id = A2DP_VendorCodecGetCodecId(p_codec_info);
    507 
    508   // Check for aptX
    509   if (vendor_id == A2DP_APTX_VENDOR_ID &&
    510       codec_id == A2DP_APTX_CODEC_ID_BLUETOOTH) {
    511     return A2DP_VendorSourceCodecIndexAptx(p_codec_info);
    512   }
    513 
    514   // Check for aptX-HD
    515   if (vendor_id == A2DP_APTX_HD_VENDOR_ID &&
    516       codec_id == A2DP_APTX_HD_CODEC_ID_BLUETOOTH) {
    517     return A2DP_VendorSourceCodecIndexAptxHd(p_codec_info);
    518   }
    519 
    520   // Check for LDAC
    521   if (vendor_id == A2DP_LDAC_VENDOR_ID && codec_id == A2DP_LDAC_CODEC_ID) {
    522     return A2DP_VendorSourceCodecIndexLdac(p_codec_info);
    523   }
    524 
    525   // Add checks based on <vendor_id, codec_id>
    526 
    527   return BTAV_A2DP_CODEC_INDEX_MAX;
    528 }
    529 
    530 const char* A2DP_VendorCodecIndexStr(btav_a2dp_codec_index_t codec_index) {
    531   // Add checks based on codec_index
    532   switch (codec_index) {
    533     case BTAV_A2DP_CODEC_INDEX_SOURCE_SBC:
    534     case BTAV_A2DP_CODEC_INDEX_SINK_SBC:
    535     case BTAV_A2DP_CODEC_INDEX_SOURCE_AAC:
    536       break;  // These are not vendor-specific codecs
    537     case BTAV_A2DP_CODEC_INDEX_SOURCE_APTX:
    538       return A2DP_VendorCodecIndexStrAptx();
    539     case BTAV_A2DP_CODEC_INDEX_SOURCE_APTX_HD:
    540       return A2DP_VendorCodecIndexStrAptxHd();
    541     case BTAV_A2DP_CODEC_INDEX_SOURCE_LDAC:
    542       return A2DP_VendorCodecIndexStrLdac();
    543     // Add a switch statement for each vendor-specific codec
    544     case BTAV_A2DP_CODEC_INDEX_MAX:
    545       break;
    546   }
    547 
    548   return "UNKNOWN CODEC INDEX";
    549 }
    550 
    551 bool A2DP_VendorInitCodecConfig(btav_a2dp_codec_index_t codec_index,
    552                                 tAVDT_CFG* p_cfg) {
    553   // Add checks based on codec_index
    554   switch (codec_index) {
    555     case BTAV_A2DP_CODEC_INDEX_SOURCE_SBC:
    556     case BTAV_A2DP_CODEC_INDEX_SINK_SBC:
    557     case BTAV_A2DP_CODEC_INDEX_SOURCE_AAC:
    558       break;  // These are not vendor-specific codecs
    559     case BTAV_A2DP_CODEC_INDEX_SOURCE_APTX:
    560       return A2DP_VendorInitCodecConfigAptx(p_cfg);
    561     case BTAV_A2DP_CODEC_INDEX_SOURCE_APTX_HD:
    562       return A2DP_VendorInitCodecConfigAptxHd(p_cfg);
    563     case BTAV_A2DP_CODEC_INDEX_SOURCE_LDAC:
    564       return A2DP_VendorInitCodecConfigLdac(p_cfg);
    565     // Add a switch statement for each vendor-specific codec
    566     case BTAV_A2DP_CODEC_INDEX_MAX:
    567       break;
    568   }
    569 
    570   return false;
    571 }
    572