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