Merge "Add support for manually set surround formats." into pi-dev am: f824853eab

am: 0e66c708f9

Change-Id: If0fb97fcf33cb8b1b712238102d17f2c84c24f38
gugelfrei
Jiabin Huang 6 years ago committed by android-build-merger
commit f38ae75e82

@ -1286,6 +1286,24 @@ status_t AudioSystem::getMicrophones(std::vector<media::MicrophoneInfo> *microph
return af->getMicrophones(microphones);
}
status_t AudioSystem::getSurroundFormats(unsigned int *numSurroundFormats,
audio_format_t *surroundFormats,
bool *surroundFormatsEnabled,
bool reported)
{
const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
if (aps == 0) return PERMISSION_DENIED;
return aps->getSurroundFormats(
numSurroundFormats, surroundFormats, surroundFormatsEnabled, reported);
}
status_t AudioSystem::setSurroundFormatEnabled(audio_format_t audioFormat, bool enabled)
{
const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
if (aps == 0) return PERMISSION_DENIED;
return aps->setSurroundFormatEnabled(audioFormat, enabled);
}
// ---------------------------------------------------------------------------
int AudioSystem::AudioPolicyServiceClient::addAudioPortCallback(

@ -80,7 +80,9 @@ enum {
SET_AUDIO_PORT_CALLBACK_ENABLED,
SET_MASTER_MONO,
GET_MASTER_MONO,
GET_STREAM_VOLUME_DB
GET_STREAM_VOLUME_DB,
GET_SURROUND_FORMATS,
SET_SURROUND_FORMAT_ENABLED
};
#define MAX_ITEMS_PER_LIST 1024
@ -829,6 +831,54 @@ public:
}
return reply.readFloat();
}
virtual status_t getSurroundFormats(unsigned int *numSurroundFormats,
audio_format_t *surroundFormats,
bool *surroundFormatsEnabled,
bool reported)
{
if (numSurroundFormats == NULL || (*numSurroundFormats != 0 &&
(surroundFormats == NULL || surroundFormatsEnabled == NULL))) {
return BAD_VALUE;
}
Parcel data, reply;
data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor());
unsigned int numSurroundFormatsReq = *numSurroundFormats;
data.writeUint32(numSurroundFormatsReq);
data.writeBool(reported);
status_t status = remote()->transact(GET_SURROUND_FORMATS, data, &reply);
if (status == NO_ERROR && (status = (status_t)reply.readInt32()) == NO_ERROR) {
*numSurroundFormats = reply.readUint32();
}
if (status == NO_ERROR) {
if (numSurroundFormatsReq > *numSurroundFormats) {
numSurroundFormatsReq = *numSurroundFormats;
}
if (numSurroundFormatsReq > 0) {
status = reply.read(surroundFormats,
numSurroundFormatsReq * sizeof(audio_format_t));
if (status != NO_ERROR) {
return status;
}
status = reply.read(surroundFormatsEnabled,
numSurroundFormatsReq * sizeof(bool));
}
}
return status;
}
virtual status_t setSurroundFormatEnabled(audio_format_t audioFormat, bool enabled)
{
Parcel data, reply;
data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor());
data.writeInt32(audioFormat);
data.writeBool(enabled);
status_t status = remote()->transact(SET_SURROUND_FORMAT_ENABLED, data, &reply);
if (status != NO_ERROR) {
return status;
}
return reply.readInt32();
}
};
IMPLEMENT_META_INTERFACE(AudioPolicyService, "android.media.IAudioPolicyService");
@ -883,7 +933,9 @@ status_t BnAudioPolicyService::onTransact(
case REGISTER_POLICY_MIXES:
case SET_MASTER_MONO:
case START_AUDIO_SOURCE:
case STOP_AUDIO_SOURCE: {
case STOP_AUDIO_SOURCE:
case GET_SURROUND_FORMATS:
case SET_SURROUND_FORMAT_ENABLED: {
if (multiuser_get_app_id(IPCThreadState::self()->getCallingUid()) >= AID_APP_START) {
ALOGW("%s: transaction %d received from PID %d unauthorized UID %d",
__func__, code, IPCThreadState::self()->getCallingPid(),
@ -1489,6 +1541,50 @@ status_t BnAudioPolicyService::onTransact(
return NO_ERROR;
}
case GET_SURROUND_FORMATS: {
CHECK_INTERFACE(IAudioPolicyService, data, reply);
unsigned int numSurroundFormatsReq = data.readUint32();
if (numSurroundFormatsReq > MAX_ITEMS_PER_LIST) {
numSurroundFormatsReq = MAX_ITEMS_PER_LIST;
}
bool reported = data.readBool();
unsigned int numSurroundFormats = numSurroundFormatsReq;
audio_format_t *surroundFormats = (audio_format_t *)calloc(
numSurroundFormats, sizeof(audio_format_t));
bool *surroundFormatsEnabled = (bool *)calloc(numSurroundFormats, sizeof(bool));
if (numSurroundFormatsReq > 0 &&
(surroundFormats == NULL || surroundFormatsEnabled == NULL)) {
free(surroundFormats);
free(surroundFormatsEnabled);
reply->writeInt32(NO_MEMORY);
return NO_ERROR;
}
status_t status = getSurroundFormats(
&numSurroundFormats, surroundFormats, surroundFormatsEnabled, reported);
reply->writeInt32(status);
if (status == NO_ERROR) {
reply->writeUint32(numSurroundFormats);
if (numSurroundFormatsReq > numSurroundFormats) {
numSurroundFormatsReq = numSurroundFormats;
}
reply->write(surroundFormats, numSurroundFormatsReq * sizeof(audio_format_t));
reply->write(surroundFormatsEnabled, numSurroundFormatsReq * sizeof(bool));
}
free(surroundFormats);
free(surroundFormatsEnabled);
return NO_ERROR;
}
case SET_SURROUND_FORMAT_ENABLED: {
CHECK_INTERFACE(IAudioPolicyService, data, reply);
audio_format_t audioFormat = (audio_format_t) data.readInt32();
bool enabled = data.readBool();
status_t status = setSurroundFormatEnabled(audioFormat, enabled);
reply->writeInt32(status);
return NO_ERROR;
}
default:
return BBinder::onTransact(code, data, reply, flags);
}

@ -340,6 +340,15 @@ public:
static status_t getMicrophones(std::vector<media::MicrophoneInfo> *microphones);
// numSurroundFormats holds the maximum number of formats and bool value allowed in the array.
// When numSurroundFormats is 0, surroundFormats and surroundFormatsEnabled will not be
// populated. The actual number of surround formats should be returned at numSurroundFormats.
static status_t getSurroundFormats(unsigned int *numSurroundFormats,
audio_format_t *surroundFormats,
bool *surroundFormatsEnabled,
bool reported);
static status_t setSurroundFormatEnabled(audio_format_t audioFormat, bool enabled);
// ----------------------------------------------------------------------------
class AudioPortCallback : public RefBase

@ -166,6 +166,12 @@ public:
virtual status_t getMasterMono(bool *mono) = 0;
virtual float getStreamVolumeDB(
audio_stream_type_t stream, int index, audio_devices_t device) = 0;
virtual status_t getSurroundFormats(unsigned int *numSurroundFormats,
audio_format_t *surroundFormats,
bool *surroundFormatsEnabled,
bool reported) = 0;
virtual status_t setSurroundFormatEnabled(audio_format_t audioFormat, bool enabled) = 0;
};

@ -245,6 +245,12 @@ public:
virtual float getStreamVolumeDB(
audio_stream_type_t stream, int index, audio_devices_t device) = 0;
virtual status_t getSurroundFormats(unsigned int *numSurroundFormats,
audio_format_t *surroundFormats,
bool *surroundFormatsEnabled,
bool reported) = 0;
virtual status_t setSurroundFormatEnabled(audio_format_t audioFormat, bool enabled) = 0;
virtual void setRecordSilenced(uid_t uid, bool silenced);
};

@ -148,7 +148,8 @@ status_t Engine::setForceUse(audio_policy_force_use_t usage, audio_policy_forced
case AUDIO_POLICY_FORCE_FOR_ENCODED_SURROUND:
if (config != AUDIO_POLICY_FORCE_NONE &&
config != AUDIO_POLICY_FORCE_ENCODED_SURROUND_NEVER &&
config != AUDIO_POLICY_FORCE_ENCODED_SURROUND_ALWAYS) {
config != AUDIO_POLICY_FORCE_ENCODED_SURROUND_ALWAYS &&
config != AUDIO_POLICY_FORCE_ENCODED_SURROUND_MANUAL) {
ALOGW("setForceUse() invalid config %d for ENCODED_SURROUND", config);
return BAD_VALUE;
}

@ -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) {

@ -18,6 +18,7 @@
#include <atomic>
#include <memory>
#include <unordered_set>
#include <stdint.h>
#include <sys/types.h>
@ -237,6 +238,12 @@ public:
virtual float getStreamVolumeDB(
audio_stream_type_t stream, int index, audio_devices_t device);
virtual status_t getSurroundFormats(unsigned int *numSurroundFormats,
audio_format_t *surroundFormats,
bool *surroundFormatsEnabled,
bool reported);
virtual status_t setSurroundFormatEnabled(audio_format_t audioFormat, bool enabled);
// return the strategy corresponding to a given stream type
routing_strategy getStrategy(audio_stream_type_t stream) const;
@ -596,11 +603,16 @@ protected:
// Audio Policy Engine Interface.
AudioPolicyManagerInterface *mEngine;
// Surround formats that are enabled.
std::unordered_set<audio_format_t> mSurroundFormats;
private:
// Add or remove AC3 DTS encodings based on user preferences.
void filterSurroundFormats(FormatVector *formatsPtr);
void filterSurroundChannelMasks(ChannelsVector *channelMasksPtr);
status_t getSupportedFormats(audio_io_handle_t ioHandle, FormatVector& formats);
// If any, resolve any "dynamic" fields of an Audio Profiles collection
void updateAudioProfiles(audio_devices_t device, audio_io_handle_t ioHandle,
AudioProfileVector &profiles);

@ -986,5 +986,28 @@ float AudioPolicyService::getStreamVolumeDB(
return mAudioPolicyManager->getStreamVolumeDB(stream, index, device);
}
status_t AudioPolicyService::getSurroundFormats(unsigned int *numSurroundFormats,
audio_format_t *surroundFormats,
bool *surroundFormatsEnabled,
bool reported)
{
if (mAudioPolicyManager == NULL) {
return NO_INIT;
}
Mutex::Autolock _l(mLock);
AutoCallerClear acc;
return mAudioPolicyManager->getSurroundFormats(numSurroundFormats, surroundFormats,
surroundFormatsEnabled, reported);
}
status_t AudioPolicyService::setSurroundFormatEnabled(audio_format_t audioFormat, bool enabled)
{
if (mAudioPolicyManager == NULL) {
return NO_INIT;
}
Mutex::Autolock _l(mLock);
AutoCallerClear acc;
return mAudioPolicyManager->setSurroundFormatEnabled(audioFormat, enabled);
}
} // namespace android

@ -203,6 +203,12 @@ public:
virtual float getStreamVolumeDB(
audio_stream_type_t stream, int index, audio_devices_t device);
virtual status_t getSurroundFormats(unsigned int *numSurroundFormats,
audio_format_t *surroundFormats,
bool *surroundFormatsEnabled,
bool reported);
virtual status_t setSurroundFormatEnabled(audio_format_t audioFormat, bool enabled);
status_t doStopOutput(audio_io_handle_t output,
audio_stream_type_t stream,
audio_session_t session);

Loading…
Cancel
Save