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

Commit 648452df authored by Presubmit Automerger Backend's avatar Presubmit Automerger Backend
Browse files

[automerge] AudioPolicy: several spatializer output management fixes 2p: d23aa163

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/av/+/17122763

Bug: 210803914
Change-Id: Ifc1968cad02c39efc6b766a6e2d351c274d0f3d1
Merged-In: I1c5ca3ce0a230d674f3a22fcb1fe1d904665efe9
parents a5783932 d23aa163
Loading
Loading
Loading
Loading
+5 −0
Original line number Diff line number Diff line
@@ -577,6 +577,11 @@ status_t SwAudioOutputDescriptor::open(const audio_config_t *halConfig,
    audio_output_flags_t halFlags = mFlags;
    if ((mFlags & AUDIO_OUTPUT_FLAG_SPATIALIZER) != 0) {
        halFlags = (audio_output_flags_t)(AUDIO_OUTPUT_FLAG_FAST | AUDIO_OUTPUT_FLAG_DEEP_BUFFER);
        // If no mixer config is specified for a spatializer output, default to 5.1 for proper
        // configuration of the final downmixer or spatializer
        if (mixerConfig == nullptr) {
            lMixerConfig.channel_mask = AUDIO_CHANNEL_OUT_5POINT1;
        }
    }

    ALOGV("opening output for device %s profile %p name %s",
+39 −34
Original line number Diff line number Diff line
@@ -1390,7 +1390,8 @@ audio_io_handle_t AudioPolicyManager::getOutputForDevices(
    }

    if (mSpatializerOutput != nullptr
            && canBeSpatialized(attr, config, devices.toTypeAddrVector())) {
            && canBeSpatializedInt(attr, config,
                    devices.toTypeAddrVector(), false /* allowCurrentOutputReconfig */)) {
        return mSpatializerOutput->mIoHandle;
    }

@@ -4882,9 +4883,10 @@ bool AudioPolicyManager::isChannelMaskSpatialized(audio_channel_mask_t channels)
    }
}

