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.
43static 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
51A2dpCodecConfig::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
76A2dpCodecConfig::~A2dpCodecConfig() {}
77
78void 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
88void 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
98A2dpCodecConfig* 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
138bool A2dpCodecConfig::isValid() const { return true; }
139
140bool 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
152btav_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
159btav_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
166btav_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
173btav_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
180btav_a2dp_codec_config_t A2dpCodecConfig::getCodecUserConfig() {
181  std::lock_guard<std::recursive_mutex> lock(codec_mutex_);
182
183  return codec_user_config_;
184}
185
186btav_a2dp_codec_config_t A2dpCodecConfig::getCodecAudioConfig() {
187  std::lock_guard<std::recursive_mutex> lock(codec_mutex_);
188
189  return codec_audio_config_;
190}
191
192uint8_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
208bool 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
221bool 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
286bool 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
295std::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
311std::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
348std::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
373std::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
394void 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//
416static 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
423A2dpCodecs::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
432A2dpCodecs::~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
443bool 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
505A2dpCodecConfig* 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
516bool 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
533bool 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
645fail:
646  current_codec_config_ = last_codec_config;
647  return false;
648}
649
650bool 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
676bool 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
753fail:
754  current_codec_config_ = last_codec_config;
755  return false;
756}
757
758bool 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
796void 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
813tA2DP_CODEC_TYPE A2DP_GetCodecType(const uint8_t* p_codec_info) {
814  return (tA2DP_CODEC_TYPE)(p_codec_info[AVDT_CODEC_TYPE_INDEX]);
815}
816
817bool 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
836bool 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
855bool 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
874bool 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
893bool 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
913bool 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
933void A2DP_InitDefaultCodec(uint8_t* p_codec_info) {
934  A2DP_InitDefaultCodecSbc(p_codec_info);
935}
936
937tA2DP_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
958bool 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
967uint8_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
972const 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
992bool 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
1014bool 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
1036int 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
1056int 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
1076int 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
1096int 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
1120bool 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
1139bool 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
1159const 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
1180bool 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
1198btav_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
1218const 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
1236bool 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
1262bool 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