blob: 43934188d4268a477d8cb904e338533ed4284a6d [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"
Naresh Tanniru9d027a62015-03-13 01:32:10 +053073#define MIXER_ENC_FMT_SBC "SBC"
74#define MIXER_ENC_FMT_AAC "AAC"
75#define MIXER_ENC_FMT_APTX "APTX"
76#define MIXER_ENC_FMT_APTXHD "APTXHD"
77#define MIXER_ENC_FMT_NONE "NONE"
yidongh0515e042017-07-06 15:00:34 +080078#define ENCODER_LATENCY_SBC 10
79#define ENCODER_LATENCY_APTX 40
80#define ENCODER_LATENCY_APTX_HD 20
81#define ENCODER_LATENCY_AAC 70
Preetam Singh Ranawat0d645ea2017-08-07 18:12:07 +053082//To Do: Fine Tune Encoder CELT latency.
83#define ENCODER_LATENCY_CELT 40
yidongh0515e042017-07-06 15:00:34 +080084#define DEFAULT_SINK_LATENCY_SBC 140
85#define DEFAULT_SINK_LATENCY_APTX 160
86#define DEFAULT_SINK_LATENCY_APTX_HD 180
87#define DEFAULT_SINK_LATENCY_AAC 180
Preetam Singh Ranawat0d645ea2017-08-07 18:12:07 +053088//To Do: Fine Tune Default CELT Latency.
89#define DEFAULT_SINK_LATENCY_CELT 180
90
91/*
92 * Below enum values are extended from audio_base.h to
93 * to keep encoder codec type local to bthost_ipc
94 * and audio_hal as these are intended only for handshake
95 * between IPC lib and Audio HAL.
96 */
97typedef enum {
98 ENC_CODEC_TYPE_INVALID = 4294967295u, // 0xFFFFFFFFUL
99 ENC_CODEC_TYPE_AAC = 67108864u, // 0x04000000UL
100 ENC_CODEC_TYPE_SBC = 520093696u, // 0x1F000000UL
101 ENC_CODEC_TYPE_APTX = 536870912u, // 0x20000000UL
102 ENC_CODEC_TYPE_APTX_HD = 553648128u, // 0x21000000UL
103 ENC_CODEC_TYPE_CELT = 603979776u, // 0x24000000UL
104}enc_codec_t;
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530105
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530106typedef int (*audio_stream_open_t)(void);
107typedef int (*audio_stream_close_t)(void);
108typedef int (*audio_start_stream_t)(void);
109typedef int (*audio_stop_stream_t)(void);
110typedef int (*audio_suspend_stream_t)(void);
111typedef void (*audio_handoff_triggered_t)(void);
112typedef void (*clear_a2dpsuspend_flag_t)(void);
113typedef void * (*audio_get_codec_config_t)(uint8_t *multicast_status,uint8_t *num_dev,
Preetam Singh Ranawat0d645ea2017-08-07 18:12:07 +0530114 enc_codec_t *codec_type);
Preetam Singh Ranawata1849ba2017-02-06 14:10:11 +0530115typedef int (*audio_check_a2dp_ready_t)(void);
yidongh0515e042017-07-06 15:00:34 +0800116typedef uint16_t (*audio_get_a2dp_sink_latency_t)(void);
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530117
118enum A2DP_STATE {
119 A2DP_STATE_CONNECTED,
120 A2DP_STATE_STARTED,
121 A2DP_STATE_STOPPED,
122 A2DP_STATE_DISCONNECTED,
123};
124
125/* structure used to update a2dp state machine
126 * to communicate IPC library
127 * to store DSP encoder configuration information
128 */
129struct a2dp_data {
130 struct audio_device *adev;
131 void *bt_lib_handle;
132 audio_stream_open_t audio_stream_open;
133 audio_stream_close_t audio_stream_close;
134 audio_start_stream_t audio_start_stream;
135 audio_stop_stream_t audio_stop_stream;
136 audio_suspend_stream_t audio_suspend_stream;
137 audio_handoff_triggered_t audio_handoff_triggered;
138 clear_a2dpsuspend_flag_t clear_a2dpsuspend_flag;
139 audio_get_codec_config_t audio_get_codec_config;
Preetam Singh Ranawata1849ba2017-02-06 14:10:11 +0530140 audio_check_a2dp_ready_t audio_check_a2dp_ready;
yidongh0515e042017-07-06 15:00:34 +0800141 audio_get_a2dp_sink_latency_t audio_get_a2dp_sink_latency;
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530142 enum A2DP_STATE bt_state;
Preetam Singh Ranawat0d645ea2017-08-07 18:12:07 +0530143 enc_codec_t bt_encoder_format;
Naresh Tanniruf5ba8d02016-09-29 18:06:37 +0530144 uint32_t enc_sampling_rate;
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530145 bool a2dp_started;
146 bool a2dp_suspended;
147 int a2dp_total_active_session_request;
148 bool is_a2dp_offload_supported;
149 bool is_handoff_in_progress;
150};
151
152struct a2dp_data a2dp;
153
154/* START of DSP configurable structures
155 * These values should match with DSP interface defintion
156 */
157
158/* AAC encoder configuration structure. */
159typedef struct aac_enc_cfg_t aac_enc_cfg_t;
160
161/* supported enc_mode are AAC_LC, AAC_SBR, AAC_PS
162 * supported aac_fmt_flag are ADTS/RAW
163 * supported channel_cfg are Native mode, Mono , Stereo
164 */
165struct aac_enc_cfg_t {
166 uint32_t enc_format;
167 uint32_t bit_rate;
168 uint32_t enc_mode;
169 uint16_t aac_fmt_flag;
Naresh Tannirua42d0bd2016-09-21 15:30:46 +0530170 uint16_t channel_cfg;
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530171 uint32_t sample_rate;
172} ;
173
174/* SBC encoder configuration structure. */
175typedef struct sbc_enc_cfg_t sbc_enc_cfg_t;
176
177/* supported num_subbands are 4/8
178 * supported blk_len are 4, 8, 12, 16
179 * supported channel_mode are MONO, STEREO, DUAL_MONO, JOINT_STEREO
180 * supported alloc_method are LOUNDNESS/SNR
181 * supported bit_rate for mono channel is max 320kbps
182 * supported bit rate for stereo channel is max 512 kbps
183 */
184struct sbc_enc_cfg_t{
185 uint32_t enc_format;
186 uint32_t num_subbands;
187 uint32_t blk_len;
188 uint32_t channel_mode;
189 uint32_t alloc_method;
190 uint32_t bit_rate;
191 uint32_t sample_rate;
192};
193
194
195/* supported num_channels are Mono/Stereo
196 * supported channel_mapping for mono is CHANNEL_C
197 * supported channel mapping for stereo is CHANNEL_L and CHANNEL_R
198 * custom size and reserved are not used(for future enhancement)
199 */
Preetam Singh Ranawat0d645ea2017-08-07 18:12:07 +0530200struct custom_enc_cfg_t
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530201{
202 uint32_t enc_format;
203 uint32_t sample_rate;
204 uint16_t num_channels;
205 uint16_t reserved;
206 uint8_t channel_mapping[8];
207 uint32_t custom_size;
208};
209
Preetam Singh Ranawat0d645ea2017-08-07 18:12:07 +0530210struct celt_specific_enc_cfg_t
211{
212 uint32_t bit_rate;
213 uint16_t frame_size;
214 uint16_t complexity;
215 uint16_t prediction_mode;
216 uint16_t vbr_flag;
217};
218
219struct celt_enc_cfg_t
220{
221 struct custom_enc_cfg_t custom_cfg;
222 struct celt_specific_enc_cfg_t celt_cfg;
223};
Sachin Mohan Gadag1657c052017-09-13 16:00:27 +0530224/* In LE BT source code uses system/audio.h for below
225 * structure definition. To avoid multiple definition
226 * compilation error for audiohal in LE , masking structure
227 * definition under "LINUX_ENABLED" which is defined only
228 * in LE
229 */
230#ifndef LINUX_ENABLED
Satya Krishna Pindiprolif7d65712017-04-26 14:24:53 +0530231/* TODO: Define the following structures only for O using PLATFORM_VERSION */
232/* Information about BT SBC encoder configuration
233 * This data is used between audio HAL module and
234 * BT IPC library to configure DSP encoder
235 */
236typedef struct {
Preetam Singh Ranawat0d645ea2017-08-07 18:12:07 +0530237 uint32_t subband; /* 4, 8 */
238 uint32_t blk_len; /* 4, 8, 12, 16 */
239 uint16_t sampling_rate; /*44.1khz,48khz*/
240 uint8_t channels; /*0(Mono),1(Dual_mono),2(Stereo),3(JS)*/
241 uint8_t alloc; /*0(Loudness),1(SNR)*/
242 uint8_t min_bitpool; /* 2 */
243 uint8_t max_bitpool; /*53(44.1khz),51 (48khz) */
244 uint32_t bitrate; /* 320kbps to 512kbps */
Satya Krishna Pindiprolif7d65712017-04-26 14:24:53 +0530245} audio_sbc_encoder_config;
246
Satya Krishna Pindiprolif7d65712017-04-26 14:24:53 +0530247/* Information about BT APTX encoder configuration
248 * This data is used between audio HAL module and
249 * BT IPC library to configure DSP encoder
250 */
251typedef struct {
252 uint16_t sampling_rate;
253 uint8_t channels;
254 uint32_t bitrate;
255} audio_aptx_encoder_config;
256
257
258/* Information about BT AAC encoder configuration
259 * This data is used between audio HAL module and
260 * BT IPC library to configure DSP encoder
261 */
262typedef struct {
263 uint32_t enc_mode; /* LC, SBR, PS */
264 uint16_t format_flag; /* RAW, ADTS */
265 uint16_t channels; /* 1-Mono, 2-Stereo */
266 uint32_t sampling_rate;
267 uint32_t bitrate;
268} audio_aac_encoder_config;
Sachin Mohan Gadag1657c052017-09-13 16:00:27 +0530269#endif
Satya Krishna Pindiprolif7d65712017-04-26 14:24:53 +0530270
Preetam Singh Ranawat0d645ea2017-08-07 18:12:07 +0530271/* Information about BT CELT encoder configuration
272 * This data is used between audio HAL module and
273 * BT IPC library to configure DSP encoder
274 */
275typedef struct {
276 uint32_t sampling_rate; /* 32000 - 48000, 48000 */
277 uint16_t channels; /* 1-Mono, 2-Stereo, 2*/
278 uint16_t frame_size; /* 64-128-256-512, 512 */
279 uint16_t complexity; /* 0-10, 1 */
280 uint16_t prediction_mode; /* 0-1-2, 0 */
281 uint16_t vbr_flag; /* 0-1, 0*/
282 uint32_t bitrate; /*32000 - 1536000, 139500*/
283} audio_celt_encoder_config;
284
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530285/*********** END of DSP configurable structures ********************/
286
287/* API to identify DSP encoder captabilities */
288static void a2dp_offload_codec_cap_parser(char *value)
289{
Naresh Tannirucd2353e2016-08-19 00:37:25 +0530290 char *tok = NULL,*saveptr;
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530291
Naresh Tannirucd2353e2016-08-19 00:37:25 +0530292 tok = strtok_r(value, "-", &saveptr);
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530293 while (tok != NULL) {
294 if (strcmp(tok, "sbc") == 0) {
295 ALOGD("%s: SBC offload supported\n",__func__);
296 a2dp.is_a2dp_offload_supported = true;
297 break;
298 } else if (strcmp(tok, "aptx") == 0) {
299 ALOGD("%s: aptx offload supported\n",__func__);
300 a2dp.is_a2dp_offload_supported = true;
301 break;
Naresh Tannirued694c82017-02-07 17:01:28 +0530302 } else if (strcmp(tok, "aptxhd") == 0) {
303 ALOGD("%s: aptx HD offload supported\n",__func__);
304 a2dp.is_a2dp_offload_supported = true;
305 break;
306 } else if (strcmp(tok, "aac") == 0) {
307 ALOGD("%s: aac offload supported\n",__func__);
308 a2dp.is_a2dp_offload_supported = true;
309 break;
Preetam Singh Ranawat0d645ea2017-08-07 18:12:07 +0530310 } else if (strcmp(tok, "celt") == 0) {
311 ALOGD("%s: celt offload supported\n",__func__);
312 a2dp.is_a2dp_offload_supported = true;
313 break;
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530314 }
Naresh Tannirucd2353e2016-08-19 00:37:25 +0530315 tok = strtok_r(NULL, "-", &saveptr);
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530316 };
317}
318
319static void update_offload_codec_capabilities()
320{
321 char value[PROPERTY_VALUE_MAX] = {'\0'};
322
Aniket Kumar Lata8fc67e62017-05-02 12:33:46 -0700323 property_get("persist.vendor.bt.a2dp_offload_cap", value, "false");
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530324 ALOGD("get_offload_codec_capabilities = %s",value);
325 a2dp.is_a2dp_offload_supported =
Aniket Kumar Lata8fc67e62017-05-02 12:33:46 -0700326 property_get_bool("persist.vendor.bt.a2dp_offload_cap", false);
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530327 if (strcmp(value, "false") != 0)
328 a2dp_offload_codec_cap_parser(value);
329 ALOGD("%s: codec cap = %s",__func__,value);
330}
331
332/* API to open BT IPC library to start IPC communication */
333static void open_a2dp_output()
334{
335 int ret = 0;
336
337 ALOGD(" Open A2DP output start ");
338 if (a2dp.bt_lib_handle == NULL){
339 ALOGD(" Requesting for BT lib handle");
340 a2dp.bt_lib_handle = dlopen(BT_IPC_LIB_NAME, RTLD_NOW);
341
342 if (a2dp.bt_lib_handle == NULL) {
343 ALOGE("%s: DLOPEN failed for %s", __func__, BT_IPC_LIB_NAME);
344 ret = -ENOSYS;
345 goto init_fail;
346 } else {
347 a2dp.audio_stream_open = (audio_stream_open_t)
348 dlsym(a2dp.bt_lib_handle, "audio_stream_open");
349 a2dp.audio_start_stream = (audio_start_stream_t)
350 dlsym(a2dp.bt_lib_handle, "audio_start_stream");
351 a2dp.audio_get_codec_config = (audio_get_codec_config_t)
352 dlsym(a2dp.bt_lib_handle, "audio_get_codec_config");
353 a2dp.audio_suspend_stream = (audio_suspend_stream_t)
354 dlsym(a2dp.bt_lib_handle, "audio_suspend_stream");
355 a2dp.audio_handoff_triggered = (audio_handoff_triggered_t)
356 dlsym(a2dp.bt_lib_handle, "audio_handoff_triggered");
357 a2dp.clear_a2dpsuspend_flag = (clear_a2dpsuspend_flag_t)
358 dlsym(a2dp.bt_lib_handle, "clear_a2dpsuspend_flag");
359 a2dp.audio_stop_stream = (audio_stop_stream_t)
360 dlsym(a2dp.bt_lib_handle, "audio_stop_stream");
361 a2dp.audio_stream_close = (audio_stream_close_t)
362 dlsym(a2dp.bt_lib_handle, "audio_stream_close");
Preetam Singh Ranawata1849ba2017-02-06 14:10:11 +0530363 a2dp.audio_check_a2dp_ready = (audio_check_a2dp_ready_t)
364 dlsym(a2dp.bt_lib_handle,"audio_check_a2dp_ready");
yidongh0515e042017-07-06 15:00:34 +0800365 a2dp.audio_get_a2dp_sink_latency = (audio_get_a2dp_sink_latency_t)
366 dlsym(a2dp.bt_lib_handle,"audio_get_a2dp_sink_latency");
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530367 }
368 }
369
370 if (a2dp.bt_lib_handle && a2dp.audio_stream_open) {
371 if (a2dp.bt_state == A2DP_STATE_DISCONNECTED) {
372 ALOGD("calling BT stream open");
373 ret = a2dp.audio_stream_open();
374 if(ret != 0) {
375 ALOGE("Failed to open output stream for a2dp: status %d", ret);
376 goto init_fail;
377 }
378 a2dp.bt_state = A2DP_STATE_CONNECTED;
379 } else {
380 ALOGD("Called a2dp open with improper state, Ignoring request state %d", a2dp.bt_state);
381 }
382 } else {
383 ALOGE("a2dp handle is not identified, Ignoring open request");
384 a2dp.bt_state = A2DP_STATE_DISCONNECTED;
385 goto init_fail;
386 }
387
388init_fail:
389 if(ret != 0 && (a2dp.bt_lib_handle != NULL)) {
390 dlclose(a2dp.bt_lib_handle);
391 a2dp.bt_lib_handle = NULL;
392 }
393}
394
395static int close_a2dp_output()
396{
397 ALOGV("%s\n",__func__);
398 if (!(a2dp.bt_lib_handle && a2dp.audio_stream_close)) {
399 ALOGE("a2dp handle is not identified, Ignoring close request");
400 return -ENOSYS;
401 }
Preetam Singh Ranawata1849ba2017-02-06 14:10:11 +0530402 if (a2dp.bt_state != A2DP_STATE_DISCONNECTED) {
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530403 ALOGD("calling BT stream close");
404 if(a2dp.audio_stream_close() == false)
405 ALOGE("failed close a2dp control path from BT library");
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530406 }
Preetam Singh Ranawata1849ba2017-02-06 14:10:11 +0530407 a2dp.a2dp_started = false;
408 a2dp.a2dp_total_active_session_request = 0;
409 a2dp.a2dp_suspended = false;
Preetam Singh Ranawat0d645ea2017-08-07 18:12:07 +0530410 a2dp.bt_encoder_format = ENC_CODEC_TYPE_INVALID;
Preetam Singh Ranawata1849ba2017-02-06 14:10:11 +0530411 a2dp.enc_sampling_rate = 48000;
412 a2dp.bt_state = A2DP_STATE_DISCONNECTED;
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530413
414 return 0;
415}
416
417/* API to configure SBC DSP encoder */
418bool configure_sbc_enc_format(audio_sbc_encoder_config *sbc_bt_cfg)
419{
Naresh Tanniruf5ba8d02016-09-29 18:06:37 +0530420 struct mixer_ctl *ctl_enc_data = NULL, *ctrl_bit_format = NULL;
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530421 struct sbc_enc_cfg_t sbc_dsp_cfg;
422 bool is_configured = false;
423 int ret = 0;
424
425 if(sbc_bt_cfg == NULL)
426 return false;
427
428 ctl_enc_data = mixer_get_ctl_by_name(a2dp.adev->mixer, MIXER_ENC_CONFIG_BLOCK);
429 if (!ctl_enc_data) {
430 ALOGE(" ERROR a2dp encoder CONFIG data mixer control not identifed");
431 is_configured = false;
432 goto fail;
433 }
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530434 memset(&sbc_dsp_cfg, 0x0, sizeof(struct sbc_enc_cfg_t));
435 sbc_dsp_cfg.enc_format = ENC_MEDIA_FMT_SBC;
436 sbc_dsp_cfg.num_subbands = sbc_bt_cfg->subband;
437 sbc_dsp_cfg.blk_len = sbc_bt_cfg->blk_len;
438 switch(sbc_bt_cfg->channels) {
439 case 0:
440 sbc_dsp_cfg.channel_mode = MEDIA_FMT_SBC_CHANNEL_MODE_MONO;
441 break;
442 case 1:
443 sbc_dsp_cfg.channel_mode = MEDIA_FMT_SBC_CHANNEL_MODE_DUAL_MONO;
444 break;
445 case 3:
446 sbc_dsp_cfg.channel_mode = MEDIA_FMT_SBC_CHANNEL_MODE_JOINT_STEREO;
447 break;
448 case 2:
449 default:
450 sbc_dsp_cfg.channel_mode = MEDIA_FMT_SBC_CHANNEL_MODE_STEREO;
451 break;
452 }
453 if (sbc_bt_cfg->alloc)
454 sbc_dsp_cfg.alloc_method = MEDIA_FMT_SBC_ALLOCATION_METHOD_LOUDNESS;
455 else
456 sbc_dsp_cfg.alloc_method = MEDIA_FMT_SBC_ALLOCATION_METHOD_SNR;
457 sbc_dsp_cfg.bit_rate = sbc_bt_cfg->bitrate;
458 sbc_dsp_cfg.sample_rate = sbc_bt_cfg->sampling_rate;
459 ret = mixer_ctl_set_array(ctl_enc_data, (void *)&sbc_dsp_cfg,
460 sizeof(struct sbc_enc_cfg_t));
461 if (ret != 0) {
462 ALOGE("%s: failed to set SBC encoder config", __func__);
463 is_configured = false;
Naresh Tanniruf5ba8d02016-09-29 18:06:37 +0530464 goto fail;
465 }
466 ctrl_bit_format = mixer_get_ctl_by_name(a2dp.adev->mixer,
467 MIXER_ENC_BIT_FORMAT);
468 if (!ctrl_bit_format) {
469 ALOGE(" ERROR bit format CONFIG data mixer control not identifed");
470 is_configured = false;
471 goto fail;
472 }
473 ret = mixer_ctl_set_enum_by_string(ctrl_bit_format, "S16_LE");
474 if (ret != 0) {
475 ALOGE("%s: Failed to set bit format to encoder", __func__);
476 is_configured = false;
477 goto fail;
478 }
479 is_configured = true;
Preetam Singh Ranawat0d645ea2017-08-07 18:12:07 +0530480 a2dp.bt_encoder_format = ENC_CODEC_TYPE_SBC;
Naresh Tanniruf5ba8d02016-09-29 18:06:37 +0530481 a2dp.enc_sampling_rate = sbc_bt_cfg->sampling_rate;
482 ALOGV("Successfully updated SBC enc format with samplingrate: %d channelmode:%d",
483 sbc_dsp_cfg.sample_rate, sbc_dsp_cfg.channel_mode);
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530484fail:
485 return is_configured;
486}
487
488/* API to configure APTX DSP encoder */
489bool configure_aptx_enc_format(audio_aptx_encoder_config *aptx_bt_cfg)
490{
Naresh Tanniruf5ba8d02016-09-29 18:06:37 +0530491 struct mixer_ctl *ctl_enc_data = NULL, *ctrl_bit_format = NULL;
Preetam Singh Ranawat0d645ea2017-08-07 18:12:07 +0530492 struct custom_enc_cfg_t aptx_dsp_cfg;
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530493 bool is_configured = false;
494 int ret = 0;
495
496 if(aptx_bt_cfg == NULL)
497 return false;
498
499 ctl_enc_data = mixer_get_ctl_by_name(a2dp.adev->mixer, MIXER_ENC_CONFIG_BLOCK);
500 if (!ctl_enc_data) {
501 ALOGE(" ERROR a2dp encoder CONFIG data mixer control not identifed");
502 is_configured = false;
503 goto fail;
504 }
Preetam Singh Ranawat0d645ea2017-08-07 18:12:07 +0530505 memset(&aptx_dsp_cfg, 0x0, sizeof(struct custom_enc_cfg_t));
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530506 aptx_dsp_cfg.enc_format = ENC_MEDIA_FMT_APTX;
507 aptx_dsp_cfg.sample_rate = aptx_bt_cfg->sampling_rate;
508 aptx_dsp_cfg.num_channels = aptx_bt_cfg->channels;
509 switch(aptx_dsp_cfg.num_channels) {
510 case 1:
511 aptx_dsp_cfg.channel_mapping[0] = PCM_CHANNEL_C;
512 break;
513 case 2:
514 default:
515 aptx_dsp_cfg.channel_mapping[0] = PCM_CHANNEL_L;
516 aptx_dsp_cfg.channel_mapping[1] = PCM_CHANNEL_R;
517 break;
518 }
519 ret = mixer_ctl_set_array(ctl_enc_data, (void *)&aptx_dsp_cfg,
Preetam Singh Ranawat0d645ea2017-08-07 18:12:07 +0530520 sizeof(struct custom_enc_cfg_t));
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530521 if (ret != 0) {
522 ALOGE("%s: Failed to set APTX encoder config", __func__);
523 is_configured = false;
524 goto fail;
525 }
Naresh Tanniruf5ba8d02016-09-29 18:06:37 +0530526 ctrl_bit_format = mixer_get_ctl_by_name(a2dp.adev->mixer,
527 MIXER_ENC_BIT_FORMAT);
528 if (!ctrl_bit_format) {
529 ALOGE("ERROR bit format CONFIG data mixer control not identifed");
530 is_configured = false;
531 goto fail;
532 } else {
533 ret = mixer_ctl_set_enum_by_string(ctrl_bit_format, "S16_LE");
534 if (ret != 0) {
535 ALOGE("%s: Failed to set bit format to encoder", __func__);
536 is_configured = false;
537 goto fail;
538 }
539 }
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530540 is_configured = true;
Preetam Singh Ranawat0d645ea2017-08-07 18:12:07 +0530541 a2dp.bt_encoder_format = ENC_CODEC_TYPE_APTX;
Naresh Tanniruf5ba8d02016-09-29 18:06:37 +0530542 a2dp.enc_sampling_rate = aptx_bt_cfg->sampling_rate;
543 ALOGV("Successfully updated APTX enc format with samplingrate: %d channels:%d",
544 aptx_dsp_cfg.sample_rate, aptx_dsp_cfg.num_channels);
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530545fail:
546 return is_configured;
547}
548
549/* API to configure APTX HD DSP encoder
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530550 */
551bool configure_aptx_hd_enc_format(audio_aptx_encoder_config *aptx_bt_cfg)
552{
Naresh Tanniruf5ba8d02016-09-29 18:06:37 +0530553 struct mixer_ctl *ctl_enc_data = NULL, *ctrl_bit_format = NULL;
Preetam Singh Ranawat0d645ea2017-08-07 18:12:07 +0530554 struct custom_enc_cfg_t aptx_dsp_cfg;
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530555 bool is_configured = false;
556 int ret = 0;
557
558 if(aptx_bt_cfg == NULL)
559 return false;
560
561 ctl_enc_data = mixer_get_ctl_by_name(a2dp.adev->mixer, MIXER_ENC_CONFIG_BLOCK);
562 if (!ctl_enc_data) {
563 ALOGE(" ERROR a2dp encoder CONFIG data mixer control not identifed");
564 is_configured = false;
565 goto fail;
566 }
Naresh Tanniruf5ba8d02016-09-29 18:06:37 +0530567
Preetam Singh Ranawat0d645ea2017-08-07 18:12:07 +0530568 memset(&aptx_dsp_cfg, 0x0, sizeof(struct custom_enc_cfg_t));
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530569 aptx_dsp_cfg.enc_format = ENC_MEDIA_FMT_APTX_HD;
570 aptx_dsp_cfg.sample_rate = aptx_bt_cfg->sampling_rate;
571 aptx_dsp_cfg.num_channels = aptx_bt_cfg->channels;
572 switch(aptx_dsp_cfg.num_channels) {
573 case 1:
574 aptx_dsp_cfg.channel_mapping[0] = PCM_CHANNEL_C;
575 break;
576 case 2:
577 default:
578 aptx_dsp_cfg.channel_mapping[0] = PCM_CHANNEL_L;
579 aptx_dsp_cfg.channel_mapping[1] = PCM_CHANNEL_R;
580 break;
581 }
582 ret = mixer_ctl_set_array(ctl_enc_data, (void *)&aptx_dsp_cfg,
Preetam Singh Ranawat0d645ea2017-08-07 18:12:07 +0530583 sizeof(struct custom_enc_cfg_t));
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530584 if (ret != 0) {
585 ALOGE("%s: Failed to set APTX HD encoder config", __func__);
586 is_configured = false;
587 goto fail;
588 }
Naresh Tanniruf5ba8d02016-09-29 18:06:37 +0530589 ctrl_bit_format = mixer_get_ctl_by_name(a2dp.adev->mixer, MIXER_ENC_BIT_FORMAT);
590 if (!ctrl_bit_format) {
591 ALOGE(" ERROR bit format CONFIG data mixer control not identifed");
592 is_configured = false;
593 goto fail;
594 }
595 ret = mixer_ctl_set_enum_by_string(ctrl_bit_format, "S24_LE");
596 if (ret != 0) {
597 ALOGE("%s: Failed to set APTX HD encoder config", __func__);
598 is_configured = false;
599 goto fail;
600 }
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530601 is_configured = true;
Preetam Singh Ranawat0d645ea2017-08-07 18:12:07 +0530602 a2dp.bt_encoder_format = ENC_CODEC_TYPE_APTX_HD;
Naresh Tanniruf5ba8d02016-09-29 18:06:37 +0530603 a2dp.enc_sampling_rate = aptx_bt_cfg->sampling_rate;
604 ALOGV("Successfully updated APTX HD encformat with samplingrate: %d channels:%d",
605 aptx_dsp_cfg.sample_rate, aptx_dsp_cfg.num_channels);
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530606fail:
607 return is_configured;
608}
609
610/* API to configure AAC DSP encoder */
611bool configure_aac_enc_format(audio_aac_encoder_config *aac_bt_cfg)
612{
Naresh Tanniruf5ba8d02016-09-29 18:06:37 +0530613 struct mixer_ctl *ctl_enc_data = NULL, *ctrl_bit_format = NULL;
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530614 struct aac_enc_cfg_t aac_dsp_cfg;
615 bool is_configured = false;
616 int ret = 0;
617
618 if(aac_bt_cfg == NULL)
619 return false;
620
621 ctl_enc_data = mixer_get_ctl_by_name(a2dp.adev->mixer, MIXER_ENC_CONFIG_BLOCK);
622 if (!ctl_enc_data) {
623 ALOGE(" ERROR a2dp encoder CONFIG data mixer control not identifed");
624 is_configured = false;
625 goto fail;
626 }
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530627 memset(&aac_dsp_cfg, 0x0, sizeof(struct aac_enc_cfg_t));
628 aac_dsp_cfg.enc_format = ENC_MEDIA_FMT_AAC;
629 aac_dsp_cfg.bit_rate = aac_bt_cfg->bitrate;
Naresh Tannirua42d0bd2016-09-21 15:30:46 +0530630 aac_dsp_cfg.sample_rate = aac_bt_cfg->sampling_rate;
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530631 switch(aac_bt_cfg->enc_mode) {
632 case 0:
633 aac_dsp_cfg.enc_mode = MEDIA_FMT_AAC_AOT_LC;
634 break;
635 case 2:
636 aac_dsp_cfg.enc_mode = MEDIA_FMT_AAC_AOT_PS;
637 break;
638 case 1:
639 default:
640 aac_dsp_cfg.enc_mode = MEDIA_FMT_AAC_AOT_SBR;
641 break;
642 }
Naresh Tannirua42d0bd2016-09-21 15:30:46 +0530643 aac_dsp_cfg.aac_fmt_flag = aac_bt_cfg->format_flag;
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530644 aac_dsp_cfg.channel_cfg = aac_bt_cfg->channels;
645 ret = mixer_ctl_set_array(ctl_enc_data, (void *)&aac_dsp_cfg,
646 sizeof(struct aac_enc_cfg_t));
647 if (ret != 0) {
648 ALOGE("%s: failed to set SBC encoder config", __func__);
649 is_configured = false;
Naresh Tanniruf5ba8d02016-09-29 18:06:37 +0530650 goto fail;
651 }
652 ctrl_bit_format = mixer_get_ctl_by_name(a2dp.adev->mixer,
653 MIXER_ENC_BIT_FORMAT);
654 if (!ctrl_bit_format) {
655 is_configured = false;
656 ALOGE(" ERROR bit format CONFIG data mixer control not identifed");
657 goto fail;
658 }
659 ret = mixer_ctl_set_enum_by_string(ctrl_bit_format, "S16_LE");
660 if (ret != 0) {
661 ALOGE("%s: Failed to set bit format to encoder", __func__);
662 is_configured = false;
663 goto fail;
664 }
665 is_configured = true;
Preetam Singh Ranawat0d645ea2017-08-07 18:12:07 +0530666 a2dp.bt_encoder_format = ENC_CODEC_TYPE_AAC;
Naresh Tanniruf5ba8d02016-09-29 18:06:37 +0530667 a2dp.enc_sampling_rate = aac_bt_cfg->sampling_rate;
668 ALOGV("Successfully updated AAC enc format with samplingrate: %d channels:%d",
669 aac_dsp_cfg.sample_rate, aac_dsp_cfg.channel_cfg);
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530670fail:
671 return is_configured;
672}
673
Preetam Singh Ranawat0d645ea2017-08-07 18:12:07 +0530674bool configure_celt_enc_format(audio_celt_encoder_config *celt_bt_cfg)
675{
676 struct mixer_ctl *ctl_enc_data = NULL, *ctrl_bit_format = NULL;
677 struct celt_enc_cfg_t celt_dsp_cfg;
678 bool is_configured = false;
679 int ret = 0;
680 if(celt_bt_cfg == NULL)
681 return false;
682
683 ctl_enc_data = mixer_get_ctl_by_name(a2dp.adev->mixer, MIXER_ENC_CONFIG_BLOCK);
684 if (!ctl_enc_data) {
685 ALOGE(" ERROR a2dp encoder CONFIG data mixer control not identifed");
686 is_configured = false;
687 goto fail;
688 }
689 memset(&celt_dsp_cfg, 0x0, sizeof(struct celt_enc_cfg_t));
690
691 celt_dsp_cfg.custom_cfg.enc_format = ENC_MEDIA_FMT_CELT;
692 celt_dsp_cfg.custom_cfg.sample_rate = celt_bt_cfg->sampling_rate;
693 celt_dsp_cfg.custom_cfg.num_channels = celt_bt_cfg->channels;
694 switch(celt_dsp_cfg.custom_cfg.num_channels) {
695 case 1:
696 celt_dsp_cfg.custom_cfg.channel_mapping[0] = PCM_CHANNEL_C;
697 break;
698 case 2:
699 default:
700 celt_dsp_cfg.custom_cfg.channel_mapping[0] = PCM_CHANNEL_L;
701 celt_dsp_cfg.custom_cfg.channel_mapping[1] = PCM_CHANNEL_R;
702 break;
703 }
704
705 celt_dsp_cfg.custom_cfg.custom_size = sizeof(struct celt_enc_cfg_t);
706
707 celt_dsp_cfg.celt_cfg.frame_size = celt_bt_cfg->frame_size;
708 celt_dsp_cfg.celt_cfg.complexity = celt_bt_cfg->complexity;
709 celt_dsp_cfg.celt_cfg.prediction_mode = celt_bt_cfg->prediction_mode;
710 celt_dsp_cfg.celt_cfg.vbr_flag = celt_bt_cfg->vbr_flag;
711 celt_dsp_cfg.celt_cfg.bit_rate = celt_bt_cfg->bitrate;
712
713 ret = mixer_ctl_set_array(ctl_enc_data, (void *)&celt_dsp_cfg,
714 sizeof(struct celt_enc_cfg_t));
715 if (ret != 0) {
716 ALOGE("%s: Failed to set CELT encoder config", __func__);
717 is_configured = false;
718 goto fail;
719 }
720 ctrl_bit_format = mixer_get_ctl_by_name(a2dp.adev->mixer, MIXER_ENC_BIT_FORMAT);
721 if (!ctrl_bit_format) {
722 ALOGE(" ERROR bit format CONFIG data mixer control not identifed");
723 is_configured = false;
724 goto fail;
725 }
726 ret = mixer_ctl_set_enum_by_string(ctrl_bit_format, "S16_LE");
727 if (ret != 0) {
728 ALOGE("%s: Failed to set bit format to encoder", __func__);
729 is_configured = false;
730 goto fail;
731 }
732 is_configured = true;
733 a2dp.bt_encoder_format = ENC_CODEC_TYPE_CELT;
734 a2dp.enc_sampling_rate = celt_bt_cfg->sampling_rate;
735 ALOGV("Successfully updated CELT encformat with samplingrate: %d channels:%d",
736 celt_dsp_cfg.custom_cfg.sample_rate, celt_dsp_cfg.custom_cfg.num_channels);
737fail:
738 return is_configured;
739}
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530740bool configure_a2dp_encoder_format()
741{
742 void *codec_info = NULL;
743 uint8_t multi_cast = 0, num_dev = 1;
Preetam Singh Ranawat0d645ea2017-08-07 18:12:07 +0530744 enc_codec_t codec_type = ENC_CODEC_TYPE_INVALID;
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530745 bool is_configured = false;
746
747 if (!a2dp.audio_get_codec_config) {
748 ALOGE(" a2dp handle is not identified, ignoring a2dp encoder config");
749 return false;
750 }
751 ALOGD("configure_a2dp_encoder_format start");
752 codec_info = a2dp.audio_get_codec_config(&multi_cast, &num_dev,
753 &codec_type);
754
755 switch(codec_type) {
Preetam Singh Ranawat0d645ea2017-08-07 18:12:07 +0530756 case ENC_CODEC_TYPE_SBC:
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530757 ALOGD(" Received SBC encoder supported BT device");
758 is_configured =
759 configure_sbc_enc_format((audio_sbc_encoder_config *)codec_info);
760 break;
Preetam Singh Ranawat0d645ea2017-08-07 18:12:07 +0530761 case ENC_CODEC_TYPE_APTX:
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530762 ALOGD(" Received APTX encoder supported BT device");
763 is_configured =
764 configure_aptx_enc_format((audio_aptx_encoder_config *)codec_info);
765 break;
Preetam Singh Ranawat0d645ea2017-08-07 18:12:07 +0530766 case ENC_CODEC_TYPE_APTX_HD:
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530767 ALOGD(" Received APTX HD encoder supported BT device");
768 is_configured =
769 configure_aptx_hd_enc_format((audio_aptx_encoder_config *)codec_info);
770 break;
Preetam Singh Ranawat0d645ea2017-08-07 18:12:07 +0530771 case ENC_CODEC_TYPE_AAC:
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530772 ALOGD(" Received AAC encoder supported BT device");
773 is_configured =
774 configure_aac_enc_format((audio_aac_encoder_config *)codec_info);
775 break;
Preetam Singh Ranawat0d645ea2017-08-07 18:12:07 +0530776 case ENC_CODEC_TYPE_CELT:
777 ALOGD(" Received CELT encoder supported BT device");
778 is_configured =
779 configure_celt_enc_format((audio_celt_encoder_config *)codec_info);
780 break;
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530781 default:
782 ALOGD(" Received Unsupported encoder formar");
783 is_configured = false;
784 break;
785 }
786 return is_configured;
787}
788
789int audio_extn_a2dp_start_playback()
790{
791 int ret = 0;
792
793 ALOGD("audio_extn_a2dp_start_playback start");
794
795 if(!(a2dp.bt_lib_handle && a2dp.audio_start_stream
796 && a2dp.audio_get_codec_config)) {
797 ALOGE("a2dp handle is not identified, Ignoring start request");
798 return -ENOSYS;
799 }
800
801 if(a2dp.a2dp_suspended == true) {
802 //session will be restarted after suspend completion
803 ALOGD("a2dp start requested during suspend state");
Naresh Tannirucd2353e2016-08-19 00:37:25 +0530804 return -ENOSYS;
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530805 }
806
807 if (!a2dp.a2dp_started && !a2dp.a2dp_total_active_session_request) {
808 ALOGD("calling BT module stream start");
809 /* This call indicates BT IPC lib to start playback */
810 ret = a2dp.audio_start_stream();
811 ALOGE("BT controller start return = %d",ret);
812 if (ret != 0 ) {
813 ALOGE("BT controller start failed");
814 a2dp.a2dp_started = false;
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530815 } else {
816 if(configure_a2dp_encoder_format() == true) {
817 a2dp.a2dp_started = true;
818 ret = 0;
819 ALOGD("Start playback successful to BT library");
820 } else {
821 ALOGD(" unable to configure DSP encoder");
822 a2dp.a2dp_started = false;
823 ret = -ETIMEDOUT;
824 }
825 }
826 }
827
828 if (a2dp.a2dp_started)
829 a2dp.a2dp_total_active_session_request++;
830
831 ALOGD("start A2DP playback total active sessions :%d",
832 a2dp.a2dp_total_active_session_request);
833 return ret;
834}
835
Naresh Tanniru03f9dd52016-10-19 18:46:22 +0530836static void reset_a2dp_enc_config_params()
837{
838 int ret =0;
839
840 struct mixer_ctl *ctl_enc_config, *ctrl_bit_format;
841 struct sbc_enc_cfg_t dummy_reset_config;
842
843 memset(&dummy_reset_config, 0x0, sizeof(struct sbc_enc_cfg_t));
844 ctl_enc_config = mixer_get_ctl_by_name(a2dp.adev->mixer,
845 MIXER_ENC_CONFIG_BLOCK);
846 if (!ctl_enc_config) {
847 ALOGE(" ERROR a2dp encoder format mixer control not identifed");
848 } else {
849 ret = mixer_ctl_set_array(ctl_enc_config, (void *)&dummy_reset_config,
850 sizeof(struct sbc_enc_cfg_t));
851 a2dp.bt_encoder_format = ENC_MEDIA_FMT_NONE;
852 }
853 ctrl_bit_format = mixer_get_ctl_by_name(a2dp.adev->mixer,
854 MIXER_ENC_BIT_FORMAT);
855 if (!ctrl_bit_format) {
856 ALOGE(" ERROR bit format CONFIG data mixer control not identifed");
857 } else {
858 ret = mixer_ctl_set_enum_by_string(ctrl_bit_format, "S16_LE");
859 if (ret != 0) {
860 ALOGE("%s: Failed to set bit format to encoder", __func__);
861 }
862 }
863}
864
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530865int audio_extn_a2dp_stop_playback()
866{
867 int ret =0;
868
869 ALOGV("audio_extn_a2dp_stop_playback start");
870 if(!(a2dp.bt_lib_handle && a2dp.audio_stop_stream)) {
871 ALOGE("a2dp handle is not identified, Ignoring start request");
872 return -ENOSYS;
873 }
874
Preetam Singh Ranawata1849ba2017-02-06 14:10:11 +0530875 if (a2dp.a2dp_total_active_session_request > 0)
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530876 a2dp.a2dp_total_active_session_request--;
877
878 if ( a2dp.a2dp_started && !a2dp.a2dp_total_active_session_request) {
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530879 ALOGV("calling BT module stream stop");
880 ret = a2dp.audio_stop_stream();
881 if (ret < 0)
882 ALOGE("stop stream to BT IPC lib failed");
883 else
884 ALOGV("stop steam to BT IPC lib successful");
Naresh Tanniru03f9dd52016-10-19 18:46:22 +0530885 reset_a2dp_enc_config_params();
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530886 }
887 if(!a2dp.a2dp_total_active_session_request)
888 a2dp.a2dp_started = false;
889 ALOGD("Stop A2DP playback total active sessions :%d",
890 a2dp.a2dp_total_active_session_request);
891 return 0;
892}
893
894void audio_extn_a2dp_set_parameters(struct str_parms *parms)
895{
896 int ret, val;
897 char value[32]={0};
Chaithanya Krishna Bacharaju69d2e4c2017-05-26 18:22:46 +0530898 struct audio_usecase *uc_info;
899 struct listnode *node;
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530900
901 if(a2dp.is_a2dp_offload_supported == false) {
902 ALOGV("no supported encoders identified,ignoring a2dp setparam");
903 return;
904 }
905
906 ret = str_parms_get_str(parms, AUDIO_PARAMETER_DEVICE_CONNECT, value,
907 sizeof(value));
908 if( ret >= 0) {
909 val = atoi(value);
910 if (val & AUDIO_DEVICE_OUT_ALL_A2DP) {
911 ALOGV("Received device connect request for A2DP");
912 open_a2dp_output();
913 }
914 goto param_handled;
915 }
916
917 ret = str_parms_get_str(parms, AUDIO_PARAMETER_DEVICE_DISCONNECT, value,
918 sizeof(value));
919
920 if( ret >= 0) {
921 val = atoi(value);
922 if (val & AUDIO_DEVICE_OUT_ALL_A2DP) {
923 ALOGV("Received device dis- connect request");
Naresh Tanniru03f9dd52016-10-19 18:46:22 +0530924 reset_a2dp_enc_config_params();
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530925 close_a2dp_output();
926 }
927 goto param_handled;
928 }
929
930 ret = str_parms_get_str(parms, "A2dpSuspended", value, sizeof(value));
931 if (ret >= 0) {
932 if (a2dp.bt_lib_handle && (a2dp.bt_state != A2DP_STATE_DISCONNECTED) ) {
933 if ((!strncmp(value,"true",sizeof(value)))) {
934 ALOGD("Setting a2dp to suspend state");
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530935 a2dp.a2dp_suspended = true;
Chaithanya Krishna Bacharaju69d2e4c2017-05-26 18:22:46 +0530936 list_for_each(node, &a2dp.adev->usecase_list) {
937 uc_info = node_to_item(node, struct audio_usecase, list);
Zhou Songc66eb7e2017-08-08 18:29:07 +0800938 if (uc_info->type == PCM_PLAYBACK &&
939 (uc_info->stream.out->devices & AUDIO_DEVICE_OUT_ALL_A2DP)) {
Chaithanya Krishna Bacharaju69d2e4c2017-05-26 18:22:46 +0530940 pthread_mutex_unlock(&a2dp.adev->lock);
941 check_a2dp_restore(a2dp.adev, uc_info->stream.out, false);
942 pthread_mutex_lock(&a2dp.adev->lock);
943 }
944 }
Naresh Tanniru03f9dd52016-10-19 18:46:22 +0530945 reset_a2dp_enc_config_params();
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530946 if(a2dp.audio_suspend_stream)
947 a2dp.audio_suspend_stream();
948 } else if (a2dp.a2dp_suspended == true) {
949 ALOGD("Resetting a2dp suspend state");
Zhou Song10617ed2017-05-26 13:28:48 +0800950 struct audio_usecase *uc_info;
951 struct listnode *node;
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530952 if(a2dp.clear_a2dpsuspend_flag)
953 a2dp.clear_a2dpsuspend_flag();
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530954 a2dp.a2dp_suspended = false;
Naresh Tanniru649871a2016-11-04 18:08:32 +0530955 /*
956 * It is possible that before suspend,a2dp sessions can be active
957 * for example during music + voice activation concurrency
958 * a2dp suspend will be called & BT will change to sco mode
959 * though music is paused as a part of voice activation
960 * compress session close happens only after pause timeout(10secs)
961 * so if resume request comes before pause timeout as a2dp session
962 * is already active IPC start will not be called from APM/audio_hw
963 * Fix is to call a2dp start for IPC library post suspend
964 * based on number of active session count
965 */
966 if (a2dp.a2dp_total_active_session_request > 0) {
967 ALOGD(" Calling IPC lib start post suspend state");
968 if(a2dp.audio_start_stream) {
969 ret = a2dp.audio_start_stream();
970 if (ret != 0) {
971 ALOGE("BT controller start failed");
972 a2dp.a2dp_started = false;
973 }
974 }
975 }
Zhou Song10617ed2017-05-26 13:28:48 +0800976 list_for_each(node, &a2dp.adev->usecase_list) {
977 uc_info = node_to_item(node, struct audio_usecase, list);
Zhou Songc66eb7e2017-08-08 18:29:07 +0800978 if (uc_info->type == PCM_PLAYBACK &&
979 (uc_info->stream.out->devices & AUDIO_DEVICE_OUT_ALL_A2DP)) {
Chaithanya Krishna Bacharaju69d2e4c2017-05-26 18:22:46 +0530980 pthread_mutex_unlock(&a2dp.adev->lock);
981 check_a2dp_restore(a2dp.adev, uc_info->stream.out, true);
982 pthread_mutex_lock(&a2dp.adev->lock);
983 }
Zhou Song10617ed2017-05-26 13:28:48 +0800984 }
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530985 }
986 }
987 goto param_handled;
988 }
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530989param_handled:
990 ALOGV("end of a2dp setparam");
991}
992
Naresh Tannirucd2353e2016-08-19 00:37:25 +0530993void audio_extn_a2dp_set_handoff_mode(bool is_on)
994{
995 a2dp.is_handoff_in_progress = is_on;
996}
997
Naresh Tanniru9d027a62015-03-13 01:32:10 +0530998bool audio_extn_a2dp_is_force_device_switch()
999{
1000 //During encoder reconfiguration mode, force a2dp device switch
Ashish Jainc597d102016-12-12 10:31:34 +05301001 // Or if a2dp device is selected but earlier start failed ( as a2dp
1002 // was suspended, force retry.
1003 return a2dp.is_handoff_in_progress || !a2dp.a2dp_started;
Naresh Tanniru9d027a62015-03-13 01:32:10 +05301004}
1005
Naresh Tanniruf5ba8d02016-09-29 18:06:37 +05301006void audio_extn_a2dp_get_apptype_params(uint32_t *sample_rate,
1007 uint32_t *bit_width)
1008{
Preetam Singh Ranawat0d645ea2017-08-07 18:12:07 +05301009 if(a2dp.bt_encoder_format == ENC_CODEC_TYPE_APTX_HD)
Naresh Tanniruf5ba8d02016-09-29 18:06:37 +05301010 *bit_width = 24;
1011 else
1012 *bit_width = 16;
1013 *sample_rate = a2dp.enc_sampling_rate;
1014}
Preetam Singh Ranawata1849ba2017-02-06 14:10:11 +05301015
1016bool audio_extn_a2dp_is_ready()
1017{
1018 bool ret = false;
1019
Chaithanya Krishna Bacharaju69d2e4c2017-05-26 18:22:46 +05301020 if (a2dp.a2dp_suspended)
1021 return ret;
1022
Aniket Kumar Lata901bcb82017-03-10 15:42:46 -08001023 if ((a2dp.bt_state != A2DP_STATE_DISCONNECTED) &&
1024 (a2dp.is_a2dp_offload_supported) &&
Preetam Singh Ranawata1849ba2017-02-06 14:10:11 +05301025 (a2dp.audio_check_a2dp_ready))
1026 ret = a2dp.audio_check_a2dp_ready();
1027 return ret;
1028}
1029
Chaithanya Krishna Bacharaju69d2e4c2017-05-26 18:22:46 +05301030bool audio_extn_a2dp_is_suspended()
1031{
1032 return a2dp.a2dp_suspended;
1033}
1034
Naresh Tanniru9d027a62015-03-13 01:32:10 +05301035void audio_extn_a2dp_init (void *adev)
1036{
1037 a2dp.adev = (struct audio_device*)adev;
1038 a2dp.bt_lib_handle = NULL;
1039 a2dp.a2dp_started = false;
1040 a2dp.bt_state = A2DP_STATE_DISCONNECTED;
1041 a2dp.a2dp_total_active_session_request = 0;
1042 a2dp.a2dp_suspended = false;
Preetam Singh Ranawat0d645ea2017-08-07 18:12:07 +05301043 a2dp.bt_encoder_format = ENC_CODEC_TYPE_INVALID;
Naresh Tanniruf5ba8d02016-09-29 18:06:37 +05301044 a2dp.enc_sampling_rate = 48000;
Naresh Tanniru9d027a62015-03-13 01:32:10 +05301045 a2dp.is_a2dp_offload_supported = false;
1046 a2dp.is_handoff_in_progress = false;
kunleiz5a127262017-09-08 14:47:48 +08001047 reset_a2dp_enc_config_params();
Naresh Tanniru9d027a62015-03-13 01:32:10 +05301048 update_offload_codec_capabilities();
1049}
Aniket Kumar Latad5972fa2017-02-08 13:53:48 -08001050
1051uint32_t audio_extn_a2dp_get_encoder_latency()
1052{
Aniket Kumar Latad5972fa2017-02-08 13:53:48 -08001053 uint32_t latency = 0;
1054 int avsync_runtime_prop = 0;
Preetam Singh Ranawat0d645ea2017-08-07 18:12:07 +05301055 int sbc_offset = 0, aptx_offset = 0, aptxhd_offset = 0, aac_offset = 0, celt_offset = 0;
Aniket Kumar Latad5972fa2017-02-08 13:53:48 -08001056 char value[PROPERTY_VALUE_MAX];
1057
Aniket Kumar Latad5972fa2017-02-08 13:53:48 -08001058 memset(value, '\0', sizeof(char)*PROPERTY_VALUE_MAX);
Aniket Kumar Lata8fc67e62017-05-02 12:33:46 -07001059 avsync_runtime_prop = property_get("vendor.audio.a2dp.codec.latency", value, NULL);
Aniket Kumar Latad5972fa2017-02-08 13:53:48 -08001060 if (avsync_runtime_prop > 0) {
Preetam Singh Ranawat0d645ea2017-08-07 18:12:07 +05301061 if (sscanf(value, "%d/%d/%d/%d/%d",
1062 &sbc_offset, &aptx_offset, &aptxhd_offset, &aac_offset, &celt_offset) != 5) {
Aniket Kumar Latad5972fa2017-02-08 13:53:48 -08001063 ALOGI("Failed to parse avsync offset params from '%s'.", value);
1064 avsync_runtime_prop = 0;
1065 }
1066 }
1067
yidongh0515e042017-07-06 15:00:34 +08001068 uint32_t slatency = 0;
1069 if (a2dp.audio_get_a2dp_sink_latency && a2dp.bt_state != A2DP_STATE_DISCONNECTED) {
1070 slatency = a2dp.audio_get_a2dp_sink_latency();
1071 }
1072
Aniket Kumar Latafaaffde2017-03-22 19:18:15 -07001073 switch(a2dp.bt_encoder_format) {
Preetam Singh Ranawat0d645ea2017-08-07 18:12:07 +05301074 case ENC_CODEC_TYPE_SBC:
yidongh0515e042017-07-06 15:00:34 +08001075 latency = (avsync_runtime_prop > 0) ? sbc_offset : ENCODER_LATENCY_SBC;
1076 latency += (slatency <= 0) ? DEFAULT_SINK_LATENCY_SBC : slatency;
Aniket Kumar Latad5972fa2017-02-08 13:53:48 -08001077 break;
Preetam Singh Ranawat0d645ea2017-08-07 18:12:07 +05301078 case ENC_CODEC_TYPE_APTX:
yidongh0515e042017-07-06 15:00:34 +08001079 latency = (avsync_runtime_prop > 0) ? aptx_offset : ENCODER_LATENCY_APTX;
1080 latency += (slatency <= 0) ? DEFAULT_SINK_LATENCY_APTX : slatency;
Aniket Kumar Latad5972fa2017-02-08 13:53:48 -08001081 break;
Preetam Singh Ranawat0d645ea2017-08-07 18:12:07 +05301082 case ENC_CODEC_TYPE_APTX_HD:
yidongh0515e042017-07-06 15:00:34 +08001083 latency = (avsync_runtime_prop > 0) ? aptxhd_offset : ENCODER_LATENCY_APTX_HD;
1084 latency += (slatency <= 0) ? DEFAULT_SINK_LATENCY_APTX_HD : slatency;
Aniket Kumar Latad5972fa2017-02-08 13:53:48 -08001085 break;
Preetam Singh Ranawat0d645ea2017-08-07 18:12:07 +05301086 case ENC_CODEC_TYPE_AAC:
yidongh0515e042017-07-06 15:00:34 +08001087 latency = (avsync_runtime_prop > 0) ? aac_offset : ENCODER_LATENCY_AAC;
1088 latency += (slatency <= 0) ? DEFAULT_SINK_LATENCY_AAC : slatency;
Aniket Kumar Latad5972fa2017-02-08 13:53:48 -08001089 break;
Preetam Singh Ranawat0d645ea2017-08-07 18:12:07 +05301090 case ENC_CODEC_TYPE_CELT:
1091 latency = (avsync_runtime_prop > 0) ? celt_offset : ENCODER_LATENCY_CELT;
1092 latency += (slatency <= 0) ? DEFAULT_SINK_LATENCY_CELT : slatency;
1093 break;
Aniket Kumar Latad5972fa2017-02-08 13:53:48 -08001094 default:
1095 latency = 200;
1096 break;
1097 }
1098 return latency;
1099}
Naresh Tanniru9d027a62015-03-13 01:32:10 +05301100#endif // SPLIT_A2DP_ENABLED