audio : refactoring of compress passthrough changes.
Add DTS fomat support for compress passthrough.
Code clean-up and refactoring.
Keep Alive fixes.
Disable Compress Passthrough and DAP by default.
Change-Id: Id0b67630077e06284b8a396be69ebe0c72747c90
diff --git a/configs/msm8996/audio_output_policy.conf b/configs/msm8996/audio_output_policy.conf
index 93cd0c2..0563503 100644
--- a/configs/msm8996/audio_output_policy.conf
+++ b/configs/msm8996/audio_output_policy.conf
@@ -46,11 +46,18 @@
bit_width 24
app_type 69940
}
- compress_passthrough {
+ compress_passthrough_16 {
flags AUDIO_OUTPUT_FLAG_DIRECT|AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD|AUDIO_OUTPUT_FLAG_NON_BLOCKING|AUDIO_OUTPUT_FLAG_COMPRESS_PASSTHROUGH
formats AUDIO_FORMAT_AC3|AUDIO_FORMAT_E_AC3|AUDIO_FORMAT_E_AC3_JOC|AUDIO_FORMAT_DTS|AUDIO_FORMAT_DTS_HD
sampling_rates 32000|44100|48000|88200|96000|176400|192000
- bit_width 16|24
+ bit_width 16
+ app_type 69941
+ }
+ compress_passthrough_24 {
+ flags AUDIO_OUTPUT_FLAG_DIRECT|AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD|AUDIO_OUTPUT_FLAG_NON_BLOCKING|AUDIO_OUTPUT_FLAG_COMPRESS_PASSTHROUGH
+ formats AUDIO_FORMAT_AC3|AUDIO_FORMAT_E_AC3|AUDIO_FORMAT_E_AC3_JOC|AUDIO_FORMAT_DTS|AUDIO_FORMAT_DTS_HD
+ sampling_rates 32000|44100|48000|88200|96000|176400|192000
+ bit_width 24
app_type 69941
}
compress_offload_16 {
diff --git a/configs/msm8996/mixer_paths_tasha.xml b/configs/msm8996/mixer_paths_tasha.xml
index 360e80b..596b016 100644
--- a/configs/msm8996/mixer_paths_tasha.xml
+++ b/configs/msm8996/mixer_paths_tasha.xml
@@ -120,6 +120,7 @@
<ctl name="HDMI Mixer MultiMedia4" value="0" />
<ctl name="HDMI Mixer MultiMedia5" value="0" />
<ctl name="HDMI Mixer MultiMedia7" value="0" />
+ <ctl name="HDMI Mixer MultiMedia9" value="0" />
<ctl name="HDMI Mixer MultiMedia10" value="0" />
<ctl name="HDMI Mixer MultiMedia11" value="0" />
<ctl name="HDMI Mixer MultiMedia12" value="0" />
@@ -755,6 +756,10 @@
<ctl name="HDMI Mixer MultiMedia4" value="1" />
</path>
+ <path name="silence-playback hdmi">
+ <ctl name="HDMI Mixer MultiMedia9" value="1" />
+ </path>
+
<path name="compress-offload-playback bt-sco">
<ctl name="AUX_PCM_RX Audio Mixer MultiMedia4" value="1" />
</path>
diff --git a/configs/msm8996/msm8996.mk b/configs/msm8996/msm8996.mk
index 2b70a81..d0ddf24 100644
--- a/configs/msm8996/msm8996.mk
+++ b/configs/msm8996/msm8996.mk
@@ -19,7 +19,8 @@
AUDIO_FEATURE_ENABLED_FLUENCE := true
AUDIO_FEATURE_ENABLED_HDMI_SPK := true
AUDIO_FEATURE_ENABLED_HDMI_EDID := true
-AUDIO_FEATURE_ENABLED_HDMI_PASSTHROUGH := true
+#AUDIO_FEATURE_ENABLED_HDMI_PASSTHROUGH := true
+#AUDIO_FEATURE_ENABLED_KEEP_ALIVE := true
AUDIO_FEATURE_ENABLED_HFP := true
AUDIO_FEATURE_ENABLED_INCALL_MUSIC := false
AUDIO_FEATURE_ENABLED_MULTI_VOICE_SESSIONS := true
@@ -45,8 +46,8 @@
MM_AUDIO_ENABLED_SAFX := true
TARGET_USES_QCOM_MM_AUDIO := true
AUDIO_FEATURE_ENABLED_HW_ACCELERATED_EFFECTS := false
-DOLBY_DDP := true
#AUDIO_FEATURE_ENABLED_DS2_DOLBY_DAP := true
+#DOLBY_DDP := true
AUDIO_FEATURE_ENABLED_SOURCE_TRACKING := true
AUDIO_FEATURE_ENABLED_AUDIOSPHERE := true
##AUDIO_FEATURE_FLAGS
diff --git a/hal/audio_extn/audio_extn.h b/hal/audio_extn/audio_extn.h
index 0420105..090e6b0 100644
--- a/hal/audio_extn/audio_extn.h
+++ b/hal/audio_extn/audio_extn.h
@@ -354,7 +354,6 @@
AUDIO_CHANNEL_OUT_FRONT_CENTER | AUDIO_CHANNEL_OUT_BACK_CENTER)
#endif
-
#if defined(DS1_DOLBY_DDP_ENABLED) || defined(DS1_DOLBY_DAP_ENABLED) || defined(DS2_DOLBY_DAP_ENABLED)
void audio_extn_dolby_set_license(struct audio_device *adev);
#else
@@ -389,13 +388,13 @@
#endif
#ifndef HDMI_PASSTHROUGH_ENABLED
-#define audio_extn_dolby_update_passt_stream_configuration(adev, out) (0)
-#define audio_extn_dolby_is_passt_convert_supported(adev, out) (0)
-#define audio_extn_dolby_is_passt_supported(adev, out) (0)
-#define audio_extn_dolby_is_passthrough_stream(out) (0)
-#define audio_extn_dolby_get_passt_buffer_size(info) (0)
-#define audio_extn_dolby_set_passt_volume(out, mute) (0)
-#define audio_extn_dolby_set_passt_latency(out, latency) (0)
+#define audio_extn_passthru_update_stream_configuration(adev, out) (0)
+#define audio_extn_passthru_is_convert_supported(adev, out) (0)
+#define audio_extn_passthru_is_passt_supported(adev, out) (0)
+#define audio_extn_passthru_is_passthrough_stream(out) (0)
+#define audio_extn_passthru_get_buffer_size(info) (0)
+#define audio_extn_passthru_set_volume(out, mute) (0)
+#define audio_extn_passthru_set_latency(out, latency) (0)
#define audio_extn_passthru_is_supported_format(f) (0)
#define audio_extn_passthru_should_drop_data(o) (0)
#define audio_extn_passthru_on_start(o) do {} while(0)
@@ -409,16 +408,16 @@
#define AUDIO_OUTPUT_FLAG_COMPRESS_PASSTHROUGH 0x1000
#else
-bool audio_extn_dolby_is_passt_convert_supported(struct audio_device *adev,
+bool audio_extn_passthru_is_convert_supported(struct audio_device *adev,
struct stream_out *out);
-bool audio_extn_dolby_is_passt_supported(struct audio_device *adev,
+bool audio_extn_passthru_is_passt_supported(struct audio_device *adev,
struct stream_out *out);
-void audio_extn_dolby_update_passt_stream_configuration(struct audio_device *adev,
+void audio_extn_passthru_update_stream_configuration(struct audio_device *adev,
struct stream_out *out);
-bool audio_extn_dolby_is_passthrough_stream(struct stream_out *out);
-int audio_extn_dolby_get_passt_buffer_size(audio_offload_info_t* info);
-int audio_extn_dolby_set_passt_volume(struct stream_out *out, int mute);
-int audio_extn_dolby_set_passt_latency(struct stream_out *out, int latency);
+bool audio_extn_passthru_is_passthrough_stream(struct stream_out *out);
+int audio_extn_passthru_get_buffer_size(audio_offload_info_t* info);
+int audio_extn_passthru_set_volume(struct stream_out *out, int mute);
+int audio_extn_passthru_set_latency(struct stream_out *out, int latency);
bool audio_extn_passthru_is_supported_format(audio_format_t format);
bool audio_extn_passthru_should_drop_data(struct stream_out * out);
void audio_extn_passthru_on_start(struct stream_out *out);
@@ -430,7 +429,6 @@
bool audio_extn_passthru_is_active();
void audio_extn_passthru_init(struct audio_device *adev);
bool audio_extn_passthru_should_standby(struct stream_out *out);
-
#endif
#ifndef HFP_ENABLED
diff --git a/hal/audio_extn/dolby.c b/hal/audio_extn/dolby.c
index ad8f8a4..f07c66a 100644
--- a/hal/audio_extn/dolby.c
+++ b/hal/audio_extn/dolby.c
@@ -357,45 +357,6 @@
#endif /* DS1_DOLBY_DDP_ENABLED */
#if defined(DS1_DOLBY_DDP_ENABLED) || defined(DS2_DOLBY_DAP_ENABLED)
-int audio_extn_dolby_get_snd_codec_id(struct audio_device *adev,
- struct stream_out *out,
- 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;
-#ifdef DS1_DOLBY_DDP_ENABLED
- send_ddp_endp_params_stream(out, out->devices,
- channel_cap, true /* set_cache */);
-#endif
- audio_extn_dolby_set_dmid(adev);
- break;
- case AUDIO_FORMAT_E_AC3:
- case AUDIO_FORMAT_E_AC3_JOC:
- id = SND_AUDIOCODEC_EAC3;
-#ifdef DS1_DOLBY_DDP_ENABLED
- send_ddp_endp_params_stream(out, out->devices,
- channel_cap, true /* set_cache */);
-#endif
- audio_extn_dolby_set_dmid(adev);
- break;
- default:
- ALOGE("%s: Unsupported audio format :%x", __func__, format);
- }
-
- return id;
-}
-
bool audio_extn_is_dolby_format(audio_format_t format)
{
if (format == AUDIO_FORMAT_AC3 ||
@@ -407,121 +368,6 @@
}
#endif /* DS1_DOLBY_DDP_ENABLED || DS2_DOLBY_DAP_ENABLED */
-#ifdef HDMI_PASSTHROUGH_ENABLED
-bool audio_extn_dolby_is_passt_convert_supported(struct audio_device *adev,
- struct stream_out *out) {
-
- bool convert = false;
- switch (out->format) {
- case AUDIO_FORMAT_E_AC3:
- case AUDIO_FORMAT_E_AC3_JOC:
- if (!platform_is_edid_supported_format(adev->platform,
- AUDIO_FORMAT_E_AC3)) {
- ALOGV("%s:PASSTHROUGH_CONVERT supported", __func__);
- convert = true;
- }
- break;
- default:
- ALOGE("%s: PASSTHROUGH_CONVERT not supported for format 0x%x",
- __func__, out->format);
- break;
- }
- ALOGE("%s: convert %d", __func__, convert);
- return convert;
-}
-
-bool audio_extn_dolby_is_passt_supported(struct audio_device *adev,
- struct stream_out *out) {
- bool passt = false;
- switch (out->format) {
- case AUDIO_FORMAT_E_AC3:
- if (platform_is_edid_supported_format(adev->platform, out->format)) {
- ALOGV("%s:PASSTHROUGH supported for format %x",
- __func__, out->format);
- passt = true;
- }
- break;
- case AUDIO_FORMAT_AC3:
- if (platform_is_edid_supported_format(adev->platform, AUDIO_FORMAT_AC3)
- || platform_is_edid_supported_format(adev->platform,
- AUDIO_FORMAT_E_AC3)) {
- ALOGV("%s:PASSTHROUGH supported for format %x",
- __func__, out->format);
- passt = true;
- }
- break;
- case AUDIO_FORMAT_E_AC3_JOC:
- /* Check for DDP capability in edid for JOC contents.*/
- if (platform_is_edid_supported_format(adev->platform,
- AUDIO_FORMAT_E_AC3)) {
- ALOGV("%s:PASSTHROUGH supported for format %x",
- __func__, out->format);
- passt = true;
- }
- default:
- ALOGV("%s:Passthrough not supported", __func__);
- }
- return passt;
-}
-
-void audio_extn_dolby_update_passt_stream_configuration(
- struct audio_device *adev, struct stream_out *out) {
- if (audio_extn_dolby_is_passt_supported(adev, out)) {
- ALOGV("%s:PASSTHROUGH", __func__);
- out->compr_config.codec->compr_passthr = PASSTHROUGH;
- } else if (audio_extn_dolby_is_passt_convert_supported(adev, out)){
- ALOGV("%s:PASSTHROUGH CONVERT", __func__);
- out->compr_config.codec->compr_passthr = PASSTHROUGH_CONVERT;
- } else {
- ALOGV("%s:NO PASSTHROUGH", __func__);
- out->compr_config.codec->compr_passthr = LEGACY_PCM;
- }
-}
-
-bool audio_extn_dolby_is_passthrough_stream(struct stream_out *out) {
-
- //check passthrough system property
- if (!property_get_bool("audio.offload.passthrough", false)) {
- return false;
- }
-
- //check supported device, currently only on HDMI.
- if (out->devices & AUDIO_DEVICE_OUT_AUX_DIGITAL) {
- //passthrough flag
- if (out->flags & AUDIO_OUTPUT_FLAG_COMPRESS_PASSTHROUGH)
- return true;
- //direct flag, check supported formats.
- if (out->flags & AUDIO_OUTPUT_FLAG_DIRECT) {
- if (audio_extn_passthru_is_supported_format(out->format)) {
- if (platform_is_edid_supported_format(out->dev->platform,
- out->format)) {
- return true;
- } else if (audio_extn_is_dolby_format(out->format) &&
- platform_is_edid_supported_format(out->dev->platform,
- AUDIO_FORMAT_AC3)){
- //return true for EAC3/EAC3_JOC formats
- //if sink supports only AC3
- return true;
- }
- }
- }
- }
-
- return false;
-}
-
-int audio_extn_dolby_get_passt_buffer_size(audio_offload_info_t* info) {
- return platform_get_compress_passthrough_buffer_size(info);
-}
-
-int audio_extn_dolby_set_passt_volume(struct stream_out *out, int mute) {
- return platform_set_device_params(out, DEVICE_PARAM_MUTE_ID, mute);
-}
-
-int audio_extn_dolby_set_passt_latency(struct stream_out *out, int latency) {
- return platform_set_device_params(out, DEVICE_PARAM_LATENCY_ID, latency);
-}
-#endif /* HDMI_PASSTHROUGH_ENABLED */
#ifdef DS1_DOLBY_DAP_ENABLED
void audio_extn_dolby_set_endpoint(struct audio_device *adev)
diff --git a/hal/audio_extn/keep_alive.c b/hal/audio_extn/keep_alive.c
index ab663ef..1a4f135 100644
--- a/hal/audio_extn/keep_alive.c
+++ b/hal/audio_extn/keep_alive.c
@@ -37,7 +37,7 @@
#include <platform.h>
#define SILENCE_MIXER_PATH "silence-playback hdmi"
-#define SILENCE_DEV_ID 5 /* index into machine driver */
+#define SILENCE_DEV_ID 32 /* index into machine driver */
#define SILENCE_INTERVAL_US 2000000
typedef enum {
@@ -147,22 +147,71 @@
void audio_extn_keep_alive_start()
{
struct audio_device * adev = (struct audio_device *)ka.userdata;
-
- if (ka.state == STATE_DEINIT)
- return;
-
- if (audio_extn_passthru_is_active())
- return;
+ char mixer_ctl_name[MAX_LENGTH_MIXER_CONTROL_IN_INT];
+ int app_type_cfg[MAX_LENGTH_MIXER_CONTROL_IN_INT], len = 0, rc;
+ struct mixer_ctl *ctl;
+ int acdb_dev_id, snd_device;
+ int32_t sample_rate = DEFAULT_OUTPUT_SAMPLING_RATE;
pthread_mutex_lock(&ka.lock);
- if (ka.state == STATE_ACTIVE)
+ if (ka.state == STATE_DEINIT) {
+ ALOGE(" %s : Invalid state ",__func__);
+ return;
+ }
+
+ if (audio_extn_passthru_is_active()) {
+ ALOGE(" %s : Pass through is already active", __func__);
+ return;
+ }
+
+ if (ka.state == STATE_ACTIVE) {
+ ALOGV(" %s : Keep alive state is already Active",__func__ );
goto exit;
+ }
ka.done = false;
- //todo: platform_send_audio_calibration is replaced by audio_extn_utils_send_audio_calibration
- //check why audio cal needs to be set
- //platform_send_audio_calibration(adev->platform, SND_DEVICE_OUT_HDMI);
+
+ /*configure app type */
+ snprintf(mixer_ctl_name, sizeof(mixer_ctl_name),
+ "Audio Stream %d App Type Cfg",SILENCE_DEV_ID);
+
+ ctl = mixer_get_ctl_by_name(adev->mixer, mixer_ctl_name);
+ if (!ctl) {
+ ALOGE("%s: Could not get ctl for mixer cmd - %s", __func__,
+ mixer_ctl_name);
+ rc = -EINVAL;
+ goto exit;
+ }
+
+ snd_device = SND_DEVICE_OUT_HDMI;
+ acdb_dev_id = platform_get_snd_device_acdb_id(snd_device);
+ if (acdb_dev_id < 0) {
+ ALOGE("%s: Couldn't get the acdb dev id", __func__);
+ rc = -EINVAL;
+ goto exit;
+ }
+
+ sample_rate = DEFAULT_OUTPUT_SAMPLING_RATE;
+ app_type_cfg[len++] = platform_get_default_app_type(adev->platform);
+ app_type_cfg[len++] = acdb_dev_id;
+ app_type_cfg[len++] = sample_rate;
+
+ ALOGI("%s:%d PLAYBACK app_type %d, acdb_dev_id %d, sample_rate %d",
+ __func__, __LINE__,
+ platform_get_default_app_type(adev->platform),
+ acdb_dev_id, sample_rate);
+ mixer_ctl_set_array(ctl, app_type_cfg, len);
+
+ /*send calibration*/
+ struct audio_usecase *usecase = calloc(1, sizeof(struct audio_usecase));
+ usecase->type = PCM_PLAYBACK;
+ usecase->out_snd_device = SND_DEVICE_OUT_HDMI;
+
+ platform_send_audio_calibration(adev->platform, usecase,
+ platform_get_default_app_type(adev->platform), sample_rate);
+
+ /*apply audio route */
audio_route_apply_and_update_path(adev->audio_route, SILENCE_MIXER_PATH);
if (open_silence_stream() == 0) {
@@ -181,11 +230,11 @@
{
struct audio_device * adev = (struct audio_device *)ka.userdata;
+ pthread_mutex_lock(&ka.lock);
+
if (ka.state == STATE_DEINIT)
return;
- pthread_mutex_lock(&ka.lock);
-
if (ka.state == STATE_IDLE)
goto exit;
@@ -211,7 +260,7 @@
char value[32];
int ret;
- ret = str_parms_get_str(parms, "connect", value, sizeof(value));
+ ret = str_parms_get_str(parms, AUDIO_PARAMETER_DEVICE_CONNECT, value, sizeof(value));
if (ret >= 0) {
int val = atoi(value);
if (val & AUDIO_DEVICE_OUT_AUX_DIGITAL) {
@@ -237,12 +286,10 @@
static void * keep_alive_loop(void * context __unused)
{
- struct audio_device *adev = (struct audio_device *)ka.userdata;
struct keep_alive_cmd *cmd = NULL;
struct listnode *item;
uint8_t * silence = NULL;
- int32_t bytes = 0, count = 0, i;
- struct stream_out * p_out = NULL;
+ int32_t bytes = 0;
while (true) {
pthread_mutex_lock(&ka.lock);
diff --git a/hal/audio_extn/passthru.c b/hal/audio_extn/passthru.c
index d87303b..e6ac4dd 100644
--- a/hal/audio_extn/passthru.c
+++ b/hal/audio_extn/passthru.c
@@ -37,10 +37,14 @@
#include "audio_extn.h"
#include "platform_api.h"
#include <platform.h>
+#include <cutils/properties.h>
+
+#include "sound/compress_params.h"
static const audio_format_t audio_passthru_formats[] = {
AUDIO_FORMAT_AC3,
AUDIO_FORMAT_E_AC3,
+ AUDIO_FORMAT_E_AC3_JOC,
AUDIO_FORMAT_DTS,
AUDIO_FORMAT_DTS_HD
};
@@ -63,9 +67,11 @@
for (i = 0; i < num_passthru_formats; i++) {
if (format == audio_passthru_formats[i]) {
+ ALOGD("%s : pass through format is true", __func__);
return true;
}
}
+ ALOGD("%s : pass through format is false", __func__);
return false;
}
@@ -76,11 +82,6 @@
*/
bool audio_extn_passthru_should_drop_data(struct stream_out * out)
{
- /* Make this product specific */
- if (!(out->devices & AUDIO_DEVICE_OUT_AUX_DIGITAL)) {
- ALOGI("drop data as end device 0x%x is unsupported", out->devices);
- return true;
- }
if (out->usecase != USECASE_AUDIO_PLAYBACK_OFFLOAD) {
if (android_atomic_acquire_load(&compress_passthru_active) > 0) {
@@ -158,8 +159,6 @@
{
if (android_atomic_acquire_load(&compress_passthru_active) == 0)
return;
-
- android_atomic_dec(&compress_passthru_active);
}
int audio_extn_passthru_set_parameters(struct audio_device *adev __unused,
@@ -183,3 +182,143 @@
{
return true;
}
+
+bool audio_extn_passthru_is_convert_supported(struct audio_device *adev,
+ struct stream_out *out)
+{
+
+ bool convert = false;
+ switch (out->format) {
+ case AUDIO_FORMAT_E_AC3:
+ case AUDIO_FORMAT_E_AC3_JOC:
+ case AUDIO_FORMAT_DTS_HD:
+ if (!platform_is_edid_supported_format(adev->platform,
+ out->format)) {
+ ALOGD("%s:PASSTHROUGH_CONVERT supported", __func__);
+ convert = true;
+ }
+ break;
+ default:
+ ALOGD("%s: PASSTHROUGH_CONVERT not supported for format 0x%x",
+ __func__, out->format);
+ break;
+ }
+ ALOGD("%s: convert %d", __func__, convert);
+ return convert;
+}
+
+bool audio_extn_passthru_is_passt_supported(struct audio_device *adev,
+ struct stream_out *out)
+{
+ bool passt = false;
+ switch (out->format) {
+ case AUDIO_FORMAT_E_AC3:
+ if (platform_is_edid_supported_format(adev->platform, out->format)) {
+ ALOGV("%s:PASSTHROUGH supported for format %x",
+ __func__, out->format);
+ passt = true;
+ }
+ break;
+ case AUDIO_FORMAT_AC3:
+ if (platform_is_edid_supported_format(adev->platform, AUDIO_FORMAT_AC3)
+ || platform_is_edid_supported_format(adev->platform,
+ AUDIO_FORMAT_E_AC3)) {
+ ALOGV("%s:PASSTHROUGH supported for format %x",
+ __func__, out->format);
+ passt = true;
+ }
+ break;
+ case AUDIO_FORMAT_E_AC3_JOC:
+ /* Check for DDP capability in edid for JOC contents.*/
+ if (platform_is_edid_supported_format(adev->platform,
+ AUDIO_FORMAT_E_AC3)) {
+ ALOGV("%s:PASSTHROUGH supported for format %x",
+ __func__, out->format);
+ passt = true;
+ }
+ break;
+ case AUDIO_FORMAT_DTS:
+ if (platform_is_edid_supported_format(adev->platform, AUDIO_FORMAT_DTS)
+ || platform_is_edid_supported_format(adev->platform,
+ AUDIO_FORMAT_DTS_HD)) {
+ ALOGV("%s:PASSTHROUGH supported for format %x",
+ __func__, out->format);
+ passt = true;
+ }
+ break;
+ case AUDIO_FORMAT_DTS_HD:
+ if (platform_is_edid_supported_format(adev->platform, out->format)) {
+ ALOGV("%s:PASSTHROUGH supported for format %x",
+ __func__, out->format);
+ passt = true;
+ }
+ break;
+ default:
+ ALOGV("%s:Passthrough not supported", __func__);
+ }
+ return passt;
+}
+
+void audio_extn_passthru_update_stream_configuration(
+ struct audio_device *adev, struct stream_out *out)
+{
+ if (audio_extn_passthru_is_passt_supported(adev, out)) {
+ ALOGV("%s:PASSTHROUGH", __func__);
+ out->compr_config.codec->compr_passthr = PASSTHROUGH;
+ } else if (audio_extn_passthru_is_convert_supported(adev, out)){
+ ALOGV("%s:PASSTHROUGH CONVERT", __func__);
+ out->compr_config.codec->compr_passthr = PASSTHROUGH_CONVERT;
+ } else {
+ ALOGV("%s:NO PASSTHROUGH", __func__);
+ out->compr_config.codec->compr_passthr = LEGACY_PCM;
+ }
+}
+
+bool audio_extn_passthru_is_passthrough_stream(struct stream_out *out)
+{
+ //check passthrough system property
+ if (!property_get_bool("audio.offload.passthrough", false)) {
+ return false;
+ }
+
+ //check supported device, currently only on HDMI.
+ if (out->devices & AUDIO_DEVICE_OUT_AUX_DIGITAL) {
+ //passthrough flag
+ if (out->flags & AUDIO_OUTPUT_FLAG_COMPRESS_PASSTHROUGH)
+ return true;
+ //direct flag, check supported formats.
+ if (out->flags & AUDIO_OUTPUT_FLAG_DIRECT) {
+ if (audio_extn_passthru_is_supported_format(out->format)) {
+ if (platform_is_edid_supported_format(out->dev->platform,
+ out->format)) {
+ ALOGV("%s : return true",__func__);
+ return true;
+ } else if (audio_extn_is_dolby_format(out->format) &&
+ platform_is_edid_supported_format(out->dev->platform,
+ AUDIO_FORMAT_AC3)){
+ //return true for EAC3/EAC3_JOC formats
+ //if sink supports only AC3
+ ALOGV("%s : return true",__func__);
+ return true;
+ }
+ }
+ }
+ }
+ ALOGV("%s : return false",__func__);
+ return false;
+}
+
+int audio_extn_passthru_get_buffer_size(audio_offload_info_t* info)
+{
+ return platform_get_compress_passthrough_buffer_size(info);
+}
+
+int audio_extn_passthru_set_volume(struct stream_out *out, int mute)
+{
+ return platform_set_device_params(out, DEVICE_PARAM_MUTE_ID, mute);
+}
+
+int audio_extn_passthru_set_latency(struct stream_out *out, int latency)
+{
+ return platform_set_device_params(out, DEVICE_PARAM_LATENCY_ID, latency);
+}
diff --git a/hal/audio_extn/utils.c b/hal/audio_extn/utils.c
index cd9ead7..cb646cf 100644
--- a/hal/audio_extn/utils.c
+++ b/hal/audio_extn/utils.c
@@ -107,8 +107,10 @@
STRING_TO_ENUM(AUDIO_FORMAT_AMR_WB),
STRING_TO_ENUM(AUDIO_FORMAT_AC3),
STRING_TO_ENUM(AUDIO_FORMAT_E_AC3),
-#ifdef AUDIO_EXTN_FORMATS_ENABLED
STRING_TO_ENUM(AUDIO_FORMAT_DTS),
+ STRING_TO_ENUM(AUDIO_FORMAT_DTS_HD),
+#ifdef AUDIO_EXTN_FORMATS_ENABLED
+ STRING_TO_ENUM(AUDIO_FORMAT_E_AC3_JOC),
STRING_TO_ENUM(AUDIO_FORMAT_WMA),
STRING_TO_ENUM(AUDIO_FORMAT_WMA_PRO),
STRING_TO_ENUM(AUDIO_FORMAT_AAC_ADIF),
@@ -639,20 +641,6 @@
sample_rate = CODEC_BACKEND_DEFAULT_SAMPLE_RATE;
}
- app_type_cfg[len++] = usecase->stream.out->app_type_cfg.app_type;
- app_type_cfg[len++] = acdb_dev_id;
- if (((usecase->stream.out->format == AUDIO_FORMAT_E_AC3) ||
- (usecase->stream.out->format == AUDIO_FORMAT_E_AC3_JOC)) &&
- (usecase->stream.out->flags & AUDIO_OUTPUT_FLAG_COMPRESS_PASSTHROUGH))
- app_type_cfg[len++] = sample_rate * 4;
- else
- app_type_cfg[len++] = sample_rate;
-
- ALOGI("%s:%d PLAYBACK app_type %d, acdb_dev_id %d, sample_rate %d",
- __func__, __LINE__,
- platform_get_default_app_type(adev->platform),
- acdb_dev_id, sample_rate);
-
if ((24 == usecase->stream.out->bit_width) &&
(usecase->stream.out->devices & AUDIO_DEVICE_OUT_SPEAKER)) {
usecase->stream.out->app_type_cfg.sample_rate = DEFAULT_OUTPUT_SAMPLING_RATE;
@@ -667,7 +655,7 @@
app_type_cfg[len++] = acdb_dev_id;
if (((usecase->stream.out->format == AUDIO_FORMAT_E_AC3) ||
(usecase->stream.out->format == AUDIO_FORMAT_E_AC3_JOC))
- && audio_extn_dolby_is_passthrough_stream(usecase->stream.out)) {
+ && audio_extn_passthru_is_passthrough_stream(usecase->stream.out)) {
app_type_cfg[len++] = sample_rate * 4;
} else {
app_type_cfg[len++] = sample_rate;
@@ -1009,7 +997,7 @@
if (audio_extn_is_dolby_format(out->format) &&
/*TODO:Extend code to support DTS passthrough*/
/*set compressed channel status bits*/
- audio_extn_dolby_is_passthrough_stream(out)){
+ audio_extn_passthru_is_passthrough_stream(out)){
get_compressed_channel_status(buffer, bytes, channel_status, AUDIO_PARSER_CODEC_AC3);
} else
#endif
diff --git a/hal/audio_hw.c b/hal/audio_hw.c
index 17f71cc..e679c64 100644
--- a/hal/audio_hw.c
+++ b/hal/audio_hw.c
@@ -338,6 +338,10 @@
format == AUDIO_FORMAT_PCM_24_BIT_PACKED ||
format == AUDIO_FORMAT_PCM_8_24_BIT ||
format == AUDIO_FORMAT_PCM_16_BIT ||
+ format == AUDIO_FORMAT_AC3 ||
+ format == AUDIO_FORMAT_E_AC3 ||
+ format == AUDIO_FORMAT_DTS ||
+ format == AUDIO_FORMAT_DTS_HD ||
format == AUDIO_FORMAT_FLAC ||
format == AUDIO_FORMAT_ALAC ||
format == AUDIO_FORMAT_APE ||
@@ -384,6 +388,17 @@
case AUDIO_FORMAT_WMA_PRO:
id = SND_AUDIOCODEC_WMA_PRO;
break;
+ case AUDIO_FORMAT_AC3:
+ id = SND_AUDIOCODEC_AC3;
+ break;
+ case AUDIO_FORMAT_E_AC3:
+ case AUDIO_FORMAT_E_AC3_JOC:
+ id = SND_AUDIOCODEC_EAC3;
+ break;
+ case AUDIO_FORMAT_DTS:
+ case AUDIO_FORMAT_DTS_HD:
+ id = SND_AUDIOCODEC_DTS;
+ break;
default:
ALOGE("%s: Unsupported audio format :%x", __func__, format);
}
@@ -856,9 +871,6 @@
out->supported_channel_masks[i++] = AUDIO_CHANNEL_OUT_QUAD;
out->supported_channel_masks[i++] = AUDIO_CHANNEL_OUT_SURROUND;
out->supported_channel_masks[i++] = AUDIO_CHANNEL_OUT_2POINT1;
- case 2:
- ALOGV("%s: HDMI supports 2 channels", __func__);
- out->supported_channel_masks[i++] = AUDIO_CHANNEL_OUT_STEREO;
break;
default:
ALOGE("invalid/nonstandard channal count[%d]",channels);
@@ -1739,8 +1751,9 @@
ALOGV("%s usecase %s out->format:%x out->bit_width:%d", __func__, use_case_table[out->usecase],out->format,out->bit_width);
if (is_offload_usecase(out->usecase) &&
- audio_extn_dolby_is_passthrough_stream(out)) {
+ audio_extn_passthru_is_passthrough_stream(out)) {
enable_passthru = true;
+ ALOGV("%s : enable_passthru is set to true", __func__);
}
/* Check if change in HDMI channel config is allowed */
@@ -1754,7 +1767,7 @@
if (enable_passthru) {
audio_extn_passthru_on_start(out);
- audio_extn_dolby_update_passt_stream_configuration(adev, out);
+ audio_extn_passthru_update_stream_configuration(adev, out);
}
/* For pass through case, the backend should be configured as stereo */
@@ -1789,7 +1802,7 @@
}
if (is_offload_usecase(out->usecase) &&
- !(audio_extn_dolby_is_passthrough_stream(out))) {
+ !(audio_extn_passthru_is_passthrough_stream(out))) {
if (adev->visualizer_stop_output != NULL)
adev->visualizer_stop_output(out->handle, out->pcm_device_id);
@@ -1809,21 +1822,21 @@
free(uc_info);
if (is_offload_usecase(out->usecase) &&
- (audio_extn_dolby_is_passthrough_stream(out))) {
+ (audio_extn_passthru_is_passthrough_stream(out))) {
ALOGV("Disable passthrough , reset mixer to pcm");
/* NO_PASSTHROUGH */
out->compr_config.codec->compr_passthr = 0;
- /* Must be called after removing the usecase from list */
- if (out->devices & AUDIO_DEVICE_OUT_AUX_DIGITAL)
- check_and_set_hdmi_config(adev, DEFAULT_HDMI_OUT_CHANNELS,
- DEFAULT_HDMI_OUT_SAMPLE_RATE,
- DEFAULT_HDMI_OUT_FORMAT,
- false);
audio_extn_passthru_on_stop(out);
audio_extn_dolby_set_dap_bypass(adev, DAP_STATE_ON);
}
+ /* Must be called after removing the usecase from list */
+ if (out->devices & AUDIO_DEVICE_OUT_AUX_DIGITAL)
+ check_and_set_hdmi_config(adev, DEFAULT_HDMI_OUT_CHANNELS,
+ DEFAULT_HDMI_OUT_SAMPLE_RATE,
+ DEFAULT_HDMI_OUT_FORMAT,
+ false);
ALOGV("%s: exit: status(%d)", __func__, ret);
return ret;
}
@@ -1964,7 +1977,7 @@
if (audio_extn_is_dolby_format(out->format))
audio_extn_dolby_send_ddp_endp_params(adev);
#endif
- if (!(audio_extn_dolby_is_passthrough_stream(out))) {
+ if (!(audio_extn_passthru_is_passthrough_stream(out))) {
if (adev->visualizer_start_output != NULL)
adev->visualizer_start_output(out->handle, out->pcm_device_id);
if (adev->offload_effects_start_output != NULL)
@@ -2248,7 +2261,7 @@
*/
if ((out->devices == AUDIO_DEVICE_OUT_AUX_DIGITAL) &&
(val == AUDIO_DEVICE_NONE) &&
- !audio_extn_dolby_is_passthrough_stream(out) &&
+ !audio_extn_passthru_is_passthrough_stream(out) &&
(platform_get_edid_info(adev->platform) != 0) /* HDMI disconnected */) {
val = AUDIO_DEVICE_OUT_SPEAKER;
}
@@ -2471,13 +2484,13 @@
out->muted = (left == 0.0f);
return 0;
} else if (is_offload_usecase(out->usecase)) {
- if (audio_extn_dolby_is_passthrough_stream(out)) {
+ if (audio_extn_passthru_is_passthrough_stream(out)) {
/*
* Set mute or umute on HDMI passthrough stream.
* Only take left channel into account.
* Mute is 0 and unmute 1
*/
- audio_extn_dolby_set_passt_volume(out, (left == 0.0f));
+ audio_extn_passthru_set_volume(out, (left == 0.0f));
} else {
char mixer_ctl_name[128];
struct audio_device *adev = out->dev;
@@ -2531,6 +2544,13 @@
}
}
+ if (audio_extn_passthru_should_drop_data(out)) {
+ ALOGD(" %s : Drop data as compress passthrough session is going on", __func__);
+ usleep((uint64_t)bytes * 1000000 / audio_stream_out_frame_size(stream) /
+ out_get_sample_rate(&out->stream.common));
+ goto exit;
+ }
+
if (out->standby) {
out->standby = false;
pthread_mutex_lock(&adev->lock);
@@ -3379,7 +3399,7 @@
}
if (!is_supported_format(config->offload_info.format) &&
- !audio_extn_is_dolby_format(config->offload_info.format)) {
+ !audio_extn_passthru_is_supported_format(config->offload_info.format)) {
ALOGE("%s: Unsupported audio format %x " , __func__, config->offload_info.format);
ret = -EINVAL;
goto error_open;
@@ -3433,21 +3453,19 @@
out->bit_width = CODEC_BACKEND_DEFAULT_BIT_WIDTH;
- if (audio_extn_is_dolby_format(config->offload_info.format))
- out->compr_config.codec->id =
- audio_extn_dolby_get_snd_codec_id(adev, out,
- config->offload_info.format);
- else
- out->compr_config.codec->id =
- get_snd_codec_id(config->offload_info.format);
+ out->compr_config.codec->id = get_snd_codec_id(config->offload_info.format);
+ if (audio_extn_is_dolby_format(config->offload_info.format)) {
+ audio_extn_dolby_send_ddp_endp_params(adev);
+ audio_extn_dolby_set_dmid(adev);
+ }
if ((config->offload_info.format & AUDIO_FORMAT_MAIN_MASK) == AUDIO_FORMAT_PCM) {
out->compr_config.fragment_size =
platform_get_pcm_offload_buffer_size(&config->offload_info);
out->compr_config.fragments = DIRECT_PCM_NUM_FRAGMENTS;
- } else if (audio_extn_dolby_is_passthrough_stream(out)) {
+ } else if (audio_extn_passthru_is_passthrough_stream(out)) {
out->compr_config.fragment_size =
- audio_extn_dolby_get_passt_buffer_size(&config->offload_info);
+ audio_extn_passthru_get_buffer_size(&config->offload_info);
out->compr_config.fragments = COMPRESS_OFFLOAD_NUM_FRAGMENTS;
} else {
out->compr_config.fragment_size =
@@ -3501,14 +3519,14 @@
* AV playback
* Direct PCM playback
*/
- if (audio_extn_dolby_is_passthrough_stream(out) ||
+ if (audio_extn_passthru_is_passthrough_stream(out) ||
config->offload_info.has_video ||
out->flags & AUDIO_OUTPUT_FLAG_DIRECT_PCM) {
check_and_set_gapless_mode(adev, false);
} else
check_and_set_gapless_mode(adev, true);
- if (audio_extn_dolby_is_passthrough_stream(out)) {
+ if (audio_extn_passthru_is_passthrough_stream(out)) {
out->flags |= AUDIO_OUTPUT_FLAG_COMPRESS_PASSTHROUGH;
}
} else if (out->flags & AUDIO_OUTPUT_FLAG_INCALL_MUSIC) {
diff --git a/hal/msm8974/platform.c b/hal/msm8974/platform.c
index d60d67c..8922a4e 100644
--- a/hal/msm8974/platform.c
+++ b/hal/msm8974/platform.c
@@ -1642,6 +1642,9 @@
platform_acdb_init(my_data);
}
+ /* init keep-alive for compress passthru */
+ audio_extn_keep_alive_init(adev);
+
acdb_init_fail:
set_platform_defaults(my_data);