Merge "hal: add support for I2S based external modem"
diff --git a/hal/audio_extn/audio_extn.c b/hal/audio_extn/audio_extn.c
index c6a8e68..245f5ca 100644
--- a/hal/audio_extn/audio_extn.c
+++ b/hal/audio_extn/audio_extn.c
@@ -174,7 +174,7 @@
#endif /* ANC_HEADSET_ENABLED */
#ifndef AFE_PROXY_ENABLED
-#define audio_extn_set_afe_proxy_parameters(parms) (0)
+#define audio_extn_set_afe_proxy_parameters(adev, parms) (0)
#define audio_extn_get_afe_proxy_parameters(query, reply) (0)
#else
/* Front left channel. */
@@ -290,7 +290,8 @@
return ret;
}
-void audio_extn_set_afe_proxy_parameters(struct str_parms *parms)
+void audio_extn_set_afe_proxy_parameters(struct audio_device *adev,
+ struct str_parms *parms)
{
int ret, val;
char value[32]={0};
@@ -300,6 +301,7 @@
if (ret >= 0) {
val = atoi(value);
aextnmod.proxy_channel_num = val;
+ adev->cur_wfd_channels = val;
ALOGD("%s: channel capability set to: %d", __func__,
aextnmod.proxy_channel_num);
}
@@ -358,7 +360,7 @@
struct str_parms *parms)
{
audio_extn_set_anc_parameters(adev, parms);
- audio_extn_set_afe_proxy_parameters(parms);
+ audio_extn_set_afe_proxy_parameters(adev, parms);
audio_extn_fm_set_parameters(adev, parms);
audio_extn_listen_set_parameters(adev, parms);
audio_extn_hfp_set_parameters(adev, parms);
diff --git a/hal/audio_extn/audio_extn.h b/hal/audio_extn/audio_extn.h
index fb428db..d432670 100644
--- a/hal/audio_extn/audio_extn.h
+++ b/hal/audio_extn/audio_extn.h
@@ -184,8 +184,10 @@
#ifndef HFP_ENABLED
#define audio_extn_hfp_is_active(adev) (0)
+#define audio_extn_hfp_get_usecase() (0)
#else
bool audio_extn_hfp_is_active(struct audio_device *adev);
+audio_usecase_t audio_extn_hfp_get_usecase();
#endif
#endif /* AUDIO_EXTN_H */
diff --git a/hal/audio_extn/dolby.c b/hal/audio_extn/dolby.c
index bcc7381..99fa2b7 100644
--- a/hal/audio_extn/dolby.c
+++ b/hal/audio_extn/dolby.c
@@ -64,7 +64,7 @@
/* DS1-DDP Endp Params */
#define DDP_ENDP_NUM_PARAMS 17
-#define DDP_ENDP_NUM_DEVICES 22
+#define DDP_ENDP_NUM_DEVICES 23
static int ddp_endp_params_id[DDP_ENDP_NUM_PARAMS] = {
PARAM_ID_MAX_OUTPUT_CHANNELS, PARAM_ID_CTL_RUNNING_MODE,
PARAM_ID_CTL_ERROR_CONCEAL, PARAM_ID_CTL_ERROR_MAX_RPTS,
@@ -147,7 +147,10 @@
{8, 0, 0, 0, 0, 0, 0, 21, 1, 6, 0, 0, 0, 0, 0, 0, 0},
{1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0} },
{AUDIO_DEVICE_OUT_PROXY, 2,
- {8, 0, 0, 0, 0, 0, 0, 21, 1, 6, 0, 0, 0, 0, 0, 0, 0},
+ {8, 0, 0, 0, 0, 0, 0, 21, 1, 2, 0, 0, 0, 0, 0, 0, 0},
+ {1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0} },
+ {AUDIO_DEVICE_OUT_PROXY, 6,
+ {8, 0, 0, 0, 0, 0, 0, 21, 1, 2, 0, 0, 0, 0, 0, 0, 0},
{1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0} },
};
@@ -264,9 +267,16 @@
(usecase->stream.out->flags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) &&
((usecase->stream.out->format == AUDIO_FORMAT_AC3) ||
(usecase->stream.out->format == AUDIO_FORMAT_EAC3))) {
+ /*
+ * Use wfd /hdmi sink channel cap for dolby params if device is wfd
+ * or hdmi. Otherwise use stereo configuration
+ */
+ int channel_cap = usecase->devices & AUDIO_DEVICE_OUT_AUX_DIGITAL ?
+ adev->cur_hdmi_channels :
+ usecase->devices & AUDIO_DEVICE_OUT_PROXY ?
+ adev->cur_wfd_channels : 2;
send_ddp_endp_params_stream(usecase->stream.out, usecase->devices,
- usecase->devices & AUDIO_DEVICE_OUT_AUX_DIGITAL ?
- adev->cur_hdmi_channels : 2, false /* set cache */);
+ channel_cap, false /* set cache */);
}
}
}
@@ -334,7 +344,9 @@
update_ddp_endp_table(ddp_dev, dev_ch_cap,
PARAM_ID_OUT_CTL_STEREO_MODE, val);
}
-
+ /* TODO: Do we need device channel caps here?
+ * We dont have that information as this is from dolby modules
+ */
send_ddp_endp_params(adev, ddp_dev, dev_ch_cap);
}
@@ -343,13 +355,20 @@
audio_format_t format)
{
int id = 0;
+ /*
+ * Use wfd /hdmi sink channel cap for dolby params if device is wfd
+ * or hdmi. Otherwise use stereo configuration
+ */
+ int channel_cap = out->devices & AUDIO_DEVICE_OUT_AUX_DIGITAL ?
+ adev->cur_hdmi_channels :
+ out->devices & AUDIO_DEVICE_OUT_PROXY ?
+ adev->cur_wfd_channels : 2;
switch (format) {
case AUDIO_FORMAT_AC3:
id = SND_AUDIOCODEC_AC3;
send_ddp_endp_params_stream(out, out->devices,
- out->devices & AUDIO_DEVICE_OUT_AUX_DIGITAL ?
- adev->cur_hdmi_channels : 2, true /* set_cache */);
+ channel_cap, true /* set_cache */);
#ifndef DS1_DOLBY_DAP_ENABLED
audio_extn_dolby_set_dmid(adev);
#endif
@@ -357,8 +376,7 @@
case AUDIO_FORMAT_EAC3:
id = SND_AUDIOCODEC_EAC3;
send_ddp_endp_params_stream(out, out->devices,
- out->devices & AUDIO_DEVICE_OUT_AUX_DIGITAL ?
- adev->cur_hdmi_channels : 2, true /* set_cache */);
+ channel_cap, true /* set_cache */);
#ifndef DS1_DOLBY_DAP_ENABLED
audio_extn_dolby_set_dmid(adev);
#endif
@@ -430,8 +448,7 @@
list_for_each(node, &adev->usecase_list) {
usecase = node_to_item(node, struct audio_usecase, list);
- if ((usecase->type == PCM_PLAYBACK) &&
- (usecase->id != USECASE_AUDIO_PLAYBACK_LOW_LATENCY))
+ if (usecase->type == PCM_PLAYBACK)
send = true;
}
if (!send)
diff --git a/hal/audio_extn/hfp.c b/hal/audio_extn/hfp.c
index 2d6e1e0..c480490 100644
--- a/hal/audio_extn/hfp.c
+++ b/hal/audio_extn/hfp.c
@@ -220,7 +220,7 @@
bool audio_extn_hfp_is_active(struct audio_device *adev)
{
struct audio_usecase *hfp_usecase = NULL;
- hfp_usecase = get_usecase_from_list(adev, USECASE_AUDIO_HFP_SCO);
+ hfp_usecase = get_usecase_from_list(adev, hfpmod.ucid);
if (hfp_usecase != NULL)
return true;
@@ -228,6 +228,11 @@
return false;
}
+audio_usecase_t audio_extn_hfp_get_usecase()
+{
+ return hfpmod.ucid;
+}
+
void audio_extn_hfp_set_parameters(struct audio_device *adev, struct str_parms *parms)
{
int ret;
diff --git a/hal/audio_hw.c b/hal/audio_hw.c
index 147146c..3bb9098 100644
--- a/hal/audio_hw.c
+++ b/hal/audio_hw.c
@@ -602,6 +602,7 @@
struct audio_usecase *vc_usecase = NULL;
struct audio_usecase *voip_usecase = NULL;
struct audio_usecase *hfp_usecase = NULL;
+ audio_usecase_t hfp_ucid;
struct listnode *node;
int status = 0;
@@ -641,7 +642,8 @@
out_snd_device = voip_usecase->out_snd_device;
}
} else if (audio_extn_hfp_is_active(adev)) {
- hfp_usecase = get_usecase_from_list(adev, USECASE_AUDIO_HFP_SCO);
+ hfp_ucid = audio_extn_hfp_get_usecase();
+ hfp_usecase = get_usecase_from_list(adev, hfp_ucid);
if (hfp_usecase->devices & AUDIO_DEVICE_OUT_ALL_CODEC_BACKEND) {
in_snd_device = hfp_usecase->in_snd_device;
out_snd_device = hfp_usecase->out_snd_device;
@@ -920,24 +922,30 @@
send_callback = false;
switch(cmd->cmd) {
case OFFLOAD_CMD_WAIT_FOR_BUFFER:
+ ALOGD("copl(%x):calling compress_wait", (unsigned int)out);
compress_wait(out->compr, -1);
+ ALOGD("copl(%x):out of compress_wait", (unsigned int)out);
send_callback = true;
event = STREAM_CBK_EVENT_WRITE_READY;
break;
case OFFLOAD_CMD_PARTIAL_DRAIN:
ret = compress_next_track(out->compr);
- if(ret == 0)
+ if(ret == 0) {
+ ALOGD("copl(%x):calling compress_partial_drain", (unsigned int)out);
compress_partial_drain(out->compr);
+ ALOGD("copl(%x):out of compress_partial_drain", (unsigned int)out);
+ }
else if(ret == -ETIMEDOUT)
compress_drain(out->compr);
else
ALOGE("%s: Next track returned error %d",__func__, ret);
-
send_callback = true;
event = STREAM_CBK_EVENT_DRAIN_READY;
break;
case OFFLOAD_CMD_DRAIN:
+ ALOGD("copl(%x):calling compress_drain", (unsigned int)out);
compress_drain(out->compr);
+ ALOGD("copl(%x):calling compress_drain", (unsigned int)out);
send_callback = true;
event = STREAM_CBK_EVENT_DRAIN_READY;
break;
@@ -1012,6 +1020,12 @@
"no change in HDMI channels", __func__);
ret = false;
break;
+ } else if (usecase->id == USECASE_AUDIO_PLAYBACK_OFFLOAD &&
+ popcount(usecase->stream.out->channel_mask) > 2) {
+ ALOGD("%s: multi-channel(%x) compress offload playback is active, "
+ "no change in HDMI channels", __func__, usecase->stream.out->channel_mask);
+ ret = false;
+ break;
}
}
}
@@ -1109,7 +1123,7 @@
struct audio_usecase *uc_info;
struct audio_device *adev = out->dev;
- ALOGV("%s: enter: usecase(%d: %s) devices(%#x)",
+ ALOGD("%s: enter: usecase(%d: %s) devices(%#x)",
__func__, out->usecase, use_case_table[out->usecase], out->devices);
out->pcm_device_id = platform_get_pcm_device_id(out->usecase, PCM_PLAYBACK);
if (out->pcm_device_id < 0) {
@@ -1311,6 +1325,7 @@
out->pcm = NULL;
}
} else {
+ ALOGD("copl(%x):standby", (unsigned int)out);
stop_compressed_output_l(out);
out->gapless_mdata.encoder_delay = 0;
out->gapless_mdata.encoder_padding = 0;
@@ -1594,9 +1609,9 @@
}
if (out->usecase == USECASE_AUDIO_PLAYBACK_OFFLOAD) {
- ALOGVV("%s: writing buffer (%d bytes) to compress device", __func__, bytes);
+ ALOGD("copl(%x): writing buffer (%d bytes) to compress device", (unsigned int)out, bytes);
if (out->send_new_metadata) {
- ALOGVV("send new gapless metadata");
+ ALOGD("copl(%x):send new gapless metadata", (unsigned int)out);
compress_set_gapless_metadata(out->compr, &out->gapless_mdata);
out->send_new_metadata = 0;
}
@@ -1604,6 +1619,7 @@
ret = compress_write(out->compr, buffer, bytes);
ALOGVV("%s: writing buffer (%d bytes) to compress device returned %d", __func__, bytes, ret);
if (ret >= 0 && ret < (ssize_t)bytes) {
+ ALOGD("No space available in compress driver, post msg to cb thread");
send_offload_cmd_l(out, OFFLOAD_CMD_WAIT_FOR_BUFFER);
}
if (!out->playback_started) {
@@ -1736,6 +1752,7 @@
int status = -ENOSYS;
ALOGV("%s", __func__);
if (out->usecase == USECASE_AUDIO_PLAYBACK_OFFLOAD) {
+ ALOGD("copl(%x):pause compress driver", (unsigned int)out);
pthread_mutex_lock(&out->lock);
if (out->compr != NULL && out->offload_state == OFFLOAD_STATE_PLAYING) {
status = compress_pause(out->compr);
@@ -1752,6 +1769,7 @@
int status = -ENOSYS;
ALOGV("%s", __func__);
if (out->usecase == USECASE_AUDIO_PLAYBACK_OFFLOAD) {
+ ALOGD("copl(%x):resume compress driver", (unsigned int)out);
status = 0;
pthread_mutex_lock(&out->lock);
if (out->compr != NULL && out->offload_state == OFFLOAD_STATE_PAUSED) {
@@ -1784,9 +1802,11 @@
struct stream_out *out = (struct stream_out *)stream;
ALOGV("%s", __func__);
if (out->usecase == USECASE_AUDIO_PLAYBACK_OFFLOAD) {
+ ALOGD("copl(%x):calling compress flush", (unsigned int)out);
pthread_mutex_lock(&out->lock);
stop_compressed_output_l(out);
pthread_mutex_unlock(&out->lock);
+ ALOGD("copl(%x):out of compress flush", (unsigned int)out);
return 0;
}
return -ENOSYS;
@@ -2125,6 +2145,9 @@
goto error_open;
}
} else if (out->flags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) {
+ ALOGD("%s: copl(%x): sample_rate(%d) channel_mask(%#x) devices(%#x) flags(%#x)",
+ __func__, (unsigned int)out, config->sample_rate, config->channel_mask, devices, flags);
+
if (config->offload_info.version != AUDIO_INFO_INITIALIZER.version ||
config->offload_info.size != AUDIO_INFO_INITIALIZER.size) {
ALOGE("%s: Unsupported Offload information", __func__);
@@ -2672,6 +2695,7 @@
adev->snd_dev_ref_cnt = calloc(SND_DEVICE_MAX, sizeof(int));
voice_init(adev);
list_init(&adev->usecase_list);
+ adev->cur_wfd_channels = 2;
/* Loads platform specific libraries dynamically */
adev->platform = platform_init(adev);
diff --git a/hal/audio_hw.h b/hal/audio_hw.h
index 205977b..21b7790 100644
--- a/hal/audio_hw.h
+++ b/hal/audio_hw.h
@@ -223,6 +223,7 @@
bool speaker_lr_swap;
struct voice voice;
unsigned int cur_hdmi_channels;
+ unsigned int cur_wfd_channels;
int snd_card;
void *platform;
diff --git a/mm-audio/aenc-aac/qdsp6/inc/omx_aac_aenc.h b/mm-audio/aenc-aac/qdsp6/inc/omx_aac_aenc.h
index 276eaa3..623caa8 100644
--- a/mm-audio/aenc-aac/qdsp6/inc/omx_aac_aenc.h
+++ b/mm-audio/aenc-aac/qdsp6/inc/omx_aac_aenc.h
@@ -1,5 +1,5 @@
/*--------------------------------------------------------------------------
-Copyright (c) 2010, The Linux Foundation. All rights reserved.
+Copyright (c) 2010-2014, 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 met:
@@ -358,7 +358,10 @@
OMX_COMPONENT_OUTPUT_DISABLE_PENDING =0x7
};
-
+ #define MIN_BITRATE 24000
+ #define MAX_BITRATE 192000
+ #define MAX_BITRATE_MULFACTOR 12
+ #define BITRATE_DIVFACTOR 2
typedef Map<OMX_BUFFERHEADERTYPE*, OMX_BUFFERHEADERTYPE*>
input_buffer_map;
@@ -619,6 +622,7 @@
OMX_U8 num_bits_reqd,
OMX_U32 value,
OMX_U16 *hdr_bit_index);
+ int get_updated_bit_rate(int bitrate);
};
#endif
diff --git a/mm-audio/aenc-aac/qdsp6/src/omx_aac_aenc.cpp b/mm-audio/aenc-aac/qdsp6/src/omx_aac_aenc.cpp
index 52aa915..6521265 100644
--- a/mm-audio/aenc-aac/qdsp6/src/omx_aac_aenc.cpp
+++ b/mm-audio/aenc-aac/qdsp6/src/omx_aac_aenc.cpp
@@ -1,5 +1,5 @@
/*--------------------------------------------------------------------------
-Copyright (c) 2010, The Linux Foundation. All rights reserved.
+Copyright (c) 2010-2014, 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 met:
@@ -1438,10 +1438,12 @@
}
drv_aac_enc_config.channels = m_aac_param.nChannels;
drv_aac_enc_config.sample_rate = m_aac_param.nSampleRate;
- drv_aac_enc_config.bit_rate = m_aac_param.nBitRate;
- DEBUG_PRINT("aac config %lu,%lu,%lu %d\n",
+ drv_aac_enc_config.bit_rate =
+ get_updated_bit_rate(m_aac_param.nBitRate);
+ DEBUG_PRINT("aac config %lu,%lu,%lu %d updated bitrate %d\n",
m_aac_param.nChannels,m_aac_param.nSampleRate,
- m_aac_param.nBitRate,m_aac_param.eAACStreamFormat);
+ m_aac_param.nBitRate,m_aac_param.eAACStreamFormat,
+ drv_aac_enc_config.bit_rate);
switch(m_aac_param.eAACStreamFormat)
{
@@ -5014,3 +5016,44 @@
}
+int omx_aac_aenc::get_updated_bit_rate(int bitrate)
+{
+ int updated_rate, min_bitrate, max_bitrate;
+
+ max_bitrate = m_aac_param.nSampleRate *
+ MAX_BITRATE_MULFACTOR;
+ switch(m_aac_param.eAACProfile)
+ {
+ case OMX_AUDIO_AACObjectLC:
+ min_bitrate = m_aac_param.nSampleRate;
+ if (m_aac_param.nChannels == 1) {
+ min_bitrate = min_bitrate/BITRATE_DIVFACTOR;
+ max_bitrate = max_bitrate/BITRATE_DIVFACTOR;
+ }
+ break;
+ case OMX_AUDIO_AACObjectHE:
+ min_bitrate = MIN_BITRATE;
+ if (m_aac_param.nChannels == 1)
+ max_bitrate = max_bitrate/BITRATE_DIVFACTOR;
+ break;
+ case OMX_AUDIO_AACObjectHE_PS:
+ min_bitrate = MIN_BITRATE;
+ break;
+ default:
+ return bitrate;
+ break;
+ }
+ /* Update MIN and MAX values*/
+ if (min_bitrate > MIN_BITRATE)
+ min_bitrate = MIN_BITRATE;
+ if (max_bitrate > MAX_BITRATE)
+ max_bitrate = MAX_BITRATE;
+ /* Update the bitrate in the range */
+ if (bitrate < min_bitrate)
+ updated_rate = min_bitrate;
+ else if(bitrate > max_bitrate)
+ updated_rate = max_bitrate;
+ else
+ updated_rate = bitrate;
+ return updated_rate;
+}
diff --git a/post_proc/bass_boost.c b/post_proc/bass_boost.c
index a925e8e..9e6c1fc 100644
--- a/post_proc/bass_boost.c
+++ b/post_proc/bass_boost.c
@@ -211,9 +211,14 @@
bassboost_context_t *bass_ctxt = (bassboost_context_t *)context;
ALOGV("%s", __func__);
-
- if (!offload_bassboost_get_enable_flag(&(bass_ctxt->offload_bass)))
+ if (!offload_bassboost_get_enable_flag(&(bass_ctxt->offload_bass))) {
offload_bassboost_set_enable_flag(&(bass_ctxt->offload_bass), true);
+ if (bass_ctxt->ctl && bass_ctxt->strength)
+ offload_bassboost_send_params(bass_ctxt->ctl,
+ bass_ctxt->offload_bass,
+ OFFLOAD_SEND_BASSBOOST_ENABLE_FLAG |
+ OFFLOAD_SEND_BASSBOOST_STRENGTH);
+ }
return 0;
}
diff --git a/post_proc/virtualizer.c b/post_proc/virtualizer.c
index 9682b93..4190129 100644
--- a/post_proc/virtualizer.c
+++ b/post_proc/virtualizer.c
@@ -210,9 +210,14 @@
virtualizer_context_t *virt_ctxt = (virtualizer_context_t *)context;
ALOGV("%s", __func__);
-
- if (!offload_virtualizer_get_enable_flag(&(virt_ctxt->offload_virt)))
+ if (!offload_virtualizer_get_enable_flag(&(virt_ctxt->offload_virt))) {
offload_virtualizer_set_enable_flag(&(virt_ctxt->offload_virt), true);
+ if (virt_ctxt->ctl && virt_ctxt->strength)
+ offload_virtualizer_send_params(virt_ctxt->ctl,
+ virt_ctxt->offload_virt,
+ OFFLOAD_SEND_VIRTUALIZER_ENABLE_FLAG |
+ OFFLOAD_SEND_BASSBOOST_STRENGTH);
+ }
return 0;
}