|
|
|
@ -60,6 +60,26 @@ namespace android {
|
|
|
|
|
// media / notification / system volume.
|
|
|
|
|
constexpr float IN_CALL_EARPIECE_HEADROOM_DB = 3.f;
|
|
|
|
|
|
|
|
|
|
#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
|
|
|
|
|
// Array of all surround formats.
|
|
|
|
|
static const audio_format_t SURROUND_FORMATS[] = {
|
|
|
|
|
AUDIO_FORMAT_AC3,
|
|
|
|
|
AUDIO_FORMAT_E_AC3,
|
|
|
|
|
AUDIO_FORMAT_DTS,
|
|
|
|
|
AUDIO_FORMAT_DTS_HD,
|
|
|
|
|
AUDIO_FORMAT_AAC_LC,
|
|
|
|
|
AUDIO_FORMAT_DOLBY_TRUEHD,
|
|
|
|
|
AUDIO_FORMAT_E_AC3_JOC,
|
|
|
|
|
};
|
|
|
|
|
// Array of all AAC formats. When AAC is enabled by users, all AAC formats should be enabled.
|
|
|
|
|
static const audio_format_t AAC_FORMATS[] = {
|
|
|
|
|
AUDIO_FORMAT_AAC_LC,
|
|
|
|
|
AUDIO_FORMAT_AAC_HE_V1,
|
|
|
|
|
AUDIO_FORMAT_AAC_HE_V2,
|
|
|
|
|
AUDIO_FORMAT_AAC_ELD,
|
|
|
|
|
AUDIO_FORMAT_AAC_XHE,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
|
// AudioPolicyInterface implementation
|
|
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
@ -3448,6 +3468,275 @@ float AudioPolicyManager::getStreamVolumeDB(
|
|
|
|
|
return computeVolume(stream, index, device);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
status_t AudioPolicyManager::getSupportedFormats(audio_io_handle_t ioHandle,
|
|
|
|
|
FormatVector& formats) {
|
|
|
|
|
if (ioHandle == AUDIO_IO_HANDLE_NONE) {
|
|
|
|
|
return BAD_VALUE;
|
|
|
|
|
}
|
|
|
|
|
String8 reply;
|
|
|
|
|
reply = mpClientInterface->getParameters(
|
|
|
|
|
ioHandle, String8(AudioParameter::keyStreamSupportedFormats));
|
|
|
|
|
ALOGV("%s: supported formats %s", __FUNCTION__, reply.string());
|
|
|
|
|
AudioParameter repliedParameters(reply);
|
|
|
|
|
if (repliedParameters.get(
|
|
|
|
|
String8(AudioParameter::keyStreamSupportedFormats), reply) != NO_ERROR) {
|
|
|
|
|
ALOGE("%s: failed to retrieve format, bailing out", __FUNCTION__);
|
|
|
|
|
return BAD_VALUE;
|
|
|
|
|
}
|
|
|
|
|
for (auto format : formatsFromString(reply.string())) {
|
|
|
|
|
// Only AUDIO_FORMAT_AAC_LC will be used in Settings UI for all AAC formats.
|
|
|
|
|
for (size_t i = 0; i < ARRAY_SIZE(AAC_FORMATS); i++) {
|
|
|
|
|
if (format == AAC_FORMATS[i]) {
|
|
|
|
|
format = AUDIO_FORMAT_AAC_LC;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
bool exist = false;
|
|
|
|
|
for (size_t i = 0; i < formats.size(); i++) {
|
|
|
|
|
if (format == formats[i]) {
|
|
|
|
|
exist = true;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
bool isSurroundFormat = false;
|
|
|
|
|
for (size_t i = 0; i < ARRAY_SIZE(SURROUND_FORMATS); i++) {
|
|
|
|
|
if (SURROUND_FORMATS[i] == format) {
|
|
|
|
|
isSurroundFormat = true;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (!exist && isSurroundFormat) {
|
|
|
|
|
formats.add(format);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return NO_ERROR;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
status_t AudioPolicyManager::getSurroundFormats(unsigned int *numSurroundFormats,
|
|
|
|
|
audio_format_t *surroundFormats,
|
|
|
|
|
bool *surroundFormatsEnabled,
|
|
|
|
|
bool reported)
|
|
|
|
|
{
|
|
|
|
|
if (numSurroundFormats == NULL || (*numSurroundFormats != 0 &&
|
|
|
|
|
(surroundFormats == NULL || surroundFormatsEnabled == NULL))) {
|
|
|
|
|
return BAD_VALUE;
|
|
|
|
|
}
|
|
|
|
|
ALOGV("getSurroundFormats() numSurroundFormats %d surroundFormats %p surroundFormatsEnabled %p",
|
|
|
|
|
*numSurroundFormats, surroundFormats, surroundFormatsEnabled);
|
|
|
|
|
|
|
|
|
|
// Only return value if there is HDMI output.
|
|
|
|
|
if ((mAvailableOutputDevices.types() & AUDIO_DEVICE_OUT_HDMI) == 0) {
|
|
|
|
|
return INVALID_OPERATION;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
size_t formatsWritten = 0;
|
|
|
|
|
size_t formatsMax = *numSurroundFormats;
|
|
|
|
|
*numSurroundFormats = 0;
|
|
|
|
|
FormatVector formats;
|
|
|
|
|
if (reported) {
|
|
|
|
|
// Only get surround formats which are reported by device.
|
|
|
|
|
// First list already open outputs that can be routed to this device
|
|
|
|
|
audio_devices_t device = AUDIO_DEVICE_OUT_HDMI;
|
|
|
|
|
SortedVector<audio_io_handle_t> outputs;
|
|
|
|
|
bool reportedFormatFound = false;
|
|
|
|
|
status_t status;
|
|
|
|
|
sp<SwAudioOutputDescriptor> desc;
|
|
|
|
|
for (size_t i = 0; i < mOutputs.size(); i++) {
|
|
|
|
|
desc = mOutputs.valueAt(i);
|
|
|
|
|
if (!desc->isDuplicated() && (desc->supportedDevices() & device)) {
|
|
|
|
|
outputs.add(mOutputs.keyAt(i));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
// Open an output to query dynamic parameters.
|
|
|
|
|
DeviceVector hdmiOutputDevices = mAvailableOutputDevices.getDevicesFromType(
|
|
|
|
|
AUDIO_DEVICE_OUT_HDMI);
|
|
|
|
|
for (size_t i = 0; i < hdmiOutputDevices.size(); i++) {
|
|
|
|
|
String8 address = hdmiOutputDevices[i]->mAddress;
|
|
|
|
|
for (const auto& hwModule : mHwModules) {
|
|
|
|
|
for (size_t i = 0; i < hwModule->getOutputProfiles().size(); i++) {
|
|
|
|
|
sp<IOProfile> profile = hwModule->getOutputProfiles()[i];
|
|
|
|
|
if (profile->supportDevice(AUDIO_DEVICE_OUT_HDMI) &&
|
|
|
|
|
profile->supportDeviceAddress(address)) {
|
|
|
|
|
size_t j;
|
|
|
|
|
for (j = 0; j < outputs.size(); j++) {
|
|
|
|
|
desc = mOutputs.valueFor(outputs.itemAt(j));
|
|
|
|
|
if (!desc->isDuplicated() && desc->mProfile == profile) {
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (j != outputs.size()) {
|
|
|
|
|
status = getSupportedFormats(outputs.itemAt(j), formats);
|
|
|
|
|
reportedFormatFound |= (status == NO_ERROR);
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!profile->canOpenNewIo()) {
|
|
|
|
|
ALOGW("Max Output number %u already opened for this profile %s",
|
|
|
|
|
profile->maxOpenCount, profile->getTagName().c_str());
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ALOGV("opening output for device %08x with params %s profile %p name %s",
|
|
|
|
|
device, address.string(), profile.get(), profile->getName().string());
|
|
|
|
|
desc = new SwAudioOutputDescriptor(profile, mpClientInterface);
|
|
|
|
|
audio_io_handle_t output = AUDIO_IO_HANDLE_NONE;
|
|
|
|
|
status_t status = desc->open(nullptr, device, address,
|
|
|
|
|
AUDIO_STREAM_DEFAULT, AUDIO_OUTPUT_FLAG_NONE,
|
|
|
|
|
&output);
|
|
|
|
|
|
|
|
|
|
if (status == NO_ERROR) {
|
|
|
|
|
status = getSupportedFormats(output, formats);
|
|
|
|
|
reportedFormatFound |= (status == NO_ERROR);
|
|
|
|
|
desc->close();
|
|
|
|
|
output = AUDIO_IO_HANDLE_NONE;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!reportedFormatFound) {
|
|
|
|
|
return UNKNOWN_ERROR;
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
for (size_t i = 0; i < ARRAY_SIZE(SURROUND_FORMATS); i++) {
|
|
|
|
|
formats.add(SURROUND_FORMATS[i]);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
for (size_t i = 0; i < formats.size(); i++) {
|
|
|
|
|
if (formatsWritten < formatsMax) {
|
|
|
|
|
surroundFormats[formatsWritten] = formats[i];
|
|
|
|
|
bool formatEnabled = false;
|
|
|
|
|
if (formats[i] == AUDIO_FORMAT_AAC_LC) {
|
|
|
|
|
for (size_t j = 0; j < ARRAY_SIZE(AAC_FORMATS); j++) {
|
|
|
|
|
formatEnabled =
|
|
|
|
|
mSurroundFormats.find(AAC_FORMATS[i]) != mSurroundFormats.end();
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
formatEnabled = mSurroundFormats.find(formats[i]) != mSurroundFormats.end();
|
|
|
|
|
}
|
|
|
|
|
surroundFormatsEnabled[formatsWritten++] = formatEnabled;
|
|
|
|
|
}
|
|
|
|
|
(*numSurroundFormats)++;
|
|
|
|
|
}
|
|
|
|
|
return NO_ERROR;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
status_t AudioPolicyManager::setSurroundFormatEnabled(audio_format_t audioFormat, bool enabled)
|
|
|
|
|
{
|
|
|
|
|
// Check if audio format is a surround formats.
|
|
|
|
|
bool isSurroundFormat = false;
|
|
|
|
|
for (size_t i = 0; i < ARRAY_SIZE(SURROUND_FORMATS); i++) {
|
|
|
|
|
if (audioFormat == SURROUND_FORMATS[i]) {
|
|
|
|
|
isSurroundFormat = true;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (!isSurroundFormat) {
|
|
|
|
|
return BAD_VALUE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Should only be called when MANUAL.
|
|
|
|
|
audio_policy_forced_cfg_t forceUse = mEngine->getForceUse(
|
|
|
|
|
AUDIO_POLICY_FORCE_FOR_ENCODED_SURROUND);
|
|
|
|
|
if (forceUse != AUDIO_POLICY_FORCE_ENCODED_SURROUND_MANUAL) {
|
|
|
|
|
return INVALID_OPERATION;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if ((mSurroundFormats.find(audioFormat) != mSurroundFormats.end() && enabled)
|
|
|
|
|
|| (mSurroundFormats.find(audioFormat) == mSurroundFormats.end() && !enabled)) {
|
|
|
|
|
return NO_ERROR;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// The operation is valid only when there is HDMI output available.
|
|
|
|
|
if ((mAvailableOutputDevices.types() & AUDIO_DEVICE_OUT_HDMI) == 0) {
|
|
|
|
|
return INVALID_OPERATION;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (enabled) {
|
|
|
|
|
if (audioFormat == AUDIO_FORMAT_AAC_LC) {
|
|
|
|
|
for (size_t i = 0; i < ARRAY_SIZE(AAC_FORMATS); i++) {
|
|
|
|
|
mSurroundFormats.insert(AAC_FORMATS[i]);
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
mSurroundFormats.insert(audioFormat);
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
if (audioFormat == AUDIO_FORMAT_AAC_LC) {
|
|
|
|
|
for (size_t i = 0; i < ARRAY_SIZE(AAC_FORMATS); i++) {
|
|
|
|
|
mSurroundFormats.erase(AAC_FORMATS[i]);
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
mSurroundFormats.erase(audioFormat);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
sp<SwAudioOutputDescriptor> outputDesc;
|
|
|
|
|
bool profileUpdated = false;
|
|
|
|
|
DeviceVector hdmiOutputDevices = mAvailableOutputDevices.getDevicesFromType(
|
|
|
|
|
AUDIO_DEVICE_OUT_HDMI);
|
|
|
|
|
for (size_t i = 0; i < hdmiOutputDevices.size(); i++) {
|
|
|
|
|
// Simulate reconnection to update enabled surround sound formats.
|
|
|
|
|
String8 address = hdmiOutputDevices[i]->mAddress;
|
|
|
|
|
String8 name = hdmiOutputDevices[i]->getName();
|
|
|
|
|
status_t status = setDeviceConnectionStateInt(AUDIO_DEVICE_OUT_HDMI,
|
|
|
|
|
AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE,
|
|
|
|
|
address.c_str(),
|
|
|
|
|
name.c_str());
|
|
|
|
|
if (status != NO_ERROR) {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
status = setDeviceConnectionStateInt(AUDIO_DEVICE_OUT_HDMI,
|
|
|
|
|
AUDIO_POLICY_DEVICE_STATE_AVAILABLE,
|
|
|
|
|
address.c_str(),
|
|
|
|
|
name.c_str());
|
|
|
|
|
profileUpdated |= (status == NO_ERROR);
|
|
|
|
|
}
|
|
|
|
|
DeviceVector hdmiInputDevices = mAvailableInputDevices.getDevicesFromType(
|
|
|
|
|
AUDIO_DEVICE_IN_HDMI);
|
|
|
|
|
for (size_t i = 0; i < hdmiInputDevices.size(); i++) {
|
|
|
|
|
// Simulate reconnection to update enabled surround sound formats.
|
|
|
|
|
String8 address = hdmiInputDevices[i]->mAddress;
|
|
|
|
|
String8 name = hdmiInputDevices[i]->getName();
|
|
|
|
|
status_t status = setDeviceConnectionStateInt(AUDIO_DEVICE_IN_HDMI,
|
|
|
|
|
AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE,
|
|
|
|
|
address.c_str(),
|
|
|
|
|
name.c_str());
|
|
|
|
|
if (status != NO_ERROR) {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
status = setDeviceConnectionStateInt(AUDIO_DEVICE_IN_HDMI,
|
|
|
|
|
AUDIO_POLICY_DEVICE_STATE_AVAILABLE,
|
|
|
|
|
address.c_str(),
|
|
|
|
|
name.c_str());
|
|
|
|
|
profileUpdated |= (status == NO_ERROR);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Undo the surround formats change due to no audio profiles updated.
|
|
|
|
|
if (!profileUpdated) {
|
|
|
|
|
if (enabled) {
|
|
|
|
|
if (audioFormat == AUDIO_FORMAT_AAC_LC) {
|
|
|
|
|
for (size_t i = 0; i < ARRAY_SIZE(AAC_FORMATS); i++) {
|
|
|
|
|
mSurroundFormats.erase(AAC_FORMATS[i]);
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
mSurroundFormats.erase(audioFormat);
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
if (audioFormat == AUDIO_FORMAT_AAC_LC) {
|
|
|
|
|
for (size_t i = 0; i < ARRAY_SIZE(AAC_FORMATS); i++) {
|
|
|
|
|
mSurroundFormats.insert(AAC_FORMATS[i]);
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
mSurroundFormats.insert(audioFormat);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return profileUpdated ? NO_ERROR : INVALID_OPERATION;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void AudioPolicyManager::setRecordSilenced(uid_t uid, bool silenced)
|
|
|
|
|
{
|
|
|
|
|
ALOGV("AudioPolicyManager:setRecordSilenced(uid:%d, silenced:%d)", uid, silenced);
|
|
|
|
@ -3822,6 +4111,7 @@ AudioPolicyManager::~AudioPolicyManager()
|
|
|
|
|
mInputs.clear();
|
|
|
|
|
mHwModules.clear();
|
|
|
|
|
mHwModulesAll.clear();
|
|
|
|
|
mSurroundFormats.clear();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
status_t AudioPolicyManager::initCheck()
|
|
|
|
@ -5578,81 +5868,110 @@ void AudioPolicyManager::filterSurroundFormats(FormatVector *formatsPtr) {
|
|
|
|
|
AUDIO_POLICY_FORCE_FOR_ENCODED_SURROUND);
|
|
|
|
|
ALOGD("%s: forced use = %d", __FUNCTION__, forceUse);
|
|
|
|
|
|
|
|
|
|
// Analyze original support for various formats.
|
|
|
|
|
bool supportsAC3 = false;
|
|
|
|
|
bool supportsOtherSurround = false;
|
|
|
|
|
bool supportsIEC61937 = false;
|
|
|
|
|
for (ssize_t formatIndex = 0; formatIndex < (ssize_t)formats.size(); formatIndex++) {
|
|
|
|
|
audio_format_t format = formats[formatIndex];
|
|
|
|
|
switch (format) {
|
|
|
|
|
case AUDIO_FORMAT_AC3:
|
|
|
|
|
supportsAC3 = true;
|
|
|
|
|
break;
|
|
|
|
|
case AUDIO_FORMAT_E_AC3:
|
|
|
|
|
case AUDIO_FORMAT_DTS:
|
|
|
|
|
case AUDIO_FORMAT_DTS_HD:
|
|
|
|
|
// If ALWAYS, remove all other surround formats here since we will add them later.
|
|
|
|
|
if (forceUse == AUDIO_POLICY_FORCE_ENCODED_SURROUND_ALWAYS) {
|
|
|
|
|
formats.removeAt(formatIndex);
|
|
|
|
|
formatIndex--;
|
|
|
|
|
// If MANUAL, keep the supported surround sound formats as current enabled ones.
|
|
|
|
|
if (forceUse == AUDIO_POLICY_FORCE_ENCODED_SURROUND_MANUAL) {
|
|
|
|
|
formats.clear();
|
|
|
|
|
for (auto it = mSurroundFormats.begin(); it != mSurroundFormats.end(); it++) {
|
|
|
|
|
formats.add(*it);
|
|
|
|
|
}
|
|
|
|
|
// Always enable IEC61937 when in MANUAL mode.
|
|
|
|
|
formats.add(AUDIO_FORMAT_IEC61937);
|
|
|
|
|
} else { // NEVER, AUTO or ALWAYS
|
|
|
|
|
// Analyze original support for various formats.
|
|
|
|
|
bool supportsAC3 = false;
|
|
|
|
|
bool supportsOtherSurround = false;
|
|
|
|
|
bool supportsIEC61937 = false;
|
|
|
|
|
mSurroundFormats.clear();
|
|
|
|
|
for (ssize_t formatIndex = 0; formatIndex < (ssize_t)formats.size(); formatIndex++) {
|
|
|
|
|
audio_format_t format = formats[formatIndex];
|
|
|
|
|
switch (format) {
|
|
|
|
|
case AUDIO_FORMAT_AC3:
|
|
|
|
|
supportsAC3 = true;
|
|
|
|
|
break;
|
|
|
|
|
case AUDIO_FORMAT_E_AC3:
|
|
|
|
|
case AUDIO_FORMAT_DTS:
|
|
|
|
|
case AUDIO_FORMAT_DTS_HD:
|
|
|
|
|
// If ALWAYS, remove all other surround formats here
|
|
|
|
|
// since we will add them later.
|
|
|
|
|
if (forceUse == AUDIO_POLICY_FORCE_ENCODED_SURROUND_ALWAYS) {
|
|
|
|
|
formats.removeAt(formatIndex);
|
|
|
|
|
formatIndex--;
|
|
|
|
|
}
|
|
|
|
|
supportsOtherSurround = true;
|
|
|
|
|
break;
|
|
|
|
|
case AUDIO_FORMAT_IEC61937:
|
|
|
|
|
supportsIEC61937 = true;
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Modify formats based on surround preferences.
|
|
|
|
|
// If NEVER, remove support for surround formats.
|
|
|
|
|
if (forceUse == AUDIO_POLICY_FORCE_ENCODED_SURROUND_NEVER) {
|
|
|
|
|
if (supportsAC3 || supportsOtherSurround || supportsIEC61937) {
|
|
|
|
|
// Remove surround sound related formats.
|
|
|
|
|
for (size_t formatIndex = 0; formatIndex < formats.size(); ) {
|
|
|
|
|
audio_format_t format = formats[formatIndex];
|
|
|
|
|
switch(format) {
|
|
|
|
|
case AUDIO_FORMAT_AC3:
|
|
|
|
|
case AUDIO_FORMAT_E_AC3:
|
|
|
|
|
case AUDIO_FORMAT_DTS:
|
|
|
|
|
case AUDIO_FORMAT_DTS_HD:
|
|
|
|
|
case AUDIO_FORMAT_IEC61937:
|
|
|
|
|
formats.removeAt(formatIndex);
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
formatIndex++; // keep it
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
supportsAC3 = false;
|
|
|
|
|
supportsOtherSurround = false;
|
|
|
|
|
supportsIEC61937 = false;
|
|
|
|
|
}
|
|
|
|
|
} else { // AUTO or ALWAYS
|
|
|
|
|
// Most TVs support AC3 even if they do not report it in the EDID.
|
|
|
|
|
if ((alwaysForceAC3 || (forceUse == AUDIO_POLICY_FORCE_ENCODED_SURROUND_ALWAYS))
|
|
|
|
|
&& !supportsAC3) {
|
|
|
|
|
formats.add(AUDIO_FORMAT_AC3);
|
|
|
|
|
supportsAC3 = true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// If ALWAYS, add support for raw surround formats if all are missing.
|
|
|
|
|
// This assumes that if any of these formats are reported by the HAL
|
|
|
|
|
// then the report is valid and should not be modified.
|
|
|
|
|
if (forceUse == AUDIO_POLICY_FORCE_ENCODED_SURROUND_ALWAYS) {
|
|
|
|
|
formats.add(AUDIO_FORMAT_E_AC3);
|
|
|
|
|
formats.add(AUDIO_FORMAT_DTS);
|
|
|
|
|
formats.add(AUDIO_FORMAT_DTS_HD);
|
|
|
|
|
supportsOtherSurround = true;
|
|
|
|
|
break;
|
|
|
|
|
case AUDIO_FORMAT_IEC61937:
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Add support for IEC61937 if any raw surround supported.
|
|
|
|
|
// The HAL could do this but add it here, just in case.
|
|
|
|
|
if ((supportsAC3 || supportsOtherSurround) && !supportsIEC61937) {
|
|
|
|
|
formats.add(AUDIO_FORMAT_IEC61937);
|
|
|
|
|
supportsIEC61937 = true;
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Modify formats based on surround preferences.
|
|
|
|
|
// If NEVER, remove support for surround formats.
|
|
|
|
|
if (forceUse == AUDIO_POLICY_FORCE_ENCODED_SURROUND_NEVER) {
|
|
|
|
|
if (supportsAC3 || supportsOtherSurround || supportsIEC61937) {
|
|
|
|
|
// Remove surround sound related formats.
|
|
|
|
|
for (size_t formatIndex = 0; formatIndex < formats.size(); ) {
|
|
|
|
|
// Add reported surround sound formats to enabled surround formats.
|
|
|
|
|
for (size_t formatIndex = 0; formatIndex < formats.size(); formatIndex++) {
|
|
|
|
|
audio_format_t format = formats[formatIndex];
|
|
|
|
|
switch(format) {
|
|
|
|
|
case AUDIO_FORMAT_AC3:
|
|
|
|
|
case AUDIO_FORMAT_E_AC3:
|
|
|
|
|
case AUDIO_FORMAT_DTS:
|
|
|
|
|
case AUDIO_FORMAT_DTS_HD:
|
|
|
|
|
case AUDIO_FORMAT_IEC61937:
|
|
|
|
|
formats.removeAt(formatIndex);
|
|
|
|
|
break;
|
|
|
|
|
case AUDIO_FORMAT_AAC_LC:
|
|
|
|
|
case AUDIO_FORMAT_DOLBY_TRUEHD:
|
|
|
|
|
case AUDIO_FORMAT_E_AC3_JOC:
|
|
|
|
|
mSurroundFormats.insert(format);
|
|
|
|
|
default:
|
|
|
|
|
formatIndex++; // keep it
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
supportsAC3 = false;
|
|
|
|
|
supportsOtherSurround = false;
|
|
|
|
|
supportsIEC61937 = false;
|
|
|
|
|
}
|
|
|
|
|
} else { // AUTO or ALWAYS
|
|
|
|
|
// Most TVs support AC3 even if they do not report it in the EDID.
|
|
|
|
|
if ((alwaysForceAC3 || (forceUse == AUDIO_POLICY_FORCE_ENCODED_SURROUND_ALWAYS))
|
|
|
|
|
&& !supportsAC3) {
|
|
|
|
|
formats.add(AUDIO_FORMAT_AC3);
|
|
|
|
|
supportsAC3 = true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// If ALWAYS, add support for raw surround formats if all are missing.
|
|
|
|
|
// This assumes that if any of these formats are reported by the HAL
|
|
|
|
|
// then the report is valid and should not be modified.
|
|
|
|
|
if (forceUse == AUDIO_POLICY_FORCE_ENCODED_SURROUND_ALWAYS) {
|
|
|
|
|
formats.add(AUDIO_FORMAT_E_AC3);
|
|
|
|
|
formats.add(AUDIO_FORMAT_DTS);
|
|
|
|
|
formats.add(AUDIO_FORMAT_DTS_HD);
|
|
|
|
|
supportsOtherSurround = true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Add support for IEC61937 if any raw surround supported.
|
|
|
|
|
// The HAL could do this but add it here, just in case.
|
|
|
|
|
if ((supportsAC3 || supportsOtherSurround) && !supportsIEC61937) {
|
|
|
|
|
formats.add(AUDIO_FORMAT_IEC61937);
|
|
|
|
|
supportsIEC61937 = true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
@ -5674,8 +5993,9 @@ void AudioPolicyManager::filterSurroundChannelMasks(ChannelsVector *channelMasks
|
|
|
|
|
maskIndex++;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
// If ALWAYS, then make sure we at least support 5.1
|
|
|
|
|
} else if (forceUse == AUDIO_POLICY_FORCE_ENCODED_SURROUND_ALWAYS) {
|
|
|
|
|
// If ALWAYS or MANUAL, then make sure we at least support 5.1
|
|
|
|
|
} else if (forceUse == AUDIO_POLICY_FORCE_ENCODED_SURROUND_ALWAYS
|
|
|
|
|
|| forceUse == AUDIO_POLICY_FORCE_ENCODED_SURROUND_MANUAL) {
|
|
|
|
|
bool supports5dot1 = false;
|
|
|
|
|
// Are there any channel masks that can be considered "surround"?
|
|
|
|
|
for (audio_channel_mask_t channelMask : channelMasks) {
|
|
|
|
@ -5702,7 +6022,7 @@ void AudioPolicyManager::updateAudioProfiles(audio_devices_t device,
|
|
|
|
|
if (profiles.hasDynamicFormat()) {
|
|
|
|
|
reply = mpClientInterface->getParameters(
|
|
|
|
|
ioHandle, String8(AudioParameter::keyStreamSupportedFormats));
|
|
|
|
|
ALOGV("%s: supported formats %s", __FUNCTION__, reply.string());
|
|
|
|
|
ALOGV("%s: supported formats %d, %s", __FUNCTION__, ioHandle, reply.string());
|
|
|
|
|
AudioParameter repliedParameters(reply);
|
|
|
|
|
if (repliedParameters.get(
|
|
|
|
|
String8(AudioParameter::keyStreamSupportedFormats), reply) != NO_ERROR) {
|
|
|
|
|