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