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