audio: unify hal
Unify audio hal components
CRs-Fixed: 2380934
Change-Id: Iacafdc44d935de5f343240421a1572a0a3241bd0
diff --git a/hal/audio_extn/a2dp.c b/hal/audio_extn/a2dp.c
index f08f379..b193d67 100644
--- a/hal/audio_extn/a2dp.c
+++ b/hal/audio_extn/a2dp.c
@@ -1,5 +1,5 @@
/*
-* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved.
+* Copyright (c) 2015-2019, The Linux Foundation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -26,12 +26,13 @@
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#define LOG_TAG "split_a2dp"
+#define LOG_TAG "a2dp_offload"
/*#define LOG_NDEBUG 0*/
#define LOG_NDDEBUG 0
#include <errno.h>
-#include <cutils/log.h>
+#include <log/log.h>
#include <dlfcn.h>
+#include <pthread.h>
#include "audio_hw.h"
#include "platform.h"
#include "platform_api.h"
@@ -48,7 +49,7 @@
#include <log_utils.h>
#endif
-#ifdef SPLIT_A2DP_ENABLED
+#ifdef A2DP_OFFLOAD_ENABLED
#define AUDIO_PARAMETER_A2DP_STARTED "A2dpStarted"
#define BT_IPC_SOURCE_LIB_NAME "libbthost_if.so"
#define BT_IPC_SINK_LIB_NAME "libbthost_if_sink.so"
@@ -93,6 +94,7 @@
#define MIXER_ENC_FMT_APTX "APTX"
#define MIXER_FMT_TWS_CHANNEL_MODE "TWS Channel Mode"
#define MIXER_ENC_FMT_APTXHD "APTXHD"
+#define MIXER_END_FMT_LDAC "LDAC"
#define MIXER_ENC_FMT_NONE "NONE"
#define ENCODER_LATENCY_SBC 10
#define ENCODER_LATENCY_APTX 40
@@ -101,6 +103,7 @@
//To Do: Fine Tune Encoder CELT/LDAC latency.
#define ENCODER_LATENCY_CELT 40
#define ENCODER_LATENCY_LDAC 40
+#define ENCODER_LATENCY_PCM 50
#define DEFAULT_SINK_LATENCY_SBC 140
#define DEFAULT_SINK_LATENCY_APTX 160
#define DEFAULT_SINK_LATENCY_APTX_HD 180
@@ -108,6 +111,17 @@
//To Do: Fine Tune Default CELT/LDAC Latency.
#define DEFAULT_SINK_LATENCY_CELT 180
#define DEFAULT_SINK_LATENCY_LDAC 180
+#define DEFAULT_SINK_LATENCY_PCM 140
+
+#define SYSPROP_A2DP_OFFLOAD_SUPPORTED "ro.bluetooth.a2dp_offload.supported"
+#define SYSPROP_A2DP_OFFLOAD_DISABLED "persist.bluetooth.a2dp_offload.disabled"
+#define SYSPROP_A2DP_CODEC_LATENCIES "vendor.audio.a2dp.codec.latency"
+
+// Default encoder bit width
+#define DEFAULT_ENCODER_BIT_FORMAT 16
+
+// Default encoder latency
+#define DEFAULT_ENCODER_LATENCY 200
// Slimbus Tx sample rate for ABR feedback channel
#define ABR_TX_SAMPLE_RATE "KHZ_8"
@@ -146,6 +160,7 @@
CODEC_TYPE_LDAC = AUDIO_FORMAT_LDAC, // 0x23000000UL
CODEC_TYPE_CELT = 603979776u, // 0x24000000UL
CODEC_TYPE_APTX_AD = 620756992u, // 0x25000000UL
+ CODEC_TYPE_PCM = AUDIO_FORMAT_PCM_16_BIT, // 0x1u
}codec_t;
/*
@@ -605,6 +620,7 @@
uint32_t sampling_rate;
uint32_t bitrate;
uint32_t bits_per_sample;
+ struct aac_frame_size_control_t frame_ctl;
} audio_aac_encoder_config;
#endif
@@ -667,60 +683,15 @@
/*********** END of DSP configurable structures ********************/
-/* API to identify DSP encoder captabilities */
-static void a2dp_offload_codec_cap_parser(char *value)
-{
- char *tok = NULL,*saveptr;
-
- tok = strtok_r(value, "-", &saveptr);
- while (tok != NULL) {
- if (strcmp(tok, "sbc") == 0) {
- ALOGD("%s: SBC offload supported\n",__func__);
- a2dp.is_a2dp_offload_supported = true;
- break;
- } else if (strcmp(tok, "aptx") == 0) {
- ALOGD("%s: aptx offload supported\n",__func__);
- a2dp.is_a2dp_offload_supported = true;
- break;
- } else if (strcmp(tok, "aptxtws") == 0) {
- ALOGD("%s: aptx dual mono offload supported\n",__func__);
- a2dp.is_a2dp_offload_supported = true;
- break;
- } else if (strcmp(tok, "aptxhd") == 0) {
- ALOGD("%s: aptx HD offload supported\n",__func__);
- a2dp.is_a2dp_offload_supported = true;
- break;
- } else if (strcmp(tok, "aac") == 0) {
- ALOGD("%s: aac offload supported\n",__func__);
- a2dp.is_a2dp_offload_supported = true;
- break;
- } else if (strcmp(tok, "celt") == 0) {
- ALOGD("%s: celt offload supported\n",__func__);
- a2dp.is_a2dp_offload_supported = true;
- break;
- } else if (strcmp(tok, "ldac") == 0) {
- ALOGD("%s: ldac offload supported\n",__func__);
- a2dp.is_a2dp_offload_supported = true;
- break;
- } else if( strcmp(tok, "aptxadaptive") == 0) {
- ALOGD("%s: aptx adaptive offload supported\n",__func__);
- a2dp.is_a2dp_offload_supported = true;
- }
- tok = strtok_r(NULL, "-", &saveptr);
- };
-}
-
static void update_offload_codec_capabilities()
{
- char value[PROPERTY_VALUE_MAX] = {'\0'};
- property_get("persist.vendor.bt.a2dp_offload_cap", value, "false");
- ALOGD("get_offload_codec_capabilities = %s",value);
a2dp.is_a2dp_offload_supported =
- property_get_bool("persist.vendor.bt.a2dp_offload_cap", false);
- if (strcmp(value, "false") != 0)
- a2dp_offload_codec_cap_parser(value);
- ALOGD("%s: codec cap = %s",__func__,value);
+ property_get_bool(SYSPROP_A2DP_OFFLOAD_SUPPORTED, false) &&
+ !property_get_bool(SYSPROP_A2DP_OFFLOAD_DISABLED, false);
+
+ ALOGD("%s: A2DP offload supported = %d",__func__,
+ a2dp.is_a2dp_offload_supported);
}
static int stop_abr()
@@ -852,17 +823,17 @@
a2dp.audio_source_open = (audio_source_open_t)
dlsym(a2dp.bt_lib_source_handle, "audio_stream_open");
a2dp.audio_source_start = (audio_source_start_t)
- dlsym(a2dp.bt_lib_source_handle, "audio_start_stream");
+ dlsym(a2dp.bt_lib_source_handle, "audio_stream_start");
a2dp.audio_get_enc_config = (audio_get_enc_config_t)
dlsym(a2dp.bt_lib_source_handle, "audio_get_codec_config");
a2dp.audio_source_suspend = (audio_source_suspend_t)
- dlsym(a2dp.bt_lib_source_handle, "audio_suspend_stream");
+ dlsym(a2dp.bt_lib_source_handle, "audio_stream_suspend");
a2dp.audio_source_handoff_triggered = (audio_source_handoff_triggered_t)
dlsym(a2dp.bt_lib_source_handle, "audio_handoff_triggered");
a2dp.clear_source_a2dpsuspend_flag = (clear_source_a2dpsuspend_flag_t)
dlsym(a2dp.bt_lib_source_handle, "clear_a2dpsuspend_flag");
a2dp.audio_source_stop = (audio_source_stop_t)
- dlsym(a2dp.bt_lib_source_handle, "audio_stop_stream");
+ dlsym(a2dp.bt_lib_source_handle, "audio_stream_stop");
a2dp.audio_source_close = (audio_source_close_t)
dlsym(a2dp.bt_lib_source_handle, "audio_stream_close");
a2dp.audio_source_check_a2dp_ready = (audio_source_check_a2dp_ready_t)
@@ -1026,6 +997,11 @@
sampling_rate = sampling_rate *2;
}
+ // No need to configure backend for PCM format.
+ if (a2dp.bt_encoder_format == CODEC_TYPE_PCM) {
+ return 0;
+ }
+
//Configure backend sampling rate
switch (sampling_rate) {
case 44100:
@@ -2168,6 +2144,11 @@
configure_a2dp_source_decoder_format(MEDIA_FMT_APTX_AD));
break;
#endif
+ case CODEC_TYPE_PCM:
+ ALOGD("Received PCM format for BT device");
+ a2dp.bt_encoder_format = CODEC_TYPE_PCM;
+ is_configured = true;
+ break;
default:
ALOGD(" Received Unsupported encoder formar");
is_configured = false;
@@ -2318,7 +2299,7 @@
{
int ret =0;
- struct mixer_ctl *ctl_enc_config, *ctrl_bit_format, *ctl_channel_mode;
+ struct mixer_ctl *ctl_enc_config, *ctl_channel_mode;
struct sbc_enc_cfg_t dummy_reset_config;
char* channel_mode;
@@ -2332,16 +2313,9 @@
sizeof(struct sbc_enc_cfg_t));
a2dp.bt_encoder_format = MEDIA_FMT_NONE;
}
- ctrl_bit_format = mixer_get_ctl_by_name(a2dp.adev->mixer,
- MIXER_ENC_BIT_FORMAT);
- if (!ctrl_bit_format) {
- ALOGE(" ERROR bit format CONFIG data mixer control not identified");
- } else {
- ret = mixer_ctl_set_enum_by_string(ctrl_bit_format, "S16_LE");
- if (ret != 0) {
- ALOGE("%s: Failed to set bit format to encoder", __func__);
- }
- }
+
+ a2dp_set_bit_format(DEFAULT_ENCODER_BIT_FORMAT);
+
ctl_channel_mode = mixer_get_ctl_by_name(a2dp.adev->mixer,MIXER_FMT_TWS_CHANNEL_MODE);
if (!ctl_channel_mode) {
@@ -2420,6 +2394,8 @@
if (a2dp.a2dp_source_total_active_session_requests > 0)
a2dp.a2dp_source_total_active_session_requests--;
+ else
+ ALOGE("%s: No active playback session requests on A2DP", __func__);
if ( a2dp.a2dp_source_started && !a2dp.a2dp_source_total_active_session_requests) {
ALOGV("calling BT module stream stop");
@@ -2474,16 +2450,17 @@
return 0;
}
-void audio_extn_a2dp_set_parameters(struct str_parms *parms)
+int audio_extn_a2dp_set_parameters(struct str_parms *parms, bool *reconfig)
{
- int ret, val;
+ int ret = 0, val, status = 0;
char value[32]={0};
struct audio_usecase *uc_info;
struct listnode *node;
if(a2dp.is_a2dp_offload_supported == false) {
- ALOGV("no supported codecs identified,ignoring a2dp setparam");
- return;
+ ALOGV("no supported encoders identified,ignoring a2dp setparam");
+ status = -EINVAL;
+ goto param_handled;
}
ret = str_parms_get_str(parms, AUDIO_PARAMETER_DEVICE_CONNECT, value,
@@ -2532,6 +2509,10 @@
if (ret >= 0) {
if (a2dp.bt_lib_source_handle) {
if ((!strncmp(value,"true",sizeof(value)))) {
+ if (a2dp.a2dp_source_suspended) {
+ ALOGD("%s: A2DP is already suspended", __func__);
+ goto param_handled;
+ }
ALOGD("Setting a2dp to suspend state");
a2dp.a2dp_source_suspended = true;
if (a2dp.bt_state_source == A2DP_STATE_DISCONNECTED)
@@ -2590,8 +2571,20 @@
}
goto param_handled;
}
+
+ ret = str_parms_get_str(parms, AUDIO_PARAMETER_RECONFIG_A2DP, value,
+ sizeof(value));
+ if (ret >= 0) {
+ if (a2dp.is_a2dp_offload_supported &&
+ a2dp.bt_state_source != A2DP_STATE_DISCONNECTED) {
+ *reconfig = true;
+ }
+ goto param_handled;
+ }
+
param_handled:
ALOGV("end of a2dp setparam");
+ return status;
}
void audio_extn_a2dp_set_handoff_mode(bool is_on)
@@ -2688,7 +2681,7 @@
char value[PROPERTY_VALUE_MAX];
memset(value, '\0', sizeof(char)*PROPERTY_VALUE_MAX);
- avsync_runtime_prop = property_get("vendor.audio.a2dp.codec.latency", value, NULL);
+ avsync_runtime_prop = property_get(SYSPROP_A2DP_CODEC_LATENCIES, value, NULL);
if (avsync_runtime_prop > 0) {
if (sscanf(value, "%d/%d/%d/%d/%d%d",
&sbc_offset, &aptx_offset, &aptxhd_offset, &aac_offset, &celt_offset, &ldac_offset) != 6) {
@@ -2730,10 +2723,31 @@
case CODEC_TYPE_APTX_AD: // for aptx adaptive the latency depends on the mode (HQ/LL) and
latency = slatency; // BT IPC will take care of accomodating the mode factor and return latency
break;
+ case CODEC_TYPE_PCM:
+ latency = ENCODER_LATENCY_PCM;
+ latency += DEFAULT_SINK_LATENCY_PCM;
+ break;
default:
latency = 200;
break;
}
return latency;
}
-#endif // SPLIT_A2DP_ENABLED
+
+int audio_extn_a2dp_get_parameters(struct str_parms *query,
+ struct str_parms *reply)
+{
+ int ret, val = 0;
+ char value[32]={0};
+
+ ret = str_parms_get_str(query, AUDIO_PARAMETER_A2DP_RECONFIG_SUPPORTED,
+ value, sizeof(value));
+ if (ret >= 0) {
+ val = a2dp.is_a2dp_offload_supported;
+ str_parms_add_int(reply, AUDIO_PARAMETER_A2DP_RECONFIG_SUPPORTED, val);
+ ALOGV("%s: called ... isReconfigA2dpSupported %d", __func__, val);
+ }
+
+ return 0;
+}
+#endif // A2DP_OFFLOAD_ENABLED