blob: 1524f5e3ac38afea3bcf0e6b6ff50d3a852f171a [file] [log] [blame]
Josh Wu20bac522021-12-29 23:52:39 -08001/*
2 * Copyright (C) 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 "BTAudioCodecsAidl"
18
19#include "BluetoothAudioCodecs.h"
20
21#include <aidl/android/hardware/bluetooth/audio/AacCapabilities.h>
22#include <aidl/android/hardware/bluetooth/audio/AacObjectType.h>
23#include <aidl/android/hardware/bluetooth/audio/AptxCapabilities.h>
24#include <aidl/android/hardware/bluetooth/audio/ChannelMode.h>
25#include <aidl/android/hardware/bluetooth/audio/LdacCapabilities.h>
26#include <aidl/android/hardware/bluetooth/audio/LdacChannelMode.h>
27#include <aidl/android/hardware/bluetooth/audio/LdacQualityIndex.h>
28#include <aidl/android/hardware/bluetooth/audio/LeAudioConfiguration.h>
Omer Osmana2587da2022-05-01 03:54:11 +000029#include <aidl/android/hardware/bluetooth/audio/OpusCapabilities.h>
30#include <aidl/android/hardware/bluetooth/audio/OpusConfiguration.h>
Josh Wu20bac522021-12-29 23:52:39 -080031#include <aidl/android/hardware/bluetooth/audio/SbcCapabilities.h>
32#include <aidl/android/hardware/bluetooth/audio/SbcChannelMode.h>
33#include <android-base/logging.h>
34
shihchienc8ed901a2022-09-06 08:44:44 +000035#include "BluetoothLeAudioCodecsProvider.h"
36
Josh Wu20bac522021-12-29 23:52:39 -080037namespace aidl {
38namespace android {
39namespace hardware {
40namespace bluetooth {
41namespace audio {
42
43static const PcmCapabilities kDefaultSoftwarePcmCapabilities = {
Yuyang Huangaa70c112023-10-26 16:01:45 -070044 .sampleRateHz = {8000, 16000, 24000, 32000, 44100, 48000, 88200, 96000},
Josh Wu20bac522021-12-29 23:52:39 -080045 .channelMode = {ChannelMode::MONO, ChannelMode::STEREO},
46 .bitsPerSample = {16, 24, 32},
47 .dataIntervalUs = {},
48};
49
50static const SbcCapabilities kDefaultOffloadSbcCapability = {
51 .sampleRateHz = {44100},
52 .channelMode = {SbcChannelMode::MONO, SbcChannelMode::JOINT_STEREO},
53 .blockLength = {4, 8, 12, 16},
54 .numSubbands = {8},
55 .allocMethod = {SbcAllocMethod::ALLOC_MD_L},
56 .bitsPerSample = {16},
57 .minBitpool = 2,
58 .maxBitpool = 53};
59
60static const AacCapabilities kDefaultOffloadAacCapability = {
61 .objectType = {AacObjectType::MPEG2_LC},
62 .sampleRateHz = {44100},
63 .channelMode = {ChannelMode::STEREO},
64 .variableBitRateSupported = true,
65 .bitsPerSample = {16}};
66
67static const LdacCapabilities kDefaultOffloadLdacCapability = {
68 .sampleRateHz = {44100, 48000, 88200, 96000},
69 .channelMode = {LdacChannelMode::DUAL, LdacChannelMode::STEREO},
70 .qualityIndex = {LdacQualityIndex::HIGH},
71 .bitsPerSample = {16, 24, 32}};
72
73static const AptxCapabilities kDefaultOffloadAptxCapability = {
74 .sampleRateHz = {44100, 48000},
75 .channelMode = {ChannelMode::STEREO},
76 .bitsPerSample = {16},
77};
78
79static const AptxCapabilities kDefaultOffloadAptxHdCapability = {
80 .sampleRateHz = {44100, 48000},
81 .channelMode = {ChannelMode::STEREO},
82 .bitsPerSample = {24},
83};
84
Omer Osmana2587da2022-05-01 03:54:11 +000085static const OpusCapabilities kDefaultOffloadOpusCapability = {
86 .samplingFrequencyHz = {48000},
87 .frameDurationUs = {10000, 20000},
Josh Wu20bac522021-12-29 23:52:39 -080088 .channelMode = {ChannelMode::MONO, ChannelMode::STEREO},
89};
90
91const std::vector<CodecCapabilities> kDefaultOffloadA2dpCodecCapabilities = {
92 {.codecType = CodecType::SBC, .capabilities = {}},
93 {.codecType = CodecType::AAC, .capabilities = {}},
94 {.codecType = CodecType::LDAC, .capabilities = {}},
95 {.codecType = CodecType::APTX, .capabilities = {}},
96 {.codecType = CodecType::APTX_HD, .capabilities = {}},
Omer Osmana2587da2022-05-01 03:54:11 +000097 {.codecType = CodecType::OPUS, .capabilities = {}}};
Josh Wu20bac522021-12-29 23:52:39 -080098
99std::vector<LeAudioCodecCapabilitiesSetting> kDefaultOffloadLeAudioCapabilities;
Bao Do6aeb5d72023-12-11 10:53:18 +0000100std::unordered_map<SessionType, std::vector<CodecInfo>>
101 kDefaultOffloadLeAudioCodecInfoMap;
Josh Wu20bac522021-12-29 23:52:39 -0800102
Josh Wu20bac522021-12-29 23:52:39 -0800103template <class T>
104bool BluetoothAudioCodecs::ContainedInVector(
105 const std::vector<T>& vector, const typename identity<T>::type& target) {
106 return std::find(vector.begin(), vector.end(), target) != vector.end();
107}
108
109bool BluetoothAudioCodecs::IsOffloadSbcConfigurationValid(
110 const CodecConfiguration::CodecSpecific& codec_specific) {
111 if (codec_specific.getTag() != CodecConfiguration::CodecSpecific::sbcConfig) {
112 LOG(WARNING) << __func__
113 << ": Invalid CodecSpecific=" << codec_specific.toString();
114 return false;
115 }
116 const SbcConfiguration sbc_data =
117 codec_specific.get<CodecConfiguration::CodecSpecific::sbcConfig>();
118
119 if (ContainedInVector(kDefaultOffloadSbcCapability.sampleRateHz,
120 sbc_data.sampleRateHz) &&
121 ContainedInVector(kDefaultOffloadSbcCapability.blockLength,
122 sbc_data.blockLength) &&
123 ContainedInVector(kDefaultOffloadSbcCapability.numSubbands,
124 sbc_data.numSubbands) &&
125 ContainedInVector(kDefaultOffloadSbcCapability.bitsPerSample,
126 sbc_data.bitsPerSample) &&
127 ContainedInVector(kDefaultOffloadSbcCapability.channelMode,
128 sbc_data.channelMode) &&
129 ContainedInVector(kDefaultOffloadSbcCapability.allocMethod,
130 sbc_data.allocMethod) &&
131 sbc_data.minBitpool <= sbc_data.maxBitpool &&
132 kDefaultOffloadSbcCapability.minBitpool <= sbc_data.minBitpool &&
133 kDefaultOffloadSbcCapability.maxBitpool >= sbc_data.maxBitpool) {
134 return true;
135 }
136 LOG(WARNING) << __func__
137 << ": Unsupported CodecSpecific=" << codec_specific.toString();
138 return false;
139}
140
141bool BluetoothAudioCodecs::IsOffloadAacConfigurationValid(
142 const CodecConfiguration::CodecSpecific& codec_specific) {
143 if (codec_specific.getTag() != CodecConfiguration::CodecSpecific::aacConfig) {
144 LOG(WARNING) << __func__
145 << ": Invalid CodecSpecific=" << codec_specific.toString();
146 return false;
147 }
148 const AacConfiguration aac_data =
149 codec_specific.get<CodecConfiguration::CodecSpecific::aacConfig>();
150
151 if (ContainedInVector(kDefaultOffloadAacCapability.sampleRateHz,
152 aac_data.sampleRateHz) &&
153 ContainedInVector(kDefaultOffloadAacCapability.bitsPerSample,
154 aac_data.bitsPerSample) &&
155 ContainedInVector(kDefaultOffloadAacCapability.channelMode,
156 aac_data.channelMode) &&
157 ContainedInVector(kDefaultOffloadAacCapability.objectType,
158 aac_data.objectType) &&
159 (!aac_data.variableBitRateEnabled ||
160 kDefaultOffloadAacCapability.variableBitRateSupported)) {
161 return true;
162 }
163 LOG(WARNING) << __func__
164 << ": Unsupported CodecSpecific=" << codec_specific.toString();
165 return false;
166}
167
168bool BluetoothAudioCodecs::IsOffloadLdacConfigurationValid(
169 const CodecConfiguration::CodecSpecific& codec_specific) {
170 if (codec_specific.getTag() !=
171 CodecConfiguration::CodecSpecific::ldacConfig) {
172 LOG(WARNING) << __func__
173 << ": Invalid CodecSpecific=" << codec_specific.toString();
174 return false;
175 }
176 const LdacConfiguration ldac_data =
177 codec_specific.get<CodecConfiguration::CodecSpecific::ldacConfig>();
178
179 if (ContainedInVector(kDefaultOffloadLdacCapability.sampleRateHz,
180 ldac_data.sampleRateHz) &&
181 ContainedInVector(kDefaultOffloadLdacCapability.bitsPerSample,
182 ldac_data.bitsPerSample) &&
183 ContainedInVector(kDefaultOffloadLdacCapability.channelMode,
184 ldac_data.channelMode) &&
185 ContainedInVector(kDefaultOffloadLdacCapability.qualityIndex,
186 ldac_data.qualityIndex)) {
187 return true;
188 }
189 LOG(WARNING) << __func__
190 << ": Unsupported CodecSpecific=" << codec_specific.toString();
191 return false;
192}
193
194bool BluetoothAudioCodecs::IsOffloadAptxConfigurationValid(
195 const CodecConfiguration::CodecSpecific& codec_specific) {
196 if (codec_specific.getTag() !=
197 CodecConfiguration::CodecSpecific::aptxConfig) {
198 LOG(WARNING) << __func__
199 << ": Invalid CodecSpecific=" << codec_specific.toString();
200 return false;
201 }
202 const AptxConfiguration aptx_data =
203 codec_specific.get<CodecConfiguration::CodecSpecific::aptxConfig>();
204
205 if (ContainedInVector(kDefaultOffloadAptxCapability.sampleRateHz,
206 aptx_data.sampleRateHz) &&
207 ContainedInVector(kDefaultOffloadAptxCapability.bitsPerSample,
208 aptx_data.bitsPerSample) &&
209 ContainedInVector(kDefaultOffloadAptxCapability.channelMode,
210 aptx_data.channelMode)) {
211 return true;
212 }
213 LOG(WARNING) << __func__
214 << ": Unsupported CodecSpecific=" << codec_specific.toString();
215 return false;
216}
217
218bool BluetoothAudioCodecs::IsOffloadAptxHdConfigurationValid(
219 const CodecConfiguration::CodecSpecific& codec_specific) {
220 if (codec_specific.getTag() !=
221 CodecConfiguration::CodecSpecific::aptxConfig) {
222 LOG(WARNING) << __func__
223 << ": Invalid CodecSpecific=" << codec_specific.toString();
224 return false;
225 }
226 const AptxConfiguration aptx_data =
227 codec_specific.get<CodecConfiguration::CodecSpecific::aptxConfig>();
228
229 if (ContainedInVector(kDefaultOffloadAptxHdCapability.sampleRateHz,
230 aptx_data.sampleRateHz) &&
231 ContainedInVector(kDefaultOffloadAptxHdCapability.bitsPerSample,
232 aptx_data.bitsPerSample) &&
233 ContainedInVector(kDefaultOffloadAptxHdCapability.channelMode,
234 aptx_data.channelMode)) {
235 return true;
236 }
237 LOG(WARNING) << __func__
238 << ": Unsupported CodecSpecific=" << codec_specific.toString();
239 return false;
240}
241
Omer Osmana2587da2022-05-01 03:54:11 +0000242bool BluetoothAudioCodecs::IsOffloadOpusConfigurationValid(
Josh Wu20bac522021-12-29 23:52:39 -0800243 const CodecConfiguration::CodecSpecific& codec_specific) {
Omer Osmana2587da2022-05-01 03:54:11 +0000244 if (codec_specific.getTag() !=
245 CodecConfiguration::CodecSpecific::opusConfig) {
Josh Wu20bac522021-12-29 23:52:39 -0800246 LOG(WARNING) << __func__
247 << ": Invalid CodecSpecific=" << codec_specific.toString();
248 return false;
249 }
Omer Osmana2587da2022-05-01 03:54:11 +0000250 std::optional<OpusConfiguration> opus_data =
251 codec_specific.get<CodecConfiguration::CodecSpecific::opusConfig>();
Josh Wu20bac522021-12-29 23:52:39 -0800252
Omer Osmana2587da2022-05-01 03:54:11 +0000253 if (opus_data.has_value() &&
254 ContainedInVector(kDefaultOffloadOpusCapability.samplingFrequencyHz,
255 opus_data->samplingFrequencyHz) &&
256 ContainedInVector(kDefaultOffloadOpusCapability.frameDurationUs,
257 opus_data->frameDurationUs) &&
258 ContainedInVector(kDefaultOffloadOpusCapability.channelMode,
259 opus_data->channelMode)) {
Josh Wu20bac522021-12-29 23:52:39 -0800260 return true;
261 }
262 LOG(WARNING) << __func__
263 << ": Unsupported CodecSpecific=" << codec_specific.toString();
264 return false;
265}
266
Josh Wu20bac522021-12-29 23:52:39 -0800267std::vector<PcmCapabilities>
268BluetoothAudioCodecs::GetSoftwarePcmCapabilities() {
269 return {kDefaultSoftwarePcmCapabilities};
270}
271
272std::vector<CodecCapabilities>
273BluetoothAudioCodecs::GetA2dpOffloadCodecCapabilities(
274 const SessionType& session_type) {
Alice Kuoadcceec2022-03-28 13:28:43 +0800275 if (session_type != SessionType::A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH &&
276 session_type != SessionType::A2DP_HARDWARE_OFFLOAD_DECODING_DATAPATH) {
Josh Wu20bac522021-12-29 23:52:39 -0800277 return {};
278 }
279 std::vector<CodecCapabilities> offload_a2dp_codec_capabilities =
280 kDefaultOffloadA2dpCodecCapabilities;
281 for (auto& codec_capability : offload_a2dp_codec_capabilities) {
282 switch (codec_capability.codecType) {
283 case CodecType::SBC:
284 codec_capability.capabilities
285 .set<CodecCapabilities::Capabilities::sbcCapabilities>(
286 kDefaultOffloadSbcCapability);
287 break;
288 case CodecType::AAC:
289 codec_capability.capabilities
290 .set<CodecCapabilities::Capabilities::aacCapabilities>(
291 kDefaultOffloadAacCapability);
292 break;
293 case CodecType::LDAC:
294 codec_capability.capabilities
295 .set<CodecCapabilities::Capabilities::ldacCapabilities>(
296 kDefaultOffloadLdacCapability);
297 break;
298 case CodecType::APTX:
299 codec_capability.capabilities
300 .set<CodecCapabilities::Capabilities::aptxCapabilities>(
301 kDefaultOffloadAptxCapability);
302 break;
303 case CodecType::APTX_HD:
304 codec_capability.capabilities
305 .set<CodecCapabilities::Capabilities::aptxCapabilities>(
306 kDefaultOffloadAptxHdCapability);
307 break;
Omer Osmana2587da2022-05-01 03:54:11 +0000308 case CodecType::OPUS:
Josh Wu20bac522021-12-29 23:52:39 -0800309 codec_capability.capabilities
Omer Osmana2587da2022-05-01 03:54:11 +0000310 .set<CodecCapabilities::Capabilities::opusCapabilities>(
311 kDefaultOffloadOpusCapability);
Josh Wu20bac522021-12-29 23:52:39 -0800312 break;
313 case CodecType::UNKNOWN:
Alice Kuo79c936d2022-01-20 23:10:10 +0800314 case CodecType::VENDOR:
Omer Osmana2587da2022-05-01 03:54:11 +0000315 case CodecType::LC3:
Sagar Vermad13bbb32022-01-08 20:09:04 +0530316 case CodecType::APTX_ADAPTIVE:
Sagar Verma62df9102022-12-07 17:56:04 +0530317 case CodecType::APTX_ADAPTIVE_LE:
318 case CodecType::APTX_ADAPTIVE_LEX:
Josh Wu20bac522021-12-29 23:52:39 -0800319 break;
320 }
321 }
322 return offload_a2dp_codec_capabilities;
323}
324
325bool BluetoothAudioCodecs::IsSoftwarePcmConfigurationValid(
326 const PcmConfiguration& pcm_config) {
327 if (ContainedInVector(kDefaultSoftwarePcmCapabilities.sampleRateHz,
328 pcm_config.sampleRateHz) &&
329 ContainedInVector(kDefaultSoftwarePcmCapabilities.bitsPerSample,
330 pcm_config.bitsPerSample) &&
331 ContainedInVector(kDefaultSoftwarePcmCapabilities.channelMode,
332 pcm_config.channelMode)
333 // data interval is not checked for now
334 // && pcm_config.dataIntervalUs != 0
335 ) {
336 return true;
337 }
338 LOG(WARNING) << __func__
339 << ": Unsupported CodecSpecific=" << pcm_config.toString();
340 return false;
341}
342
343bool BluetoothAudioCodecs::IsOffloadCodecConfigurationValid(
344 const SessionType& session_type, const CodecConfiguration& codec_config) {
Alice Kuoadcceec2022-03-28 13:28:43 +0800345 if (session_type != SessionType::A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH &&
346 session_type != SessionType::A2DP_HARDWARE_OFFLOAD_DECODING_DATAPATH) {
Josh Wu20bac522021-12-29 23:52:39 -0800347 LOG(ERROR) << __func__
348 << ": Invalid SessionType=" << toString(session_type);
349 return false;
350 }
351 const CodecConfiguration::CodecSpecific& codec_specific = codec_config.config;
352 switch (codec_config.codecType) {
353 case CodecType::SBC:
354 if (IsOffloadSbcConfigurationValid(codec_specific)) {
355 return true;
356 }
357 break;
358 case CodecType::AAC:
359 if (IsOffloadAacConfigurationValid(codec_specific)) {
360 return true;
361 }
362 break;
363 case CodecType::LDAC:
364 if (IsOffloadLdacConfigurationValid(codec_specific)) {
365 return true;
366 }
367 break;
368 case CodecType::APTX:
369 if (IsOffloadAptxConfigurationValid(codec_specific)) {
370 return true;
371 }
372 break;
373 case CodecType::APTX_HD:
374 if (IsOffloadAptxHdConfigurationValid(codec_specific)) {
375 return true;
376 }
377 break;
Omer Osmana2587da2022-05-01 03:54:11 +0000378 case CodecType::OPUS:
379 if (IsOffloadOpusConfigurationValid(codec_specific)) {
Josh Wu20bac522021-12-29 23:52:39 -0800380 return true;
381 }
382 break;
Sagar Vermad13bbb32022-01-08 20:09:04 +0530383 case CodecType::APTX_ADAPTIVE:
Sagar Verma62df9102022-12-07 17:56:04 +0530384 case CodecType::APTX_ADAPTIVE_LE:
385 case CodecType::APTX_ADAPTIVE_LEX:
Omer Osmana2587da2022-05-01 03:54:11 +0000386 case CodecType::LC3:
Josh Wu20bac522021-12-29 23:52:39 -0800387 case CodecType::UNKNOWN:
Alice Kuo79c936d2022-01-20 23:10:10 +0800388 case CodecType::VENDOR:
Josh Wu20bac522021-12-29 23:52:39 -0800389 break;
390 }
391 return false;
392}
393
Josh Wu20bac522021-12-29 23:52:39 -0800394std::vector<LeAudioCodecCapabilitiesSetting>
395BluetoothAudioCodecs::GetLeAudioOffloadCodecCapabilities(
396 const SessionType& session_type) {
397 if (session_type !=
398 SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH &&
399 session_type !=
Josh Wu5d50dc02022-02-15 08:41:53 -0800400 SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH &&
401 session_type !=
402 SessionType::LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH) {
Josh Wu20bac522021-12-29 23:52:39 -0800403 return std::vector<LeAudioCodecCapabilitiesSetting>(0);
404 }
405
406 if (kDefaultOffloadLeAudioCapabilities.empty()) {
shihchiencd7f565a2022-10-14 13:45:37 +0000407 auto le_audio_offload_setting =
408 BluetoothLeAudioCodecsProvider::ParseFromLeAudioOffloadSettingFile();
shihchienc8ed901a2022-09-06 08:44:44 +0000409 kDefaultOffloadLeAudioCapabilities =
shihchiencd7f565a2022-10-14 13:45:37 +0000410 BluetoothLeAudioCodecsProvider::GetLeAudioCodecCapabilities(
411 le_audio_offload_setting);
Sagar Verma62df9102022-12-07 17:56:04 +0530412 }
Josh Wu20bac522021-12-29 23:52:39 -0800413 return kDefaultOffloadLeAudioCapabilities;
414}
415
Bao Do6aeb5d72023-12-11 10:53:18 +0000416std::vector<CodecInfo> BluetoothAudioCodecs::GetLeAudioOffloadCodecInfo(
417 const SessionType& session_type) {
418 if (session_type !=
419 SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH &&
420 session_type !=
421 SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH &&
422 session_type !=
423 SessionType::LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH) {
424 return std::vector<CodecInfo>();
425 }
426
427 if (kDefaultOffloadLeAudioCodecInfoMap.empty()) {
428 auto le_audio_offload_setting =
429 BluetoothLeAudioCodecsProvider::ParseFromLeAudioOffloadSettingFile();
430 auto kDefaultOffloadLeAudioCodecInfoMap =
431 BluetoothLeAudioCodecsProvider::GetLeAudioCodecInfo(
432 le_audio_offload_setting);
433 }
434 auto codec_info_map_iter =
435 kDefaultOffloadLeAudioCodecInfoMap.find(session_type);
436 if (codec_info_map_iter == kDefaultOffloadLeAudioCodecInfoMap.end())
437 return std::vector<CodecInfo>();
438 return codec_info_map_iter->second;
439}
440
Josh Wu20bac522021-12-29 23:52:39 -0800441} // namespace audio
442} // namespace bluetooth
443} // namespace hardware
444} // namespace android
Sagar Vermad13bbb32022-01-08 20:09:04 +0530445} // namespace aidl