1 /*
2 * Copyright 2016 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 /******************************************************************************
18 *
19 * Utility functions to help build and parse the aptX-HD Codec Information
20 * Element and Media Payload.
21 *
22 ******************************************************************************/
23
24 #define LOG_TAG "bluetooth-a2dp"
25
26 #include "a2dp_vendor_aptx_hd.h"
27
28 #include <bluetooth/log.h>
29 #include <string.h>
30
31 #include "a2dp_vendor.h"
32 #include "a2dp_vendor_aptx_hd_encoder.h"
33 #include "btif/include/btif_av_co.h"
34 #include "internal_include/bt_trace.h"
35 #include "os/log.h"
36 #include "osi/include/osi.h"
37 #include "stack/include/bt_hdr.h"
38
39 using namespace bluetooth;
40
41 // data type for the aptX-HD Codec Information Element */
42 typedef struct {
43 uint32_t vendorId;
44 uint16_t codecId; /* Codec ID for aptX-HD */
45 uint8_t sampleRate; /* Sampling Frequency */
46 uint8_t channelMode; /* STEREO/DUAL/MONO */
47 uint8_t acl_sprint_reserved0;
48 uint8_t acl_sprint_reserved1;
49 uint8_t acl_sprint_reserved2;
50 uint8_t acl_sprint_reserved3;
51 btav_a2dp_codec_bits_per_sample_t bits_per_sample;
52 } tA2DP_APTX_HD_CIE;
53
54 /* aptX-HD Source codec capabilities */
55 static const tA2DP_APTX_HD_CIE a2dp_aptx_hd_source_caps = {
56 A2DP_APTX_HD_VENDOR_ID, /* vendorId */
57 A2DP_APTX_HD_CODEC_ID_BLUETOOTH, /* codecId */
58 (A2DP_APTX_HD_SAMPLERATE_44100 |
59 A2DP_APTX_HD_SAMPLERATE_48000), /* sampleRate */
60 A2DP_APTX_HD_CHANNELS_STEREO, /* channelMode */
61 A2DP_APTX_HD_ACL_SPRINT_RESERVED0, /* acl_sprint_reserved0 */
62 A2DP_APTX_HD_ACL_SPRINT_RESERVED1, /* acl_sprint_reserved1 */
63 A2DP_APTX_HD_ACL_SPRINT_RESERVED2, /* acl_sprint_reserved2 */
64 A2DP_APTX_HD_ACL_SPRINT_RESERVED3, /* acl_sprint_reserved3 */
65 BTAV_A2DP_CODEC_BITS_PER_SAMPLE_24 /* bits_per_sample */
66 };
67
68 /* Default aptX-HD codec configuration */
69 static const tA2DP_APTX_HD_CIE a2dp_aptx_hd_default_config = {
70 A2DP_APTX_HD_VENDOR_ID, /* vendorId */
71 A2DP_APTX_HD_CODEC_ID_BLUETOOTH, /* codecId */
72 A2DP_APTX_HD_SAMPLERATE_48000, /* sampleRate */
73 A2DP_APTX_HD_CHANNELS_STEREO, /* channelMode */
74 A2DP_APTX_HD_ACL_SPRINT_RESERVED0, /* acl_sprint_reserved0 */
75 A2DP_APTX_HD_ACL_SPRINT_RESERVED1, /* acl_sprint_reserved1 */
76 A2DP_APTX_HD_ACL_SPRINT_RESERVED2, /* acl_sprint_reserved2 */
77 A2DP_APTX_HD_ACL_SPRINT_RESERVED3, /* acl_sprint_reserved3 */
78 BTAV_A2DP_CODEC_BITS_PER_SAMPLE_24 /* bits_per_sample */
79 };
80
81 static const tA2DP_ENCODER_INTERFACE a2dp_encoder_interface_aptx_hd = {
82 a2dp_vendor_aptx_hd_encoder_init,
83 a2dp_vendor_aptx_hd_encoder_cleanup,
84 a2dp_vendor_aptx_hd_feeding_reset,
85 a2dp_vendor_aptx_hd_feeding_flush,
86 a2dp_vendor_aptx_hd_get_encoder_interval_ms,
87 a2dp_vendor_aptx_hd_get_effective_frame_size,
88 a2dp_vendor_aptx_hd_send_frames,
89 nullptr // set_transmit_queue_length
90 };
91
92 static tA2DP_STATUS A2DP_CodecInfoMatchesCapabilityAptxHd(
93 const tA2DP_APTX_HD_CIE* p_cap, const uint8_t* p_codec_info,
94 bool is_peer_codec_info);
95
96 // Builds the aptX-HD Media Codec Capabilities byte sequence beginning from the
97 // LOSC octet. |media_type| is the media type |AVDT_MEDIA_TYPE_*|.
98 // |p_ie| is a pointer to the aptX-HD Codec Information Element information.
99 // The result is stored in |p_result|. Returns A2DP_SUCCESS on success,
100 // otherwise the corresponding A2DP error status code.
A2DP_BuildInfoAptxHd(uint8_t media_type,const tA2DP_APTX_HD_CIE * p_ie,uint8_t * p_result)101 static tA2DP_STATUS A2DP_BuildInfoAptxHd(uint8_t media_type,
102 const tA2DP_APTX_HD_CIE* p_ie,
103 uint8_t* p_result) {
104 if (p_ie == NULL || p_result == NULL) {
105 return A2DP_INVALID_PARAMS;
106 }
107
108 *p_result++ = A2DP_APTX_HD_CODEC_LEN;
109 *p_result++ = (media_type << 4);
110 *p_result++ = A2DP_MEDIA_CT_NON_A2DP;
111 *p_result++ = (uint8_t)(p_ie->vendorId & 0x000000FF);
112 *p_result++ = (uint8_t)((p_ie->vendorId & 0x0000FF00) >> 8);
113 *p_result++ = (uint8_t)((p_ie->vendorId & 0x00FF0000) >> 16);
114 *p_result++ = (uint8_t)((p_ie->vendorId & 0xFF000000) >> 24);
115 *p_result++ = (uint8_t)(p_ie->codecId & 0x00FF);
116 *p_result++ = (uint8_t)((p_ie->codecId & 0xFF00) >> 8);
117 *p_result++ = p_ie->sampleRate | p_ie->channelMode;
118 *p_result++ = p_ie->acl_sprint_reserved0;
119 *p_result++ = p_ie->acl_sprint_reserved1;
120 *p_result++ = p_ie->acl_sprint_reserved2;
121 *p_result++ = p_ie->acl_sprint_reserved3;
122
123 return A2DP_SUCCESS;
124 }
125
126 // Parses the aptX-HD Media Codec Capabilities byte sequence beginning from the
127 // LOSC octet. The result is stored in |p_ie|. The byte sequence to parse is
128 // |p_codec_info|. If |is_capability| is true, the byte sequence is
129 // codec capabilities, otherwise is codec configuration.
130 // Returns A2DP_SUCCESS on success, otherwise the corresponding A2DP error
131 // status code.
A2DP_ParseInfoAptxHd(tA2DP_APTX_HD_CIE * p_ie,const uint8_t * p_codec_info,bool is_capability)132 static tA2DP_STATUS A2DP_ParseInfoAptxHd(tA2DP_APTX_HD_CIE* p_ie,
133 const uint8_t* p_codec_info,
134 bool is_capability) {
135 uint8_t losc;
136 uint8_t media_type;
137 tA2DP_CODEC_TYPE codec_type;
138
139 if (p_ie == NULL || p_codec_info == NULL) return A2DP_INVALID_PARAMS;
140
141 // Check the codec capability length
142 losc = *p_codec_info++;
143 if (losc != A2DP_APTX_HD_CODEC_LEN) return A2DP_WRONG_CODEC;
144
145 media_type = (*p_codec_info++) >> 4;
146 codec_type = *p_codec_info++;
147 /* Check the Media Type and Media Codec Type */
148 if (media_type != AVDT_MEDIA_TYPE_AUDIO ||
149 codec_type != A2DP_MEDIA_CT_NON_A2DP) {
150 return A2DP_WRONG_CODEC;
151 }
152
153 // Check the Vendor ID and Codec ID */
154 p_ie->vendorId = (*p_codec_info & 0x000000FF) |
155 (*(p_codec_info + 1) << 8 & 0x0000FF00) |
156 (*(p_codec_info + 2) << 16 & 0x00FF0000) |
157 (*(p_codec_info + 3) << 24 & 0xFF000000);
158 p_codec_info += 4;
159 p_ie->codecId =
160 (*p_codec_info & 0x00FF) | (*(p_codec_info + 1) << 8 & 0xFF00);
161 p_codec_info += 2;
162 if (p_ie->vendorId != A2DP_APTX_HD_VENDOR_ID ||
163 p_ie->codecId != A2DP_APTX_HD_CODEC_ID_BLUETOOTH) {
164 return A2DP_WRONG_CODEC;
165 }
166
167 p_ie->channelMode = *p_codec_info & 0x0F;
168 p_ie->sampleRate = *p_codec_info & 0xF0;
169 p_codec_info++;
170
171 p_ie->acl_sprint_reserved0 = *(p_codec_info++);
172 p_ie->acl_sprint_reserved1 = *(p_codec_info++);
173 p_ie->acl_sprint_reserved2 = *(p_codec_info++);
174 p_ie->acl_sprint_reserved3 = *(p_codec_info++);
175
176 if (is_capability) {
177 // NOTE: The checks here are very liberal. We should be using more
178 // pedantic checks specific to the SRC or SNK as specified in the spec.
179 if (A2DP_BitsSet(p_ie->sampleRate) == A2DP_SET_ZERO_BIT)
180 return A2DP_BAD_SAMP_FREQ;
181 if (A2DP_BitsSet(p_ie->channelMode) == A2DP_SET_ZERO_BIT)
182 return A2DP_BAD_CH_MODE;
183
184 return A2DP_SUCCESS;
185 }
186
187 if (A2DP_BitsSet(p_ie->sampleRate) != A2DP_SET_ONE_BIT)
188 return A2DP_BAD_SAMP_FREQ;
189 if (A2DP_BitsSet(p_ie->channelMode) != A2DP_SET_ONE_BIT)
190 return A2DP_BAD_CH_MODE;
191
192 return A2DP_SUCCESS;
193 }
194
A2DP_IsVendorSourceCodecValidAptxHd(const uint8_t * p_codec_info)195 bool A2DP_IsVendorSourceCodecValidAptxHd(const uint8_t* p_codec_info) {
196 tA2DP_APTX_HD_CIE cfg_cie;
197
198 /* Use a liberal check when parsing the codec info */
199 return (A2DP_ParseInfoAptxHd(&cfg_cie, p_codec_info, false) ==
200 A2DP_SUCCESS) ||
201 (A2DP_ParseInfoAptxHd(&cfg_cie, p_codec_info, true) == A2DP_SUCCESS);
202 }
203
A2DP_IsVendorPeerSinkCodecValidAptxHd(const uint8_t * p_codec_info)204 bool A2DP_IsVendorPeerSinkCodecValidAptxHd(const uint8_t* p_codec_info) {
205 tA2DP_APTX_HD_CIE cfg_cie;
206
207 /* Use a liberal check when parsing the codec info */
208 return (A2DP_ParseInfoAptxHd(&cfg_cie, p_codec_info, false) ==
209 A2DP_SUCCESS) ||
210 (A2DP_ParseInfoAptxHd(&cfg_cie, p_codec_info, true) == A2DP_SUCCESS);
211 }
212
213 // Checks whether A2DP aptX-HD codec configuration matches with a device's
214 // codec capabilities. |p_cap| is the aptX-HD codec configuration.
215 // |p_codec_info| is the device's codec capabilities.
216 // If |is_capability| is true, the byte sequence is codec capabilities,
217 // otherwise is codec configuration.
218 // |p_codec_info| contains the codec capabilities for a peer device that
219 // is acting as an A2DP source.
220 // Returns A2DP_SUCCESS if the codec configuration matches with capabilities,
221 // otherwise the corresponding A2DP error status code.
A2DP_CodecInfoMatchesCapabilityAptxHd(const tA2DP_APTX_HD_CIE * p_cap,const uint8_t * p_codec_info,bool is_capability)222 UNUSED_ATTR static tA2DP_STATUS A2DP_CodecInfoMatchesCapabilityAptxHd(
223 const tA2DP_APTX_HD_CIE* p_cap, const uint8_t* p_codec_info,
224 bool is_capability) {
225 tA2DP_STATUS status;
226 tA2DP_APTX_HD_CIE cfg_cie;
227
228 /* parse configuration */
229 status = A2DP_ParseInfoAptxHd(&cfg_cie, p_codec_info, is_capability);
230 if (status != A2DP_SUCCESS) {
231 log::error("parsing failed {}", status);
232 return status;
233 }
234
235 /* verify that each parameter is in range */
236
237 log::verbose("FREQ peer: 0x{:x}, capability 0x{:x}", cfg_cie.sampleRate,
238 p_cap->sampleRate);
239 log::verbose("CH_MODE peer: 0x{:x}, capability 0x{:x}", cfg_cie.channelMode,
240 p_cap->channelMode);
241
242 /* sampling frequency */
243 if ((cfg_cie.sampleRate & p_cap->sampleRate) == 0) return A2DP_NS_SAMP_FREQ;
244
245 /* channel mode */
246 if ((cfg_cie.channelMode & p_cap->channelMode) == 0) return A2DP_NS_CH_MODE;
247
248 return A2DP_SUCCESS;
249 }
250
A2DP_VendorUsesRtpHeaderAptxHd(bool,const uint8_t *)251 bool A2DP_VendorUsesRtpHeaderAptxHd(bool /* content_protection_enabled */,
252 const uint8_t* /* p_codec_info */) {
253 return true;
254 }
255
A2DP_VendorCodecNameAptxHd(const uint8_t *)256 const char* A2DP_VendorCodecNameAptxHd(const uint8_t* /* p_codec_info */) {
257 return "aptX-HD";
258 }
259
A2DP_VendorCodecTypeEqualsAptxHd(const uint8_t * p_codec_info_a,const uint8_t * p_codec_info_b)260 bool A2DP_VendorCodecTypeEqualsAptxHd(const uint8_t* p_codec_info_a,
261 const uint8_t* p_codec_info_b) {
262 tA2DP_APTX_HD_CIE aptx_hd_cie_a;
263 tA2DP_APTX_HD_CIE aptx_hd_cie_b;
264
265 // Check whether the codec info contains valid data
266 tA2DP_STATUS a2dp_status =
267 A2DP_ParseInfoAptxHd(&aptx_hd_cie_a, p_codec_info_a, true);
268 if (a2dp_status != A2DP_SUCCESS) {
269 log::error("cannot decode codec information: {}", a2dp_status);
270 return false;
271 }
272 a2dp_status = A2DP_ParseInfoAptxHd(&aptx_hd_cie_b, p_codec_info_b, true);
273 if (a2dp_status != A2DP_SUCCESS) {
274 log::error("cannot decode codec information: {}", a2dp_status);
275 return false;
276 }
277
278 return true;
279 }
280
A2DP_VendorCodecEqualsAptxHd(const uint8_t * p_codec_info_a,const uint8_t * p_codec_info_b)281 bool A2DP_VendorCodecEqualsAptxHd(const uint8_t* p_codec_info_a,
282 const uint8_t* p_codec_info_b) {
283 tA2DP_APTX_HD_CIE aptx_hd_cie_a;
284 tA2DP_APTX_HD_CIE aptx_hd_cie_b;
285
286 // Check whether the codec info contains valid data
287 tA2DP_STATUS a2dp_status =
288 A2DP_ParseInfoAptxHd(&aptx_hd_cie_a, p_codec_info_a, true);
289 if (a2dp_status != A2DP_SUCCESS) {
290 log::error("cannot decode codec information: {}", a2dp_status);
291 return false;
292 }
293 a2dp_status = A2DP_ParseInfoAptxHd(&aptx_hd_cie_b, p_codec_info_b, true);
294 if (a2dp_status != A2DP_SUCCESS) {
295 log::error("cannot decode codec information: {}", a2dp_status);
296 return false;
297 }
298
299 return (aptx_hd_cie_a.sampleRate == aptx_hd_cie_b.sampleRate) &&
300 (aptx_hd_cie_a.channelMode == aptx_hd_cie_b.channelMode);
301 }
302
A2DP_VendorGetBitRateAptxHd(const uint8_t * p_codec_info)303 int A2DP_VendorGetBitRateAptxHd(const uint8_t* p_codec_info) {
304 A2dpCodecConfig* CodecConfig = bta_av_get_a2dp_current_codec();
305 tA2DP_BITS_PER_SAMPLE bits_per_sample = CodecConfig->getAudioBitsPerSample();
306 uint16_t samplerate = A2DP_GetTrackSampleRate(p_codec_info);
307 return (samplerate * bits_per_sample * 2) / 4;
308 }
309
A2DP_VendorGetTrackSampleRateAptxHd(const uint8_t * p_codec_info)310 int A2DP_VendorGetTrackSampleRateAptxHd(const uint8_t* p_codec_info) {
311 tA2DP_APTX_HD_CIE aptx_hd_cie;
312
313 // Check whether the codec info contains valid data
314 tA2DP_STATUS a2dp_status =
315 A2DP_ParseInfoAptxHd(&aptx_hd_cie, p_codec_info, false);
316 if (a2dp_status != A2DP_SUCCESS) {
317 log::error("cannot decode codec information: {}", a2dp_status);
318 return -1;
319 }
320
321 if (aptx_hd_cie.sampleRate == A2DP_APTX_HD_SAMPLERATE_44100) return 44100;
322 if (aptx_hd_cie.sampleRate == A2DP_APTX_HD_SAMPLERATE_48000) return 48000;
323
324 return -1;
325 }
326
A2DP_VendorGetTrackBitsPerSampleAptxHd(const uint8_t * p_codec_info)327 int A2DP_VendorGetTrackBitsPerSampleAptxHd(const uint8_t* p_codec_info) {
328 tA2DP_APTX_HD_CIE aptx_hd_cie;
329
330 // Check whether the codec info contains valid data
331 tA2DP_STATUS a2dp_status =
332 A2DP_ParseInfoAptxHd(&aptx_hd_cie, p_codec_info, false);
333 if (a2dp_status != A2DP_SUCCESS) {
334 log::error("cannot decode codec information: {}", a2dp_status);
335 return -1;
336 }
337
338 // NOTE: The bits per sample never changes for aptX-HD
339 return 24;
340 }
341
A2DP_VendorGetTrackChannelCountAptxHd(const uint8_t * p_codec_info)342 int A2DP_VendorGetTrackChannelCountAptxHd(const uint8_t* p_codec_info) {
343 tA2DP_APTX_HD_CIE aptx_hd_cie;
344
345 // Check whether the codec info contains valid data
346 tA2DP_STATUS a2dp_status =
347 A2DP_ParseInfoAptxHd(&aptx_hd_cie, p_codec_info, false);
348 if (a2dp_status != A2DP_SUCCESS) {
349 log::error("cannot decode codec information: {}", a2dp_status);
350 return -1;
351 }
352
353 switch (aptx_hd_cie.channelMode) {
354 case A2DP_APTX_HD_CHANNELS_MONO:
355 return 1;
356 case A2DP_APTX_HD_CHANNELS_STEREO:
357 return 2;
358 }
359
360 return -1;
361 }
362
A2DP_VendorGetPacketTimestampAptxHd(const uint8_t *,const uint8_t * p_data,uint32_t * p_timestamp)363 bool A2DP_VendorGetPacketTimestampAptxHd(const uint8_t* /* p_codec_info */,
364 const uint8_t* p_data,
365 uint32_t* p_timestamp) {
366 // TODO: Is this function really codec-specific?
367 *p_timestamp = *(const uint32_t*)p_data;
368 return true;
369 }
370
A2DP_VendorBuildCodecHeaderAptxHd(const uint8_t *,BT_HDR *,uint16_t)371 bool A2DP_VendorBuildCodecHeaderAptxHd(const uint8_t* /* p_codec_info */,
372 BT_HDR* /* p_buf */,
373 uint16_t /* frames_per_packet */) {
374 // Nothing to do
375 return true;
376 }
377
A2DP_VendorCodecInfoStringAptxHd(const uint8_t * p_codec_info)378 std::string A2DP_VendorCodecInfoStringAptxHd(const uint8_t* p_codec_info) {
379 std::stringstream res;
380 std::string field;
381 tA2DP_STATUS a2dp_status;
382 tA2DP_APTX_HD_CIE aptx_hd_cie;
383
384 a2dp_status = A2DP_ParseInfoAptxHd(&aptx_hd_cie, p_codec_info, true);
385 if (a2dp_status != A2DP_SUCCESS) {
386 res << "A2DP_ParseInfoAptxHd fail: "
387 << loghex(static_cast<uint8_t>(a2dp_status));
388 return res.str();
389 }
390
391 res << "\tname: aptX-HD\n";
392
393 // Sample frequency
394 field.clear();
395 AppendField(&field, (aptx_hd_cie.sampleRate == 0), "NONE");
396 AppendField(&field, (aptx_hd_cie.sampleRate & A2DP_APTX_HD_SAMPLERATE_44100),
397 "44100");
398 AppendField(&field, (aptx_hd_cie.sampleRate & A2DP_APTX_HD_SAMPLERATE_48000),
399 "48000");
400 res << "\tsamp_freq: " << field << " (" << loghex(aptx_hd_cie.sampleRate)
401 << ")\n";
402
403 // Channel mode
404 field.clear();
405 AppendField(&field, (aptx_hd_cie.channelMode == 0), "NONE");
406 AppendField(&field, (aptx_hd_cie.channelMode & A2DP_APTX_HD_CHANNELS_MONO),
407 "Mono");
408 AppendField(&field, (aptx_hd_cie.channelMode & A2DP_APTX_HD_CHANNELS_STEREO),
409 "Stereo");
410 res << "\tch_mode: " << field << " (" << loghex(aptx_hd_cie.channelMode)
411 << ")\n";
412
413 return res.str();
414 }
415
A2DP_VendorGetEncoderInterfaceAptxHd(const uint8_t * p_codec_info)416 const tA2DP_ENCODER_INTERFACE* A2DP_VendorGetEncoderInterfaceAptxHd(
417 const uint8_t* p_codec_info) {
418 if (!A2DP_IsVendorSourceCodecValidAptxHd(p_codec_info)) return NULL;
419
420 return &a2dp_encoder_interface_aptx_hd;
421 }
422
A2DP_VendorAdjustCodecAptxHd(uint8_t * p_codec_info)423 bool A2DP_VendorAdjustCodecAptxHd(uint8_t* p_codec_info) {
424 tA2DP_APTX_HD_CIE cfg_cie;
425
426 // Nothing to do: just verify the codec info is valid
427 if (A2DP_ParseInfoAptxHd(&cfg_cie, p_codec_info, true) != A2DP_SUCCESS)
428 return false;
429
430 return true;
431 }
432
A2DP_VendorSourceCodecIndexAptxHd(const uint8_t * p_codec_info)433 btav_a2dp_codec_index_t A2DP_VendorSourceCodecIndexAptxHd(
434 const uint8_t* p_codec_info) {
435 return BTAV_A2DP_CODEC_INDEX_SOURCE_APTX_HD;
436 }
437
A2DP_VendorCodecIndexStrAptxHd(void)438 const char* A2DP_VendorCodecIndexStrAptxHd(void) { return "aptX-HD"; }
439
A2DP_VendorInitCodecConfigAptxHd(AvdtpSepConfig * p_cfg)440 bool A2DP_VendorInitCodecConfigAptxHd(AvdtpSepConfig* p_cfg) {
441 if (A2DP_BuildInfoAptxHd(AVDT_MEDIA_TYPE_AUDIO, &a2dp_aptx_hd_source_caps,
442 p_cfg->codec_info) != A2DP_SUCCESS) {
443 return false;
444 }
445
446 return true;
447 }
448
A2dpCodecConfigAptxHd(btav_a2dp_codec_priority_t codec_priority)449 A2dpCodecConfigAptxHd::A2dpCodecConfigAptxHd(
450 btav_a2dp_codec_priority_t codec_priority)
451 : A2dpCodecConfig(BTAV_A2DP_CODEC_INDEX_SOURCE_APTX_HD,
452 A2DP_CODEC_ID_APTX_HD, A2DP_VendorCodecIndexStrAptxHd(),
453 codec_priority) {
454 // Compute the local capability
455 if (a2dp_aptx_hd_source_caps.sampleRate & A2DP_APTX_HD_SAMPLERATE_44100) {
456 codec_local_capability_.sample_rate |= BTAV_A2DP_CODEC_SAMPLE_RATE_44100;
457 }
458 if (a2dp_aptx_hd_source_caps.sampleRate & A2DP_APTX_HD_SAMPLERATE_48000) {
459 codec_local_capability_.sample_rate |= BTAV_A2DP_CODEC_SAMPLE_RATE_48000;
460 }
461 codec_local_capability_.bits_per_sample =
462 a2dp_aptx_hd_source_caps.bits_per_sample;
463 if (a2dp_aptx_hd_source_caps.channelMode & A2DP_APTX_HD_CHANNELS_MONO) {
464 codec_local_capability_.channel_mode |= BTAV_A2DP_CODEC_CHANNEL_MODE_MONO;
465 }
466 if (a2dp_aptx_hd_source_caps.channelMode & A2DP_APTX_HD_CHANNELS_STEREO) {
467 codec_local_capability_.channel_mode |= BTAV_A2DP_CODEC_CHANNEL_MODE_STEREO;
468 }
469 }
470
~A2dpCodecConfigAptxHd()471 A2dpCodecConfigAptxHd::~A2dpCodecConfigAptxHd() {}
472
init()473 bool A2dpCodecConfigAptxHd::init() {
474 if (!isValid()) return false;
475
476 // Load the encoder
477 if (A2DP_VendorLoadEncoderAptxHd() != LOAD_SUCCESS) {
478 log::error("cannot load the encoder");
479 return false;
480 }
481
482 return true;
483 }
484
useRtpHeaderMarkerBit() const485 bool A2dpCodecConfigAptxHd::useRtpHeaderMarkerBit() const { return false; }
486
487 //
488 // Selects the best sample rate from |sampleRate|.
489 // The result is stored in |p_result| and p_codec_config|.
490 // Returns true if a selection was made, otherwise false.
491 //
select_best_sample_rate(uint8_t sampleRate,tA2DP_APTX_HD_CIE * p_result,btav_a2dp_codec_config_t * p_codec_config)492 static bool select_best_sample_rate(uint8_t sampleRate,
493 tA2DP_APTX_HD_CIE* p_result,
494 btav_a2dp_codec_config_t* p_codec_config) {
495 if (sampleRate & A2DP_APTX_HD_SAMPLERATE_48000) {
496 p_result->sampleRate = A2DP_APTX_HD_SAMPLERATE_48000;
497 p_codec_config->sample_rate = BTAV_A2DP_CODEC_SAMPLE_RATE_48000;
498 return true;
499 }
500 if (sampleRate & A2DP_APTX_HD_SAMPLERATE_44100) {
501 p_result->sampleRate = A2DP_APTX_HD_SAMPLERATE_44100;
502 p_codec_config->sample_rate = BTAV_A2DP_CODEC_SAMPLE_RATE_44100;
503 return true;
504 }
505 return false;
506 }
507
508 //
509 // Selects the audio sample rate from |p_codec_audio_config|.
510 // |sampleRate| contains the capability.
511 // The result is stored in |p_result| and |p_codec_config|.
512 // Returns true if a selection was made, otherwise false.
513 //
select_audio_sample_rate(const btav_a2dp_codec_config_t * p_codec_audio_config,uint8_t sampleRate,tA2DP_APTX_HD_CIE * p_result,btav_a2dp_codec_config_t * p_codec_config)514 static bool select_audio_sample_rate(
515 const btav_a2dp_codec_config_t* p_codec_audio_config, uint8_t sampleRate,
516 tA2DP_APTX_HD_CIE* p_result, btav_a2dp_codec_config_t* p_codec_config) {
517 switch (p_codec_audio_config->sample_rate) {
518 case BTAV_A2DP_CODEC_SAMPLE_RATE_44100:
519 if (sampleRate & A2DP_APTX_HD_SAMPLERATE_44100) {
520 p_result->sampleRate = A2DP_APTX_HD_SAMPLERATE_44100;
521 p_codec_config->sample_rate = BTAV_A2DP_CODEC_SAMPLE_RATE_44100;
522 return true;
523 }
524 break;
525 case BTAV_A2DP_CODEC_SAMPLE_RATE_48000:
526 if (sampleRate & A2DP_APTX_HD_SAMPLERATE_48000) {
527 p_result->sampleRate = A2DP_APTX_HD_SAMPLERATE_48000;
528 p_codec_config->sample_rate = BTAV_A2DP_CODEC_SAMPLE_RATE_48000;
529 return true;
530 }
531 break;
532 case BTAV_A2DP_CODEC_SAMPLE_RATE_88200:
533 case BTAV_A2DP_CODEC_SAMPLE_RATE_96000:
534 case BTAV_A2DP_CODEC_SAMPLE_RATE_176400:
535 case BTAV_A2DP_CODEC_SAMPLE_RATE_192000:
536 case BTAV_A2DP_CODEC_SAMPLE_RATE_16000:
537 case BTAV_A2DP_CODEC_SAMPLE_RATE_24000:
538 case BTAV_A2DP_CODEC_SAMPLE_RATE_NONE:
539 break;
540 }
541 return false;
542 }
543
544 //
545 // Selects the best bits per sample.
546 // The result is stored in |p_codec_config|.
547 // Returns true if a selection was made, otherwise false.
548 //
select_best_bits_per_sample(btav_a2dp_codec_config_t * p_codec_config)549 static bool select_best_bits_per_sample(
550 btav_a2dp_codec_config_t* p_codec_config) {
551 p_codec_config->bits_per_sample = BTAV_A2DP_CODEC_BITS_PER_SAMPLE_24;
552 return true;
553 }
554
555 //
556 // Selects the audio bits per sample from |p_codec_audio_config|.
557 // The result is stored in |p_codec_config|.
558 // Returns true if a selection was made, otherwise false.
559 //
select_audio_bits_per_sample(const btav_a2dp_codec_config_t * p_codec_audio_config,btav_a2dp_codec_config_t * p_codec_config)560 static bool select_audio_bits_per_sample(
561 const btav_a2dp_codec_config_t* p_codec_audio_config,
562 btav_a2dp_codec_config_t* p_codec_config) {
563 switch (p_codec_audio_config->bits_per_sample) {
564 case BTAV_A2DP_CODEC_BITS_PER_SAMPLE_24:
565 p_codec_config->bits_per_sample = BTAV_A2DP_CODEC_BITS_PER_SAMPLE_24;
566 return true;
567 case BTAV_A2DP_CODEC_BITS_PER_SAMPLE_16:
568 case BTAV_A2DP_CODEC_BITS_PER_SAMPLE_32:
569 case BTAV_A2DP_CODEC_BITS_PER_SAMPLE_NONE:
570 break;
571 }
572 return false;
573 }
574
575 //
576 // Selects the best channel mode from |channelMode|.
577 // The result is stored in |p_result| and |p_codec_config|.
578 // Returns true if a selection was made, otherwise false.
579 //
select_best_channel_mode(uint8_t channelMode,tA2DP_APTX_HD_CIE * p_result,btav_a2dp_codec_config_t * p_codec_config)580 static bool select_best_channel_mode(uint8_t channelMode,
581 tA2DP_APTX_HD_CIE* p_result,
582 btav_a2dp_codec_config_t* p_codec_config) {
583 if (channelMode & A2DP_APTX_HD_CHANNELS_STEREO) {
584 p_result->channelMode = A2DP_APTX_HD_CHANNELS_STEREO;
585 p_codec_config->channel_mode = BTAV_A2DP_CODEC_CHANNEL_MODE_STEREO;
586 return true;
587 }
588 if (channelMode & A2DP_APTX_HD_CHANNELS_MONO) {
589 p_result->channelMode = A2DP_APTX_HD_CHANNELS_MONO;
590 p_codec_config->channel_mode = BTAV_A2DP_CODEC_CHANNEL_MODE_MONO;
591 return true;
592 }
593 return false;
594 }
595
596 //
597 // Selects the audio channel mode from |p_codec_audio_config|.
598 // |channelMode| contains the capability.
599 // The result is stored in |p_result| and |p_codec_config|.
600 // Returns true if a selection was made, otherwise false.
601 //
select_audio_channel_mode(const btav_a2dp_codec_config_t * p_codec_audio_config,uint8_t channelMode,tA2DP_APTX_HD_CIE * p_result,btav_a2dp_codec_config_t * p_codec_config)602 static bool select_audio_channel_mode(
603 const btav_a2dp_codec_config_t* p_codec_audio_config, uint8_t channelMode,
604 tA2DP_APTX_HD_CIE* p_result, btav_a2dp_codec_config_t* p_codec_config) {
605 switch (p_codec_audio_config->channel_mode) {
606 case BTAV_A2DP_CODEC_CHANNEL_MODE_MONO:
607 if (channelMode & A2DP_APTX_HD_CHANNELS_MONO) {
608 p_result->channelMode = A2DP_APTX_HD_CHANNELS_MONO;
609 p_codec_config->channel_mode = BTAV_A2DP_CODEC_CHANNEL_MODE_MONO;
610 return true;
611 }
612 break;
613 case BTAV_A2DP_CODEC_CHANNEL_MODE_STEREO:
614 if (channelMode & A2DP_APTX_HD_CHANNELS_STEREO) {
615 p_result->channelMode = A2DP_APTX_HD_CHANNELS_STEREO;
616 p_codec_config->channel_mode = BTAV_A2DP_CODEC_CHANNEL_MODE_STEREO;
617 return true;
618 }
619 break;
620 case BTAV_A2DP_CODEC_CHANNEL_MODE_NONE:
621 break;
622 }
623
624 return false;
625 }
626
setCodecConfig(const uint8_t * p_peer_codec_info,bool is_capability,uint8_t * p_result_codec_config)627 bool A2dpCodecConfigAptxHd::setCodecConfig(const uint8_t* p_peer_codec_info,
628 bool is_capability,
629 uint8_t* p_result_codec_config) {
630 std::lock_guard<std::recursive_mutex> lock(codec_mutex_);
631 tA2DP_APTX_HD_CIE peer_info_cie;
632 tA2DP_APTX_HD_CIE result_config_cie;
633 uint8_t sampleRate;
634 uint8_t channelMode;
635
636 // Save the internal state
637 btav_a2dp_codec_config_t saved_codec_config = codec_config_;
638 btav_a2dp_codec_config_t saved_codec_capability = codec_capability_;
639 btav_a2dp_codec_config_t saved_codec_selectable_capability =
640 codec_selectable_capability_;
641 btav_a2dp_codec_config_t saved_codec_user_config = codec_user_config_;
642 btav_a2dp_codec_config_t saved_codec_audio_config = codec_audio_config_;
643 uint8_t saved_ota_codec_config[AVDT_CODEC_SIZE];
644 uint8_t saved_ota_codec_peer_capability[AVDT_CODEC_SIZE];
645 uint8_t saved_ota_codec_peer_config[AVDT_CODEC_SIZE];
646 memcpy(saved_ota_codec_config, ota_codec_config_, sizeof(ota_codec_config_));
647 memcpy(saved_ota_codec_peer_capability, ota_codec_peer_capability_,
648 sizeof(ota_codec_peer_capability_));
649 memcpy(saved_ota_codec_peer_config, ota_codec_peer_config_,
650 sizeof(ota_codec_peer_config_));
651
652 tA2DP_STATUS status =
653 A2DP_ParseInfoAptxHd(&peer_info_cie, p_peer_codec_info, is_capability);
654 if (status != A2DP_SUCCESS) {
655 log::error("can't parse peer's capabilities: error = {}", status);
656 goto fail;
657 }
658
659 //
660 // Build the preferred configuration
661 //
662 memset(&result_config_cie, 0, sizeof(result_config_cie));
663 result_config_cie.vendorId = a2dp_aptx_hd_source_caps.vendorId;
664 result_config_cie.codecId = a2dp_aptx_hd_source_caps.codecId;
665
666 //
667 // Select the sample frequency
668 //
669 sampleRate = a2dp_aptx_hd_source_caps.sampleRate & peer_info_cie.sampleRate;
670 codec_config_.sample_rate = BTAV_A2DP_CODEC_SAMPLE_RATE_NONE;
671 switch (codec_user_config_.sample_rate) {
672 case BTAV_A2DP_CODEC_SAMPLE_RATE_44100:
673 if (sampleRate & A2DP_APTX_HD_SAMPLERATE_44100) {
674 result_config_cie.sampleRate = A2DP_APTX_HD_SAMPLERATE_44100;
675 codec_capability_.sample_rate = codec_user_config_.sample_rate;
676 codec_config_.sample_rate = codec_user_config_.sample_rate;
677 }
678 break;
679 case BTAV_A2DP_CODEC_SAMPLE_RATE_48000:
680 if (sampleRate & A2DP_APTX_HD_SAMPLERATE_48000) {
681 result_config_cie.sampleRate = A2DP_APTX_HD_SAMPLERATE_48000;
682 codec_capability_.sample_rate = codec_user_config_.sample_rate;
683 codec_config_.sample_rate = codec_user_config_.sample_rate;
684 }
685 break;
686 case BTAV_A2DP_CODEC_SAMPLE_RATE_88200:
687 case BTAV_A2DP_CODEC_SAMPLE_RATE_96000:
688 case BTAV_A2DP_CODEC_SAMPLE_RATE_176400:
689 case BTAV_A2DP_CODEC_SAMPLE_RATE_192000:
690 case BTAV_A2DP_CODEC_SAMPLE_RATE_16000:
691 case BTAV_A2DP_CODEC_SAMPLE_RATE_24000:
692 case BTAV_A2DP_CODEC_SAMPLE_RATE_NONE:
693 codec_capability_.sample_rate = BTAV_A2DP_CODEC_SAMPLE_RATE_NONE;
694 codec_config_.sample_rate = BTAV_A2DP_CODEC_SAMPLE_RATE_NONE;
695 break;
696 }
697
698 // Select the sample frequency if there is no user preference
699 do {
700 // Compute the selectable capability
701 if (sampleRate & A2DP_APTX_HD_SAMPLERATE_44100) {
702 codec_selectable_capability_.sample_rate |=
703 BTAV_A2DP_CODEC_SAMPLE_RATE_44100;
704 }
705 if (sampleRate & A2DP_APTX_HD_SAMPLERATE_48000) {
706 codec_selectable_capability_.sample_rate |=
707 BTAV_A2DP_CODEC_SAMPLE_RATE_48000;
708 }
709
710 if (codec_config_.sample_rate != BTAV_A2DP_CODEC_SAMPLE_RATE_NONE) break;
711
712 // Compute the common capability
713 if (sampleRate & A2DP_APTX_HD_SAMPLERATE_44100)
714 codec_capability_.sample_rate |= BTAV_A2DP_CODEC_SAMPLE_RATE_44100;
715 if (sampleRate & A2DP_APTX_HD_SAMPLERATE_48000)
716 codec_capability_.sample_rate |= BTAV_A2DP_CODEC_SAMPLE_RATE_48000;
717
718 // No user preference - try the codec audio config
719 if (select_audio_sample_rate(&codec_audio_config_, sampleRate,
720 &result_config_cie, &codec_config_)) {
721 break;
722 }
723
724 // No user preference - try the default config
725 if (select_best_sample_rate(
726 a2dp_aptx_hd_default_config.sampleRate & peer_info_cie.sampleRate,
727 &result_config_cie, &codec_config_)) {
728 break;
729 }
730
731 // No user preference - use the best match
732 if (select_best_sample_rate(sampleRate, &result_config_cie,
733 &codec_config_)) {
734 break;
735 }
736 } while (false);
737 if (codec_config_.sample_rate == BTAV_A2DP_CODEC_SAMPLE_RATE_NONE) {
738 log::error(
739 "cannot match sample frequency: local caps = 0x{:x} peer info = 0x{:x}",
740 a2dp_aptx_hd_source_caps.sampleRate, peer_info_cie.sampleRate);
741 goto fail;
742 }
743
744 //
745 // Select the bits per sample
746 //
747 // NOTE: this information is NOT included in the aptX-HD A2DP codec
748 // description that is sent OTA.
749 codec_config_.bits_per_sample = BTAV_A2DP_CODEC_BITS_PER_SAMPLE_NONE;
750 switch (codec_user_config_.bits_per_sample) {
751 case BTAV_A2DP_CODEC_BITS_PER_SAMPLE_24:
752 codec_capability_.bits_per_sample = codec_user_config_.bits_per_sample;
753 codec_config_.bits_per_sample = codec_user_config_.bits_per_sample;
754 break;
755 case BTAV_A2DP_CODEC_BITS_PER_SAMPLE_16:
756 case BTAV_A2DP_CODEC_BITS_PER_SAMPLE_32:
757 case BTAV_A2DP_CODEC_BITS_PER_SAMPLE_NONE:
758 codec_capability_.bits_per_sample = BTAV_A2DP_CODEC_BITS_PER_SAMPLE_NONE;
759 codec_config_.bits_per_sample = BTAV_A2DP_CODEC_BITS_PER_SAMPLE_NONE;
760 break;
761 }
762
763 // Select the bits per sample if there is no user preference
764 do {
765 // Compute the selectable capability
766 codec_selectable_capability_.bits_per_sample =
767 a2dp_aptx_hd_source_caps.bits_per_sample;
768
769 if (codec_config_.bits_per_sample != BTAV_A2DP_CODEC_BITS_PER_SAMPLE_NONE)
770 break;
771
772 // Compute the common capability
773 codec_capability_.bits_per_sample = BTAV_A2DP_CODEC_BITS_PER_SAMPLE_24;
774
775 // No user preference - try the codec audio config
776 if (select_audio_bits_per_sample(&codec_audio_config_, &codec_config_)) {
777 break;
778 }
779
780 // No user preference - try the default config
781 if (select_best_bits_per_sample(&codec_config_)) {
782 break;
783 }
784
785 // No user preference - use the best match
786 // NOTE: no-op - kept here for consistency
787 if (select_best_bits_per_sample(&codec_config_)) {
788 break;
789 }
790 } while (false);
791 if (codec_config_.bits_per_sample == BTAV_A2DP_CODEC_BITS_PER_SAMPLE_NONE) {
792 log::error("cannot match bits per sample: user preference = 0x{:x}",
793 codec_user_config_.bits_per_sample);
794 goto fail;
795 }
796
797 //
798 // Select the channel mode
799 //
800 channelMode =
801 a2dp_aptx_hd_source_caps.channelMode & peer_info_cie.channelMode;
802 codec_config_.channel_mode = BTAV_A2DP_CODEC_CHANNEL_MODE_NONE;
803 switch (codec_user_config_.channel_mode) {
804 case BTAV_A2DP_CODEC_CHANNEL_MODE_MONO:
805 if (channelMode & A2DP_APTX_HD_CHANNELS_MONO) {
806 result_config_cie.channelMode = A2DP_APTX_HD_CHANNELS_MONO;
807 codec_capability_.channel_mode = codec_user_config_.channel_mode;
808 codec_config_.channel_mode = codec_user_config_.channel_mode;
809 }
810 break;
811 case BTAV_A2DP_CODEC_CHANNEL_MODE_STEREO:
812 if (channelMode & A2DP_APTX_HD_CHANNELS_STEREO) {
813 result_config_cie.channelMode = A2DP_APTX_HD_CHANNELS_STEREO;
814 codec_capability_.channel_mode = codec_user_config_.channel_mode;
815 codec_config_.channel_mode = codec_user_config_.channel_mode;
816 }
817 break;
818 case BTAV_A2DP_CODEC_CHANNEL_MODE_NONE:
819 codec_capability_.channel_mode = BTAV_A2DP_CODEC_CHANNEL_MODE_NONE;
820 codec_config_.channel_mode = BTAV_A2DP_CODEC_CHANNEL_MODE_NONE;
821 break;
822 }
823
824 // Select the channel mode if there is no user preference
825 do {
826 // Compute the selectable capability
827 if (channelMode & A2DP_APTX_HD_CHANNELS_MONO) {
828 codec_selectable_capability_.channel_mode |=
829 BTAV_A2DP_CODEC_CHANNEL_MODE_MONO;
830 }
831 if (channelMode & A2DP_APTX_HD_CHANNELS_STEREO) {
832 codec_selectable_capability_.channel_mode |=
833 BTAV_A2DP_CODEC_CHANNEL_MODE_STEREO;
834 }
835
836 if (codec_config_.channel_mode != BTAV_A2DP_CODEC_CHANNEL_MODE_NONE) break;
837
838 // Compute the common capability
839 if (channelMode & A2DP_APTX_HD_CHANNELS_MONO)
840 codec_capability_.channel_mode |= BTAV_A2DP_CODEC_CHANNEL_MODE_MONO;
841 if (channelMode & A2DP_APTX_HD_CHANNELS_STEREO)
842 codec_capability_.channel_mode |= BTAV_A2DP_CODEC_CHANNEL_MODE_STEREO;
843
844 // No user preference - try the codec audio config
845 if (select_audio_channel_mode(&codec_audio_config_, channelMode,
846 &result_config_cie, &codec_config_)) {
847 break;
848 }
849
850 // No user preference - try the default config
851 if (select_best_channel_mode(
852 a2dp_aptx_hd_default_config.channelMode & peer_info_cie.channelMode,
853 &result_config_cie, &codec_config_)) {
854 break;
855 }
856
857 // No user preference - use the best match
858 if (select_best_channel_mode(channelMode, &result_config_cie,
859 &codec_config_)) {
860 break;
861 }
862 } while (false);
863 if (codec_config_.channel_mode == BTAV_A2DP_CODEC_CHANNEL_MODE_NONE) {
864 log::error(
865 "cannot match channel mode: local caps = 0x{:x} peer info = 0x{:x}",
866 a2dp_aptx_hd_source_caps.channelMode, peer_info_cie.channelMode);
867 goto fail;
868 }
869
870 //
871 // Set the rest of the fields as bit-wise AND operation
872 //
873 result_config_cie.acl_sprint_reserved0 =
874 a2dp_aptx_hd_source_caps.acl_sprint_reserved0 &
875 peer_info_cie.acl_sprint_reserved0;
876 result_config_cie.acl_sprint_reserved1 =
877 a2dp_aptx_hd_source_caps.acl_sprint_reserved1 &
878 peer_info_cie.acl_sprint_reserved1;
879 result_config_cie.acl_sprint_reserved2 =
880 a2dp_aptx_hd_source_caps.acl_sprint_reserved2 &
881 peer_info_cie.acl_sprint_reserved2;
882 result_config_cie.acl_sprint_reserved3 =
883 a2dp_aptx_hd_source_caps.acl_sprint_reserved3 &
884 peer_info_cie.acl_sprint_reserved3;
885
886 if (A2DP_BuildInfoAptxHd(AVDT_MEDIA_TYPE_AUDIO, &result_config_cie,
887 p_result_codec_config) != A2DP_SUCCESS) {
888 goto fail;
889 }
890
891 //
892 // Copy the codec-specific fields if they are not zero
893 //
894 if (codec_user_config_.codec_specific_1 != 0)
895 codec_config_.codec_specific_1 = codec_user_config_.codec_specific_1;
896 if (codec_user_config_.codec_specific_2 != 0)
897 codec_config_.codec_specific_2 = codec_user_config_.codec_specific_2;
898 if (codec_user_config_.codec_specific_3 != 0)
899 codec_config_.codec_specific_3 = codec_user_config_.codec_specific_3;
900 if (codec_user_config_.codec_specific_4 != 0)
901 codec_config_.codec_specific_4 = codec_user_config_.codec_specific_4;
902
903 // Create a local copy of the peer codec capability/config, and the
904 // result codec config.
905 if (is_capability) {
906 status = A2DP_BuildInfoAptxHd(AVDT_MEDIA_TYPE_AUDIO, &peer_info_cie,
907 ota_codec_peer_capability_);
908 } else {
909 status = A2DP_BuildInfoAptxHd(AVDT_MEDIA_TYPE_AUDIO, &peer_info_cie,
910 ota_codec_peer_config_);
911 }
912 log::assert_that(status == A2DP_SUCCESS,
913 "assert failed: status == A2DP_SUCCESS");
914 status = A2DP_BuildInfoAptxHd(AVDT_MEDIA_TYPE_AUDIO, &result_config_cie,
915 ota_codec_config_);
916 log::assert_that(status == A2DP_SUCCESS,
917 "assert failed: status == A2DP_SUCCESS");
918 return true;
919
920 fail:
921 // Restore the internal state
922 codec_config_ = saved_codec_config;
923 codec_capability_ = saved_codec_capability;
924 codec_selectable_capability_ = saved_codec_selectable_capability;
925 codec_user_config_ = saved_codec_user_config;
926 codec_audio_config_ = saved_codec_audio_config;
927 memcpy(ota_codec_config_, saved_ota_codec_config, sizeof(ota_codec_config_));
928 memcpy(ota_codec_peer_capability_, saved_ota_codec_peer_capability,
929 sizeof(ota_codec_peer_capability_));
930 memcpy(ota_codec_peer_config_, saved_ota_codec_peer_config,
931 sizeof(ota_codec_peer_config_));
932 return false;
933 }
934
setPeerCodecCapabilities(const uint8_t * p_peer_codec_capabilities)935 bool A2dpCodecConfigAptxHd::setPeerCodecCapabilities(
936 const uint8_t* p_peer_codec_capabilities) {
937 std::lock_guard<std::recursive_mutex> lock(codec_mutex_);
938 tA2DP_APTX_HD_CIE peer_info_cie;
939 uint8_t sampleRate;
940 uint8_t channelMode;
941
942 // Save the internal state
943 btav_a2dp_codec_config_t saved_codec_selectable_capability =
944 codec_selectable_capability_;
945 uint8_t saved_ota_codec_peer_capability[AVDT_CODEC_SIZE];
946 memcpy(saved_ota_codec_peer_capability, ota_codec_peer_capability_,
947 sizeof(ota_codec_peer_capability_));
948
949 tA2DP_STATUS status =
950 A2DP_ParseInfoAptxHd(&peer_info_cie, p_peer_codec_capabilities, true);
951 if (status != A2DP_SUCCESS) {
952 log::error("can't parse peer's capabilities: error = {}", status);
953 goto fail;
954 }
955
956 // Compute the selectable capability - sample rate
957 sampleRate = a2dp_aptx_hd_source_caps.sampleRate & peer_info_cie.sampleRate;
958 if (sampleRate & A2DP_APTX_HD_SAMPLERATE_44100) {
959 codec_selectable_capability_.sample_rate |=
960 BTAV_A2DP_CODEC_SAMPLE_RATE_44100;
961 }
962 if (sampleRate & A2DP_APTX_HD_SAMPLERATE_48000) {
963 codec_selectable_capability_.sample_rate |=
964 BTAV_A2DP_CODEC_SAMPLE_RATE_48000;
965 }
966
967 // Compute the selectable capability - bits per sample
968 codec_selectable_capability_.bits_per_sample =
969 a2dp_aptx_hd_source_caps.bits_per_sample;
970
971 // Compute the selectable capability - channel mode
972 channelMode =
973 a2dp_aptx_hd_source_caps.channelMode & peer_info_cie.channelMode;
974 if (channelMode & A2DP_APTX_HD_CHANNELS_MONO) {
975 codec_selectable_capability_.channel_mode |=
976 BTAV_A2DP_CODEC_CHANNEL_MODE_MONO;
977 }
978 if (channelMode & A2DP_APTX_HD_CHANNELS_STEREO) {
979 codec_selectable_capability_.channel_mode |=
980 BTAV_A2DP_CODEC_CHANNEL_MODE_STEREO;
981 }
982
983 status = A2DP_BuildInfoAptxHd(AVDT_MEDIA_TYPE_AUDIO, &peer_info_cie,
984 ota_codec_peer_capability_);
985 log::assert_that(status == A2DP_SUCCESS,
986 "assert failed: status == A2DP_SUCCESS");
987 return true;
988
989 fail:
990 // Restore the internal state
991 codec_selectable_capability_ = saved_codec_selectable_capability;
992 memcpy(ota_codec_peer_capability_, saved_ota_codec_peer_capability,
993 sizeof(ota_codec_peer_capability_));
994 return false;
995 }
996