• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
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>
29 #include <aidl/android/hardware/bluetooth/audio/OpusCapabilities.h>
30 #include <aidl/android/hardware/bluetooth/audio/OpusConfiguration.h>
31 #include <aidl/android/hardware/bluetooth/audio/SbcCapabilities.h>
32 #include <aidl/android/hardware/bluetooth/audio/SbcChannelMode.h>
33 #include <android-base/logging.h>
34 
35 #include "BluetoothLeAudioCodecsProvider.h"
36 
37 namespace aidl {
38 namespace android {
39 namespace hardware {
40 namespace bluetooth {
41 namespace audio {
42 
43 static const PcmCapabilities kDefaultSoftwarePcmCapabilities = {
44     .sampleRateHz = {16000, 24000, 32000, 44100, 48000, 88200, 96000},
45     .channelMode = {ChannelMode::MONO, ChannelMode::STEREO},
46     .bitsPerSample = {16, 24, 32},
47     .dataIntervalUs = {},
48 };
49 
50 static 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 
60 static const AacCapabilities kDefaultOffloadAacCapability = {
61     .objectType = {AacObjectType::MPEG2_LC},
62     .sampleRateHz = {44100},
63     .channelMode = {ChannelMode::STEREO},
64     .variableBitRateSupported = true,
65     .bitsPerSample = {16}};
66 
67 static 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 
73 static const AptxCapabilities kDefaultOffloadAptxCapability = {
74     .sampleRateHz = {44100, 48000},
75     .channelMode = {ChannelMode::STEREO},
76     .bitsPerSample = {16},
77 };
78 
79 static const AptxCapabilities kDefaultOffloadAptxHdCapability = {
80     .sampleRateHz = {44100, 48000},
81     .channelMode = {ChannelMode::STEREO},
82     .bitsPerSample = {24},
83 };
84 
85 static const OpusCapabilities kDefaultOffloadOpusCapability = {
86     .samplingFrequencyHz = {48000},
87     .frameDurationUs = {10000, 20000},
88     .channelMode = {ChannelMode::MONO, ChannelMode::STEREO},
89 };
90 
91 const 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 = {}},
97     {.codecType = CodecType::OPUS, .capabilities = {}}};
98 
99 std::vector<LeAudioCodecCapabilitiesSetting> kDefaultOffloadLeAudioCapabilities;
100 
101 template <class T>
ContainedInVector(const std::vector<T> & vector,const typename identity<T>::type & target)102 bool BluetoothAudioCodecs::ContainedInVector(
103     const std::vector<T>& vector, const typename identity<T>::type& target) {
104   return std::find(vector.begin(), vector.end(), target) != vector.end();
105 }
106 
IsOffloadSbcConfigurationValid(const CodecConfiguration::CodecSpecific & codec_specific)107 bool BluetoothAudioCodecs::IsOffloadSbcConfigurationValid(
108     const CodecConfiguration::CodecSpecific& codec_specific) {
109   if (codec_specific.getTag() != CodecConfiguration::CodecSpecific::sbcConfig) {
110     LOG(WARNING) << __func__
111                  << ": Invalid CodecSpecific=" << codec_specific.toString();
112     return false;
113   }
114   const SbcConfiguration sbc_data =
115       codec_specific.get<CodecConfiguration::CodecSpecific::sbcConfig>();
116 
117   if (ContainedInVector(kDefaultOffloadSbcCapability.sampleRateHz,
118                         sbc_data.sampleRateHz) &&
119       ContainedInVector(kDefaultOffloadSbcCapability.blockLength,
120                         sbc_data.blockLength) &&
121       ContainedInVector(kDefaultOffloadSbcCapability.numSubbands,
122                         sbc_data.numSubbands) &&
123       ContainedInVector(kDefaultOffloadSbcCapability.bitsPerSample,
124                         sbc_data.bitsPerSample) &&
125       ContainedInVector(kDefaultOffloadSbcCapability.channelMode,
126                         sbc_data.channelMode) &&
127       ContainedInVector(kDefaultOffloadSbcCapability.allocMethod,
128                         sbc_data.allocMethod) &&
129       sbc_data.minBitpool <= sbc_data.maxBitpool &&
130       kDefaultOffloadSbcCapability.minBitpool <= sbc_data.minBitpool &&
131       kDefaultOffloadSbcCapability.maxBitpool >= sbc_data.maxBitpool) {
132     return true;
133   }
134   LOG(WARNING) << __func__
135                << ": Unsupported CodecSpecific=" << codec_specific.toString();
136   return false;
137 }
138 
IsOffloadAacConfigurationValid(const CodecConfiguration::CodecSpecific & codec_specific)139 bool BluetoothAudioCodecs::IsOffloadAacConfigurationValid(
140     const CodecConfiguration::CodecSpecific& codec_specific) {
141   if (codec_specific.getTag() != CodecConfiguration::CodecSpecific::aacConfig) {
142     LOG(WARNING) << __func__
143                  << ": Invalid CodecSpecific=" << codec_specific.toString();
144     return false;
145   }
146   const AacConfiguration aac_data =
147       codec_specific.get<CodecConfiguration::CodecSpecific::aacConfig>();
148 
149   if (ContainedInVector(kDefaultOffloadAacCapability.sampleRateHz,
150                         aac_data.sampleRateHz) &&
151       ContainedInVector(kDefaultOffloadAacCapability.bitsPerSample,
152                         aac_data.bitsPerSample) &&
153       ContainedInVector(kDefaultOffloadAacCapability.channelMode,
154                         aac_data.channelMode) &&
155       ContainedInVector(kDefaultOffloadAacCapability.objectType,
156                         aac_data.objectType) &&
157       (!aac_data.variableBitRateEnabled ||
158        kDefaultOffloadAacCapability.variableBitRateSupported)) {
159     return true;
160   }
161   LOG(WARNING) << __func__
162                << ": Unsupported CodecSpecific=" << codec_specific.toString();
163   return false;
164 }
165 
IsOffloadLdacConfigurationValid(const CodecConfiguration::CodecSpecific & codec_specific)166 bool BluetoothAudioCodecs::IsOffloadLdacConfigurationValid(
167     const CodecConfiguration::CodecSpecific& codec_specific) {
168   if (codec_specific.getTag() !=
169       CodecConfiguration::CodecSpecific::ldacConfig) {
170     LOG(WARNING) << __func__
171                  << ": Invalid CodecSpecific=" << codec_specific.toString();
172     return false;
173   }
174   const LdacConfiguration ldac_data =
175       codec_specific.get<CodecConfiguration::CodecSpecific::ldacConfig>();
176 
177   if (ContainedInVector(kDefaultOffloadLdacCapability.sampleRateHz,
178                         ldac_data.sampleRateHz) &&
179       ContainedInVector(kDefaultOffloadLdacCapability.bitsPerSample,
180                         ldac_data.bitsPerSample) &&
181       ContainedInVector(kDefaultOffloadLdacCapability.channelMode,
182                         ldac_data.channelMode) &&
183       ContainedInVector(kDefaultOffloadLdacCapability.qualityIndex,
184                         ldac_data.qualityIndex)) {
185     return true;
186   }
187   LOG(WARNING) << __func__
188                << ": Unsupported CodecSpecific=" << codec_specific.toString();
189   return false;
190 }
191 
IsOffloadAptxConfigurationValid(const CodecConfiguration::CodecSpecific & codec_specific)192 bool BluetoothAudioCodecs::IsOffloadAptxConfigurationValid(
193     const CodecConfiguration::CodecSpecific& codec_specific) {
194   if (codec_specific.getTag() !=
195       CodecConfiguration::CodecSpecific::aptxConfig) {
196     LOG(WARNING) << __func__
197                  << ": Invalid CodecSpecific=" << codec_specific.toString();
198     return false;
199   }
200   const AptxConfiguration aptx_data =
201       codec_specific.get<CodecConfiguration::CodecSpecific::aptxConfig>();
202 
203   if (ContainedInVector(kDefaultOffloadAptxCapability.sampleRateHz,
204                         aptx_data.sampleRateHz) &&
205       ContainedInVector(kDefaultOffloadAptxCapability.bitsPerSample,
206                         aptx_data.bitsPerSample) &&
207       ContainedInVector(kDefaultOffloadAptxCapability.channelMode,
208                         aptx_data.channelMode)) {
209     return true;
210   }
211   LOG(WARNING) << __func__
212                << ": Unsupported CodecSpecific=" << codec_specific.toString();
213   return false;
214 }
215 
IsOffloadAptxHdConfigurationValid(const CodecConfiguration::CodecSpecific & codec_specific)216 bool BluetoothAudioCodecs::IsOffloadAptxHdConfigurationValid(
217     const CodecConfiguration::CodecSpecific& codec_specific) {
218   if (codec_specific.getTag() !=
219       CodecConfiguration::CodecSpecific::aptxConfig) {
220     LOG(WARNING) << __func__
221                  << ": Invalid CodecSpecific=" << codec_specific.toString();
222     return false;
223   }
224   const AptxConfiguration aptx_data =
225       codec_specific.get<CodecConfiguration::CodecSpecific::aptxConfig>();
226 
227   if (ContainedInVector(kDefaultOffloadAptxHdCapability.sampleRateHz,
228                         aptx_data.sampleRateHz) &&
229       ContainedInVector(kDefaultOffloadAptxHdCapability.bitsPerSample,
230                         aptx_data.bitsPerSample) &&
231       ContainedInVector(kDefaultOffloadAptxHdCapability.channelMode,
232                         aptx_data.channelMode)) {
233     return true;
234   }
235   LOG(WARNING) << __func__
236                << ": Unsupported CodecSpecific=" << codec_specific.toString();
237   return false;
238 }
239 
IsOffloadOpusConfigurationValid(const CodecConfiguration::CodecSpecific & codec_specific)240 bool BluetoothAudioCodecs::IsOffloadOpusConfigurationValid(
241     const CodecConfiguration::CodecSpecific& codec_specific) {
242   if (codec_specific.getTag() !=
243       CodecConfiguration::CodecSpecific::opusConfig) {
244     LOG(WARNING) << __func__
245                  << ": Invalid CodecSpecific=" << codec_specific.toString();
246     return false;
247   }
248   std::optional<OpusConfiguration> opus_data =
249       codec_specific.get<CodecConfiguration::CodecSpecific::opusConfig>();
250 
251   if (opus_data.has_value() &&
252       ContainedInVector(kDefaultOffloadOpusCapability.samplingFrequencyHz,
253                         opus_data->samplingFrequencyHz) &&
254       ContainedInVector(kDefaultOffloadOpusCapability.frameDurationUs,
255                         opus_data->frameDurationUs) &&
256       ContainedInVector(kDefaultOffloadOpusCapability.channelMode,
257                         opus_data->channelMode)) {
258     return true;
259   }
260   LOG(WARNING) << __func__
261                << ": Unsupported CodecSpecific=" << codec_specific.toString();
262   return false;
263 }
264 
265 std::vector<PcmCapabilities>
GetSoftwarePcmCapabilities()266 BluetoothAudioCodecs::GetSoftwarePcmCapabilities() {
267   return {kDefaultSoftwarePcmCapabilities};
268 }
269 
270 std::vector<CodecCapabilities>
GetA2dpOffloadCodecCapabilities(const SessionType & session_type)271 BluetoothAudioCodecs::GetA2dpOffloadCodecCapabilities(
272     const SessionType& session_type) {
273   if (session_type != SessionType::A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH &&
274       session_type != SessionType::A2DP_HARDWARE_OFFLOAD_DECODING_DATAPATH) {
275     return {};
276   }
277   std::vector<CodecCapabilities> offload_a2dp_codec_capabilities =
278       kDefaultOffloadA2dpCodecCapabilities;
279   for (auto& codec_capability : offload_a2dp_codec_capabilities) {
280     switch (codec_capability.codecType) {
281       case CodecType::SBC:
282         codec_capability.capabilities
283             .set<CodecCapabilities::Capabilities::sbcCapabilities>(
284                 kDefaultOffloadSbcCapability);
285         break;
286       case CodecType::AAC:
287         codec_capability.capabilities
288             .set<CodecCapabilities::Capabilities::aacCapabilities>(
289                 kDefaultOffloadAacCapability);
290         break;
291       case CodecType::LDAC:
292         codec_capability.capabilities
293             .set<CodecCapabilities::Capabilities::ldacCapabilities>(
294                 kDefaultOffloadLdacCapability);
295         break;
296       case CodecType::APTX:
297         codec_capability.capabilities
298             .set<CodecCapabilities::Capabilities::aptxCapabilities>(
299                 kDefaultOffloadAptxCapability);
300         break;
301       case CodecType::APTX_HD:
302         codec_capability.capabilities
303             .set<CodecCapabilities::Capabilities::aptxCapabilities>(
304                 kDefaultOffloadAptxHdCapability);
305         break;
306       case CodecType::OPUS:
307         codec_capability.capabilities
308             .set<CodecCapabilities::Capabilities::opusCapabilities>(
309                 kDefaultOffloadOpusCapability);
310         break;
311       case CodecType::UNKNOWN:
312       case CodecType::VENDOR:
313       case CodecType::LC3:
314       case CodecType::APTX_ADAPTIVE:
315         break;
316     }
317   }
318   return offload_a2dp_codec_capabilities;
319 }
320 
IsSoftwarePcmConfigurationValid(const PcmConfiguration & pcm_config)321 bool BluetoothAudioCodecs::IsSoftwarePcmConfigurationValid(
322     const PcmConfiguration& pcm_config) {
323   if (ContainedInVector(kDefaultSoftwarePcmCapabilities.sampleRateHz,
324                         pcm_config.sampleRateHz) &&
325       ContainedInVector(kDefaultSoftwarePcmCapabilities.bitsPerSample,
326                         pcm_config.bitsPerSample) &&
327       ContainedInVector(kDefaultSoftwarePcmCapabilities.channelMode,
328                         pcm_config.channelMode)
329       // data interval is not checked for now
330       // && pcm_config.dataIntervalUs != 0
331   ) {
332     return true;
333   }
334   LOG(WARNING) << __func__
335                << ": Unsupported CodecSpecific=" << pcm_config.toString();
336   return false;
337 }
338 
IsOffloadCodecConfigurationValid(const SessionType & session_type,const CodecConfiguration & codec_config)339 bool BluetoothAudioCodecs::IsOffloadCodecConfigurationValid(
340     const SessionType& session_type, const CodecConfiguration& codec_config) {
341   if (session_type != SessionType::A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH &&
342       session_type != SessionType::A2DP_HARDWARE_OFFLOAD_DECODING_DATAPATH) {
343     LOG(ERROR) << __func__
344                << ": Invalid SessionType=" << toString(session_type);
345     return false;
346   }
347   const CodecConfiguration::CodecSpecific& codec_specific = codec_config.config;
348   switch (codec_config.codecType) {
349     case CodecType::SBC:
350       if (IsOffloadSbcConfigurationValid(codec_specific)) {
351         return true;
352       }
353       break;
354     case CodecType::AAC:
355       if (IsOffloadAacConfigurationValid(codec_specific)) {
356         return true;
357       }
358       break;
359     case CodecType::LDAC:
360       if (IsOffloadLdacConfigurationValid(codec_specific)) {
361         return true;
362       }
363       break;
364     case CodecType::APTX:
365       if (IsOffloadAptxConfigurationValid(codec_specific)) {
366         return true;
367       }
368       break;
369     case CodecType::APTX_HD:
370       if (IsOffloadAptxHdConfigurationValid(codec_specific)) {
371         return true;
372       }
373       break;
374     case CodecType::OPUS:
375       if (IsOffloadOpusConfigurationValid(codec_specific)) {
376         return true;
377       }
378       break;
379     case CodecType::APTX_ADAPTIVE:
380     case CodecType::LC3:
381     case CodecType::UNKNOWN:
382     case CodecType::VENDOR:
383       break;
384   }
385   return false;
386 }
387 
388 std::vector<LeAudioCodecCapabilitiesSetting>
GetLeAudioOffloadCodecCapabilities(const SessionType & session_type)389 BluetoothAudioCodecs::GetLeAudioOffloadCodecCapabilities(
390     const SessionType& session_type) {
391   if (session_type !=
392           SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH &&
393       session_type !=
394           SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH &&
395       session_type !=
396           SessionType::LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH) {
397     return std::vector<LeAudioCodecCapabilitiesSetting>(0);
398   }
399 
400   if (kDefaultOffloadLeAudioCapabilities.empty()) {
401     auto le_audio_offload_setting =
402         BluetoothLeAudioCodecsProvider::ParseFromLeAudioOffloadSettingFile();
403     kDefaultOffloadLeAudioCapabilities =
404         BluetoothLeAudioCodecsProvider::GetLeAudioCodecCapabilities(
405             le_audio_offload_setting);
406   }
407 
408   return kDefaultOffloadLeAudioCapabilities;
409 }
410 
411 }  // namespace audio
412 }  // namespace bluetooth
413 }  // namespace hardware
414 }  // namespace android
415 }  // namespace aidl
416