Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 1bdf0f91 authored by Dean Wheatley's avatar Dean Wheatley Committed by Oscar Azucena
Browse files

Preference multichannel pcm direct output over stereo mixer

If a direct output is available for a multichannel output request,
and the mixer outputs a channel count lower than the track, try the
direct output first, and fall-back to the non-direct output if
not successful.

Bug: 238286324
Test: atest audiopolicy_tests:AudioPolicyManagerCarTest#GetOutputForAttrAtmosOutputAfterRegisteringPolicyMix
Change-Id: Ic7265bd09556ab7dd0660df5b307d151abace503
Merged-In: Ic7265bd09556ab7dd0660df5b307d151abace503
(cherry picked from commit ecbf2ee4)
parent 23ecfe45
Loading
Loading
Loading
Loading
+14 −6
Original line number Diff line number Diff line
@@ -1186,19 +1186,27 @@ status_t AudioPolicyManager::getOutputForAttrInt(
                                                  primaryMix->mDeviceAddress,
                                                  AUDIO_FORMAT_DEFAULT);
        sp<SwAudioOutputDescriptor> policyDesc = primaryMix->getOutput();
        if (deviceDesc != nullptr
                && (policyDesc == nullptr || (policyDesc->mFlags & AUDIO_OUTPUT_FLAG_DIRECT))) {
        bool tryDirectForFlags = policyDesc == nullptr ||
                (policyDesc->mFlags & AUDIO_OUTPUT_FLAG_DIRECT);
        // if a direct output can be opened to deliver the track's multi-channel content to the
        // output rather than being downmixed by the primary output, then use this direct
        // output by by-passing the primary mix if possible, otherwise fall-through to primary
        // mix.
        bool tryDirectForChannelMask = policyDesc != nullptr
                    && (audio_channel_count_from_out_mask(policyDesc->getConfig().channel_mask) <
                        audio_channel_count_from_out_mask(config->channel_mask));
        if (deviceDesc != nullptr && (tryDirectForFlags || tryDirectForChannelMask)) {
            audio_io_handle_t newOutput;
            status = openDirectOutput(
                    *stream, session, config,
                    (audio_output_flags_t)(*flags | AUDIO_OUTPUT_FLAG_DIRECT),
                    DeviceVector(deviceDesc), &newOutput);
            if (status != NO_ERROR) {
                policyDesc = nullptr;
            } else {
            if (status == NO_ERROR) {
                policyDesc = mOutputs.valueFor(newOutput);
                primaryMix->setOutput(policyDesc);
            }
            } else if (tryDirectForFlags) {
                policyDesc = nullptr;
            } // otherwise use primary if available.
        }
        if (policyDesc != nullptr) {
            policyDesc->mPolicyMix = primaryMix;
+13 −1
Original line number Diff line number Diff line
@@ -1733,7 +1733,7 @@ TEST_F(AudioPolicyManagerCarTest, Dump) {
    dumpToLog();
}

TEST_F(AudioPolicyManagerCarTest, GetOutputForAttrEncodedOutputAfterRegisteringPolicyMix) {
TEST_F(AudioPolicyManagerCarTest, GetOutputForAttrAtmosOutputAfterRegisteringPolicyMix) {
    status_t ret;
    audio_config_t audioConfig = AUDIO_CONFIG_INITIALIZER;
    const std::string kTestBusMediaOutput = "bus0_media_out";
@@ -1752,6 +1752,18 @@ TEST_F(AudioPolicyManagerCarTest, GetOutputForAttrEncodedOutputAfterRegisteringP
    ASSERT_EQ(AUDIO_FORMAT_E_AC3_JOC, outDesc->getFormat());
    ASSERT_EQ(AUDIO_CHANNEL_OUT_5POINT1, outDesc->getChannelMask());
    ASSERT_EQ(k48000SamplingRate, outDesc->getSamplingRate());

    selectedDeviceId = AUDIO_PORT_HANDLE_NONE;
    output = AUDIO_IO_HANDLE_NONE;
    portId = AUDIO_PORT_HANDLE_NONE;
    getOutputForAttr(&selectedDeviceId, AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_OUT_7POINT1POINT4,
            k48000SamplingRate, AUDIO_OUTPUT_FLAG_DIRECT, &output, &portId);
    ASSERT_NE(AUDIO_PORT_HANDLE_NONE, selectedDeviceId);
    outDesc = mManager->getOutputs().valueFor(output);
    ASSERT_NE(nullptr, outDesc.get());
    ASSERT_EQ(AUDIO_FORMAT_PCM_16_BIT, outDesc->getFormat());
    ASSERT_EQ(AUDIO_CHANNEL_OUT_7POINT1POINT4, outDesc->getChannelMask());
    ASSERT_EQ(k48000SamplingRate, outDesc->getSamplingRate());
}

class AudioPolicyManagerTVTest : public AudioPolicyManagerTestWithConfigurationFile {
+9 −1
Original line number Diff line number Diff line
@@ -55,6 +55,12 @@
                             samplingRates="48000"
                             channelMasks="AUDIO_CHANNEL_OUT_STEREO,AUDIO_CHANNEL_OUT_5POINT1"/>
                </mixPort>
                <mixPort name="mixport_bus0_media_out_atmos_pcm" role="source"
                        flags="AUDIO_OUTPUT_FLAG_DIRECT">
                    <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
                             samplingRates="48000"
                             channelMasks="AUDIO_CHANNEL_OUT_7POINT1POINT4"/>
                </mixPort>
                <mixPort name="mixport_bus1_navigation_out" role="source">
                    <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
                             samplingRates="48000"
@@ -129,6 +135,8 @@
                    <profile name="" format="AUDIO_FORMAT_E_AC3_JOC"
                            samplingRates="48000"
                            channelMasks="AUDIO_CHANNEL_OUT_STEREO,AUDIO_CHANNEL_OUT_5POINT1"/>
                    <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
                            samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_7POINT1POINT4"/>
                    <gains>
                        <gain name="" mode="AUDIO_GAIN_MODE_JOINT"
                                minValueMB="-3200" maxValueMB="600" defaultValueMB="0"
@@ -276,7 +284,7 @@
            <!-- route declaration, i.e. list all available sources for a given sink -->
            <routes>
                <route type="mix" sink="bus0_media_out"
                        sources="mixport_bus0_media_out,mixport_bus0_media_out_atmos"/>
                        sources="mixport_bus0_media_out,mixport_bus0_media_out_atmos,mixport_bus0_media_out_atmos_pcm"/>
                <route type="mix" sink="bus1_navigation_out" sources="mixport_bus1_navigation_out"/>
                <route type="mix" sink="bus2_voice_command_out"
                        sources="mixport_bus2_voice_command_out"/>