bool AudioPolicyManager::canBeSpatialized(const audio_attributes_t *attr,
bool AudioPolicyManager::canBeSpatializedInt(const audio_attributes_t *attr,
                                      const audio_config_t *config,
                                      const AudioDeviceTypeAddrVector &devices)  const
                                      const AudioDeviceTypeAddrVector &devices,
                                      bool allowCurrentOutputReconfig)  const
{
    // The caller can have the audio attributes criteria ignored by either passing a null ptr or
    // the AUDIO_ATTRIBUTES_INITIALIZER value.
@@ -4920,7 +4922,8 @@ bool AudioPolicyManager::canBeSpatialized(const audio_attributes_t *attr,
        if (!isChannelMaskSpatialized(config->channel_mask)) {
            return false;
        }
        if (mSpatializerOutput != nullptr && mSpatializerOutput->mProfile == profile) {
        if (!allowCurrentOutputReconfig && mSpatializerOutput != nullptr
                && mSpatializerOutput->mProfile == profile) {
            if ((config->channel_mask & mSpatializerOutput->mMixerChannelMask)
                    != config->channel_mask) {
                return false;
@@ -4941,7 +4944,8 @@ void AudioPolicyManager::checkVirtualizerClientRoutes() {
            audio_config_base_t clientConfig = client->config();
            audio_config_t config = audio_config_initializer(&clientConfig);
            if (desc != mSpatializerOutput
                    && canBeSpatialized(&attr, &config, devicesTypeAddress)) {
                    && canBeSpatializedInt(&attr, &config,
                            devicesTypeAddress, false /* allowCurrentOutputReconfig */)) {
                streamsToInvalidate.insert(client->stream());
            }
        }
@@ -4965,7 +4969,8 @@ status_t AudioPolicyManager::getSpatializerOutput(const audio_config_base_t *mix
        config = audio_config_initializer(mixerConfig);
        configPtr = &config;
    }
    if (!canBeSpatialized(attr, configPtr, devicesTypeAddress)) {
    if (!canBeSpatializedInt(
            attr, configPtr, devicesTypeAddress)) {
        ALOGW("%s provided attributes or mixer config cannot be spatialized", __func__);
        return BAD_VALUE;
    }
@@ -4988,6 +4993,7 @@ status_t AudioPolicyManager::getSpatializerOutput(const audio_config_base_t *mix
    for (size_t i = 0; i < mOutputs.size(); i++) {
        sp<SwAudioOutputDescriptor> desc = mOutputs.valueAt(i);
        if (!desc->isDuplicated() && desc->mProfile == profile) {
            ALOGV("%s found output %d for spatializer profile", __func__, desc->mIoHandle);
            mSpatializerOutput = desc;
            break;
        }
@@ -5007,39 +5013,29 @@ status_t AudioPolicyManager::getSpatializerOutput(const audio_config_base_t *mix
        };
        DeviceVector savedDevices = mSpatializerOutput->devices();

        ALOGV("%s reopening spatializer output to match channel mask %#x (current mask %#x)",
            __func__, configPtr->channel_mask, mSpatializerOutput->mMixerChannelMask);

        closeOutput(mSpatializerOutput->mIoHandle);
        mSpatializerOutput.clear();
        //from now on mSpatializerOutput is null

        const sp<SwAudioOutputDescriptor> desc =
                new SwAudioOutputDescriptor(profile, mpClientInterface);
        status_t status = desc->open(nullptr, mixerConfig, devices,
                                                    mEngine->getStreamTypeForAttributes(*attr),
                                                    AUDIO_OUTPUT_FLAG_SPATIALIZER, output);
        if (status != NO_ERROR) {
            ALOGW("%s failed opening output: status %d, output %d", __func__, status, *output);
            if (*output != AUDIO_IO_HANDLE_NONE) {
                desc->close();
            }
        sp<SwAudioOutputDescriptor> desc =
                openOutputWithProfileAndDevice(profile, devices, mixerConfig);
        if (desc == nullptr) {
            // re open the spatializer output with previous channel mask
            status_t newStatus = desc->open(nullptr, &savedMixerConfig, savedDevices,
                                mEngine->getStreamTypeForAttributes(*attr),
                                AUDIO_OUTPUT_FLAG_SPATIALIZER, output);
            if (newStatus != NO_ERROR) {
                if (*output != AUDIO_IO_HANDLE_NONE) {
                    desc->close();
                }
                ALOGE("%s failed to re-open mSpatializerOutput, status %d", __func__, newStatus);
            desc = openOutputWithProfileAndDevice(profile, savedDevices, &savedMixerConfig);
            if (desc == nullptr) {
                ALOGE("%s failed to restore mSpatializerOutput with previous config", __func__);
            } else {
                mSpatializerOutput = desc;
                addOutput(*output, desc);
            }
            mPreviousOutputs = mOutputs;
            mpClientInterface->onAudioPortListUpdate();
            *output = AUDIO_IO_HANDLE_NONE;
            return status;
            ALOGW("%s could not open spatializer output with requested config", __func__);
            return BAD_VALUE;
        }
        mSpatializerOutput = desc;
        addOutput(*output, desc);
        mPreviousOutputs = mOutputs;
        mpClientInterface->onAudioPortListUpdate();
    }
@@ -5711,6 +5707,9 @@ void AudioPolicyManager::closeOutput(audio_io_handle_t output)

    removeOutput(output);
    mPreviousOutputs = mOutputs;
    if (closingOutput == mSpatializerOutput) {
        mSpatializerOutput.clear();
    }

    // MSD patches may have been released to support a non-MSD direct output. Reset MSD patch if
    // no direct outputs are open.
@@ -7269,7 +7268,8 @@ bool AudioPolicyManager::areAllActiveTracksRerouted(const sp<SwAudioOutputDescri
}

sp<SwAudioOutputDescriptor> AudioPolicyManager::openOutputWithProfileAndDevice(
        const sp<IOProfile>& profile, const DeviceVector& devices)
        const sp<IOProfile>& profile, const DeviceVector& devices,
        const audio_config_base_t *mixerConfig)
{
    for (const auto& device : devices) {
        // TODO: This should be checking if the profile supports the device combo.
@@ -7279,7 +7279,7 @@ sp<SwAudioOutputDescriptor> AudioPolicyManager::openOutputWithProfileAndDevice(
    }
    sp<SwAudioOutputDescriptor> desc = new SwAudioOutputDescriptor(profile, mpClientInterface);
    audio_io_handle_t output = AUDIO_IO_HANDLE_NONE;
    status_t status = desc->open(nullptr /* halConfig */, nullptr /* mixerConfig */, devices,
    status_t status = desc->open(nullptr /* halConfig */, mixerConfig, devices,
            AUDIO_STREAM_DEFAULT, AUDIO_OUTPUT_FLAG_NONE, &output);
    if (status != NO_ERROR) {
        return nullptr;
@@ -7309,7 +7309,7 @@ sp<SwAudioOutputDescriptor> AudioPolicyManager::openOutputWithProfileAndDevice(
        config.offload_info.channel_mask = config.channel_mask;
        config.offload_info.format = config.format;

        status = desc->open(&config, nullptr /* mixerConfig */, devices,
        status = desc->open(&config, mixerConfig, devices,
                            AUDIO_STREAM_DEFAULT, AUDIO_OUTPUT_FLAG_NONE, &output);
        if (status != NO_ERROR) {
            return nullptr;
@@ -7317,6 +7317,7 @@ sp<SwAudioOutputDescriptor> AudioPolicyManager::openOutputWithProfileAndDevice(
    }

    addOutput(output, desc);

    if (audio_is_remote_submix_device(deviceType) && address != "0") {
        sp<AudioPolicyMix> policyMix;
        if (mPolicyMixes.getAudioPolicyMix(deviceType, address, policyMix) == NO_ERROR) {
@@ -7327,9 +7328,13 @@ sp<SwAudioOutputDescriptor> AudioPolicyManager::openOutputWithProfileAndDevice(
                    address.string());
        }

    } else if (((desc->mFlags & AUDIO_OUTPUT_FLAG_DIRECT) == 0) && hasPrimaryOutput()) {
        // no duplicated output for direct outputs and
        // outputs used by dynamic policy mixes
    } else if (hasPrimaryOutput() && profile->getModule()
                != mHwModules.getModuleFromName(AUDIO_HARDWARE_MODULE_ID_PRIMARY)
            && ((desc->mFlags & AUDIO_OUTPUT_FLAG_DIRECT) == 0)) {
        // no duplicated output for:
        // - direct outputs
        // - outputs used by dynamic policy mixes
        // - outputs opened on the primary HW module
        audio_io_handle_t duplicatedOutput = AUDIO_IO_HANDLE_NONE;

        //TODO: configure audio effect output stage here
+41 −3
Original line number Diff line number Diff line
@@ -358,7 +358,9 @@ public:

        virtual bool canBeSpatialized(const audio_attributes_t *attr,
                                      const audio_config_t *config,
                                      const AudioDeviceTypeAddrVector &devices) const;
                                      const AudioDeviceTypeAddrVector &devices) const {
            return canBeSpatializedInt(attr, config, devices);
        }

        virtual status_t getSpatializerOutput(const audio_config_base_t *config,
                                                const audio_attributes_t *attr,
@@ -991,6 +993,30 @@ private:
                const DeviceVector &devices,
                audio_io_handle_t *output);

        /**
         * @brief Queries if some kind of spatialization will be performed if the audio playback
         * context described by the provided arguments is present.
         * The context is made of:
         * - The audio attributes describing the playback use case.
         * - The audio configuration describing the audio format, channels, sampling rate ...
         * - The devices describing the sink audio device selected for playback.
         * All arguments are optional and only the specified arguments are used to match against
         * supported criteria. For instance, supplying no argument will tell if spatialization is
         * supported or not in general.
         * @param attr audio attributes describing the playback use case
         * @param config audio configuration describing the audio format, channels, sample rate...
         * @param devices the sink audio device selected for playback
         * @param allowCurrentOutputReconfig if true, the result will be considering it is possible
         *      to close and reopen an existing spatializer output stream to match the requested
         *      criteria. If false, the criteria must be compatible with the opened sptializer
         *      output.
         * @return true if spatialization is possible for this context, false otherwise.
         */
        virtual bool canBeSpatializedInt(const audio_attributes_t *attr,
                                      const audio_config_t *config,
                                      const AudioDeviceTypeAddrVector &devices,
                                      bool allowCurrentOutputReconfig = true) const;

        sp<IOProfile> getSpatializerOutputProfile(const audio_config_t *config,
                                                  const AudioDeviceTypeAddrVector &devices) const;

@@ -1086,8 +1112,20 @@ private:

        bool areAllActiveTracksRerouted(const sp<SwAudioOutputDescriptor>& output);

        sp<SwAudioOutputDescriptor> openOutputWithProfileAndDevice(const sp<IOProfile>& profile,
                                                                   const DeviceVector& devices);
        /**
         * @brief Opens an output stream from the supplied IOProfile and route it to the
         * supplied audio devices. If a mixer config is specified, it is forwarded to audio
         * flinger. If not, a default config is derived from the output stream config.
         * Also opens a duplicating output if needed and queries the audio HAL for supported
         * audio profiles if the IOProfile is dynamic.
         * @param[in] profile IOProfile to use as template
         * @param[in] devices initial route to apply to this output stream
         * @param[in] mixerConfig if not null, use this to configure the mixer
         * @return an output descriptor for the newly opened stream or null in case of error.
         */
        sp<SwAudioOutputDescriptor> openOutputWithProfileAndDevice(
                const sp<IOProfile>& profile, const DeviceVector& devices,
                const audio_config_base_t *mixerConfig = nullptr);

};

+2 −1
Original line number Diff line number Diff line
@@ -392,7 +392,8 @@ void AudioPolicyService::doOnCheckSpatializer()
            audio_config_base_t config = mSpatializer->getAudioInConfig();
            status_t status =
                    mAudioPolicyManager->getSpatializerOutput(&config, &attr, &newOutput);

            ALOGV("%s currentOutput %d newOutput %d channel_mask %#x",
                    __func__, currentOutput, newOutput, config.channel_mask);
            if (status == NO_ERROR && currentOutput == newOutput) {
                return;
            }
+1 −5
Original line number Diff line number Diff line
@@ -227,12 +227,8 @@ status_t Spatializer::loadEngineConfiguration(sp<EffectHalInterface> effect) {
    if (status != NO_ERROR) {
        return status;
    }
    status = getHalParameter<true>(effect, SPATIALIZER_PARAM_SUPPORTED_CHANNEL_MASKS,
    return getHalParameter<true>(effect, SPATIALIZER_PARAM_SUPPORTED_CHANNEL_MASKS,
                                 &mChannelMasks);
    if (status != NO_ERROR) {
        return status;
    }
    return NO_ERROR;
}

/** Gets the channel mask, sampling rate and format set for the spatializer input. */