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 #define LOG_TAG "a2dp_vendor_ldac_decoder"
18 #define ATRACE_TAG ATRACE_TAG_AUDIO
19 
20 #include "a2dp_vendor_ldac_decoder.h"
21 
22 #ifndef OS_GENERIC
23 #include <cutils/trace.h>
24 #endif
25 #include <dlfcn.h>
26 #include <inttypes.h>
27 #include <pthread.h>
28 #include <stdio.h>
29 #include <string.h>
30 
31 #include <ldacBT.h>
32 #include <ldacBT_bco_for_fluoride.h>
33 
34 #include "a2dp_vendor.h"
35 #include "a2dp_vendor_ldac.h"
36 #include "bt_common.h"
37 #include "osi/include/log.h"
38 #include "osi/include/osi.h"
39 
40 //
41 // Decoder for LDAC Source Codec
42 //
43 
44 //
45 // The LDAC BCO shared library, and the functions to use
46 //
47 static const char* LDAC_BCO_LIB_NAME = "libldacBT_bco.so";
48 static void* ldac_bco_lib_handle = NULL;
49 
50 static const char* LDAC_BCO_INIT_NAME = "ldac_BCO_init";
51 typedef HANDLE_LDAC_BCO (*tLDAC_BCO_INIT)(
52     decoded_data_callback_t decode_callback);
53 
54 static const char* LDAC_BCO_CLEANUP_NAME = "ldac_BCO_cleanup";
55 typedef int32_t (*tLDAC_BCO_CLEANUP)(HANDLE_LDAC_BCO hLdacBco);
56 
57 static const char* LDAC_BCO_DECODE_PACKET_NAME = "ldac_BCO_decode_packet";
58 typedef int32_t (*tLDAC_BCO_DECODE_PACKET)(HANDLE_LDAC_BCO hLdacBco, void* data,
59                                            int32_t length);
60 
61 static const char* LDAC_BCO_START_NAME = "ldac_BCO_start";
62 typedef int32_t (*tLDAC_BCO_START)(HANDLE_LDAC_BCO hLdacBco);
63 
64 static const char* LDAC_BCO_SUSPEND_NAME = "ldac_BCO_suspend";
65 typedef int32_t (*tLDAC_BCO_SUSPEND)(HANDLE_LDAC_BCO hLdacBco);
66 
67 static const char* LDAC_BCO_CONFIGURE_NAME = "ldac_BCO_configure";
68 typedef int32_t (*tLDAC_BCO_CONFIGURE)(HANDLE_LDAC_BCO hLdacBco,
69                                        int32_t sample_rate,
70                                        int32_t bits_per_sample,
71                                        int32_t channel_mode);
72 
73 static tLDAC_BCO_INIT ldac_BCO_init_func;
74 static tLDAC_BCO_CLEANUP ldac_BCO_cleanup_func;
75 static tLDAC_BCO_DECODE_PACKET ldac_BCO_decode_packet_func;
76 static tLDAC_BCO_START ldac_BCO_start_func;
77 static tLDAC_BCO_SUSPEND ldac_BCO_suspend_func;
78 static tLDAC_BCO_CONFIGURE ldac_BCO_configure_func;
79 
80 // offset
81 #if (BTA_AV_CO_CP_SCMS_T == TRUE)
82 #define A2DP_LDAC_OFFSET (AVDT_MEDIA_OFFSET + A2DP_LDAC_MPL_HDR_LEN + 1)
83 #else
84 #define A2DP_LDAC_OFFSET (AVDT_MEDIA_OFFSET + A2DP_LDAC_MPL_HDR_LEN)
85 #endif
86 
87 typedef struct {
88   uint32_t sample_rate;
89   uint8_t channel_mode;
90   uint8_t bits_per_sample;
91   int pcm_wlength;
92   LDACBT_SMPL_FMT_T pcm_fmt;
93 } tA2DP_LDAC_DECODER_PARAMS;
94 
95 typedef struct {
96   pthread_mutex_t mutex;
97   bool use_SCMS_T;
98   bool is_peer_edr;          // True if the peer device supports EDR
99   bool peer_supports_3mbps;  // True if the peer device supports 3Mbps EDR
100   uint16_t peer_mtu;         // MTU of the A2DP peer
101   uint32_t timestamp;        // Timestamp for the A2DP frames
102 
103   HANDLE_LDAC_BCO ldac_handle_bco;
104   bool has_ldac_handle;  // True if ldac_handle is valid
105   unsigned char* decode_buf;
106   decoded_data_callback_t decode_callback;
107 } tA2DP_LDAC_DECODER_CB;
108 
109 static tA2DP_LDAC_DECODER_CB a2dp_ldac_decoder_cb;
110 
load_func(const char * func_name)111 static void* load_func(const char* func_name) {
112   void* func_ptr = dlsym(ldac_bco_lib_handle, func_name);
113   if (func_ptr == NULL) {
114     LOG_ERROR("%s: cannot find function '%s' in the decoder library: %s",
115               __func__, func_name, dlerror());
116     A2DP_VendorUnloadDecoderLdac();
117     return NULL;
118   }
119   return func_ptr;
120 }
121 
A2DP_VendorLoadDecoderLdac(void)122 bool A2DP_VendorLoadDecoderLdac(void) {
123   if (ldac_bco_lib_handle != NULL) return true;  // Already loaded
124 
125   // Initialize the control block
126   memset(&a2dp_ldac_decoder_cb, 0, sizeof(a2dp_ldac_decoder_cb));
127 
128   pthread_mutex_init(&(a2dp_ldac_decoder_cb.mutex), NULL);
129 
130   // Open the decoder library
131   ldac_bco_lib_handle = dlopen(LDAC_BCO_LIB_NAME, RTLD_NOW);
132   if (ldac_bco_lib_handle == NULL) {
133     LOG_ERROR("%s: cannot open LDAC decoder library %s: %s", __func__,
134               LDAC_BCO_LIB_NAME, dlerror());
135     return false;
136   }
137 
138   // Load all functions
139   ldac_BCO_init_func = (tLDAC_BCO_INIT)load_func(LDAC_BCO_INIT_NAME);
140   if (ldac_BCO_init_func == NULL) return false;
141 
142   ldac_BCO_cleanup_func = (tLDAC_BCO_CLEANUP)load_func(LDAC_BCO_CLEANUP_NAME);
143   if (ldac_BCO_cleanup_func == NULL) return false;
144 
145   ldac_BCO_decode_packet_func =
146       (tLDAC_BCO_DECODE_PACKET)load_func(LDAC_BCO_DECODE_PACKET_NAME);
147   if (ldac_BCO_decode_packet_func == NULL) return false;
148 
149   ldac_BCO_start_func = (tLDAC_BCO_START)load_func(LDAC_BCO_START_NAME);
150   if (ldac_BCO_start_func == NULL) return false;
151 
152   ldac_BCO_suspend_func = (tLDAC_BCO_SUSPEND)load_func(LDAC_BCO_SUSPEND_NAME);
153   if (ldac_BCO_suspend_func == NULL) return false;
154 
155   ldac_BCO_configure_func =
156       (tLDAC_BCO_CONFIGURE)load_func(LDAC_BCO_CONFIGURE_NAME);
157   if (ldac_BCO_configure_func == NULL) return false;
158 
159   return true;
160 }
161 
A2DP_VendorUnloadDecoderLdac(void)162 void A2DP_VendorUnloadDecoderLdac(void) {
163   // Cleanup any LDAC-related state
164   if (a2dp_ldac_decoder_cb.has_ldac_handle && ldac_BCO_cleanup_func != NULL)
165     ldac_BCO_cleanup_func(a2dp_ldac_decoder_cb.ldac_handle_bco);
166   pthread_mutex_destroy(&(a2dp_ldac_decoder_cb.mutex));
167   memset(&a2dp_ldac_decoder_cb, 0, sizeof(a2dp_ldac_decoder_cb));
168 
169   ldac_BCO_init_func = NULL;
170   ldac_BCO_cleanup_func = NULL;
171   ldac_BCO_decode_packet_func = NULL;
172   ldac_BCO_start_func = NULL;
173   ldac_BCO_suspend_func = NULL;
174   ldac_BCO_configure_func = NULL;
175 
176   if (ldac_bco_lib_handle != NULL) {
177     dlclose(ldac_bco_lib_handle);
178     ldac_bco_lib_handle = NULL;
179   }
180 }
181 
a2dp_vendor_ldac_decoder_init(decoded_data_callback_t decode_callback)182 bool a2dp_vendor_ldac_decoder_init(decoded_data_callback_t decode_callback) {
183   pthread_mutex_lock(&(a2dp_ldac_decoder_cb.mutex));
184 
185   if (a2dp_ldac_decoder_cb.has_ldac_handle)
186     ldac_BCO_cleanup_func(a2dp_ldac_decoder_cb.ldac_handle_bco);
187 
188   a2dp_ldac_decoder_cb.ldac_handle_bco = ldac_BCO_init_func(decode_callback);
189   a2dp_ldac_decoder_cb.has_ldac_handle =
190       (a2dp_ldac_decoder_cb.ldac_handle_bco != NULL);
191 
192   pthread_mutex_unlock(&(a2dp_ldac_decoder_cb.mutex));
193   return true;
194 }
195 
a2dp_vendor_ldac_decoder_cleanup(void)196 void a2dp_vendor_ldac_decoder_cleanup(void) {
197   pthread_mutex_lock(&(a2dp_ldac_decoder_cb.mutex));
198   if (a2dp_ldac_decoder_cb.has_ldac_handle)
199     ldac_BCO_cleanup_func(a2dp_ldac_decoder_cb.ldac_handle_bco);
200   a2dp_ldac_decoder_cb.ldac_handle_bco = NULL;
201   pthread_mutex_unlock(&(a2dp_ldac_decoder_cb.mutex));
202 }
203 
a2dp_vendor_ldac_decoder_decode_packet(BT_HDR * p_buf)204 bool a2dp_vendor_ldac_decoder_decode_packet(BT_HDR* p_buf) {
205   if (p_buf == nullptr) {
206     LOG_ERROR("%s Dropping packet with nullptr", __func__);
207     return false;
208   }
209   pthread_mutex_lock(&(a2dp_ldac_decoder_cb.mutex));
210   unsigned char* pBuffer =
211       reinterpret_cast<unsigned char*>(p_buf->data + p_buf->offset);
212   //  unsigned int bufferSize = p_buf->len;
213   unsigned int bytesValid = p_buf->len;
214   if (bytesValid == 0) {
215     pthread_mutex_unlock(&(a2dp_ldac_decoder_cb.mutex));
216     LOG_WARN("%s Dropping packet with zero length", __func__);
217     return false;
218   }
219 
220   LDACBT_SMPL_FMT_T fmt;
221   int bs_bytes, frame_number;
222 
223   fmt = LDACBT_SMPL_FMT_S32;
224   frame_number = (int)pBuffer[0];
225   bs_bytes = (int)bytesValid;
226   bytesValid -= 1;
227   LOG_INFO("%s:INPUT size : %d, frame : %d", __func__, bs_bytes, frame_number);
228 
229   if (a2dp_ldac_decoder_cb.has_ldac_handle)
230     ldac_BCO_decode_packet_func(a2dp_ldac_decoder_cb.ldac_handle_bco, pBuffer,
231                                 bs_bytes);
232 
233   pthread_mutex_unlock(&(a2dp_ldac_decoder_cb.mutex));
234   return true;
235 }
236 
a2dp_vendor_ldac_decoder_start(void)237 void a2dp_vendor_ldac_decoder_start(void) {
238   pthread_mutex_lock(&(a2dp_ldac_decoder_cb.mutex));
239   LOG_INFO("%s", __func__);
240   if (a2dp_ldac_decoder_cb.has_ldac_handle)
241     ldac_BCO_start_func(a2dp_ldac_decoder_cb.ldac_handle_bco);
242   pthread_mutex_unlock(&(a2dp_ldac_decoder_cb.mutex));
243 }
244 
a2dp_vendor_ldac_decoder_suspend(void)245 void a2dp_vendor_ldac_decoder_suspend(void) {
246   pthread_mutex_lock(&(a2dp_ldac_decoder_cb.mutex));
247   LOG_INFO("%s", __func__);
248   if (a2dp_ldac_decoder_cb.has_ldac_handle)
249     ldac_BCO_suspend_func(a2dp_ldac_decoder_cb.ldac_handle_bco);
250   pthread_mutex_unlock(&(a2dp_ldac_decoder_cb.mutex));
251 }
252 
a2dp_vendor_ldac_decoder_configure(const uint8_t * p_codec_info)253 void a2dp_vendor_ldac_decoder_configure(const uint8_t* p_codec_info) {
254   int32_t sample_rate;
255   int32_t bits_per_sample;
256   int32_t channel_mode;
257 
258   if (p_codec_info == NULL) {
259     LOG_ERROR("%s: p_codec_info is NULL", __func__);
260     return;
261   }
262 
263   pthread_mutex_lock(&(a2dp_ldac_decoder_cb.mutex));
264   sample_rate = A2DP_VendorGetTrackSampleRateLdac(p_codec_info);
265   bits_per_sample = A2DP_VendorGetTrackBitsPerSampleLdac(p_codec_info);
266   channel_mode = A2DP_VendorGetChannelModeCodeLdac(p_codec_info);
267 
268   LOG_INFO("%s , sample_rate=%d, bits_per_sample=%d, channel_mode=%d", __func__,
269            sample_rate, bits_per_sample, channel_mode);
270 
271   if (a2dp_ldac_decoder_cb.has_ldac_handle)
272     ldac_BCO_configure_func(a2dp_ldac_decoder_cb.ldac_handle_bco, sample_rate,
273                             bits_per_sample, channel_mode);
274   pthread_mutex_unlock(&(a2dp_ldac_decoder_cb.mutex));
275 }
276