1 /*
2  * Copyright 2022 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 #define LOG_TAG "BTAudioCodecStatusAIDL"
18 
19 #include "codec_status_aidl.h"
20 
21 #include <bluetooth/log.h>
22 
23 #include <unordered_set>
24 #include <vector>
25 
26 #include "a2dp_aac_constants.h"
27 #include "a2dp_sbc_constants.h"
28 #include "a2dp_vendor_aptx_constants.h"
29 #include "a2dp_vendor_aptx_hd_constants.h"
30 #include "a2dp_vendor_ldac_constants.h"
31 #include "bta/av/bta_av_int.h"
32 #include "client_interface_aidl.h"
33 
34 namespace bluetooth {
35 namespace audio {
36 namespace aidl {
37 namespace codec {
38 
39 using ::aidl::android::hardware::bluetooth::audio::AacCapabilities;
40 using ::aidl::android::hardware::bluetooth::audio::AacConfiguration;
41 using ::aidl::android::hardware::bluetooth::audio::AacObjectType;
42 using ::aidl::android::hardware::bluetooth::audio::AptxCapabilities;
43 using ::aidl::android::hardware::bluetooth::audio::AptxConfiguration;
44 using ::aidl::android::hardware::bluetooth::audio::AudioCapabilities;
45 using ::aidl::android::hardware::bluetooth::audio::ChannelMode;
46 using ::aidl::android::hardware::bluetooth::audio::CodecCapabilities;
47 using ::aidl::android::hardware::bluetooth::audio::CodecType;
48 using ::aidl::android::hardware::bluetooth::audio::LdacCapabilities;
49 using ::aidl::android::hardware::bluetooth::audio::LdacChannelMode;
50 using ::aidl::android::hardware::bluetooth::audio::LdacConfiguration;
51 using ::aidl::android::hardware::bluetooth::audio::LdacQualityIndex;
52 using ::aidl::android::hardware::bluetooth::audio::OpusCapabilities;
53 using ::aidl::android::hardware::bluetooth::audio::OpusConfiguration;
54 using ::aidl::android::hardware::bluetooth::audio::SbcAllocMethod;
55 using ::aidl::android::hardware::bluetooth::audio::SbcCapabilities;
56 using ::aidl::android::hardware::bluetooth::audio::SbcChannelMode;
57 using ::aidl::android::hardware::bluetooth::audio::SbcConfiguration;
58 
59 namespace {
60 
61 // capabilities from BluetoothAudioSinkClientInterface::GetAudioCapabilities()
62 std::vector<AudioCapabilities> audio_hal_capabilities(0);
63 // capabilities that audio HAL supports and frameworks / Bluetooth SoC / runtime
64 // preference would like to use.
65 std::vector<AudioCapabilities> offloading_preference(0);
66 
67 template <typename T>
68 struct identity {
69   typedef T type;
70 };
71 
72 template <class T>
ContainedInVector(const std::vector<T> & vector,const typename identity<T>::type & target)73 bool ContainedInVector(const std::vector<T>& vector,
74                        const typename identity<T>::type& target) {
75   return std::find(vector.begin(), vector.end(), target) != vector.end();
76 }
77 
sbc_offloading_capability_match(const SbcCapabilities & sbc_capability,const SbcConfiguration & sbc_config)78 bool sbc_offloading_capability_match(const SbcCapabilities& sbc_capability,
79                                      const SbcConfiguration& sbc_config) {
80   if (!ContainedInVector(sbc_capability.channelMode, sbc_config.channelMode) ||
81       !ContainedInVector(sbc_capability.allocMethod, sbc_config.allocMethod) ||
82       !ContainedInVector(sbc_capability.blockLength, sbc_config.blockLength) ||
83       !ContainedInVector(sbc_capability.numSubbands, sbc_config.numSubbands) ||
84       !ContainedInVector(sbc_capability.bitsPerSample,
85                          sbc_config.bitsPerSample) ||
86       !ContainedInVector(sbc_capability.sampleRateHz,
87                          sbc_config.sampleRateHz) ||
88       (sbc_config.minBitpool < sbc_capability.minBitpool ||
89        sbc_config.maxBitpool < sbc_config.minBitpool ||
90        sbc_capability.maxBitpool < sbc_config.maxBitpool)) {
91     log::warn("software codec={} capability={}", sbc_config.toString(),
92               sbc_capability.toString());
93     return false;
94   }
95   log::info("offload codec={} capability={}", sbc_config.toString(),
96             sbc_capability.toString());
97   return true;
98 }
99 
aac_offloading_capability_match(const AacCapabilities & aac_capability,const AacConfiguration & aac_config)100 bool aac_offloading_capability_match(const AacCapabilities& aac_capability,
101                                      const AacConfiguration& aac_config) {
102   if (!ContainedInVector(aac_capability.channelMode, aac_config.channelMode) ||
103       !ContainedInVector(aac_capability.objectType, aac_config.objectType) ||
104       !ContainedInVector(aac_capability.bitsPerSample,
105                          aac_config.bitsPerSample) ||
106       !ContainedInVector(aac_capability.sampleRateHz,
107                          aac_config.sampleRateHz) ||
108       (!aac_capability.variableBitRateSupported &&
109        aac_config.variableBitRateEnabled)) {
110     log::warn("software codec={} capability={}", aac_config.toString(),
111               aac_capability.toString());
112     return false;
113   }
114   log::info("offloading codec={} capability={}", aac_config.toString(),
115             aac_capability.toString());
116   return true;
117 }
118 
aptx_offloading_capability_match(const AptxCapabilities & aptx_capability,const AptxConfiguration & aptx_config)119 bool aptx_offloading_capability_match(const AptxCapabilities& aptx_capability,
120                                       const AptxConfiguration& aptx_config) {
121   if (!ContainedInVector(aptx_capability.channelMode,
122                          aptx_config.channelMode) ||
123       !ContainedInVector(aptx_capability.bitsPerSample,
124                          aptx_config.bitsPerSample) ||
125       !ContainedInVector(aptx_capability.sampleRateHz,
126                          aptx_config.sampleRateHz)) {
127     log::warn("software codec={} capability={}", aptx_config.toString(),
128               aptx_capability.toString());
129     return false;
130   }
131   log::info("offloading codec={} capability={}", aptx_config.toString(),
132             aptx_capability.toString());
133   return true;
134 }
135 
ldac_offloading_capability_match(const LdacCapabilities & ldac_capability,const LdacConfiguration & ldac_config)136 bool ldac_offloading_capability_match(const LdacCapabilities& ldac_capability,
137                                       const LdacConfiguration& ldac_config) {
138   if (!ContainedInVector(ldac_capability.channelMode,
139                          ldac_config.channelMode) ||
140       !ContainedInVector(ldac_capability.bitsPerSample,
141                          ldac_config.bitsPerSample) ||
142       !ContainedInVector(ldac_capability.sampleRateHz,
143                          ldac_config.sampleRateHz)) {
144     log::warn("software codec={} capability={}", ldac_config.toString(),
145               ldac_capability.toString());
146     return false;
147   }
148   log::info("offloading codec={} capability={}", ldac_config.toString(),
149             ldac_capability.toString());
150   return true;
151 }
152 
opus_offloading_capability_match(const std::optional<OpusCapabilities> & opus_capability,const std::optional<OpusConfiguration> & opus_config)153 bool opus_offloading_capability_match(
154     const std::optional<OpusCapabilities>& opus_capability,
155     const std::optional<OpusConfiguration>& opus_config) {
156   if (!ContainedInVector(opus_capability->channelMode,
157                          opus_config->channelMode) ||
158       !ContainedInVector(opus_capability->frameDurationUs,
159                          opus_config->frameDurationUs) ||
160       !ContainedInVector(opus_capability->samplingFrequencyHz,
161                          opus_config->samplingFrequencyHz)) {
162     log::warn("software codec={} capability={}", opus_config->toString(),
163               opus_capability->toString());
164     return false;
165   }
166   log::info("offloading codec={} capability={}", opus_config->toString(),
167             opus_capability->toString());
168   return true;
169 }
170 
171 }  // namespace
172 
173 const CodecConfiguration kInvalidCodecConfiguration = {};
174 
A2dpCodecToHalSampleRate(const btav_a2dp_codec_config_t & a2dp_codec_config)175 int32_t A2dpCodecToHalSampleRate(
176     const btav_a2dp_codec_config_t& a2dp_codec_config) {
177   switch (a2dp_codec_config.sample_rate) {
178     case BTAV_A2DP_CODEC_SAMPLE_RATE_44100:
179       return 44100;
180     case BTAV_A2DP_CODEC_SAMPLE_RATE_48000:
181       return 48000;
182     case BTAV_A2DP_CODEC_SAMPLE_RATE_88200:
183       return 88200;
184     case BTAV_A2DP_CODEC_SAMPLE_RATE_96000:
185       return 96000;
186     case BTAV_A2DP_CODEC_SAMPLE_RATE_176400:
187       return 176400;
188     case BTAV_A2DP_CODEC_SAMPLE_RATE_192000:
189       return 192000;
190     case BTAV_A2DP_CODEC_SAMPLE_RATE_16000:
191       return 16000;
192     case BTAV_A2DP_CODEC_SAMPLE_RATE_24000:
193       return 24000;
194     default:
195       return 0;
196   }
197 }
198 
A2dpCodecToHalBitsPerSample(const btav_a2dp_codec_config_t & a2dp_codec_config)199 int8_t A2dpCodecToHalBitsPerSample(
200     const btav_a2dp_codec_config_t& a2dp_codec_config) {
201   switch (a2dp_codec_config.bits_per_sample) {
202     case BTAV_A2DP_CODEC_BITS_PER_SAMPLE_16:
203       return 16;
204     case BTAV_A2DP_CODEC_BITS_PER_SAMPLE_24:
205       return 24;
206     case BTAV_A2DP_CODEC_BITS_PER_SAMPLE_32:
207       return 32;
208     default:
209       return 0;
210   }
211 }
212 
A2dpCodecToHalChannelMode(const btav_a2dp_codec_config_t & a2dp_codec_config)213 ChannelMode A2dpCodecToHalChannelMode(
214     const btav_a2dp_codec_config_t& a2dp_codec_config) {
215   switch (a2dp_codec_config.channel_mode) {
216     case BTAV_A2DP_CODEC_CHANNEL_MODE_MONO:
217       return ChannelMode::MONO;
218     case BTAV_A2DP_CODEC_CHANNEL_MODE_STEREO:
219       return ChannelMode::STEREO;
220     default:
221       return ChannelMode::UNKNOWN;
222   }
223 }
224 
A2dpSbcToHalConfig(CodecConfiguration * codec_config,A2dpCodecConfig * a2dp_config)225 bool A2dpSbcToHalConfig(CodecConfiguration* codec_config,
226                         A2dpCodecConfig* a2dp_config) {
227   btav_a2dp_codec_config_t current_codec = a2dp_config->getCodecConfig();
228   if (current_codec.codec_type != BTAV_A2DP_CODEC_INDEX_SOURCE_SBC &&
229       current_codec.codec_type != BTAV_A2DP_CODEC_INDEX_SINK_SBC) {
230     return false;
231   }
232   tBT_A2DP_OFFLOAD a2dp_offload;
233   a2dp_config->getCodecSpecificConfig(&a2dp_offload);
234   codec_config->codecType = CodecType::SBC;
235   SbcConfiguration sbc_config = {};
236   sbc_config.sampleRateHz = A2dpCodecToHalSampleRate(current_codec);
237   if (sbc_config.sampleRateHz <= 0) {
238     log::error("Unknown SBC sample_rate={}", current_codec.sample_rate);
239     return false;
240   }
241   uint8_t channel_mode = a2dp_offload.codec_info[3] & A2DP_SBC_IE_CH_MD_MSK;
242   switch (channel_mode) {
243     case A2DP_SBC_IE_CH_MD_JOINT:
244       sbc_config.channelMode = SbcChannelMode::JOINT_STEREO;
245       break;
246     case A2DP_SBC_IE_CH_MD_STEREO:
247       sbc_config.channelMode = SbcChannelMode::STEREO;
248       break;
249     case A2DP_SBC_IE_CH_MD_DUAL:
250       sbc_config.channelMode = SbcChannelMode::DUAL;
251       break;
252     case A2DP_SBC_IE_CH_MD_MONO:
253       sbc_config.channelMode = SbcChannelMode::MONO;
254       break;
255     default:
256       log::error("Unknown SBC channel_mode={}", channel_mode);
257       sbc_config.channelMode = SbcChannelMode::UNKNOWN;
258       return false;
259   }
260   uint8_t block_length = a2dp_offload.codec_info[0] & A2DP_SBC_IE_BLOCKS_MSK;
261   switch (block_length) {
262     case A2DP_SBC_IE_BLOCKS_4:
263       sbc_config.blockLength = 4;
264       break;
265     case A2DP_SBC_IE_BLOCKS_8:
266       sbc_config.blockLength = 8;
267       break;
268     case A2DP_SBC_IE_BLOCKS_12:
269       sbc_config.blockLength = 12;
270       break;
271     case A2DP_SBC_IE_BLOCKS_16:
272       sbc_config.blockLength = 16;
273       break;
274     default:
275       log::error("Unknown SBC block_length={}", block_length);
276       return false;
277   }
278   uint8_t sub_bands = a2dp_offload.codec_info[0] & A2DP_SBC_IE_SUBBAND_MSK;
279   switch (sub_bands) {
280     case A2DP_SBC_IE_SUBBAND_4:
281       sbc_config.numSubbands = 4;
282       break;
283     case A2DP_SBC_IE_SUBBAND_8:
284       sbc_config.numSubbands = 8;
285       break;
286     default:
287       log::error("Unknown SBC Subbands={}", sub_bands);
288       return false;
289   }
290   uint8_t alloc_method = a2dp_offload.codec_info[0] & A2DP_SBC_IE_ALLOC_MD_MSK;
291   switch (alloc_method) {
292     case A2DP_SBC_IE_ALLOC_MD_S:
293       sbc_config.allocMethod = SbcAllocMethod::ALLOC_MD_S;
294       break;
295     case A2DP_SBC_IE_ALLOC_MD_L:
296       sbc_config.allocMethod = SbcAllocMethod::ALLOC_MD_L;
297       break;
298     default:
299       log::error("Unknown SBC alloc_method={}", alloc_method);
300       return false;
301   }
302   sbc_config.minBitpool = a2dp_offload.codec_info[1];
303   sbc_config.maxBitpool = a2dp_offload.codec_info[2];
304   sbc_config.bitsPerSample = A2dpCodecToHalBitsPerSample(current_codec);
305   if (sbc_config.bitsPerSample <= 0) {
306     log::error("Unknown SBC bits_per_sample={}", current_codec.bits_per_sample);
307     return false;
308   }
309   codec_config->config.set<CodecConfiguration::CodecSpecific::sbcConfig>(
310       sbc_config);
311   return true;
312 }
313 
A2dpAacToHalConfig(CodecConfiguration * codec_config,A2dpCodecConfig * a2dp_config)314 bool A2dpAacToHalConfig(CodecConfiguration* codec_config,
315                         A2dpCodecConfig* a2dp_config) {
316   btav_a2dp_codec_config_t current_codec = a2dp_config->getCodecConfig();
317   if (current_codec.codec_type != BTAV_A2DP_CODEC_INDEX_SOURCE_AAC &&
318       current_codec.codec_type != BTAV_A2DP_CODEC_INDEX_SINK_AAC) {
319     return false;
320   }
321   tBT_A2DP_OFFLOAD a2dp_offload;
322   a2dp_config->getCodecSpecificConfig(&a2dp_offload);
323   codec_config->codecType = CodecType::AAC;
324   AacConfiguration aac_config = {};
325   uint8_t object_type = a2dp_offload.codec_info[0];
326   switch (object_type) {
327     case A2DP_AAC_OBJECT_TYPE_MPEG2_LC:
328       aac_config.objectType = AacObjectType::MPEG2_LC;
329       break;
330     case A2DP_AAC_OBJECT_TYPE_MPEG4_LC:
331       aac_config.objectType = AacObjectType::MPEG4_LC;
332       break;
333     case A2DP_AAC_OBJECT_TYPE_MPEG4_LTP:
334       aac_config.objectType = AacObjectType::MPEG4_LTP;
335       break;
336     case A2DP_AAC_OBJECT_TYPE_MPEG4_SCALABLE:
337       aac_config.objectType = AacObjectType::MPEG4_SCALABLE;
338       break;
339     default:
340       log::error("Unknown AAC object_type={}", object_type);
341       return false;
342   }
343   aac_config.sampleRateHz = A2dpCodecToHalSampleRate(current_codec);
344   if (aac_config.sampleRateHz <= 0) {
345     log::error("Unknown AAC sample_rate={}", current_codec.sample_rate);
346     return false;
347   }
348   aac_config.channelMode = A2dpCodecToHalChannelMode(current_codec);
349   if (aac_config.channelMode == ChannelMode::UNKNOWN) {
350     log::error("Unknown AAC channel_mode={}", current_codec.channel_mode);
351     return false;
352   }
353   uint8_t vbr_enabled =
354       a2dp_offload.codec_info[1] & A2DP_AAC_VARIABLE_BIT_RATE_MASK;
355   switch (vbr_enabled) {
356     case A2DP_AAC_VARIABLE_BIT_RATE_ENABLED:
357       aac_config.variableBitRateEnabled = true;
358       break;
359     case A2DP_AAC_VARIABLE_BIT_RATE_DISABLED:
360       aac_config.variableBitRateEnabled = false;
361       break;
362     default:
363       log::error("Unknown AAC VBR={}", vbr_enabled);
364       return false;
365   }
366   aac_config.bitsPerSample = A2dpCodecToHalBitsPerSample(current_codec);
367   if (aac_config.bitsPerSample <= 0) {
368     log::error("Unknown AAC bits_per_sample={}", current_codec.bits_per_sample);
369     return false;
370   }
371   codec_config->config.set<CodecConfiguration::CodecSpecific::aacConfig>(
372       aac_config);
373   return true;
374 }
375 
A2dpAptxToHalConfig(CodecConfiguration * codec_config,A2dpCodecConfig * a2dp_config)376 bool A2dpAptxToHalConfig(CodecConfiguration* codec_config,
377                          A2dpCodecConfig* a2dp_config) {
378   btav_a2dp_codec_config_t current_codec = a2dp_config->getCodecConfig();
379   if (current_codec.codec_type != BTAV_A2DP_CODEC_INDEX_SOURCE_APTX &&
380       current_codec.codec_type != BTAV_A2DP_CODEC_INDEX_SOURCE_APTX_HD) {
381     return false;
382   }
383   tBT_A2DP_OFFLOAD a2dp_offload;
384   a2dp_config->getCodecSpecificConfig(&a2dp_offload);
385   if (current_codec.codec_type == BTAV_A2DP_CODEC_INDEX_SOURCE_APTX) {
386     codec_config->codecType = CodecType::APTX;
387   } else {
388     codec_config->codecType = CodecType::APTX_HD;
389   }
390   AptxConfiguration aptx_config = {};
391   aptx_config.sampleRateHz = A2dpCodecToHalSampleRate(current_codec);
392   if (aptx_config.sampleRateHz <= 0) {
393     log::error("Unknown aptX sample_rate={}", current_codec.sample_rate);
394     return false;
395   }
396   aptx_config.channelMode = A2dpCodecToHalChannelMode(current_codec);
397   if (aptx_config.channelMode == ChannelMode::UNKNOWN) {
398     log::error("Unknown aptX channel_mode={}", current_codec.channel_mode);
399     return false;
400   }
401   aptx_config.bitsPerSample = A2dpCodecToHalBitsPerSample(current_codec);
402   if (aptx_config.bitsPerSample <= 0) {
403     log::error("Unknown aptX bits_per_sample={}",
404                current_codec.bits_per_sample);
405     return false;
406   }
407   codec_config->config.set<CodecConfiguration::CodecSpecific::aptxConfig>(
408       aptx_config);
409   return true;
410 }
411 
A2dpLdacToHalConfig(CodecConfiguration * codec_config,A2dpCodecConfig * a2dp_config)412 bool A2dpLdacToHalConfig(CodecConfiguration* codec_config,
413                          A2dpCodecConfig* a2dp_config) {
414   btav_a2dp_codec_config_t current_codec = a2dp_config->getCodecConfig();
415   if (current_codec.codec_type != BTAV_A2DP_CODEC_INDEX_SOURCE_LDAC) {
416     return false;
417   }
418   tBT_A2DP_OFFLOAD a2dp_offload;
419   a2dp_config->getCodecSpecificConfig(&a2dp_offload);
420   codec_config->codecType = CodecType::LDAC;
421   LdacConfiguration ldac_config = {};
422   ldac_config.sampleRateHz = A2dpCodecToHalSampleRate(current_codec);
423   if (ldac_config.sampleRateHz <= 0) {
424     log::error("Unknown LDAC sample_rate={}", current_codec.sample_rate);
425     return false;
426   }
427   switch (a2dp_offload.codec_info[7]) {
428     case A2DP_LDAC_CHANNEL_MODE_STEREO:
429       ldac_config.channelMode = LdacChannelMode::STEREO;
430       break;
431     case A2DP_LDAC_CHANNEL_MODE_DUAL:
432       ldac_config.channelMode = LdacChannelMode::DUAL;
433       break;
434     case A2DP_LDAC_CHANNEL_MODE_MONO:
435       ldac_config.channelMode = LdacChannelMode::MONO;
436       break;
437     default:
438       log::error("Unknown LDAC channel_mode={}", a2dp_offload.codec_info[7]);
439       ldac_config.channelMode = LdacChannelMode::UNKNOWN;
440       return false;
441   }
442   switch (a2dp_offload.codec_info[6]) {
443     case A2DP_LDAC_QUALITY_HIGH:
444       ldac_config.qualityIndex = LdacQualityIndex::HIGH;
445       break;
446     case A2DP_LDAC_QUALITY_MID:
447       ldac_config.qualityIndex = LdacQualityIndex::MID;
448       break;
449     case A2DP_LDAC_QUALITY_LOW:
450       ldac_config.qualityIndex = LdacQualityIndex::LOW;
451       break;
452     case A2DP_LDAC_QUALITY_ABR_OFFLOAD:
453       ldac_config.qualityIndex = LdacQualityIndex::ABR;
454       break;
455     default:
456       log::error("Unknown LDAC QualityIndex={}", a2dp_offload.codec_info[6]);
457       return false;
458   }
459   ldac_config.bitsPerSample = A2dpCodecToHalBitsPerSample(current_codec);
460   if (ldac_config.bitsPerSample <= 0) {
461     log::error("Unknown LDAC bits_per_sample={}",
462                current_codec.bits_per_sample);
463     return false;
464   }
465   codec_config->config.set<CodecConfiguration::CodecSpecific::ldacConfig>(
466       ldac_config);
467   return true;
468 }
469 
A2dpOpusToHalConfig(CodecConfiguration * codec_config,A2dpCodecConfig * a2dp_config)470 bool A2dpOpusToHalConfig(CodecConfiguration* codec_config,
471                          A2dpCodecConfig* a2dp_config) {
472   btav_a2dp_codec_config_t current_codec = a2dp_config->getCodecConfig();
473   if (current_codec.codec_type != BTAV_A2DP_CODEC_INDEX_SOURCE_OPUS) {
474     codec_config = {};
475     return false;
476   }
477   tBT_A2DP_OFFLOAD a2dp_offload;
478   a2dp_config->getCodecSpecificConfig(&a2dp_offload);
479   codec_config->codecType = CodecType::OPUS;
480   OpusConfiguration opus_config = {};
481 
482   opus_config.pcmBitDepth = A2dpCodecToHalBitsPerSample(current_codec);
483   if (opus_config.pcmBitDepth <= 0) {
484     log::error("Unknown Opus bits_per_sample={}",
485                current_codec.bits_per_sample);
486     return false;
487   }
488   opus_config.samplingFrequencyHz = A2dpCodecToHalSampleRate(current_codec);
489   if (opus_config.samplingFrequencyHz <= 0) {
490     log::error("Unknown Opus sample_rate={}", current_codec.sample_rate);
491     return false;
492   }
493   opus_config.channelMode = A2dpCodecToHalChannelMode(current_codec);
494   if (opus_config.channelMode == ChannelMode::UNKNOWN) {
495     log::error("Unknown Opus channel_mode={}", current_codec.channel_mode);
496     return false;
497   }
498 
499   opus_config.frameDurationUs = 20000;
500 
501   if (opus_config.channelMode == ChannelMode::STEREO) {
502     opus_config.octetsPerFrame = 640;
503   } else {
504     opus_config.octetsPerFrame = 320;
505   }
506 
507   codec_config->config.set<CodecConfiguration::CodecSpecific::opusConfig>(
508       opus_config);
509   return true;
510 }
511 
UpdateOffloadingCapabilities(const std::vector<btav_a2dp_codec_config_t> & framework_preference)512 bool UpdateOffloadingCapabilities(
513     const std::vector<btav_a2dp_codec_config_t>& framework_preference) {
514   audio_hal_capabilities =
515       BluetoothAudioSinkClientInterface::GetAudioCapabilities(
516           SessionType::A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH);
517   std::unordered_set<CodecType> codec_type_set;
518   for (auto preference : framework_preference) {
519     switch (preference.codec_type) {
520       case BTAV_A2DP_CODEC_INDEX_SOURCE_SBC:
521         codec_type_set.insert(CodecType::SBC);
522         break;
523       case BTAV_A2DP_CODEC_INDEX_SOURCE_AAC:
524         codec_type_set.insert(CodecType::AAC);
525         break;
526       case BTAV_A2DP_CODEC_INDEX_SOURCE_APTX:
527         codec_type_set.insert(CodecType::APTX);
528         break;
529       case BTAV_A2DP_CODEC_INDEX_SOURCE_APTX_HD:
530         codec_type_set.insert(CodecType::APTX_HD);
531         break;
532       case BTAV_A2DP_CODEC_INDEX_SOURCE_LDAC:
533         codec_type_set.insert(CodecType::LDAC);
534         break;
535       case BTAV_A2DP_CODEC_INDEX_SOURCE_LC3:
536         log::warn("Ignore source codec_type={}, not implemented",
537                   preference.codec_type);
538         break;
539       case BTAV_A2DP_CODEC_INDEX_SOURCE_OPUS:
540         codec_type_set.insert(CodecType::OPUS);
541         break;
542       case BTAV_A2DP_CODEC_INDEX_SINK_SBC:
543         [[fallthrough]];
544       case BTAV_A2DP_CODEC_INDEX_SINK_AAC:
545         [[fallthrough]];
546       case BTAV_A2DP_CODEC_INDEX_SINK_LDAC:
547         [[fallthrough]];
548       case BTAV_A2DP_CODEC_INDEX_SINK_OPUS:
549         log::warn("Ignore sink codec_type={}", preference.codec_type);
550         break;
551       case BTAV_A2DP_CODEC_INDEX_MAX:
552         [[fallthrough]];
553       default:
554         log::error("Unknown codec_type={}", preference.codec_type);
555         return false;
556     }
557   }
558   offloading_preference.clear();
559   for (auto capability : audio_hal_capabilities) {
560     auto codec_type =
561         capability.get<AudioCapabilities::a2dpCapabilities>().codecType;
562     if (codec_type_set.find(codec_type) != codec_type_set.end()) {
563       log::info("enabled offloading capability={}", capability.toString());
564       offloading_preference.push_back(capability);
565     } else {
566       log::info("disabled offloading capability={}", capability.toString());
567     }
568   }
569 
570   // TODO: Bluetooth SoC and runtime property
571   return true;
572 }
573 
574 /***
575  * Check whether this codec is supported by the audio HAL and is allowed to
576  * use by prefernece of framework / Bluetooth SoC / runtime property.
577  ***/
IsCodecOffloadingEnabled(const CodecConfiguration & codec_config)578 bool IsCodecOffloadingEnabled(const CodecConfiguration& codec_config) {
579   for (auto preference : offloading_preference) {
580     if (codec_config.codecType !=
581         preference.get<AudioCapabilities::a2dpCapabilities>().codecType) {
582       continue;
583     }
584     auto codec_capability =
585         preference.get<AudioCapabilities::a2dpCapabilities>();
586     switch (codec_capability.codecType) {
587       case CodecType::SBC: {
588         auto sbc_capability =
589             codec_capability.capabilities
590                 .get<CodecCapabilities::Capabilities::sbcCapabilities>();
591         auto sbc_config =
592             codec_config.config
593                 .get<CodecConfiguration::CodecSpecific::sbcConfig>();
594         return sbc_offloading_capability_match(sbc_capability, sbc_config);
595       }
596       case CodecType::AAC: {
597         auto aac_capability =
598             codec_capability.capabilities
599                 .get<CodecCapabilities::Capabilities::aacCapabilities>();
600         auto aac_config =
601             codec_config.config
602                 .get<CodecConfiguration::CodecSpecific::aacConfig>();
603         return aac_offloading_capability_match(aac_capability, aac_config);
604       }
605       case CodecType::APTX:
606         [[fallthrough]];
607       case CodecType::APTX_HD: {
608         auto aptx_capability =
609             codec_capability.capabilities
610                 .get<CodecCapabilities::Capabilities::aptxCapabilities>();
611         auto aptx_config =
612             codec_config.config
613                 .get<CodecConfiguration::CodecSpecific::aptxConfig>();
614         return aptx_offloading_capability_match(aptx_capability, aptx_config);
615       }
616       case CodecType::LDAC: {
617         auto ldac_capability =
618             codec_capability.capabilities
619                 .get<CodecCapabilities::Capabilities::ldacCapabilities>();
620         auto ldac_config =
621             codec_config.config
622                 .get<CodecConfiguration::CodecSpecific::ldacConfig>();
623         return ldac_offloading_capability_match(ldac_capability, ldac_config);
624       }
625       case CodecType::OPUS: {
626         std::optional<OpusCapabilities> opus_capability =
627             codec_capability.capabilities
628                 .get<CodecCapabilities::Capabilities::opusCapabilities>();
629         std::optional<OpusConfiguration> opus_config =
630             codec_config.config
631                 .get<CodecConfiguration::CodecSpecific::opusConfig>();
632         return opus_offloading_capability_match(opus_capability, opus_config);
633       }
634       case CodecType::UNKNOWN:
635         [[fallthrough]];
636       default:
637         log::error("Unknown codecType={}",
638                    toString(codec_capability.codecType));
639         return false;
640     }
641   }
642   log::info("software codec={}", codec_config.toString());
643   return false;
644 }
645 
646 }  // namespace codec
647 }  // namespace aidl
648 }  // namespace audio
649 }  // namespace bluetooth
650