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