Audio Policy: Parametrize encoded formats supported by device
For various reasons, we need to store the list of audio
formats supported by devices. Here we add support for this
into DeviceDescriptor. We don't read them yet from
the APM config file, but we will eventually.
Also in this change, use the formats list for parametrizing
the behavior of surround sound configuration. The special
logic for AC3 and IEC69137 formats used to be hardcoded
into 'filterSurroundFormats' function, now it is
parametrized by the device descriptor information.
Fix behavior of 'filterSurroundFormats' in 'manual'
mode, where it was removing PCM formats from the list.
Rename 'filterSurround...' functions to 'modifySurround...'
since they can both add and remove items from the provided
list.
Bug: 67479735
Bug: 117602867
Test: compare A/B APM dumps while modifying Surround Sound
settings; tested with a HDMI sink that doesn't support
any surround, and with an AV receiver
Change-Id: Ie46480d5e9519366b1f3553645c9ca20f64bdc80
diff --git a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
index 1b088bb..c8dd362 100644
--- a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
+++ b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
@@ -36,6 +36,7 @@
#include <inttypes.h>
#include <math.h>
+#include <unordered_set>
#include <vector>
#include <AudioPolicyManagerInterface.h>
@@ -4114,7 +4115,7 @@
mpClientInterface->setParameters(output, String8(param));
free(param);
}
- updateAudioProfiles(device, output, profile->getAudioProfiles());
+ updateAudioProfiles(devDesc, output, profile->getAudioProfiles());
if (!profile->hasValidAudioProfile()) {
ALOGW("checkOutputsForDevice() missing param");
desc->close();
@@ -4322,7 +4323,7 @@
mpClientInterface->setParameters(input, String8(param));
free(param);
}
- updateAudioProfiles(device, input, profile->getAudioProfiles());
+ updateAudioProfiles(devDesc, input, profile->getAudioProfiles());
if (!profile->hasValidAudioProfile()) {
ALOGW("checkInputsForDevice() direct input missing param");
desc->close();
@@ -5661,117 +5662,65 @@
}
}
-// Modify the list of surround sound formats supported.
-void AudioPolicyManager::filterSurroundFormats(FormatVector *formatsPtr) {
- FormatVector &formats = *formatsPtr;
- // TODO Set this based on Config properties.
- const bool alwaysForceAC3 = true;
+void AudioPolicyManager::modifySurroundFormats(
+ const sp<DeviceDescriptor>& devDesc, FormatVector *formatsPtr) {
+ // Use a set because FormatVector is unsorted.
+ std::unordered_set<audio_format_t> enforcedSurround(
+ devDesc->encodedFormats().begin(), devDesc->encodedFormats().end());
audio_policy_forced_cfg_t forceUse = mEngine->getForceUse(
AUDIO_POLICY_FORCE_FOR_ENCODED_SURROUND);
ALOGD("%s: forced use = %d", __FUNCTION__, forceUse);
+ std::unordered_set<audio_format_t> formatSet;
+ if (forceUse == AUDIO_POLICY_FORCE_ENCODED_SURROUND_MANUAL
+ || forceUse == AUDIO_POLICY_FORCE_ENCODED_SURROUND_NEVER) {
+ // Only copy non-surround formats to formatSet.
+ for (auto formatIter = formatsPtr->begin(); formatIter != formatsPtr->end(); ++formatIter) {
+ if (mConfig.getSurroundFormats().count(*formatIter) == 0 &&
+ enforcedSurround.count(*formatIter) == 0) {
+ formatSet.insert(*formatIter);
+ }
+ }
+ } else {
+ formatSet.insert(formatsPtr->begin(), formatsPtr->end());
+ }
+ formatsPtr->clear(); // Re-filled from the formatSet in the end.
+
// 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);
+ formatSet.insert(mSurroundFormats.begin(), mSurroundFormats.end());
+ // Enable IEC61937 when in MANUAL mode if it's enforced for this device.
+ if (enforcedSurround.count(AUDIO_FORMAT_IEC61937) != 0) {
+ formatSet.insert(AUDIO_FORMAT_IEC61937);
}
- // 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 (forceUse != AUDIO_POLICY_FORCE_ENCODED_SURROUND_NEVER) { // AUTO or ALWAYS
// 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;
+ for (const auto& format : mConfig.getSurroundFormats()) {
+ formatSet.insert(format.first);
+ }
}
+ formatSet.insert(enforcedSurround.begin(), enforcedSurround.end());
- // 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;
- }
-
- // Add reported surround sound formats to enabled surround formats.
- for (size_t formatIndex = 0; formatIndex < formats.size(); formatIndex++) {
- audio_format_t format = formats[formatIndex];
+ for (const auto& format : formatSet) {
if (mConfig.getSurroundFormats().count(format) != 0) {
mSurroundFormats.insert(format);
}
}
}
}
+ for (const auto& format : formatSet) {
+ formatsPtr->push(format);
+ }
}
-// Modify the list of channel masks supported.
-void AudioPolicyManager::filterSurroundChannelMasks(ChannelsVector *channelMasksPtr) {
+void AudioPolicyManager::modifySurroundChannelMasks(ChannelsVector *channelMasksPtr) {
ChannelsVector &channelMasks = *channelMasksPtr;
audio_policy_forced_cfg_t forceUse = mEngine->getForceUse(
AUDIO_POLICY_FORCE_FOR_ENCODED_SURROUND);
@@ -5806,11 +5755,12 @@
}
}
-void AudioPolicyManager::updateAudioProfiles(audio_devices_t device,
+void AudioPolicyManager::updateAudioProfiles(const sp<DeviceDescriptor>& devDesc,
audio_io_handle_t ioHandle,
AudioProfileVector &profiles)
{
String8 reply;
+ audio_devices_t device = devDesc->type();
// Format MUST be checked first to update the list of AudioProfile
if (profiles.hasDynamicFormat()) {
@@ -5825,7 +5775,7 @@
}
FormatVector formats = formatsFromString(reply.string());
if (device == AUDIO_DEVICE_OUT_HDMI) {
- filterSurroundFormats(&formats);
+ modifySurroundFormats(devDesc, &formats);
}
profiles.setFormats(formats);
}
@@ -5858,7 +5808,7 @@
String8(AudioParameter::keyStreamSupportedChannels), reply) == NO_ERROR) {
channelMasks = channelMasksFromString(reply.string());
if (device == AUDIO_DEVICE_OUT_HDMI) {
- filterSurroundChannelMasks(&channelMasks);
+ modifySurroundChannelMasks(&channelMasks);
}
}
}