blob: 803cf4a8e03bf9c196ea25159473533fbfb1122d [file] [log] [blame]
Naresh Tanniru9d027a62015-03-13 01:32:10 +05301/*
Naresh Tannirued694c82017-02-07 17:01:28 +05302* Copyright (c) 2015-2017, The Linux Foundation. All rights reserved.
Naresh Tanniru9d027a62015-03-13 01:32:10 +05303*
4* Redistribution and use in source and binary forms, with or without
5* modification, are permitted provided that the following conditions are
6* met:
7* * Redistributions of source code must retain the above copyright
8* notice, this list of conditions and the following disclaimer.
9* * Redistributions in binary form must reproduce the above
10* copyright notice, this list of conditions and the following
11* disclaimer in the documentation and/or other materials provided
12* with the distribution.
13* * Neither the name of The Linux Foundation nor the names of its
14* contributors may be used to endorse or promote products derived
15* from this software without specific prior written permission.
16*
17* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
18* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
19* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
20* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
21* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
24* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
25* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
26* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
27* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28*/
29#define LOG_TAG "split_a2dp"
30/*#define LOG_NDEBUG 0*/
31#define LOG_NDDEBUG 0
32#include <errno.h>
33#include <cutils/log.h>
34#include <dlfcn.h>
35#include "audio_hw.h"
36#include "platform.h"
37#include "platform_api.h"
38#include <stdlib.h>
39#include <cutils/str_parms.h>
40#include <hardware/audio.h>
41#include <hardware/hardware.h>
42#include <cutils/properties.h>
43
Revathi Uddaraju1eac8b02017-05-18 17:13:33 +053044#ifdef DYNAMIC_LOG_ENABLED
45#include <log_xml_parser.h>
46#define LOG_MASK HAL_MOD_FILE_A2DP
47#include <log_utils.h>
48#endif
49
Naresh Tanniru9d027a62015-03-13 01:32:10 +053050#ifdef SPLIT_A2DP_ENABLED
51#define AUDIO_PARAMETER_A2DP_STARTED "A2dpStarted"
52#define BT_IPC_LIB_NAME "libbthost_if.so"
53#define ENC_MEDIA_FMT_NONE 0
54#define ENC_MEDIA_FMT_AAC 0x00010DA6
55#define ENC_MEDIA_FMT_APTX 0x000131ff
56#define ENC_MEDIA_FMT_APTX_HD 0x00013200
57#define ENC_MEDIA_FMT_SBC 0x00010BF2
Preetam Singh Ranawat0d645ea2017-08-07 18:12:07 +053058#define ENC_MEDIA_FMT_CELT 0x00013221
Naresh Tanniru9d027a62015-03-13 01:32:10 +053059#define MEDIA_FMT_AAC_AOT_LC 2
60#define MEDIA_FMT_AAC_AOT_SBR 5
61#define MEDIA_FMT_AAC_AOT_PS 29
Naresh Tanniru9d027a62015-03-13 01:32:10 +053062#define PCM_CHANNEL_L 1
63#define PCM_CHANNEL_R 2
64#define PCM_CHANNEL_C 3
65#define MEDIA_FMT_SBC_CHANNEL_MODE_MONO 1
66#define MEDIA_FMT_SBC_CHANNEL_MODE_STEREO 2
67#define MEDIA_FMT_SBC_CHANNEL_MODE_DUAL_MONO 8
68#define MEDIA_FMT_SBC_CHANNEL_MODE_JOINT_STEREO 9
69#define MEDIA_FMT_SBC_ALLOCATION_METHOD_LOUDNESS 0
70#define MEDIA_FMT_SBC_ALLOCATION_METHOD_SNR 1
71#define MIXER_ENC_CONFIG_BLOCK "SLIM_7_RX Encoder Config"
Naresh Tanniruf5ba8d02016-09-29 18:06:37 +053072#define MIXER_ENC_BIT_FORMAT "AFE Input Bit Format"
Preetam Singh Ranawatc2bef792017-11-22 10:59:15 +053073#define MIXER_SCRAMBLER_MODE "AFE Scrambler Mode"
74#define MIXER_SAMPLE_RATE "BT SampleRate"
75#define MIXER_AFE_IN_CHANNELS "AFE Input Channels"
Naresh Tanniru9d027a62015-03-13 01:32:10 +053076#define MIXER_ENC_FMT_SBC "SBC"
77#define MIXER_ENC_FMT_AAC "AAC"
78#define MIXER_ENC_FMT_APTX "APTX"
79#define MIXER_ENC_FMT_APTXHD "APTXHD"
80#define MIXER_ENC_FMT_NONE "NONE"
yidongh0515e042017-07-06 15:00:34 +080081#define ENCODER_LATENCY_SBC 10
82#define ENCODER_LATENCY_APTX 40
83#define ENCODER_LATENCY_APTX_HD 20
84#define ENCODER_LATENCY_AAC 70
Preetam Singh Ranawat0d645ea2017-08-07 18:12:07 +053085//To Do: Fine Tune Encoder CELT latency.
86#define ENCODER_LATENCY_CELT 40
yidongh0515e042017-07-06 15:00:34 +080087#define DEFAULT_SINK_LATENCY_SBC 140
88#define DEFAULT_SINK_LATENCY_APTX 160
89#define DEFAULT_SINK_LATENCY_APTX_HD 180
90#define DEFAULT_SINK_LATENCY_AAC 180
Preetam Singh Ranawat0d645ea2017-08-07 18:12:07 +053091//To Do: Fine Tune Default CELT Latency.
92#define DEFAULT_SINK_LATENCY_CELT 180
93
94/*
95 * Below enum values are extended from audio_base.h to
96 * to keep encoder codec type local to bthost_ipc
97 * and audio_hal as these are intended only for handshake
98 * between IPC lib and Audio HAL.
99 */
100typedef enum {
101 ENC_CODEC_TYPE_INVALID = 4294967295u, // 0xFFFFFFFFUL
102 ENC_CODEC_TYPE_AAC = 67108864u, // 0x04000000UL
103 ENC_CODEC_TYPE_SBC = 520093696u, // 0x1F000000UL
104 ENC_CODEC_TYPE_APTX = 536870912u, // 0x20000000UL
105 ENC_CODEC_TYPE_APTX_HD = 553648128u, // 0x21000000UL
Aniket Kumar Lata53e54b12017-08-24 17:45:38 -0700106 ENC_CODEC_TYPE_APTX_DUAL_MONO = 570425344u, // 0x22000000UL
Preetam Singh Ranawat0d645ea2017-08-07 18:12:07 +0530107 ENC_CODEC_TYPE_CELT = 603979776u, // 0x24000000UL
108}enc_codec_t;
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530109
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530110typedef int (*audio_stream_open_t)(void);
111typedef int (*audio_stream_close_t)(void);
112typedef int (*audio_start_stream_t)(void);
113typedef int (*audio_stop_stream_t)(void);
114typedef int (*audio_suspend_stream_t)(void);
115typedef void (*audio_handoff_triggered_t)(void);
116typedef void (*clear_a2dpsuspend_flag_t)(void);
117typedef void * (*audio_get_codec_config_t)(uint8_t *multicast_status,uint8_t *num_dev,
Preetam Singh Ranawat0d645ea2017-08-07 18:12:07 +0530118 enc_codec_t *codec_type);
Preetam Singh Ranawata1849ba2017-02-06 14:10:11 +0530119typedef int (*audio_check_a2dp_ready_t)(void);
yidongh0515e042017-07-06 15:00:34 +0800120typedef uint16_t (*audio_get_a2dp_sink_latency_t)(void);
Preetam Singh Ranawatc2bef792017-11-22 10:59:15 +0530121typedef int (*audio_is_scrambling_enabled_t)(void);
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530122
123enum A2DP_STATE {
124 A2DP_STATE_CONNECTED,
125 A2DP_STATE_STARTED,
126 A2DP_STATE_STOPPED,
127 A2DP_STATE_DISCONNECTED,
128};
129
130/* structure used to update a2dp state machine
131 * to communicate IPC library
132 * to store DSP encoder configuration information
133 */
134struct a2dp_data {
135 struct audio_device *adev;
136 void *bt_lib_handle;
137 audio_stream_open_t audio_stream_open;
138 audio_stream_close_t audio_stream_close;
139 audio_start_stream_t audio_start_stream;
140 audio_stop_stream_t audio_stop_stream;
141 audio_suspend_stream_t audio_suspend_stream;
142 audio_handoff_triggered_t audio_handoff_triggered;
143 clear_a2dpsuspend_flag_t clear_a2dpsuspend_flag;
144 audio_get_codec_config_t audio_get_codec_config;
Preetam Singh Ranawata1849ba2017-02-06 14:10:11 +0530145 audio_check_a2dp_ready_t audio_check_a2dp_ready;
yidongh0515e042017-07-06 15:00:34 +0800146 audio_get_a2dp_sink_latency_t audio_get_a2dp_sink_latency;
Preetam Singh Ranawatc2bef792017-11-22 10:59:15 +0530147 audio_is_scrambling_enabled_t audio_is_scrambling_enabled;
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530148 enum A2DP_STATE bt_state;
Preetam Singh Ranawat0d645ea2017-08-07 18:12:07 +0530149 enc_codec_t bt_encoder_format;
Naresh Tanniruf5ba8d02016-09-29 18:06:37 +0530150 uint32_t enc_sampling_rate;
Preetam Singh Ranawatc2bef792017-11-22 10:59:15 +0530151 uint32_t enc_channels;
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530152 bool a2dp_started;
153 bool a2dp_suspended;
154 int a2dp_total_active_session_request;
155 bool is_a2dp_offload_supported;
156 bool is_handoff_in_progress;
Aniket Kumar Lata53e54b12017-08-24 17:45:38 -0700157 bool is_aptx_dual_mono_supported;
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530158};
159
160struct a2dp_data a2dp;
161
162/* START of DSP configurable structures
163 * These values should match with DSP interface defintion
164 */
165
166/* AAC encoder configuration structure. */
167typedef struct aac_enc_cfg_t aac_enc_cfg_t;
168
169/* supported enc_mode are AAC_LC, AAC_SBR, AAC_PS
170 * supported aac_fmt_flag are ADTS/RAW
171 * supported channel_cfg are Native mode, Mono , Stereo
172 */
173struct aac_enc_cfg_t {
174 uint32_t enc_format;
175 uint32_t bit_rate;
176 uint32_t enc_mode;
177 uint16_t aac_fmt_flag;
Naresh Tannirua42d0bd2016-09-21 15:30:46 +0530178 uint16_t channel_cfg;
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530179 uint32_t sample_rate;
Aniket Kumar Lata53e54b12017-08-24 17:45:38 -0700180} __packed;
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530181
182/* SBC encoder configuration structure. */
183typedef struct sbc_enc_cfg_t sbc_enc_cfg_t;
184
185/* supported num_subbands are 4/8
186 * supported blk_len are 4, 8, 12, 16
187 * supported channel_mode are MONO, STEREO, DUAL_MONO, JOINT_STEREO
188 * supported alloc_method are LOUNDNESS/SNR
189 * supported bit_rate for mono channel is max 320kbps
190 * supported bit rate for stereo channel is max 512 kbps
191 */
192struct sbc_enc_cfg_t{
193 uint32_t enc_format;
194 uint32_t num_subbands;
195 uint32_t blk_len;
196 uint32_t channel_mode;
197 uint32_t alloc_method;
198 uint32_t bit_rate;
199 uint32_t sample_rate;
Aniket Kumar Lata53e54b12017-08-24 17:45:38 -0700200} __packed;
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530201
202
203/* supported num_channels are Mono/Stereo
204 * supported channel_mapping for mono is CHANNEL_C
205 * supported channel mapping for stereo is CHANNEL_L and CHANNEL_R
206 * custom size and reserved are not used(for future enhancement)
Aniket Kumar Lata53e54b12017-08-24 17:45:38 -0700207 */
Preetam Singh Ranawat0d645ea2017-08-07 18:12:07 +0530208struct custom_enc_cfg_t
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530209{
210 uint32_t enc_format;
211 uint32_t sample_rate;
212 uint16_t num_channels;
213 uint16_t reserved;
214 uint8_t channel_mapping[8];
215 uint32_t custom_size;
Aniket Kumar Lata53e54b12017-08-24 17:45:38 -0700216} __packed;
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530217
Preetam Singh Ranawat0d645ea2017-08-07 18:12:07 +0530218struct celt_specific_enc_cfg_t
219{
220 uint32_t bit_rate;
221 uint16_t frame_size;
222 uint16_t complexity;
223 uint16_t prediction_mode;
224 uint16_t vbr_flag;
Aniket Kumar Lata53e54b12017-08-24 17:45:38 -0700225} __packed;
Preetam Singh Ranawat0d645ea2017-08-07 18:12:07 +0530226
227struct celt_enc_cfg_t
228{
229 struct custom_enc_cfg_t custom_cfg;
230 struct celt_specific_enc_cfg_t celt_cfg;
Aniket Kumar Lata53e54b12017-08-24 17:45:38 -0700231} __packed;
232
233/* sync_mode introduced with APTX V2 libraries
234 * sync mode: 0x0 = stereo sync mode
235 * 0x01 = dual mono sync mode
236 * 0x02 = dual mono with no sync on either L or R codewords
237 */
238struct aptx_v2_enc_cfg_ext_t
239{
240 uint32_t sync_mode;
241} __packed;
242
243/* APTX struct for combining custom enc and V2 fields */
244struct aptx_enc_cfg_t
245{
246 struct custom_enc_cfg_t custom_cfg;
247 struct aptx_v2_enc_cfg_ext_t aptx_v2_cfg;
248} __packed;
249
Sachin Mohan Gadag1657c052017-09-13 16:00:27 +0530250/* In LE BT source code uses system/audio.h for below
251 * structure definition. To avoid multiple definition
252 * compilation error for audiohal in LE , masking structure
253 * definition under "LINUX_ENABLED" which is defined only
254 * in LE
255 */
256#ifndef LINUX_ENABLED
Satya Krishna Pindiprolif7d65712017-04-26 14:24:53 +0530257/* TODO: Define the following structures only for O using PLATFORM_VERSION */
258/* Information about BT SBC encoder configuration
259 * This data is used between audio HAL module and
260 * BT IPC library to configure DSP encoder
261 */
262typedef struct {
Preetam Singh Ranawat0d645ea2017-08-07 18:12:07 +0530263 uint32_t subband; /* 4, 8 */
264 uint32_t blk_len; /* 4, 8, 12, 16 */
265 uint16_t sampling_rate; /*44.1khz,48khz*/
266 uint8_t channels; /*0(Mono),1(Dual_mono),2(Stereo),3(JS)*/
267 uint8_t alloc; /*0(Loudness),1(SNR)*/
268 uint8_t min_bitpool; /* 2 */
269 uint8_t max_bitpool; /*53(44.1khz),51 (48khz) */
270 uint32_t bitrate; /* 320kbps to 512kbps */
Satya Krishna Pindiprolif7d65712017-04-26 14:24:53 +0530271} audio_sbc_encoder_config;
272
Satya Krishna Pindiprolif7d65712017-04-26 14:24:53 +0530273/* Information about BT APTX encoder configuration
274 * This data is used between audio HAL module and
275 * BT IPC library to configure DSP encoder
276 */
277typedef struct {
278 uint16_t sampling_rate;
279 uint8_t channels;
280 uint32_t bitrate;
Aniket Kumar Lata53e54b12017-08-24 17:45:38 -0700281} audio_aptx_default_config;
Satya Krishna Pindiprolif7d65712017-04-26 14:24:53 +0530282
Aniket Kumar Lata53e54b12017-08-24 17:45:38 -0700283typedef struct {
284 uint16_t sampling_rate;
285 uint8_t channels;
286 uint32_t bitrate;
287 uint32_t sync_mode;
288} audio_aptx_dual_mono_config;
289
290typedef union {
291 audio_aptx_default_config *default_cfg;
292 audio_aptx_dual_mono_config *dual_mono_cfg;
293} audio_aptx_encoder_config;
Satya Krishna Pindiprolif7d65712017-04-26 14:24:53 +0530294
295/* Information about BT AAC encoder configuration
296 * This data is used between audio HAL module and
297 * BT IPC library to configure DSP encoder
298 */
299typedef struct {
300 uint32_t enc_mode; /* LC, SBR, PS */
301 uint16_t format_flag; /* RAW, ADTS */
302 uint16_t channels; /* 1-Mono, 2-Stereo */
303 uint32_t sampling_rate;
304 uint32_t bitrate;
305} audio_aac_encoder_config;
Sachin Mohan Gadag1657c052017-09-13 16:00:27 +0530306#endif
Satya Krishna Pindiprolif7d65712017-04-26 14:24:53 +0530307
Preetam Singh Ranawat0d645ea2017-08-07 18:12:07 +0530308/* Information about BT CELT encoder configuration
309 * This data is used between audio HAL module and
310 * BT IPC library to configure DSP encoder
311 */
312typedef struct {
313 uint32_t sampling_rate; /* 32000 - 48000, 48000 */
314 uint16_t channels; /* 1-Mono, 2-Stereo, 2*/
315 uint16_t frame_size; /* 64-128-256-512, 512 */
316 uint16_t complexity; /* 0-10, 1 */
317 uint16_t prediction_mode; /* 0-1-2, 0 */
318 uint16_t vbr_flag; /* 0-1, 0*/
319 uint32_t bitrate; /*32000 - 1536000, 139500*/
320} audio_celt_encoder_config;
321
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530322/*********** END of DSP configurable structures ********************/
323
324/* API to identify DSP encoder captabilities */
325static void a2dp_offload_codec_cap_parser(char *value)
326{
Naresh Tannirucd2353e2016-08-19 00:37:25 +0530327 char *tok = NULL,*saveptr;
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530328
Naresh Tannirucd2353e2016-08-19 00:37:25 +0530329 tok = strtok_r(value, "-", &saveptr);
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530330 while (tok != NULL) {
331 if (strcmp(tok, "sbc") == 0) {
332 ALOGD("%s: SBC offload supported\n",__func__);
333 a2dp.is_a2dp_offload_supported = true;
334 break;
335 } else if (strcmp(tok, "aptx") == 0) {
336 ALOGD("%s: aptx offload supported\n",__func__);
337 a2dp.is_a2dp_offload_supported = true;
338 break;
Aniket Kumar Lata53e54b12017-08-24 17:45:38 -0700339 } else if (strcmp(tok, "aptxtws") == 0) {
340 ALOGD("%s: aptx dual mono offload supported\n",__func__);
341 a2dp.is_a2dp_offload_supported = true;
342 break;
Naresh Tannirued694c82017-02-07 17:01:28 +0530343 } else if (strcmp(tok, "aptxhd") == 0) {
344 ALOGD("%s: aptx HD offload supported\n",__func__);
345 a2dp.is_a2dp_offload_supported = true;
346 break;
347 } else if (strcmp(tok, "aac") == 0) {
348 ALOGD("%s: aac offload supported\n",__func__);
349 a2dp.is_a2dp_offload_supported = true;
350 break;
Preetam Singh Ranawat0d645ea2017-08-07 18:12:07 +0530351 } else if (strcmp(tok, "celt") == 0) {
352 ALOGD("%s: celt offload supported\n",__func__);
353 a2dp.is_a2dp_offload_supported = true;
354 break;
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530355 }
Naresh Tannirucd2353e2016-08-19 00:37:25 +0530356 tok = strtok_r(NULL, "-", &saveptr);
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530357 };
358}
359
360static void update_offload_codec_capabilities()
361{
362 char value[PROPERTY_VALUE_MAX] = {'\0'};
363
Aniket Kumar Lata8fc67e62017-05-02 12:33:46 -0700364 property_get("persist.vendor.bt.a2dp_offload_cap", value, "false");
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530365 ALOGD("get_offload_codec_capabilities = %s",value);
366 a2dp.is_a2dp_offload_supported =
Aniket Kumar Lata8fc67e62017-05-02 12:33:46 -0700367 property_get_bool("persist.vendor.bt.a2dp_offload_cap", false);
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530368 if (strcmp(value, "false") != 0)
369 a2dp_offload_codec_cap_parser(value);
370 ALOGD("%s: codec cap = %s",__func__,value);
371}
372
373/* API to open BT IPC library to start IPC communication */
374static void open_a2dp_output()
375{
376 int ret = 0;
377
378 ALOGD(" Open A2DP output start ");
379 if (a2dp.bt_lib_handle == NULL){
380 ALOGD(" Requesting for BT lib handle");
381 a2dp.bt_lib_handle = dlopen(BT_IPC_LIB_NAME, RTLD_NOW);
382
383 if (a2dp.bt_lib_handle == NULL) {
384 ALOGE("%s: DLOPEN failed for %s", __func__, BT_IPC_LIB_NAME);
385 ret = -ENOSYS;
386 goto init_fail;
387 } else {
388 a2dp.audio_stream_open = (audio_stream_open_t)
389 dlsym(a2dp.bt_lib_handle, "audio_stream_open");
390 a2dp.audio_start_stream = (audio_start_stream_t)
391 dlsym(a2dp.bt_lib_handle, "audio_start_stream");
392 a2dp.audio_get_codec_config = (audio_get_codec_config_t)
393 dlsym(a2dp.bt_lib_handle, "audio_get_codec_config");
394 a2dp.audio_suspend_stream = (audio_suspend_stream_t)
395 dlsym(a2dp.bt_lib_handle, "audio_suspend_stream");
396 a2dp.audio_handoff_triggered = (audio_handoff_triggered_t)
397 dlsym(a2dp.bt_lib_handle, "audio_handoff_triggered");
398 a2dp.clear_a2dpsuspend_flag = (clear_a2dpsuspend_flag_t)
399 dlsym(a2dp.bt_lib_handle, "clear_a2dpsuspend_flag");
400 a2dp.audio_stop_stream = (audio_stop_stream_t)
401 dlsym(a2dp.bt_lib_handle, "audio_stop_stream");
402 a2dp.audio_stream_close = (audio_stream_close_t)
403 dlsym(a2dp.bt_lib_handle, "audio_stream_close");
Preetam Singh Ranawata1849ba2017-02-06 14:10:11 +0530404 a2dp.audio_check_a2dp_ready = (audio_check_a2dp_ready_t)
405 dlsym(a2dp.bt_lib_handle,"audio_check_a2dp_ready");
yidongh0515e042017-07-06 15:00:34 +0800406 a2dp.audio_get_a2dp_sink_latency = (audio_get_a2dp_sink_latency_t)
407 dlsym(a2dp.bt_lib_handle,"audio_get_a2dp_sink_latency");
Preetam Singh Ranawatc2bef792017-11-22 10:59:15 +0530408 a2dp.audio_is_scrambling_enabled = (audio_is_scrambling_enabled_t)
409 dlsym(a2dp.bt_lib_handle,"audio_is_scrambling_enabled");
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530410 }
411 }
412
413 if (a2dp.bt_lib_handle && a2dp.audio_stream_open) {
414 if (a2dp.bt_state == A2DP_STATE_DISCONNECTED) {
415 ALOGD("calling BT stream open");
416 ret = a2dp.audio_stream_open();
417 if(ret != 0) {
418 ALOGE("Failed to open output stream for a2dp: status %d", ret);
419 goto init_fail;
420 }
421 a2dp.bt_state = A2DP_STATE_CONNECTED;
422 } else {
423 ALOGD("Called a2dp open with improper state, Ignoring request state %d", a2dp.bt_state);
424 }
425 } else {
426 ALOGE("a2dp handle is not identified, Ignoring open request");
427 a2dp.bt_state = A2DP_STATE_DISCONNECTED;
428 goto init_fail;
429 }
430
431init_fail:
432 if(ret != 0 && (a2dp.bt_lib_handle != NULL)) {
433 dlclose(a2dp.bt_lib_handle);
434 a2dp.bt_lib_handle = NULL;
435 }
436}
437
438static int close_a2dp_output()
439{
440 ALOGV("%s\n",__func__);
441 if (!(a2dp.bt_lib_handle && a2dp.audio_stream_close)) {
442 ALOGE("a2dp handle is not identified, Ignoring close request");
443 return -ENOSYS;
444 }
Preetam Singh Ranawata1849ba2017-02-06 14:10:11 +0530445 if (a2dp.bt_state != A2DP_STATE_DISCONNECTED) {
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530446 ALOGD("calling BT stream close");
447 if(a2dp.audio_stream_close() == false)
448 ALOGE("failed close a2dp control path from BT library");
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530449 }
Preetam Singh Ranawata1849ba2017-02-06 14:10:11 +0530450 a2dp.a2dp_started = false;
451 a2dp.a2dp_total_active_session_request = 0;
452 a2dp.a2dp_suspended = false;
Preetam Singh Ranawat0d645ea2017-08-07 18:12:07 +0530453 a2dp.bt_encoder_format = ENC_CODEC_TYPE_INVALID;
Preetam Singh Ranawata1849ba2017-02-06 14:10:11 +0530454 a2dp.enc_sampling_rate = 48000;
Preetam Singh Ranawatc2bef792017-11-22 10:59:15 +0530455 a2dp.enc_channels = 2;
Preetam Singh Ranawata1849ba2017-02-06 14:10:11 +0530456 a2dp.bt_state = A2DP_STATE_DISCONNECTED;
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530457
458 return 0;
459}
460
Preetam Singh Ranawatc2bef792017-11-22 10:59:15 +0530461static void a2dp_check_and_set_scrambler()
462{
463 bool scrambler_mode = false;
464 struct mixer_ctl *ctrl_scrambler_mode = NULL;
465 if (a2dp.audio_is_scrambling_enabled && (a2dp.bt_state != A2DP_STATE_DISCONNECTED))
466 scrambler_mode = a2dp.audio_is_scrambling_enabled();
467
468 if (scrambler_mode) {
469 //enable scrambler in dsp
470 ctrl_scrambler_mode = mixer_get_ctl_by_name(a2dp.adev->mixer,
471 MIXER_SCRAMBLER_MODE);
472 if (!ctrl_scrambler_mode) {
473 ALOGE(" ERROR scrambler mode mixer control not identifed");
474 return;
475 } else {
476 if (mixer_ctl_set_value(ctrl_scrambler_mode, 0, true) != 0) {
477 ALOGE("%s: Could not set scrambler mode", __func__);
478 return;
479 }
480 }
481 }
482}
483
484static void a2dp_set_backend_cfg()
485{
486 char *rate_str = NULL, *in_channels = NULL;
487 struct mixer_ctl *ctl_sample_rate = NULL, *ctrl_in_channels = NULL;
488 //Configure backend sampling rate
489 switch (a2dp.enc_sampling_rate) {
490 case 44100:
491 rate_str = "KHZ_44P1";
492 break;
493 case 48000:
494 rate_str = "KHZ_48";
495 break;
496 case 88200:
497 rate_str = "KHZ_88P2";
498 break;
499 case 96000:
500 rate_str = "KHZ_96";
501 break;
502 default:
503 rate_str = "KHZ_48";
504 break;
505 }
506
507 ALOGD("%s: set backend sample rate =%s", __func__, rate_str);
508 ctl_sample_rate = mixer_get_ctl_by_name(a2dp.adev->mixer,
509 MIXER_SAMPLE_RATE);
510 if (!ctl_sample_rate) {
511 ALOGE(" ERROR backend sample rate mixer control not identifed");
512 return;
513 } else {
514 if (mixer_ctl_set_enum_by_string(ctl_sample_rate, rate_str) != 0) {
515 ALOGE("%s: Failed to set backend sample rate =%s", __func__, rate_str);
516 return;
517 }
518 }
519
520 //Configure AFE input channels
521 switch (a2dp.enc_channels) {
522 case 1:
523 in_channels = "One";
524 break;
525 case 2:
526 default:
527 in_channels = "Two";
528 break;
529 }
530
531 ALOGD("%s: set afe input channels =%d", __func__, a2dp.enc_channels);
532 ctrl_in_channels = mixer_get_ctl_by_name(a2dp.adev->mixer,
533 MIXER_AFE_IN_CHANNELS);
534 if (!ctrl_in_channels) {
535 ALOGE(" ERROR AFE input channels mixer control not identifed");
536 return;
537 } else {
538 if (mixer_ctl_set_enum_by_string(ctrl_in_channels, in_channels) != 0) {
539 ALOGE("%s: Failed to set AFE in channels =%d", __func__, a2dp.enc_channels);
540 return;
541 }
542 }
543}
544
545static void a2dp_reset_backend_cfg()
546{
547 char *rate_str = "KHZ_8", *in_channels = "Zero";
548 struct mixer_ctl *ctl_sample_rate = NULL, *ctrl_in_channels = NULL;
549
550 //reset backend sampling rate
551 ALOGD("%s: reset backend sample rate =%s", __func__, rate_str);
552 ctl_sample_rate = mixer_get_ctl_by_name(a2dp.adev->mixer,
553 MIXER_SAMPLE_RATE);
554 if (!ctl_sample_rate) {
555 ALOGE(" ERROR backend sample rate mixer control not identifed");
556 return;
557 } else {
558 if (mixer_ctl_set_enum_by_string(ctl_sample_rate, rate_str) != 0) {
559 ALOGE("%s: Failed to reset backend sample rate =%s", __func__, rate_str);
560 return;
561 }
562 }
563
564 //reset AFE input channels
565 ALOGD("%s: reset afe input channels =%s", __func__, in_channels);
566 ctrl_in_channels = mixer_get_ctl_by_name(a2dp.adev->mixer,
567 MIXER_AFE_IN_CHANNELS);
568 if (!ctrl_in_channels) {
569 ALOGE(" ERROR AFE input channels mixer control not identifed");
570 return;
571 } else {
572 if (mixer_ctl_set_enum_by_string(ctrl_in_channels, in_channels) != 0) {
573 ALOGE("%s: Failed to reset AFE in channels =%d", __func__, a2dp.enc_channels);
574 return;
575 }
576 }
577}
578
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530579/* API to configure SBC DSP encoder */
580bool configure_sbc_enc_format(audio_sbc_encoder_config *sbc_bt_cfg)
581{
Naresh Tanniruf5ba8d02016-09-29 18:06:37 +0530582 struct mixer_ctl *ctl_enc_data = NULL, *ctrl_bit_format = NULL;
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530583 struct sbc_enc_cfg_t sbc_dsp_cfg;
584 bool is_configured = false;
585 int ret = 0;
586
587 if(sbc_bt_cfg == NULL)
588 return false;
589
590 ctl_enc_data = mixer_get_ctl_by_name(a2dp.adev->mixer, MIXER_ENC_CONFIG_BLOCK);
591 if (!ctl_enc_data) {
592 ALOGE(" ERROR a2dp encoder CONFIG data mixer control not identifed");
593 is_configured = false;
594 goto fail;
595 }
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530596 memset(&sbc_dsp_cfg, 0x0, sizeof(struct sbc_enc_cfg_t));
597 sbc_dsp_cfg.enc_format = ENC_MEDIA_FMT_SBC;
598 sbc_dsp_cfg.num_subbands = sbc_bt_cfg->subband;
599 sbc_dsp_cfg.blk_len = sbc_bt_cfg->blk_len;
600 switch(sbc_bt_cfg->channels) {
601 case 0:
602 sbc_dsp_cfg.channel_mode = MEDIA_FMT_SBC_CHANNEL_MODE_MONO;
603 break;
604 case 1:
605 sbc_dsp_cfg.channel_mode = MEDIA_FMT_SBC_CHANNEL_MODE_DUAL_MONO;
606 break;
607 case 3:
608 sbc_dsp_cfg.channel_mode = MEDIA_FMT_SBC_CHANNEL_MODE_JOINT_STEREO;
609 break;
610 case 2:
611 default:
612 sbc_dsp_cfg.channel_mode = MEDIA_FMT_SBC_CHANNEL_MODE_STEREO;
613 break;
614 }
615 if (sbc_bt_cfg->alloc)
616 sbc_dsp_cfg.alloc_method = MEDIA_FMT_SBC_ALLOCATION_METHOD_LOUDNESS;
617 else
618 sbc_dsp_cfg.alloc_method = MEDIA_FMT_SBC_ALLOCATION_METHOD_SNR;
619 sbc_dsp_cfg.bit_rate = sbc_bt_cfg->bitrate;
620 sbc_dsp_cfg.sample_rate = sbc_bt_cfg->sampling_rate;
621 ret = mixer_ctl_set_array(ctl_enc_data, (void *)&sbc_dsp_cfg,
622 sizeof(struct sbc_enc_cfg_t));
623 if (ret != 0) {
624 ALOGE("%s: failed to set SBC encoder config", __func__);
625 is_configured = false;
Naresh Tanniruf5ba8d02016-09-29 18:06:37 +0530626 goto fail;
627 }
628 ctrl_bit_format = mixer_get_ctl_by_name(a2dp.adev->mixer,
629 MIXER_ENC_BIT_FORMAT);
630 if (!ctrl_bit_format) {
631 ALOGE(" ERROR bit format CONFIG data mixer control not identifed");
632 is_configured = false;
633 goto fail;
634 }
635 ret = mixer_ctl_set_enum_by_string(ctrl_bit_format, "S16_LE");
636 if (ret != 0) {
637 ALOGE("%s: Failed to set bit format to encoder", __func__);
638 is_configured = false;
639 goto fail;
640 }
641 is_configured = true;
Preetam Singh Ranawat0d645ea2017-08-07 18:12:07 +0530642 a2dp.bt_encoder_format = ENC_CODEC_TYPE_SBC;
Naresh Tanniruf5ba8d02016-09-29 18:06:37 +0530643 a2dp.enc_sampling_rate = sbc_bt_cfg->sampling_rate;
Preetam Singh Ranawatc2bef792017-11-22 10:59:15 +0530644
645 if (sbc_dsp_cfg.channel_mode == MEDIA_FMT_SBC_CHANNEL_MODE_MONO)
646 a2dp.enc_channels = 1;
647 else
648 a2dp.enc_channels = 2;
649
Naresh Tanniruf5ba8d02016-09-29 18:06:37 +0530650 ALOGV("Successfully updated SBC enc format with samplingrate: %d channelmode:%d",
651 sbc_dsp_cfg.sample_rate, sbc_dsp_cfg.channel_mode);
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530652fail:
653 return is_configured;
654}
655
656/* API to configure APTX DSP encoder */
657bool configure_aptx_enc_format(audio_aptx_encoder_config *aptx_bt_cfg)
658{
Naresh Tanniruf5ba8d02016-09-29 18:06:37 +0530659 struct mixer_ctl *ctl_enc_data = NULL, *ctrl_bit_format = NULL;
Aniket Kumar Lata53e54b12017-08-24 17:45:38 -0700660 struct aptx_enc_cfg_t aptx_dsp_cfg;
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530661 bool is_configured = false;
662 int ret = 0;
663
664 if(aptx_bt_cfg == NULL)
665 return false;
666
667 ctl_enc_data = mixer_get_ctl_by_name(a2dp.adev->mixer, MIXER_ENC_CONFIG_BLOCK);
668 if (!ctl_enc_data) {
669 ALOGE(" ERROR a2dp encoder CONFIG data mixer control not identifed");
670 is_configured = false;
671 goto fail;
672 }
Aniket Kumar Lata53e54b12017-08-24 17:45:38 -0700673
674 memset(&aptx_dsp_cfg, 0x0, sizeof(struct aptx_enc_cfg_t));
675 aptx_dsp_cfg.custom_cfg.enc_format = ENC_MEDIA_FMT_APTX;
676
677 if (!a2dp.is_aptx_dual_mono_supported) {
678 aptx_dsp_cfg.custom_cfg.sample_rate = aptx_bt_cfg->default_cfg->sampling_rate;
679 aptx_dsp_cfg.custom_cfg.num_channels = aptx_bt_cfg->default_cfg->channels;
680 } else {
681 aptx_dsp_cfg.custom_cfg.sample_rate = aptx_bt_cfg->dual_mono_cfg->sampling_rate;
682 aptx_dsp_cfg.custom_cfg.num_channels = aptx_bt_cfg->dual_mono_cfg->channels;
683 aptx_dsp_cfg.aptx_v2_cfg.sync_mode = aptx_bt_cfg->dual_mono_cfg->sync_mode;
684 }
685
686 switch(aptx_dsp_cfg.custom_cfg.num_channels) {
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530687 case 1:
Aniket Kumar Lata53e54b12017-08-24 17:45:38 -0700688 aptx_dsp_cfg.custom_cfg.channel_mapping[0] = PCM_CHANNEL_C;
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530689 break;
690 case 2:
691 default:
Aniket Kumar Lata53e54b12017-08-24 17:45:38 -0700692 aptx_dsp_cfg.custom_cfg.channel_mapping[0] = PCM_CHANNEL_L;
693 aptx_dsp_cfg.custom_cfg.channel_mapping[1] = PCM_CHANNEL_R;
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530694 break;
695 }
696 ret = mixer_ctl_set_array(ctl_enc_data, (void *)&aptx_dsp_cfg,
Aniket Kumar Lata53e54b12017-08-24 17:45:38 -0700697 sizeof(struct aptx_enc_cfg_t));
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530698 if (ret != 0) {
699 ALOGE("%s: Failed to set APTX encoder config", __func__);
700 is_configured = false;
701 goto fail;
702 }
Naresh Tanniruf5ba8d02016-09-29 18:06:37 +0530703 ctrl_bit_format = mixer_get_ctl_by_name(a2dp.adev->mixer,
704 MIXER_ENC_BIT_FORMAT);
705 if (!ctrl_bit_format) {
706 ALOGE("ERROR bit format CONFIG data mixer control not identifed");
707 is_configured = false;
708 goto fail;
709 } else {
710 ret = mixer_ctl_set_enum_by_string(ctrl_bit_format, "S16_LE");
711 if (ret != 0) {
712 ALOGE("%s: Failed to set bit format to encoder", __func__);
713 is_configured = false;
714 goto fail;
715 }
716 }
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530717 is_configured = true;
Preetam Singh Ranawat0d645ea2017-08-07 18:12:07 +0530718 a2dp.bt_encoder_format = ENC_CODEC_TYPE_APTX;
Preetam Singh Ranawatc2bef792017-11-22 10:59:15 +0530719 a2dp.enc_channels = aptx_dsp_cfg.custom_cfg.num_channels;
Aniket Kumar Lata53e54b12017-08-24 17:45:38 -0700720 if (!a2dp.is_aptx_dual_mono_supported) {
721 a2dp.enc_sampling_rate = aptx_bt_cfg->default_cfg->sampling_rate;
722 ALOGV("Successfully updated APTX enc format with samplingrate: %d \
723 channels:%d", aptx_dsp_cfg.custom_cfg.sample_rate,
724 aptx_dsp_cfg.custom_cfg.num_channels);
725 } else {
726 a2dp.enc_sampling_rate = aptx_bt_cfg->dual_mono_cfg->sampling_rate;
727 ALOGV("Successfully updated APTX dual mono enc format with \
728 samplingrate: %d channels:%d syncmode %d",
729 aptx_dsp_cfg.custom_cfg.sample_rate,
730 aptx_dsp_cfg.custom_cfg.num_channels,
731 aptx_dsp_cfg.aptx_v2_cfg.sync_mode);
732 }
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530733fail:
734 return is_configured;
735}
736
737/* API to configure APTX HD DSP encoder
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530738 */
Aniket Kumar Lata53e54b12017-08-24 17:45:38 -0700739bool configure_aptx_hd_enc_format(audio_aptx_default_config *aptx_bt_cfg)
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530740{
Naresh Tanniruf5ba8d02016-09-29 18:06:37 +0530741 struct mixer_ctl *ctl_enc_data = NULL, *ctrl_bit_format = NULL;
Preetam Singh Ranawat0d645ea2017-08-07 18:12:07 +0530742 struct custom_enc_cfg_t aptx_dsp_cfg;
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530743 bool is_configured = false;
744 int ret = 0;
745
746 if(aptx_bt_cfg == NULL)
747 return false;
748
749 ctl_enc_data = mixer_get_ctl_by_name(a2dp.adev->mixer, MIXER_ENC_CONFIG_BLOCK);
750 if (!ctl_enc_data) {
751 ALOGE(" ERROR a2dp encoder CONFIG data mixer control not identifed");
752 is_configured = false;
753 goto fail;
754 }
Naresh Tanniruf5ba8d02016-09-29 18:06:37 +0530755
Preetam Singh Ranawat0d645ea2017-08-07 18:12:07 +0530756 memset(&aptx_dsp_cfg, 0x0, sizeof(struct custom_enc_cfg_t));
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530757 aptx_dsp_cfg.enc_format = ENC_MEDIA_FMT_APTX_HD;
758 aptx_dsp_cfg.sample_rate = aptx_bt_cfg->sampling_rate;
759 aptx_dsp_cfg.num_channels = aptx_bt_cfg->channels;
760 switch(aptx_dsp_cfg.num_channels) {
761 case 1:
762 aptx_dsp_cfg.channel_mapping[0] = PCM_CHANNEL_C;
763 break;
764 case 2:
765 default:
766 aptx_dsp_cfg.channel_mapping[0] = PCM_CHANNEL_L;
767 aptx_dsp_cfg.channel_mapping[1] = PCM_CHANNEL_R;
768 break;
769 }
770 ret = mixer_ctl_set_array(ctl_enc_data, (void *)&aptx_dsp_cfg,
Preetam Singh Ranawat0d645ea2017-08-07 18:12:07 +0530771 sizeof(struct custom_enc_cfg_t));
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530772 if (ret != 0) {
773 ALOGE("%s: Failed to set APTX HD encoder config", __func__);
774 is_configured = false;
775 goto fail;
776 }
Naresh Tanniruf5ba8d02016-09-29 18:06:37 +0530777 ctrl_bit_format = mixer_get_ctl_by_name(a2dp.adev->mixer, MIXER_ENC_BIT_FORMAT);
778 if (!ctrl_bit_format) {
779 ALOGE(" ERROR bit format CONFIG data mixer control not identifed");
780 is_configured = false;
781 goto fail;
782 }
783 ret = mixer_ctl_set_enum_by_string(ctrl_bit_format, "S24_LE");
784 if (ret != 0) {
785 ALOGE("%s: Failed to set APTX HD encoder config", __func__);
786 is_configured = false;
787 goto fail;
788 }
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530789 is_configured = true;
Preetam Singh Ranawat0d645ea2017-08-07 18:12:07 +0530790 a2dp.bt_encoder_format = ENC_CODEC_TYPE_APTX_HD;
Naresh Tanniruf5ba8d02016-09-29 18:06:37 +0530791 a2dp.enc_sampling_rate = aptx_bt_cfg->sampling_rate;
Preetam Singh Ranawatc2bef792017-11-22 10:59:15 +0530792 a2dp.enc_channels = aptx_bt_cfg->channels;
Naresh Tanniruf5ba8d02016-09-29 18:06:37 +0530793 ALOGV("Successfully updated APTX HD encformat with samplingrate: %d channels:%d",
794 aptx_dsp_cfg.sample_rate, aptx_dsp_cfg.num_channels);
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530795fail:
796 return is_configured;
797}
798
799/* API to configure AAC DSP encoder */
800bool configure_aac_enc_format(audio_aac_encoder_config *aac_bt_cfg)
801{
Naresh Tanniruf5ba8d02016-09-29 18:06:37 +0530802 struct mixer_ctl *ctl_enc_data = NULL, *ctrl_bit_format = NULL;
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530803 struct aac_enc_cfg_t aac_dsp_cfg;
804 bool is_configured = false;
805 int ret = 0;
806
807 if(aac_bt_cfg == NULL)
808 return false;
809
810 ctl_enc_data = mixer_get_ctl_by_name(a2dp.adev->mixer, MIXER_ENC_CONFIG_BLOCK);
811 if (!ctl_enc_data) {
812 ALOGE(" ERROR a2dp encoder CONFIG data mixer control not identifed");
813 is_configured = false;
814 goto fail;
815 }
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530816 memset(&aac_dsp_cfg, 0x0, sizeof(struct aac_enc_cfg_t));
817 aac_dsp_cfg.enc_format = ENC_MEDIA_FMT_AAC;
818 aac_dsp_cfg.bit_rate = aac_bt_cfg->bitrate;
Naresh Tannirua42d0bd2016-09-21 15:30:46 +0530819 aac_dsp_cfg.sample_rate = aac_bt_cfg->sampling_rate;
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530820 switch(aac_bt_cfg->enc_mode) {
821 case 0:
822 aac_dsp_cfg.enc_mode = MEDIA_FMT_AAC_AOT_LC;
823 break;
824 case 2:
825 aac_dsp_cfg.enc_mode = MEDIA_FMT_AAC_AOT_PS;
826 break;
827 case 1:
828 default:
829 aac_dsp_cfg.enc_mode = MEDIA_FMT_AAC_AOT_SBR;
830 break;
831 }
Naresh Tannirua42d0bd2016-09-21 15:30:46 +0530832 aac_dsp_cfg.aac_fmt_flag = aac_bt_cfg->format_flag;
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530833 aac_dsp_cfg.channel_cfg = aac_bt_cfg->channels;
834 ret = mixer_ctl_set_array(ctl_enc_data, (void *)&aac_dsp_cfg,
835 sizeof(struct aac_enc_cfg_t));
836 if (ret != 0) {
837 ALOGE("%s: failed to set SBC encoder config", __func__);
838 is_configured = false;
Naresh Tanniruf5ba8d02016-09-29 18:06:37 +0530839 goto fail;
840 }
841 ctrl_bit_format = mixer_get_ctl_by_name(a2dp.adev->mixer,
842 MIXER_ENC_BIT_FORMAT);
843 if (!ctrl_bit_format) {
844 is_configured = false;
845 ALOGE(" ERROR bit format CONFIG data mixer control not identifed");
846 goto fail;
847 }
848 ret = mixer_ctl_set_enum_by_string(ctrl_bit_format, "S16_LE");
849 if (ret != 0) {
850 ALOGE("%s: Failed to set bit format to encoder", __func__);
851 is_configured = false;
852 goto fail;
853 }
854 is_configured = true;
Preetam Singh Ranawat0d645ea2017-08-07 18:12:07 +0530855 a2dp.bt_encoder_format = ENC_CODEC_TYPE_AAC;
Naresh Tanniruf5ba8d02016-09-29 18:06:37 +0530856 a2dp.enc_sampling_rate = aac_bt_cfg->sampling_rate;
Preetam Singh Ranawatc2bef792017-11-22 10:59:15 +0530857 a2dp.enc_channels = aac_bt_cfg->channels;;
Naresh Tanniruf5ba8d02016-09-29 18:06:37 +0530858 ALOGV("Successfully updated AAC enc format with samplingrate: %d channels:%d",
859 aac_dsp_cfg.sample_rate, aac_dsp_cfg.channel_cfg);
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530860fail:
861 return is_configured;
862}
863
Preetam Singh Ranawat0d645ea2017-08-07 18:12:07 +0530864bool configure_celt_enc_format(audio_celt_encoder_config *celt_bt_cfg)
865{
866 struct mixer_ctl *ctl_enc_data = NULL, *ctrl_bit_format = NULL;
867 struct celt_enc_cfg_t celt_dsp_cfg;
868 bool is_configured = false;
869 int ret = 0;
870 if(celt_bt_cfg == NULL)
871 return false;
872
873 ctl_enc_data = mixer_get_ctl_by_name(a2dp.adev->mixer, MIXER_ENC_CONFIG_BLOCK);
874 if (!ctl_enc_data) {
875 ALOGE(" ERROR a2dp encoder CONFIG data mixer control not identifed");
876 is_configured = false;
877 goto fail;
878 }
879 memset(&celt_dsp_cfg, 0x0, sizeof(struct celt_enc_cfg_t));
880
881 celt_dsp_cfg.custom_cfg.enc_format = ENC_MEDIA_FMT_CELT;
882 celt_dsp_cfg.custom_cfg.sample_rate = celt_bt_cfg->sampling_rate;
883 celt_dsp_cfg.custom_cfg.num_channels = celt_bt_cfg->channels;
884 switch(celt_dsp_cfg.custom_cfg.num_channels) {
885 case 1:
886 celt_dsp_cfg.custom_cfg.channel_mapping[0] = PCM_CHANNEL_C;
887 break;
888 case 2:
889 default:
890 celt_dsp_cfg.custom_cfg.channel_mapping[0] = PCM_CHANNEL_L;
891 celt_dsp_cfg.custom_cfg.channel_mapping[1] = PCM_CHANNEL_R;
892 break;
893 }
894
895 celt_dsp_cfg.custom_cfg.custom_size = sizeof(struct celt_enc_cfg_t);
896
897 celt_dsp_cfg.celt_cfg.frame_size = celt_bt_cfg->frame_size;
898 celt_dsp_cfg.celt_cfg.complexity = celt_bt_cfg->complexity;
899 celt_dsp_cfg.celt_cfg.prediction_mode = celt_bt_cfg->prediction_mode;
900 celt_dsp_cfg.celt_cfg.vbr_flag = celt_bt_cfg->vbr_flag;
901 celt_dsp_cfg.celt_cfg.bit_rate = celt_bt_cfg->bitrate;
902
903 ret = mixer_ctl_set_array(ctl_enc_data, (void *)&celt_dsp_cfg,
904 sizeof(struct celt_enc_cfg_t));
905 if (ret != 0) {
906 ALOGE("%s: Failed to set CELT encoder config", __func__);
907 is_configured = false;
908 goto fail;
909 }
910 ctrl_bit_format = mixer_get_ctl_by_name(a2dp.adev->mixer, MIXER_ENC_BIT_FORMAT);
911 if (!ctrl_bit_format) {
912 ALOGE(" ERROR bit format CONFIG data mixer control not identifed");
913 is_configured = false;
914 goto fail;
915 }
916 ret = mixer_ctl_set_enum_by_string(ctrl_bit_format, "S16_LE");
917 if (ret != 0) {
918 ALOGE("%s: Failed to set bit format to encoder", __func__);
919 is_configured = false;
920 goto fail;
921 }
922 is_configured = true;
923 a2dp.bt_encoder_format = ENC_CODEC_TYPE_CELT;
924 a2dp.enc_sampling_rate = celt_bt_cfg->sampling_rate;
Preetam Singh Ranawatc2bef792017-11-22 10:59:15 +0530925 a2dp.enc_channels = celt_bt_cfg->channels;
Preetam Singh Ranawat0d645ea2017-08-07 18:12:07 +0530926 ALOGV("Successfully updated CELT encformat with samplingrate: %d channels:%d",
927 celt_dsp_cfg.custom_cfg.sample_rate, celt_dsp_cfg.custom_cfg.num_channels);
928fail:
929 return is_configured;
930}
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530931bool configure_a2dp_encoder_format()
932{
933 void *codec_info = NULL;
934 uint8_t multi_cast = 0, num_dev = 1;
Preetam Singh Ranawat0d645ea2017-08-07 18:12:07 +0530935 enc_codec_t codec_type = ENC_CODEC_TYPE_INVALID;
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530936 bool is_configured = false;
Aniket Kumar Lata53e54b12017-08-24 17:45:38 -0700937 audio_aptx_encoder_config aptx_encoder_cfg;
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530938
939 if (!a2dp.audio_get_codec_config) {
940 ALOGE(" a2dp handle is not identified, ignoring a2dp encoder config");
941 return false;
942 }
943 ALOGD("configure_a2dp_encoder_format start");
944 codec_info = a2dp.audio_get_codec_config(&multi_cast, &num_dev,
945 &codec_type);
946
947 switch(codec_type) {
Preetam Singh Ranawat0d645ea2017-08-07 18:12:07 +0530948 case ENC_CODEC_TYPE_SBC:
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530949 ALOGD(" Received SBC encoder supported BT device");
950 is_configured =
Aniket Kumar Lata53e54b12017-08-24 17:45:38 -0700951 configure_sbc_enc_format((audio_sbc_encoder_config *)codec_info);
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530952 break;
Preetam Singh Ranawat0d645ea2017-08-07 18:12:07 +0530953 case ENC_CODEC_TYPE_APTX:
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530954 ALOGD(" Received APTX encoder supported BT device");
Aniket Kumar Lata53e54b12017-08-24 17:45:38 -0700955 a2dp.is_aptx_dual_mono_supported = false;
956 aptx_encoder_cfg.default_cfg = (audio_aptx_default_config *)codec_info;
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530957 is_configured =
Aniket Kumar Lata53e54b12017-08-24 17:45:38 -0700958 configure_aptx_enc_format(&aptx_encoder_cfg);
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530959 break;
Preetam Singh Ranawat0d645ea2017-08-07 18:12:07 +0530960 case ENC_CODEC_TYPE_APTX_HD:
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530961 ALOGD(" Received APTX HD encoder supported BT device");
962 is_configured =
Aniket Kumar Lata53e54b12017-08-24 17:45:38 -0700963 configure_aptx_hd_enc_format((audio_aptx_default_config *)codec_info);
964 break;
965 case ENC_CODEC_TYPE_APTX_DUAL_MONO:
966 ALOGD(" Received APTX dual mono encoder supported BT device");
967 a2dp.is_aptx_dual_mono_supported = true;
968 aptx_encoder_cfg.dual_mono_cfg = (audio_aptx_dual_mono_config *)codec_info;
969 is_configured =
970 configure_aptx_enc_format(&aptx_encoder_cfg);
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530971 break;
Preetam Singh Ranawat0d645ea2017-08-07 18:12:07 +0530972 case ENC_CODEC_TYPE_AAC:
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530973 ALOGD(" Received AAC encoder supported BT device");
974 is_configured =
975 configure_aac_enc_format((audio_aac_encoder_config *)codec_info);
976 break;
Preetam Singh Ranawat0d645ea2017-08-07 18:12:07 +0530977 case ENC_CODEC_TYPE_CELT:
978 ALOGD(" Received CELT encoder supported BT device");
979 is_configured =
980 configure_celt_enc_format((audio_celt_encoder_config *)codec_info);
981 break;
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530982 default:
983 ALOGD(" Received Unsupported encoder formar");
984 is_configured = false;
985 break;
986 }
987 return is_configured;
988}
989
990int audio_extn_a2dp_start_playback()
991{
992 int ret = 0;
993
994 ALOGD("audio_extn_a2dp_start_playback start");
995
996 if(!(a2dp.bt_lib_handle && a2dp.audio_start_stream
997 && a2dp.audio_get_codec_config)) {
998 ALOGE("a2dp handle is not identified, Ignoring start request");
999 return -ENOSYS;
1000 }
1001
1002 if(a2dp.a2dp_suspended == true) {
1003 //session will be restarted after suspend completion
1004 ALOGD("a2dp start requested during suspend state");
Naresh Tannirucd2353e2016-08-19 00:37:25 +05301005 return -ENOSYS;
Naresh Tanniru9d027a62015-03-13 01:32:10 +05301006 }
1007
1008 if (!a2dp.a2dp_started && !a2dp.a2dp_total_active_session_request) {
1009 ALOGD("calling BT module stream start");
1010 /* This call indicates BT IPC lib to start playback */
1011 ret = a2dp.audio_start_stream();
1012 ALOGE("BT controller start return = %d",ret);
1013 if (ret != 0 ) {
1014 ALOGE("BT controller start failed");
1015 a2dp.a2dp_started = false;
Naresh Tanniru9d027a62015-03-13 01:32:10 +05301016 } else {
1017 if(configure_a2dp_encoder_format() == true) {
1018 a2dp.a2dp_started = true;
1019 ret = 0;
1020 ALOGD("Start playback successful to BT library");
1021 } else {
1022 ALOGD(" unable to configure DSP encoder");
1023 a2dp.a2dp_started = false;
1024 ret = -ETIMEDOUT;
1025 }
1026 }
1027 }
1028
Preetam Singh Ranawatc2bef792017-11-22 10:59:15 +05301029 if (a2dp.a2dp_started) {
Naresh Tanniru9d027a62015-03-13 01:32:10 +05301030 a2dp.a2dp_total_active_session_request++;
Preetam Singh Ranawatc2bef792017-11-22 10:59:15 +05301031 a2dp_check_and_set_scrambler();
1032 a2dp_set_backend_cfg();
1033 }
Naresh Tanniru9d027a62015-03-13 01:32:10 +05301034
1035 ALOGD("start A2DP playback total active sessions :%d",
1036 a2dp.a2dp_total_active_session_request);
1037 return ret;
1038}
1039
Naresh Tanniru03f9dd52016-10-19 18:46:22 +05301040static void reset_a2dp_enc_config_params()
1041{
1042 int ret =0;
1043
1044 struct mixer_ctl *ctl_enc_config, *ctrl_bit_format;
1045 struct sbc_enc_cfg_t dummy_reset_config;
1046
1047 memset(&dummy_reset_config, 0x0, sizeof(struct sbc_enc_cfg_t));
1048 ctl_enc_config = mixer_get_ctl_by_name(a2dp.adev->mixer,
1049 MIXER_ENC_CONFIG_BLOCK);
1050 if (!ctl_enc_config) {
1051 ALOGE(" ERROR a2dp encoder format mixer control not identifed");
1052 } else {
1053 ret = mixer_ctl_set_array(ctl_enc_config, (void *)&dummy_reset_config,
1054 sizeof(struct sbc_enc_cfg_t));
1055 a2dp.bt_encoder_format = ENC_MEDIA_FMT_NONE;
1056 }
1057 ctrl_bit_format = mixer_get_ctl_by_name(a2dp.adev->mixer,
1058 MIXER_ENC_BIT_FORMAT);
1059 if (!ctrl_bit_format) {
1060 ALOGE(" ERROR bit format CONFIG data mixer control not identifed");
1061 } else {
1062 ret = mixer_ctl_set_enum_by_string(ctrl_bit_format, "S16_LE");
1063 if (ret != 0) {
1064 ALOGE("%s: Failed to set bit format to encoder", __func__);
1065 }
1066 }
1067}
1068
Naresh Tanniru9d027a62015-03-13 01:32:10 +05301069int audio_extn_a2dp_stop_playback()
1070{
1071 int ret =0;
1072
1073 ALOGV("audio_extn_a2dp_stop_playback start");
1074 if(!(a2dp.bt_lib_handle && a2dp.audio_stop_stream)) {
1075 ALOGE("a2dp handle is not identified, Ignoring start request");
1076 return -ENOSYS;
1077 }
1078
Preetam Singh Ranawata1849ba2017-02-06 14:10:11 +05301079 if (a2dp.a2dp_total_active_session_request > 0)
Naresh Tanniru9d027a62015-03-13 01:32:10 +05301080 a2dp.a2dp_total_active_session_request--;
1081
1082 if ( a2dp.a2dp_started && !a2dp.a2dp_total_active_session_request) {
Naresh Tanniru9d027a62015-03-13 01:32:10 +05301083 ALOGV("calling BT module stream stop");
1084 ret = a2dp.audio_stop_stream();
1085 if (ret < 0)
1086 ALOGE("stop stream to BT IPC lib failed");
1087 else
1088 ALOGV("stop steam to BT IPC lib successful");
Naresh Tanniru03f9dd52016-10-19 18:46:22 +05301089 reset_a2dp_enc_config_params();
Preetam Singh Ranawatc2bef792017-11-22 10:59:15 +05301090 a2dp_reset_backend_cfg();
Naresh Tanniru9d027a62015-03-13 01:32:10 +05301091 }
1092 if(!a2dp.a2dp_total_active_session_request)
1093 a2dp.a2dp_started = false;
1094 ALOGD("Stop A2DP playback total active sessions :%d",
1095 a2dp.a2dp_total_active_session_request);
1096 return 0;
1097}
1098
1099void audio_extn_a2dp_set_parameters(struct str_parms *parms)
1100{
1101 int ret, val;
1102 char value[32]={0};
Chaithanya Krishna Bacharaju69d2e4c2017-05-26 18:22:46 +05301103 struct audio_usecase *uc_info;
1104 struct listnode *node;
Naresh Tanniru9d027a62015-03-13 01:32:10 +05301105
1106 if(a2dp.is_a2dp_offload_supported == false) {
1107 ALOGV("no supported encoders identified,ignoring a2dp setparam");
1108 return;
1109 }
1110
1111 ret = str_parms_get_str(parms, AUDIO_PARAMETER_DEVICE_CONNECT, value,
1112 sizeof(value));
1113 if( ret >= 0) {
1114 val = atoi(value);
1115 if (val & AUDIO_DEVICE_OUT_ALL_A2DP) {
1116 ALOGV("Received device connect request for A2DP");
1117 open_a2dp_output();
1118 }
1119 goto param_handled;
1120 }
1121
1122 ret = str_parms_get_str(parms, AUDIO_PARAMETER_DEVICE_DISCONNECT, value,
1123 sizeof(value));
1124
1125 if( ret >= 0) {
1126 val = atoi(value);
1127 if (val & AUDIO_DEVICE_OUT_ALL_A2DP) {
1128 ALOGV("Received device dis- connect request");
Naresh Tanniru03f9dd52016-10-19 18:46:22 +05301129 reset_a2dp_enc_config_params();
Naresh Tanniru9d027a62015-03-13 01:32:10 +05301130 close_a2dp_output();
1131 }
1132 goto param_handled;
1133 }
1134
1135 ret = str_parms_get_str(parms, "A2dpSuspended", value, sizeof(value));
1136 if (ret >= 0) {
1137 if (a2dp.bt_lib_handle && (a2dp.bt_state != A2DP_STATE_DISCONNECTED) ) {
1138 if ((!strncmp(value,"true",sizeof(value)))) {
1139 ALOGD("Setting a2dp to suspend state");
Naresh Tanniru9d027a62015-03-13 01:32:10 +05301140 a2dp.a2dp_suspended = true;
Chaithanya Krishna Bacharaju69d2e4c2017-05-26 18:22:46 +05301141 list_for_each(node, &a2dp.adev->usecase_list) {
1142 uc_info = node_to_item(node, struct audio_usecase, list);
Zhou Songc66eb7e2017-08-08 18:29:07 +08001143 if (uc_info->type == PCM_PLAYBACK &&
1144 (uc_info->stream.out->devices & AUDIO_DEVICE_OUT_ALL_A2DP)) {
Chaithanya Krishna Bacharaju69d2e4c2017-05-26 18:22:46 +05301145 pthread_mutex_unlock(&a2dp.adev->lock);
1146 check_a2dp_restore(a2dp.adev, uc_info->stream.out, false);
1147 pthread_mutex_lock(&a2dp.adev->lock);
1148 }
1149 }
Naresh Tanniru03f9dd52016-10-19 18:46:22 +05301150 reset_a2dp_enc_config_params();
Naresh Tanniru9d027a62015-03-13 01:32:10 +05301151 if(a2dp.audio_suspend_stream)
1152 a2dp.audio_suspend_stream();
1153 } else if (a2dp.a2dp_suspended == true) {
1154 ALOGD("Resetting a2dp suspend state");
Zhou Song10617ed2017-05-26 13:28:48 +08001155 struct audio_usecase *uc_info;
1156 struct listnode *node;
Naresh Tanniru9d027a62015-03-13 01:32:10 +05301157 if(a2dp.clear_a2dpsuspend_flag)
1158 a2dp.clear_a2dpsuspend_flag();
Naresh Tanniru9d027a62015-03-13 01:32:10 +05301159 a2dp.a2dp_suspended = false;
Naresh Tanniru649871a2016-11-04 18:08:32 +05301160 /*
1161 * It is possible that before suspend,a2dp sessions can be active
1162 * for example during music + voice activation concurrency
1163 * a2dp suspend will be called & BT will change to sco mode
1164 * though music is paused as a part of voice activation
1165 * compress session close happens only after pause timeout(10secs)
1166 * so if resume request comes before pause timeout as a2dp session
1167 * is already active IPC start will not be called from APM/audio_hw
1168 * Fix is to call a2dp start for IPC library post suspend
1169 * based on number of active session count
1170 */
1171 if (a2dp.a2dp_total_active_session_request > 0) {
1172 ALOGD(" Calling IPC lib start post suspend state");
1173 if(a2dp.audio_start_stream) {
1174 ret = a2dp.audio_start_stream();
1175 if (ret != 0) {
1176 ALOGE("BT controller start failed");
1177 a2dp.a2dp_started = false;
1178 }
1179 }
1180 }
Zhou Song10617ed2017-05-26 13:28:48 +08001181 list_for_each(node, &a2dp.adev->usecase_list) {
1182 uc_info = node_to_item(node, struct audio_usecase, list);
Zhou Songc66eb7e2017-08-08 18:29:07 +08001183 if (uc_info->type == PCM_PLAYBACK &&
1184 (uc_info->stream.out->devices & AUDIO_DEVICE_OUT_ALL_A2DP)) {
Chaithanya Krishna Bacharaju69d2e4c2017-05-26 18:22:46 +05301185 pthread_mutex_unlock(&a2dp.adev->lock);
1186 check_a2dp_restore(a2dp.adev, uc_info->stream.out, true);
1187 pthread_mutex_lock(&a2dp.adev->lock);
1188 }
Zhou Song10617ed2017-05-26 13:28:48 +08001189 }
Naresh Tanniru9d027a62015-03-13 01:32:10 +05301190 }
1191 }
1192 goto param_handled;
1193 }
Naresh Tanniru9d027a62015-03-13 01:32:10 +05301194param_handled:
1195 ALOGV("end of a2dp setparam");
1196}
1197
Naresh Tannirucd2353e2016-08-19 00:37:25 +05301198void audio_extn_a2dp_set_handoff_mode(bool is_on)
1199{
1200 a2dp.is_handoff_in_progress = is_on;
1201}
1202
Naresh Tanniru9d027a62015-03-13 01:32:10 +05301203bool audio_extn_a2dp_is_force_device_switch()
1204{
1205 //During encoder reconfiguration mode, force a2dp device switch
Ashish Jainc597d102016-12-12 10:31:34 +05301206 // Or if a2dp device is selected but earlier start failed ( as a2dp
1207 // was suspended, force retry.
1208 return a2dp.is_handoff_in_progress || !a2dp.a2dp_started;
Naresh Tanniru9d027a62015-03-13 01:32:10 +05301209}
1210
Naresh Tanniruf5ba8d02016-09-29 18:06:37 +05301211void audio_extn_a2dp_get_apptype_params(uint32_t *sample_rate,
1212 uint32_t *bit_width)
1213{
Preetam Singh Ranawat0d645ea2017-08-07 18:12:07 +05301214 if(a2dp.bt_encoder_format == ENC_CODEC_TYPE_APTX_HD)
Naresh Tanniruf5ba8d02016-09-29 18:06:37 +05301215 *bit_width = 24;
1216 else
1217 *bit_width = 16;
1218 *sample_rate = a2dp.enc_sampling_rate;
1219}
Preetam Singh Ranawata1849ba2017-02-06 14:10:11 +05301220
1221bool audio_extn_a2dp_is_ready()
1222{
1223 bool ret = false;
1224
Chaithanya Krishna Bacharaju69d2e4c2017-05-26 18:22:46 +05301225 if (a2dp.a2dp_suspended)
1226 return ret;
1227
Aniket Kumar Lata901bcb82017-03-10 15:42:46 -08001228 if ((a2dp.bt_state != A2DP_STATE_DISCONNECTED) &&
1229 (a2dp.is_a2dp_offload_supported) &&
Preetam Singh Ranawata1849ba2017-02-06 14:10:11 +05301230 (a2dp.audio_check_a2dp_ready))
1231 ret = a2dp.audio_check_a2dp_ready();
1232 return ret;
1233}
1234
Chaithanya Krishna Bacharaju69d2e4c2017-05-26 18:22:46 +05301235bool audio_extn_a2dp_is_suspended()
1236{
1237 return a2dp.a2dp_suspended;
1238}
1239
Naresh Tanniru9d027a62015-03-13 01:32:10 +05301240void audio_extn_a2dp_init (void *adev)
1241{
1242 a2dp.adev = (struct audio_device*)adev;
1243 a2dp.bt_lib_handle = NULL;
1244 a2dp.a2dp_started = false;
1245 a2dp.bt_state = A2DP_STATE_DISCONNECTED;
1246 a2dp.a2dp_total_active_session_request = 0;
1247 a2dp.a2dp_suspended = false;
Preetam Singh Ranawat0d645ea2017-08-07 18:12:07 +05301248 a2dp.bt_encoder_format = ENC_CODEC_TYPE_INVALID;
Naresh Tanniruf5ba8d02016-09-29 18:06:37 +05301249 a2dp.enc_sampling_rate = 48000;
Naresh Tanniru9d027a62015-03-13 01:32:10 +05301250 a2dp.is_a2dp_offload_supported = false;
1251 a2dp.is_handoff_in_progress = false;
Aniket Kumar Lata53e54b12017-08-24 17:45:38 -07001252 a2dp.is_aptx_dual_mono_supported = false;
kunleiz5a127262017-09-08 14:47:48 +08001253 reset_a2dp_enc_config_params();
Naresh Tanniru9d027a62015-03-13 01:32:10 +05301254 update_offload_codec_capabilities();
1255}
Aniket Kumar Latad5972fa2017-02-08 13:53:48 -08001256
1257uint32_t audio_extn_a2dp_get_encoder_latency()
1258{
Aniket Kumar Latad5972fa2017-02-08 13:53:48 -08001259 uint32_t latency = 0;
1260 int avsync_runtime_prop = 0;
Preetam Singh Ranawat0d645ea2017-08-07 18:12:07 +05301261 int sbc_offset = 0, aptx_offset = 0, aptxhd_offset = 0, aac_offset = 0, celt_offset = 0;
Aniket Kumar Latad5972fa2017-02-08 13:53:48 -08001262 char value[PROPERTY_VALUE_MAX];
1263
Aniket Kumar Latad5972fa2017-02-08 13:53:48 -08001264 memset(value, '\0', sizeof(char)*PROPERTY_VALUE_MAX);
Aniket Kumar Lata8fc67e62017-05-02 12:33:46 -07001265 avsync_runtime_prop = property_get("vendor.audio.a2dp.codec.latency", value, NULL);
Aniket Kumar Latad5972fa2017-02-08 13:53:48 -08001266 if (avsync_runtime_prop > 0) {
Preetam Singh Ranawat0d645ea2017-08-07 18:12:07 +05301267 if (sscanf(value, "%d/%d/%d/%d/%d",
1268 &sbc_offset, &aptx_offset, &aptxhd_offset, &aac_offset, &celt_offset) != 5) {
Aniket Kumar Latad5972fa2017-02-08 13:53:48 -08001269 ALOGI("Failed to parse avsync offset params from '%s'.", value);
1270 avsync_runtime_prop = 0;
1271 }
1272 }
1273
yidongh0515e042017-07-06 15:00:34 +08001274 uint32_t slatency = 0;
1275 if (a2dp.audio_get_a2dp_sink_latency && a2dp.bt_state != A2DP_STATE_DISCONNECTED) {
1276 slatency = a2dp.audio_get_a2dp_sink_latency();
1277 }
1278
Aniket Kumar Latafaaffde2017-03-22 19:18:15 -07001279 switch(a2dp.bt_encoder_format) {
Preetam Singh Ranawat0d645ea2017-08-07 18:12:07 +05301280 case ENC_CODEC_TYPE_SBC:
yidongh0515e042017-07-06 15:00:34 +08001281 latency = (avsync_runtime_prop > 0) ? sbc_offset : ENCODER_LATENCY_SBC;
1282 latency += (slatency <= 0) ? DEFAULT_SINK_LATENCY_SBC : slatency;
Aniket Kumar Latad5972fa2017-02-08 13:53:48 -08001283 break;
Preetam Singh Ranawat0d645ea2017-08-07 18:12:07 +05301284 case ENC_CODEC_TYPE_APTX:
yidongh0515e042017-07-06 15:00:34 +08001285 latency = (avsync_runtime_prop > 0) ? aptx_offset : ENCODER_LATENCY_APTX;
1286 latency += (slatency <= 0) ? DEFAULT_SINK_LATENCY_APTX : slatency;
Aniket Kumar Latad5972fa2017-02-08 13:53:48 -08001287 break;
Preetam Singh Ranawat0d645ea2017-08-07 18:12:07 +05301288 case ENC_CODEC_TYPE_APTX_HD:
yidongh0515e042017-07-06 15:00:34 +08001289 latency = (avsync_runtime_prop > 0) ? aptxhd_offset : ENCODER_LATENCY_APTX_HD;
1290 latency += (slatency <= 0) ? DEFAULT_SINK_LATENCY_APTX_HD : slatency;
Aniket Kumar Latad5972fa2017-02-08 13:53:48 -08001291 break;
Preetam Singh Ranawat0d645ea2017-08-07 18:12:07 +05301292 case ENC_CODEC_TYPE_AAC:
yidongh0515e042017-07-06 15:00:34 +08001293 latency = (avsync_runtime_prop > 0) ? aac_offset : ENCODER_LATENCY_AAC;
1294 latency += (slatency <= 0) ? DEFAULT_SINK_LATENCY_AAC : slatency;
Aniket Kumar Latad5972fa2017-02-08 13:53:48 -08001295 break;
Preetam Singh Ranawat0d645ea2017-08-07 18:12:07 +05301296 case ENC_CODEC_TYPE_CELT:
1297 latency = (avsync_runtime_prop > 0) ? celt_offset : ENCODER_LATENCY_CELT;
1298 latency += (slatency <= 0) ? DEFAULT_SINK_LATENCY_CELT : slatency;
1299 break;
Aniket Kumar Latad5972fa2017-02-08 13:53:48 -08001300 default:
1301 latency = 200;
1302 break;
1303 }
1304 return latency;
1305}
Naresh Tanniru9d027a62015-03-13 01:32:10 +05301306#endif // SPLIT_A2DP_ENABLED