Return HAL config in datapath for SwAudioOutputDescriptor
* AudioFlinger needs to return the HAL config opened by Spdif wrappers
so that AudioPolicyManager can patch with valid port configs.
* AudioPolicyManager openDirectOutput must allow for mismatch of config
between client request and APM output descriptor config because
AudioFlinger may format convert using Spdif wrapper.
* When finding or creating a mix port config in Hal2AidlWrapper, we
need to allow for a client request with DIRECT or IEC958_NONAUDIO
to match an output without these flags for remote submix, as the
remote submix HAL may not support those flags and they are not
necessary for correct remote submix operation.
* Do not use device port config to open stream as fall back for lack
of profile for opening non-PCM mix port config for remote submix,
because the remote submix HAL does not support non PCM.
Bug: 311830316
Test: atest android.media.audio.cts.LoopbackPassthroughTest
atest audiorouting_tests
atest VirtualAudioTest
(allowing for re-running of flaky tests)
pass on remote submix AIDL and HIDL HALs.
Change-Id: I216e5bde0db240c2119f63d896f5eecc01b3bd93
diff --git a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
index 8c9b17b..b9c193f 100644
--- a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
+++ b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
@@ -1613,11 +1613,16 @@
outputDesc->open(config, nullptr /* mixerConfig */, devices, stream, &flags, output,
attributes);
- // only accept an output with the requested parameters
+ // only accept an output with the requested parameters, unless the format can be IEC61937
+ // encapsulated and opened by AudioFlinger as wrapped IEC61937.
+ const bool ignoreRequestedParametersCheck = audio_is_iec61937_compatible(config->format)
+ && (flags & AUDIO_OUTPUT_FLAG_IEC958_NONAUDIO)
+ && audio_has_proportional_frames(outputDesc->getFormat());
if (status != NO_ERROR ||
- (config->sample_rate != 0 && config->sample_rate != outputDesc->getSamplingRate()) ||
- (config->format != AUDIO_FORMAT_DEFAULT && config->format != outputDesc->getFormat()) ||
- (config->channel_mask != 0 && config->channel_mask != outputDesc->getChannelMask())) {
+ (!ignoreRequestedParametersCheck &&
+ ((config->sample_rate != 0 && config->sample_rate != outputDesc->getSamplingRate()) ||
+ (config->format != AUDIO_FORMAT_DEFAULT && config->format != outputDesc->getFormat()) ||
+ (config->channel_mask != 0 && config->channel_mask != outputDesc->getChannelMask())))) {
ALOGV("%s failed opening direct output: output %d sample rate %d %d,"
"format %d %d, channel mask %04x %04x", __func__, *output, config->sample_rate,
outputDesc->getSamplingRate(), config->format, outputDesc->getFormat(),