Merge "policy_hal: hal: add support to enable Direct PCM"
diff --git a/hal/audio_extn/utils.c b/hal/audio_extn/utils.c
index a1867d1..24dee64 100644
--- a/hal/audio_extn/utils.c
+++ b/hal/audio_extn/utils.c
@@ -59,6 +59,7 @@
const struct string_to_enum s_flag_name_to_enum_table[] = {
STRING_TO_ENUM(AUDIO_OUTPUT_FLAG_DIRECT),
+ STRING_TO_ENUM(AUDIO_OUTPUT_FLAG_DIRECT_PCM),
STRING_TO_ENUM(AUDIO_OUTPUT_FLAG_PRIMARY),
STRING_TO_ENUM(AUDIO_OUTPUT_FLAG_FAST),
STRING_TO_ENUM(AUDIO_OUTPUT_FLAG_DEEP_BUFFER),
diff --git a/hal/audio_hw.c b/hal/audio_hw.c
index fcb4e41..7c83168 100644
--- a/hal/audio_hw.c
+++ b/hal/audio_hw.c
@@ -177,6 +177,8 @@
[USECASE_AUDIO_PLAYBACK_OFFLOAD8] = "compress-offload-playback8",
[USECASE_AUDIO_PLAYBACK_OFFLOAD9] = "compress-offload-playback9",
#endif
+ [USECASE_AUDIO_DIRECT_PCM_OFFLOAD] = "compress-offload-playback2",
+
[USECASE_AUDIO_RECORD] = "audio-record",
[USECASE_AUDIO_RECORD_COMPRESS] = "audio-record-compress",
[USECASE_AUDIO_RECORD_LOW_LATENCY] = "low-latency-record",
@@ -221,6 +223,7 @@
USECASE_AUDIO_PLAYBACK_OFFLOAD8,
USECASE_AUDIO_PLAYBACK_OFFLOAD9,
#endif
+ USECASE_AUDIO_DIRECT_PCM_OFFLOAD,
};
#define STRING_TO_ENUM(string) { #string, string }
@@ -310,6 +313,7 @@
format == AUDIO_FORMAT_AAC_ADTS_HE_V2 ||
format == AUDIO_FORMAT_PCM_16_BIT_OFFLOAD ||
format == AUDIO_FORMAT_PCM_24_BIT_OFFLOAD ||
+ format == AUDIO_FORMAT_PCM_16_BIT ||
format == AUDIO_FORMAT_FLAC ||
format == AUDIO_FORMAT_ALAC ||
format == AUDIO_FORMAT_APE ||
@@ -336,6 +340,7 @@
id = SND_AUDIOCODEC_AAC;
break;
case AUDIO_FORMAT_PCM_OFFLOAD:
+ case AUDIO_FORMAT_PCM:
id = SND_AUDIOCODEC_PCM;
break;
case AUDIO_FORMAT_FLAC:
@@ -2778,7 +2783,7 @@
if ((flags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) &&
(SND_CARD_STATE_OFFLINE == get_snd_card_state(adev))) {
- ALOGE(" sound card is not active rejecting compress output open request");
+ ALOGE("sound card is not active rejecting compress output open request");
return -EINVAL;
}
@@ -2848,7 +2853,9 @@
__func__, ret);
goto error_open;
}
- } else if (out->flags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) {
+ } else if ((out->flags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) ||
+ (out->flags & AUDIO_OUTPUT_FLAG_DIRECT_PCM)) {
+
if (config->offload_info.version != AUDIO_INFO_INITIALIZER.version ||
config->offload_info.size != AUDIO_INFO_INITIALIZER.size) {
ALOGE("%s: Unsupported Offload information", __func__);
@@ -2869,7 +2876,7 @@
if (!is_supported_format(config->offload_info.format) &&
!audio_extn_is_dolby_format(config->offload_info.format)) {
- ALOGE("%s: Unsupported audio format", __func__);
+ ALOGE("%s: Unsupported audio format %x " , __func__, config->offload_info.format);
ret = -EINVAL;
goto error_open;
}
@@ -2882,7 +2889,13 @@
goto error_open;
}
- out->usecase = get_offload_usecase(adev);
+ if (out->flags & AUDIO_OUTPUT_FLAG_DIRECT_PCM) {
+ ALOGV("%s:: inserting DIRECT_PCM _USECASE", __func__);
+ out->usecase = USECASE_AUDIO_DIRECT_PCM_OFFLOAD;
+ } else {
+ ALOGV("%s:: inserting OFFLOAD_USECASE", __func__);
+ out->usecase = get_offload_usecase(adev);
+ }
if (config->offload_info.channel_mask)
out->channel_mask = config->offload_info.channel_mask;
else if (config->channel_mask) {
@@ -2906,7 +2919,9 @@
else
out->compr_config.codec->id =
get_snd_codec_id(config->offload_info.format);
- if ((config->offload_info.format & AUDIO_FORMAT_MAIN_MASK) == AUDIO_FORMAT_PCM_OFFLOAD) {
+
+ if (((config->offload_info.format & AUDIO_FORMAT_MAIN_MASK) == AUDIO_FORMAT_PCM_OFFLOAD)||
+ ((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);
} else if (audio_extn_dolby_is_passthrough_stream(out->flags)) {
@@ -2934,8 +2949,10 @@
out->compr_config.codec->format = SND_AUDIOSTREAMFORMAT_MP4ADTS;
if (config->offload_info.format == AUDIO_FORMAT_PCM_16_BIT_OFFLOAD)
out->compr_config.codec->format = SNDRV_PCM_FORMAT_S16_LE;
- if(config->offload_info.format == AUDIO_FORMAT_PCM_24_BIT_OFFLOAD)
+ if (config->offload_info.format == AUDIO_FORMAT_PCM_24_BIT_OFFLOAD)
out->compr_config.codec->format = SNDRV_PCM_FORMAT_S24_LE;
+ if (config->offload_info.format == AUDIO_FORMAT_PCM_16_BIT)
+ out->compr_config.codec->format = SNDRV_PCM_FORMAT_S16_LE;
if (out->bit_width == 24) {
out->compr_config.codec->format = SNDRV_PCM_FORMAT_S24_LE;
@@ -3076,7 +3093,7 @@
*stream_out = &out->stream;
ALOGD("%s: Stream (%p) picks up usecase (%s)", __func__, &out->stream,
- use_case_table[out->usecase]);
+ use_case_table[out->usecase]);
if (out->flags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD)
audio_extn_dts_notify_playback_state(out->usecase, 0, out->sample_rate,
diff --git a/hal/audio_hw.h b/hal/audio_hw.h
index 5e61d36..c2f37d4 100644
--- a/hal/audio_hw.h
+++ b/hal/audio_hw.h
@@ -95,6 +95,8 @@
USECASE_AUDIO_PLAYBACK_OFFLOAD9,
#endif
+ USECASE_AUDIO_DIRECT_PCM_OFFLOAD,
+
/* FM usecase */
USECASE_AUDIO_PLAYBACK_FM,
diff --git a/hal/msm8916/platform.c b/hal/msm8916/platform.c
index 5115b4c..2303e9d 100644
--- a/hal/msm8916/platform.c
+++ b/hal/msm8916/platform.c
@@ -259,6 +259,8 @@
[USECASE_AUDIO_PLAYBACK_OFFLOAD8] = {-1, -1},
[USECASE_AUDIO_PLAYBACK_OFFLOAD9] = {-1, -1},
#endif
+ [USECASE_AUDIO_DIRECT_PCM_OFFLOAD] =
+ {PLAYBACK_OFFLOAD_DEVICE, PLAYBACK_OFFLOAD_DEVICE},
[USECASE_AUDIO_RECORD] = {AUDIO_RECORD_PCM_DEVICE, AUDIO_RECORD_PCM_DEVICE},
[USECASE_AUDIO_RECORD_COMPRESS] = {COMPRESS_CAPTURE_DEVICE, COMPRESS_CAPTURE_DEVICE},
[USECASE_AUDIO_RECORD_LOW_LATENCY] = {LOWLATENCY_PCM_DEVICE,
@@ -628,6 +630,7 @@
{TO_NAME_INDEX(USECASE_AUDIO_PLAYBACK_OFFLOAD8)},
{TO_NAME_INDEX(USECASE_AUDIO_PLAYBACK_OFFLOAD9)},
#endif
+ {TO_NAME_INDEX(USECASE_AUDIO_DIRECT_PCM_OFFLOAD)},
{TO_NAME_INDEX(USECASE_AUDIO_RECORD)},
{TO_NAME_INDEX(USECASE_AUDIO_RECORD_LOW_LATENCY)},
{TO_NAME_INDEX(USECASE_VOICE_CALL)},
@@ -3365,6 +3368,7 @@
case USECASE_AUDIO_PLAYBACK_DEEP_BUFFER:
case USECASE_AUDIO_PLAYBACK_MULTI_CH:
case USECASE_AUDIO_PLAYBACK_OFFLOAD:
+ case USECASE_AUDIO_DIRECT_PCM_OFFLOAD:
needs_event = true;
break;
/* concurrent playback in low latency allowed */
@@ -3426,6 +3430,7 @@
case USECASE_AUDIO_PLAYBACK_DEEP_BUFFER:
case USECASE_AUDIO_PLAYBACK_MULTI_CH:
case USECASE_AUDIO_PLAYBACK_OFFLOAD:
+ case USECASE_AUDIO_DIRECT_PCM_OFFLOAD:
needs_event = true;
break;
/* concurrent playback in low latency allowed */
diff --git a/hal/msm8974/platform.c b/hal/msm8974/platform.c
index 242e2dc..f341241 100644
--- a/hal/msm8974/platform.c
+++ b/hal/msm8974/platform.c
@@ -255,6 +255,10 @@
[USECASE_AUDIO_PLAYBACK_OFFLOAD9] =
{PLAYBACK_OFFLOAD_DEVICE9, PLAYBACK_OFFLOAD_DEVICE9},
#endif
+
+ [USECASE_AUDIO_DIRECT_PCM_OFFLOAD] =
+ {PLAYBACK_OFFLOAD_DEVICE2, PLAYBACK_OFFLOAD_DEVICE2},
+
[USECASE_AUDIO_RECORD] = {AUDIO_RECORD_PCM_DEVICE, AUDIO_RECORD_PCM_DEVICE},
[USECASE_AUDIO_RECORD_COMPRESS] = {COMPRESS_CAPTURE_DEVICE, COMPRESS_CAPTURE_DEVICE},
[USECASE_AUDIO_RECORD_LOW_LATENCY] = {LOWLATENCY_PCM_DEVICE,
@@ -606,6 +610,7 @@
{TO_NAME_INDEX(USECASE_AUDIO_PLAYBACK_OFFLOAD8)},
{TO_NAME_INDEX(USECASE_AUDIO_PLAYBACK_OFFLOAD9)},
#endif
+ {TO_NAME_INDEX(USECASE_AUDIO_DIRECT_PCM_OFFLOAD)},
{TO_NAME_INDEX(USECASE_AUDIO_RECORD)},
{TO_NAME_INDEX(USECASE_AUDIO_RECORD_LOW_LATENCY)},
{TO_NAME_INDEX(USECASE_VOICE_CALL)},
diff --git a/hal/msm8974/platform.h b/hal/msm8974/platform.h
index 5471b3c..b8f8cee 100644
--- a/hal/msm8974/platform.h
+++ b/hal/msm8974/platform.h
@@ -266,6 +266,9 @@
#endif
#endif
+// for DIRECT_PCM
+#define PLAYBACK_OFFLOAD_DEVICE2 17
+
#define COMPRESS_VOIP_CALL_PCM_DEVICE 3
#ifdef PLATFORM_MSM8610
diff --git a/policy_hal/AudioPolicyManager.cpp b/policy_hal/AudioPolicyManager.cpp
index a2a62c6..f105e15 100644
--- a/policy_hal/AudioPolicyManager.cpp
+++ b/policy_hal/AudioPolicyManager.cpp
@@ -1127,6 +1127,45 @@
}
return false;
}
+
+status_t AudioPolicyManagerCustom::getOutputForAttr(const audio_attributes_t *attr,
+ audio_io_handle_t *output,
+ audio_session_t session,
+ audio_stream_type_t *stream,
+ uid_t uid,
+ uint32_t samplingRate,
+ audio_format_t format,
+ audio_channel_mask_t channelMask,
+ audio_output_flags_t flags,
+ audio_port_handle_t selectedDeviceId,
+ const audio_offload_info_t *offloadInfo)
+{
+ audio_offload_info_t tOffloadInfo = AUDIO_INFO_INITIALIZER;
+
+ bool pcmOffloadEnabled = property_get_bool("audio.offload.track.enable", false);
+
+ if (offloadInfo == NULL && pcmOffloadEnabled) {
+ tOffloadInfo.sample_rate = samplingRate;
+ tOffloadInfo.channel_mask = channelMask;
+ tOffloadInfo.format = format;
+ tOffloadInfo.stream_type = *stream;
+ tOffloadInfo.bit_width = 16; //hard coded for PCM_16
+ if (attr != NULL) {
+ ALOGV("found attribute .. setting usage %d ", attr->usage);
+ tOffloadInfo.usage = attr->usage;
+ } else {
+ ALOGD("%s:: attribute is NULL .. no usage set", __func__);
+ }
+ offloadInfo = &tOffloadInfo;
+ }
+
+ return AudioPolicyManager::getOutputForAttr(attr, output, session, stream,
+ (uid_t)uid, (uint32_t)samplingRate,
+ format, (audio_channel_mask_t)channelMask,
+ flags, (audio_port_handle_t)selectedDeviceId,
+ offloadInfo);
+}
+
audio_io_handle_t AudioPolicyManagerCustom::getOutputForDevice(
audio_devices_t device,
audio_session_t session __unused,
@@ -1342,7 +1381,7 @@
flags = AUDIO_OUTPUT_FLAG_FAST;
}
// open a direct output if required by specified parameters
- //force direct flag if offload flag is set: offloading implies a direct output stream
+ // force direct flag if offload flag is set: offloading implies a direct output stream
// and all common behaviors are driven by checking only the direct flag
// this should normally be set appropriately in the policy configuration file
if ((flags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) != 0) {
@@ -1351,6 +1390,18 @@
if ((flags & AUDIO_OUTPUT_FLAG_HW_AV_SYNC) != 0) {
flags = (audio_output_flags_t)(flags | AUDIO_OUTPUT_FLAG_DIRECT);
}
+
+ // Do offload magic here
+ if ((flags == AUDIO_OUTPUT_FLAG_NONE) && (stream == AUDIO_STREAM_MUSIC) &&
+ (offloadInfo != NULL) &&
+ ((offloadInfo->usage == AUDIO_USAGE_MEDIA ||
+ (offloadInfo->usage == AUDIO_USAGE_GAME)))) {
+ if ((flags & AUDIO_OUTPUT_FLAG_DIRECT) == 0) {
+ ALOGD("AudioCustomHAL --> Force Direct Flag ..");
+ flags = (audio_output_flags_t)(flags | AUDIO_OUTPUT_FLAG_DIRECT);
+ }
+ }
+
// only allow deep buffering for music stream type
if (stream != AUDIO_STREAM_MUSIC) {
flags = (audio_output_flags_t)(flags &~AUDIO_OUTPUT_FLAG_DEEP_BUFFER);
@@ -1520,7 +1571,7 @@
ALOGW_IF((output == 0), "getOutput() could not find output for stream %d, samplingRate %d,"
"format %d, channels %x, flags %x", stream, samplingRate, format, channelMask, flags);
- ALOGV(" getOutputForDevice() returns output %d", output);
+ ALOGV("getOutputForDevice() returns output %d", output);
return output;
}
diff --git a/policy_hal/AudioPolicyManager.h b/policy_hal/AudioPolicyManager.h
index 7b7535d..b5a4461 100644
--- a/policy_hal/AudioPolicyManager.h
+++ b/policy_hal/AudioPolicyManager.h
@@ -137,6 +137,18 @@
audio_channel_mask_t channelMask,
audio_output_flags_t flags,
const audio_offload_info_t *offloadInfo);
+ // internal method to fill offload info in case of Direct PCM
+ status_t getOutputForAttr(const audio_attributes_t *attr,
+ audio_io_handle_t *output,
+ audio_session_t session,
+ audio_stream_type_t *stream,
+ uid_t uid,
+ uint32_t samplingRate,
+ audio_format_t format,
+ audio_channel_mask_t channelMask,
+ audio_output_flags_t flags,
+ audio_port_handle_t selectedDeviceId,
+ const audio_offload_info_t *offloadInfo);
// Used for voip + voice concurrency usecase
int mPrevPhoneState;
int mvoice_call_state;