1 /*
2 * Copyright 2019 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 "BTAudioCodecStatusHIDL"
18
19 #include "codec_status_hidl.h"
20
21 #include <bluetooth/log.h>
22
23 #include <vector>
24
25 #include "a2dp_aac_constants.h"
26 #include "a2dp_sbc_constants.h"
27 #include "a2dp_vendor_aptx_constants.h"
28 #include "a2dp_vendor_aptx_hd_constants.h"
29 #include "a2dp_vendor_ldac_constants.h"
30 #include "bta/av/bta_av_int.h"
31 #include "client_interface_hidl.h"
32
33 namespace {
34
35 using ::android::hardware::bluetooth::audio::V2_0::AacObjectType;
36 using ::android::hardware::bluetooth::audio::V2_0::AacParameters;
37 using ::android::hardware::bluetooth::audio::V2_0::AacVariableBitRate;
38 using ::android::hardware::bluetooth::audio::V2_0::AptxParameters;
39 using ::android::hardware::bluetooth::audio::V2_0::AudioCapabilities;
40 using ::android::hardware::bluetooth::audio::V2_0::BitsPerSample;
41 using ::android::hardware::bluetooth::audio::V2_0::ChannelMode;
42 using ::android::hardware::bluetooth::audio::V2_0::CodecType;
43 using ::android::hardware::bluetooth::audio::V2_0::LdacChannelMode;
44 using ::android::hardware::bluetooth::audio::V2_0::LdacParameters;
45 using ::android::hardware::bluetooth::audio::V2_0::LdacQualityIndex;
46 using ::android::hardware::bluetooth::audio::V2_0::SampleRate;
47 using ::android::hardware::bluetooth::audio::V2_0::SbcAllocMethod;
48 using ::android::hardware::bluetooth::audio::V2_0::SbcBlockLength;
49 using ::android::hardware::bluetooth::audio::V2_0::SbcChannelMode;
50 using ::android::hardware::bluetooth::audio::V2_0::SbcNumSubbands;
51 using ::android::hardware::bluetooth::audio::V2_0::SbcParameters;
52
53 using namespace bluetooth;
54
55 // capabilities from BluetoothAudioSinkClientInterface::GetAudioCapabilities()
56 std::vector<AudioCapabilities> audio_hal_capabilities(0);
57 // capabilities that audio HAL supports and frameworks / Bluetooth SoC / runtime
58 // preference would like to use.
59 std::vector<AudioCapabilities> offloading_preference(0);
60
sbc_offloading_capability_match(const SbcParameters & sbc_capability,const SbcParameters & sbc_config)61 bool sbc_offloading_capability_match(const SbcParameters& sbc_capability,
62 const SbcParameters& sbc_config) {
63 if ((static_cast<SampleRate>(sbc_capability.sampleRate & sbc_config.sampleRate) ==
64 SampleRate::RATE_UNKNOWN) ||
65 (static_cast<SbcChannelMode>(sbc_capability.channelMode & sbc_config.channelMode) ==
66 SbcChannelMode::UNKNOWN) ||
67 (static_cast<SbcBlockLength>(sbc_capability.blockLength & sbc_config.blockLength) ==
68 static_cast<SbcBlockLength>(0)) ||
69 (static_cast<SbcNumSubbands>(sbc_capability.numSubbands & sbc_config.numSubbands) ==
70 static_cast<SbcNumSubbands>(0)) ||
71 (static_cast<SbcAllocMethod>(sbc_capability.allocMethod & sbc_config.allocMethod) ==
72 static_cast<SbcAllocMethod>(0)) ||
73 (static_cast<BitsPerSample>(sbc_capability.bitsPerSample & sbc_config.bitsPerSample) ==
74 BitsPerSample::BITS_UNKNOWN) ||
75 (sbc_config.minBitpool < sbc_capability.minBitpool ||
76 sbc_config.maxBitpool < sbc_config.minBitpool ||
77 sbc_capability.maxBitpool < sbc_config.maxBitpool)) {
78 log::warn("software codec={} capability={}", toString(sbc_config), toString(sbc_capability));
79 return false;
80 }
81 log::verbose("offloading codec={} capability={}", toString(sbc_config), toString(sbc_capability));
82 return true;
83 }
84
aac_offloading_capability_match(const AacParameters & aac_capability,const AacParameters & aac_config)85 bool aac_offloading_capability_match(const AacParameters& aac_capability,
86 const AacParameters& aac_config) {
87 if ((static_cast<AacObjectType>(aac_capability.objectType & aac_config.objectType) ==
88 static_cast<AacObjectType>(0)) ||
89 (static_cast<SampleRate>(aac_capability.sampleRate & aac_config.sampleRate) ==
90 SampleRate::RATE_UNKNOWN) ||
91 (static_cast<ChannelMode>(aac_capability.channelMode & aac_config.channelMode) ==
92 ChannelMode::UNKNOWN) ||
93 (aac_capability.variableBitRateEnabled != AacVariableBitRate::ENABLED &&
94 aac_config.variableBitRateEnabled != AacVariableBitRate::DISABLED) ||
95 (static_cast<BitsPerSample>(aac_capability.bitsPerSample & aac_config.bitsPerSample) ==
96 BitsPerSample::BITS_UNKNOWN)) {
97 log::warn("software codec={} capability={}", toString(aac_config), toString(aac_capability));
98 return false;
99 }
100 log::verbose("offloading codec={} capability={}", toString(aac_config), toString(aac_capability));
101 return true;
102 }
103
aptx_offloading_capability_match(const AptxParameters & aptx_capability,const AptxParameters & aptx_config)104 bool aptx_offloading_capability_match(const AptxParameters& aptx_capability,
105 const AptxParameters& aptx_config) {
106 if ((static_cast<SampleRate>(aptx_capability.sampleRate & aptx_config.sampleRate) ==
107 SampleRate::RATE_UNKNOWN) ||
108 (static_cast<ChannelMode>(aptx_capability.channelMode & aptx_config.channelMode) ==
109 ChannelMode::UNKNOWN) ||
110 (static_cast<BitsPerSample>(aptx_capability.bitsPerSample & aptx_config.bitsPerSample) ==
111 BitsPerSample::BITS_UNKNOWN)) {
112 log::warn("software codec={} capability={}", toString(aptx_config), toString(aptx_capability));
113 return false;
114 }
115 log::verbose("offloading codec={} capability={}", toString(aptx_config),
116 toString(aptx_capability));
117 return true;
118 }
119
ldac_offloading_capability_match(const LdacParameters & ldac_capability,const LdacParameters & ldac_config)120 bool ldac_offloading_capability_match(const LdacParameters& ldac_capability,
121 const LdacParameters& ldac_config) {
122 if ((static_cast<SampleRate>(ldac_capability.sampleRate & ldac_config.sampleRate) ==
123 SampleRate::RATE_UNKNOWN) ||
124 (static_cast<LdacChannelMode>(ldac_capability.channelMode & ldac_config.channelMode) ==
125 LdacChannelMode::UNKNOWN) ||
126 (static_cast<BitsPerSample>(ldac_capability.bitsPerSample & ldac_config.bitsPerSample) ==
127 BitsPerSample::BITS_UNKNOWN)) {
128 log::warn("software codec={} capability={}", toString(ldac_config), toString(ldac_capability));
129 return false;
130 }
131 log::verbose("offloading codec={} capability={}", toString(ldac_config),
132 toString(ldac_capability));
133 return true;
134 }
135 } // namespace
136
137 namespace bluetooth {
138 namespace audio {
139 namespace hidl {
140 namespace codec {
141
142 const CodecConfiguration kInvalidCodecConfiguration = {.codecType = CodecType::UNKNOWN,
143 .encodedAudioBitrate = 0x00000000,
144 .peerMtu = 0xffff,
145 .isScmstEnabled = false,
146 .config = {}};
147
A2dpCodecToHalSampleRate(const btav_a2dp_codec_config_t & a2dp_codec_config)148 SampleRate A2dpCodecToHalSampleRate(const btav_a2dp_codec_config_t& a2dp_codec_config) {
149 switch (a2dp_codec_config.sample_rate) {
150 case BTAV_A2DP_CODEC_SAMPLE_RATE_44100:
151 return SampleRate::RATE_44100;
152 case BTAV_A2DP_CODEC_SAMPLE_RATE_48000:
153 return SampleRate::RATE_48000;
154 case BTAV_A2DP_CODEC_SAMPLE_RATE_88200:
155 return SampleRate::RATE_88200;
156 case BTAV_A2DP_CODEC_SAMPLE_RATE_96000:
157 return SampleRate::RATE_96000;
158 case BTAV_A2DP_CODEC_SAMPLE_RATE_176400:
159 return SampleRate::RATE_176400;
160 case BTAV_A2DP_CODEC_SAMPLE_RATE_192000:
161 return SampleRate::RATE_192000;
162 case BTAV_A2DP_CODEC_SAMPLE_RATE_16000:
163 return SampleRate::RATE_16000;
164 case BTAV_A2DP_CODEC_SAMPLE_RATE_24000:
165 return SampleRate::RATE_24000;
166 default:
167 return SampleRate::RATE_UNKNOWN;
168 }
169 }
170
A2dpCodecToHalBitsPerSample(const btav_a2dp_codec_config_t & a2dp_codec_config)171 BitsPerSample A2dpCodecToHalBitsPerSample(const btav_a2dp_codec_config_t& a2dp_codec_config) {
172 switch (a2dp_codec_config.bits_per_sample) {
173 case BTAV_A2DP_CODEC_BITS_PER_SAMPLE_16:
174 return BitsPerSample::BITS_16;
175 case BTAV_A2DP_CODEC_BITS_PER_SAMPLE_24:
176 return BitsPerSample::BITS_24;
177 case BTAV_A2DP_CODEC_BITS_PER_SAMPLE_32:
178 return BitsPerSample::BITS_32;
179 default:
180 return BitsPerSample::BITS_UNKNOWN;
181 }
182 }
183
A2dpCodecToHalChannelMode(const btav_a2dp_codec_config_t & a2dp_codec_config)184 ChannelMode A2dpCodecToHalChannelMode(const btav_a2dp_codec_config_t& a2dp_codec_config) {
185 switch (a2dp_codec_config.channel_mode) {
186 case BTAV_A2DP_CODEC_CHANNEL_MODE_MONO:
187 return ChannelMode::MONO;
188 case BTAV_A2DP_CODEC_CHANNEL_MODE_STEREO:
189 return ChannelMode::STEREO;
190 default:
191 return ChannelMode::UNKNOWN;
192 }
193 }
194
A2dpSbcToHalConfig(CodecConfiguration * codec_config,A2dpCodecConfig * a2dp_config)195 bool A2dpSbcToHalConfig(CodecConfiguration* codec_config, A2dpCodecConfig* a2dp_config) {
196 btav_a2dp_codec_config_t current_codec = a2dp_config->getCodecConfig();
197 if (current_codec.codec_type != BTAV_A2DP_CODEC_INDEX_SOURCE_SBC &&
198 current_codec.codec_type != BTAV_A2DP_CODEC_INDEX_SINK_SBC) {
199 *codec_config = {};
200 return false;
201 }
202 tBT_A2DP_OFFLOAD a2dp_offload;
203 a2dp_config->getCodecSpecificConfig(&a2dp_offload);
204 codec_config->codecType = CodecType::SBC;
205 codec_config->config.sbcConfig({});
206 auto sbc_config = codec_config->config.sbcConfig();
207 sbc_config.sampleRate = A2dpCodecToHalSampleRate(current_codec);
208 if (sbc_config.sampleRate == SampleRate::RATE_UNKNOWN) {
209 log::error("Unknown SBC sample_rate={}", current_codec.sample_rate);
210 return false;
211 }
212 uint8_t channel_mode = a2dp_offload.codec_info[3] & A2DP_SBC_IE_CH_MD_MSK;
213 switch (channel_mode) {
214 case A2DP_SBC_IE_CH_MD_JOINT:
215 sbc_config.channelMode = SbcChannelMode::JOINT_STEREO;
216 break;
217 case A2DP_SBC_IE_CH_MD_STEREO:
218 sbc_config.channelMode = SbcChannelMode::STEREO;
219 break;
220 case A2DP_SBC_IE_CH_MD_DUAL:
221 sbc_config.channelMode = SbcChannelMode::DUAL;
222 break;
223 case A2DP_SBC_IE_CH_MD_MONO:
224 sbc_config.channelMode = SbcChannelMode::MONO;
225 break;
226 default:
227 log::error("Unknown SBC channel_mode={}", channel_mode);
228 sbc_config.channelMode = SbcChannelMode::UNKNOWN;
229 return false;
230 }
231 uint8_t block_length = a2dp_offload.codec_info[0] & A2DP_SBC_IE_BLOCKS_MSK;
232 switch (block_length) {
233 case A2DP_SBC_IE_BLOCKS_4:
234 sbc_config.blockLength = SbcBlockLength::BLOCKS_4;
235 break;
236 case A2DP_SBC_IE_BLOCKS_8:
237 sbc_config.blockLength = SbcBlockLength::BLOCKS_8;
238 break;
239 case A2DP_SBC_IE_BLOCKS_12:
240 sbc_config.blockLength = SbcBlockLength::BLOCKS_12;
241 break;
242 case A2DP_SBC_IE_BLOCKS_16:
243 sbc_config.blockLength = SbcBlockLength::BLOCKS_16;
244 break;
245 default:
246 log::error("Unknown SBC block_length={}", block_length);
247 return false;
248 }
249 uint8_t sub_bands = a2dp_offload.codec_info[0] & A2DP_SBC_IE_SUBBAND_MSK;
250 switch (sub_bands) {
251 case A2DP_SBC_IE_SUBBAND_4:
252 sbc_config.numSubbands = SbcNumSubbands::SUBBAND_4;
253 break;
254 case A2DP_SBC_IE_SUBBAND_8:
255 sbc_config.numSubbands = SbcNumSubbands::SUBBAND_8;
256 break;
257 default:
258 log::error("Unknown SBC Subbands={}", sub_bands);
259 return false;
260 }
261 uint8_t alloc_method = a2dp_offload.codec_info[0] & A2DP_SBC_IE_ALLOC_MD_MSK;
262 switch (alloc_method) {
263 case A2DP_SBC_IE_ALLOC_MD_S:
264 sbc_config.allocMethod = SbcAllocMethod::ALLOC_MD_S;
265 break;
266 case A2DP_SBC_IE_ALLOC_MD_L:
267 sbc_config.allocMethod = SbcAllocMethod::ALLOC_MD_L;
268 break;
269 default:
270 log::error("Unknown SBC alloc_method={}", alloc_method);
271 return false;
272 }
273 sbc_config.minBitpool = a2dp_offload.codec_info[1];
274 sbc_config.maxBitpool = a2dp_offload.codec_info[2];
275 sbc_config.bitsPerSample = A2dpCodecToHalBitsPerSample(current_codec);
276 if (sbc_config.bitsPerSample == BitsPerSample::BITS_UNKNOWN) {
277 log::error("Unknown SBC bits_per_sample={}", current_codec.bits_per_sample);
278 return false;
279 }
280 codec_config->config.sbcConfig(sbc_config);
281 return true;
282 }
283
A2dpAacToHalConfig(CodecConfiguration * codec_config,A2dpCodecConfig * a2dp_config)284 bool A2dpAacToHalConfig(CodecConfiguration* codec_config, A2dpCodecConfig* a2dp_config) {
285 btav_a2dp_codec_config_t current_codec = a2dp_config->getCodecConfig();
286 if (current_codec.codec_type != BTAV_A2DP_CODEC_INDEX_SOURCE_AAC &&
287 current_codec.codec_type != BTAV_A2DP_CODEC_INDEX_SINK_AAC) {
288 *codec_config = {};
289 return false;
290 }
291 tBT_A2DP_OFFLOAD a2dp_offload;
292 a2dp_config->getCodecSpecificConfig(&a2dp_offload);
293 codec_config->codecType = CodecType::AAC;
294 codec_config->config.aacConfig({});
295 auto aac_config = codec_config->config.aacConfig();
296 uint8_t object_type = a2dp_offload.codec_info[0];
297 switch (object_type) {
298 case A2DP_AAC_OBJECT_TYPE_MPEG2_LC:
299 aac_config.objectType = AacObjectType::MPEG2_LC;
300 break;
301 case A2DP_AAC_OBJECT_TYPE_MPEG4_LC:
302 aac_config.objectType = AacObjectType::MPEG4_LC;
303 break;
304 case A2DP_AAC_OBJECT_TYPE_MPEG4_LTP:
305 aac_config.objectType = AacObjectType::MPEG4_LTP;
306 break;
307 case A2DP_AAC_OBJECT_TYPE_MPEG4_SCALABLE:
308 aac_config.objectType = AacObjectType::MPEG4_SCALABLE;
309 break;
310 default:
311 log::error("Unknown AAC object_type={}", object_type);
312 return false;
313 }
314 aac_config.sampleRate = A2dpCodecToHalSampleRate(current_codec);
315 if (aac_config.sampleRate == SampleRate::RATE_UNKNOWN) {
316 log::error("Unknown AAC sample_rate={}", current_codec.sample_rate);
317 return false;
318 }
319 aac_config.channelMode = A2dpCodecToHalChannelMode(current_codec);
320 if (aac_config.channelMode == ChannelMode::UNKNOWN) {
321 log::error("Unknown AAC channel_mode={}", current_codec.channel_mode);
322 return false;
323 }
324 uint8_t vbr_enabled = a2dp_offload.codec_info[1] & A2DP_AAC_VARIABLE_BIT_RATE_MASK;
325 switch (vbr_enabled) {
326 case A2DP_AAC_VARIABLE_BIT_RATE_ENABLED:
327 aac_config.variableBitRateEnabled = AacVariableBitRate::ENABLED;
328 break;
329 case A2DP_AAC_VARIABLE_BIT_RATE_DISABLED:
330 aac_config.variableBitRateEnabled = AacVariableBitRate::DISABLED;
331 break;
332 default:
333 log::error("Unknown AAC VBR={}", vbr_enabled);
334 return false;
335 }
336 aac_config.bitsPerSample = A2dpCodecToHalBitsPerSample(current_codec);
337 if (aac_config.bitsPerSample == BitsPerSample::BITS_UNKNOWN) {
338 log::error("Unknown AAC bits_per_sample={}", current_codec.bits_per_sample);
339 return false;
340 }
341 codec_config->config.aacConfig(aac_config);
342 return true;
343 }
344
A2dpAptxToHalConfig(CodecConfiguration * codec_config,A2dpCodecConfig * a2dp_config)345 bool A2dpAptxToHalConfig(CodecConfiguration* codec_config, A2dpCodecConfig* a2dp_config) {
346 btav_a2dp_codec_config_t current_codec = a2dp_config->getCodecConfig();
347 if (current_codec.codec_type != BTAV_A2DP_CODEC_INDEX_SOURCE_APTX &&
348 current_codec.codec_type != BTAV_A2DP_CODEC_INDEX_SOURCE_APTX_HD) {
349 *codec_config = {};
350 return false;
351 }
352 tBT_A2DP_OFFLOAD a2dp_offload;
353 a2dp_config->getCodecSpecificConfig(&a2dp_offload);
354 if (current_codec.codec_type == BTAV_A2DP_CODEC_INDEX_SOURCE_APTX) {
355 codec_config->codecType = CodecType::APTX;
356 } else {
357 codec_config->codecType = CodecType::APTX_HD;
358 }
359 codec_config->config.aptxConfig({});
360 auto aptx_config = codec_config->config.aptxConfig();
361 aptx_config.sampleRate = A2dpCodecToHalSampleRate(current_codec);
362 if (aptx_config.sampleRate == SampleRate::RATE_UNKNOWN) {
363 log::error("Unknown aptX sample_rate={}", current_codec.sample_rate);
364 return false;
365 }
366 aptx_config.channelMode = A2dpCodecToHalChannelMode(current_codec);
367 if (aptx_config.channelMode == ChannelMode::UNKNOWN) {
368 log::error("Unknown aptX channel_mode={}", current_codec.channel_mode);
369 return false;
370 }
371 aptx_config.bitsPerSample = A2dpCodecToHalBitsPerSample(current_codec);
372 if (aptx_config.bitsPerSample == BitsPerSample::BITS_UNKNOWN) {
373 log::error("Unknown aptX bits_per_sample={}", current_codec.bits_per_sample);
374 return false;
375 }
376 codec_config->config.aptxConfig(aptx_config);
377 return true;
378 }
379
A2dpLdacToHalConfig(CodecConfiguration * codec_config,A2dpCodecConfig * a2dp_config)380 bool A2dpLdacToHalConfig(CodecConfiguration* codec_config, A2dpCodecConfig* a2dp_config) {
381 btav_a2dp_codec_config_t current_codec = a2dp_config->getCodecConfig();
382 if (current_codec.codec_type != BTAV_A2DP_CODEC_INDEX_SOURCE_LDAC) {
383 codec_config = {};
384 return false;
385 }
386 tBT_A2DP_OFFLOAD a2dp_offload;
387 a2dp_config->getCodecSpecificConfig(&a2dp_offload);
388 codec_config->codecType = CodecType::LDAC;
389 codec_config->config.ldacConfig({});
390 auto ldac_config = codec_config->config.ldacConfig();
391 ldac_config.sampleRate = A2dpCodecToHalSampleRate(current_codec);
392 if (ldac_config.sampleRate == SampleRate::RATE_UNKNOWN) {
393 log::error("Unknown LDAC sample_rate={}", current_codec.sample_rate);
394 return false;
395 }
396 switch (a2dp_offload.codec_info[7]) {
397 case A2DP_LDAC_CHANNEL_MODE_STEREO:
398 ldac_config.channelMode = LdacChannelMode::STEREO;
399 break;
400 case A2DP_LDAC_CHANNEL_MODE_DUAL:
401 ldac_config.channelMode = LdacChannelMode::DUAL;
402 break;
403 case A2DP_LDAC_CHANNEL_MODE_MONO:
404 ldac_config.channelMode = LdacChannelMode::MONO;
405 break;
406 default:
407 log::error("Unknown LDAC channel_mode={}", a2dp_offload.codec_info[7]);
408 ldac_config.channelMode = LdacChannelMode::UNKNOWN;
409 return false;
410 }
411 switch (a2dp_offload.codec_info[6]) {
412 case A2DP_LDAC_QUALITY_HIGH:
413 ldac_config.qualityIndex = LdacQualityIndex::QUALITY_HIGH;
414 break;
415 case A2DP_LDAC_QUALITY_MID:
416 ldac_config.qualityIndex = LdacQualityIndex::QUALITY_MID;
417 break;
418 case A2DP_LDAC_QUALITY_LOW:
419 ldac_config.qualityIndex = LdacQualityIndex::QUALITY_LOW;
420 break;
421 case A2DP_LDAC_QUALITY_ABR_OFFLOAD:
422 ldac_config.qualityIndex = LdacQualityIndex::QUALITY_ABR;
423 break;
424 default:
425 log::error("Unknown LDAC QualityIndex={}", a2dp_offload.codec_info[6]);
426 return false;
427 }
428 ldac_config.bitsPerSample = A2dpCodecToHalBitsPerSample(current_codec);
429 if (ldac_config.bitsPerSample == BitsPerSample::BITS_UNKNOWN) {
430 log::error("Unknown LDAC bits_per_sample={}", current_codec.bits_per_sample);
431 return false;
432 }
433 codec_config->config.ldacConfig(ldac_config);
434 return true;
435 }
436
UpdateOffloadingCapabilities(const std::vector<btav_a2dp_codec_config_t> & framework_preference)437 bool UpdateOffloadingCapabilities(
438 const std::vector<btav_a2dp_codec_config_t>& framework_preference) {
439 audio_hal_capabilities = BluetoothAudioSinkClientInterface::GetAudioCapabilities(
440 SessionType::A2DP_HARDWARE_OFFLOAD_DATAPATH);
441 uint32_t codec_type_masks = static_cast<uint32_t>(CodecType::UNKNOWN);
442 for (auto preference : framework_preference) {
443 switch (preference.codec_type) {
444 case BTAV_A2DP_CODEC_INDEX_SOURCE_SBC:
445 codec_type_masks |= CodecType::SBC;
446 break;
447 case BTAV_A2DP_CODEC_INDEX_SOURCE_AAC:
448 codec_type_masks |= CodecType::AAC;
449 break;
450 case BTAV_A2DP_CODEC_INDEX_SOURCE_APTX:
451 codec_type_masks |= CodecType::APTX;
452 break;
453 case BTAV_A2DP_CODEC_INDEX_SOURCE_APTX_HD:
454 codec_type_masks |= CodecType::APTX_HD;
455 break;
456 case BTAV_A2DP_CODEC_INDEX_SOURCE_LDAC:
457 codec_type_masks |= CodecType::LDAC;
458 break;
459 case BTAV_A2DP_CODEC_INDEX_SOURCE_LC3:
460 log::warn("Ignore source codec_type={}, not supported", preference.codec_type);
461 break;
462 case BTAV_A2DP_CODEC_INDEX_SOURCE_OPUS:
463 log::warn("Ignore source codec_type={}, not supported on HIDL", preference.codec_type);
464 break;
465 case BTAV_A2DP_CODEC_INDEX_SINK_SBC:
466 [[fallthrough]];
467 case BTAV_A2DP_CODEC_INDEX_SINK_AAC:
468 [[fallthrough]];
469 case BTAV_A2DP_CODEC_INDEX_SINK_LDAC:
470 [[fallthrough]];
471 case BTAV_A2DP_CODEC_INDEX_SINK_OPUS:
472 log::warn("Ignore sink codec_type={}", preference.codec_type);
473 break;
474 case BTAV_A2DP_CODEC_INDEX_MAX:
475 [[fallthrough]];
476 default:
477 log::error("Unknown codec_type={}", preference.codec_type);
478 return false;
479 }
480 }
481 offloading_preference.clear();
482 for (auto capability : audio_hal_capabilities) {
483 if (static_cast<CodecType>(capability.codecCapabilities().codecType & codec_type_masks) !=
484 CodecType::UNKNOWN) {
485 log::info("enabled offloading capability={}", toString(capability));
486 offloading_preference.push_back(capability);
487 } else {
488 log::info("disabled offloading capability={}", toString(capability));
489 }
490 }
491 // TODO: Bluetooth SoC and runtime property
492 return true;
493 }
494
495 // Check whether this codec is supported by the audio HAL and is allowed to use
496 // by preference of framework / Bluetooth SoC / runtime property.
IsCodecOffloadingEnabled(const CodecConfiguration & codec_config)497 bool IsCodecOffloadingEnabled(const CodecConfiguration& codec_config) {
498 for (auto preference : offloading_preference) {
499 if (codec_config.codecType != preference.codecCapabilities().codecType) {
500 continue;
501 }
502 auto codec_capability = preference.codecCapabilities();
503 switch (codec_capability.codecType) {
504 case CodecType::SBC: {
505 auto sbc_capability = codec_capability.capabilities.sbcCapabilities();
506 auto sbc_config = codec_config.config.sbcConfig();
507 return sbc_offloading_capability_match(sbc_capability, sbc_config);
508 }
509 case CodecType::AAC: {
510 auto aac_capability = codec_capability.capabilities.aacCapabilities();
511 auto aac_config = codec_config.config.aacConfig();
512 return aac_offloading_capability_match(aac_capability, aac_config);
513 }
514 case CodecType::APTX:
515 [[fallthrough]];
516 case CodecType::APTX_HD: {
517 auto aptx_capability = codec_capability.capabilities.aptxCapabilities();
518 auto aptx_config = codec_config.config.aptxConfig();
519 return aptx_offloading_capability_match(aptx_capability, aptx_config);
520 }
521 case CodecType::LDAC: {
522 auto ldac_capability = codec_capability.capabilities.ldacCapabilities();
523 auto ldac_config = codec_config.config.ldacConfig();
524 return ldac_offloading_capability_match(ldac_capability, ldac_config);
525 }
526 case CodecType::UNKNOWN:
527 [[fallthrough]];
528 default:
529 log::error("Unknown codecType={}", toString(codec_capability.codecType));
530 return false;
531 }
532 }
533 log::info("software codec={}", toString(codec_config));
534 return false;
535 }
536
537 } // namespace codec
538 } // namespace hidl
539 } // namespace audio
540 } // namespace bluetooth
541