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

Commit 527b6a93 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Automerger Merge Worker
Browse files

Merge "Add MSD support for isDirectPlaybackSupported" into tm-dev am: c11ca9e3

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

Change-Id: If60e307ed514657f66083ff4f4b0446b049a1e58
parents 196849fd c11ca9e3
Loading
Loading
Loading
Loading
+94 −33
Original line number Diff line number Diff line
@@ -935,6 +935,32 @@ void AudioPolicyManager::setSystemProperty(const char* property, const char* val
    ALOGV("setSystemProperty() property %s, value %s", property, value);
}

// Find an MSD output profile compatible with the parameters passed.
// When "directOnly" is set, restrict search to profiles for direct outputs.
sp<IOProfile> AudioPolicyManager::getMsdProfileForOutput(
                                                   const DeviceVector& devices,
                                                   uint32_t samplingRate,
                                                   audio_format_t format,
                                                   audio_channel_mask_t channelMask,
                                                   audio_output_flags_t flags,
                                                   bool directOnly)
{
    flags = getRelevantFlags(flags, directOnly);

    sp<HwModule> msdModule = mHwModules.getModuleFromName(AUDIO_HARDWARE_MODULE_ID_MSD);
    if (msdModule != nullptr) {
        // for the msd module check if there are patches to the output devices
        if (msdHasPatchesToAllDevices(devices.toTypeAddrVector())) {
            HwModuleCollection modules;
            modules.add(msdModule);
            return searchCompatibleProfileHwModules(
                    modules, getMsdAudioOutDevices(), samplingRate, format, channelMask,
                    flags, directOnly);
        }
    }
    return nullptr;
}

// Find an output profile compatible with the parameters passed. When "directOnly" is set, restrict
// search to profiles for direct outputs.
sp<IOProfile> AudioPolicyManager::getProfileForOutput(
@@ -945,19 +971,35 @@ sp<IOProfile> AudioPolicyManager::getProfileForOutput(
                                                   audio_output_flags_t flags,
                                                   bool directOnly)
{
    flags = getRelevantFlags(flags, directOnly);

    return searchCompatibleProfileHwModules(
            mHwModules, devices, samplingRate, format, channelMask, flags, directOnly);
}

audio_output_flags_t AudioPolicyManager::getRelevantFlags (
                                            audio_output_flags_t flags, bool directOnly) {
    if (directOnly) {
         // only retain flags that will drive the direct output profile selection
         // if explicitly requested
         static const uint32_t kRelevantFlags =
                (AUDIO_OUTPUT_FLAG_HW_AV_SYNC | AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD |
                AUDIO_OUTPUT_FLAG_VOIP_RX | AUDIO_OUTPUT_FLAG_MMAP_NOIRQ);
        flags =
            (audio_output_flags_t)((flags & kRelevantFlags) | AUDIO_OUTPUT_FLAG_DIRECT);
         flags = (audio_output_flags_t)((flags & kRelevantFlags) | AUDIO_OUTPUT_FLAG_DIRECT);
    }
    return flags;
}

sp<IOProfile> AudioPolicyManager::searchCompatibleProfileHwModules (
                                        const HwModuleCollection& hwModules,
                                        const DeviceVector& devices,
                                        uint32_t samplingRate,
                                        audio_format_t format,
                                        audio_channel_mask_t channelMask,
                                        audio_output_flags_t flags,
                                        bool directOnly) {
    sp<IOProfile> profile;

    for (const auto& hwModule : mHwModules) {
    for (const auto& hwModule : hwModules) {
        for (const auto& curProfile : hwModule->getOutputProfiles()) {
             if (!curProfile->isCompatibleProfile(devices,
                     samplingRate, NULL /*updatedSamplingRate*/,
@@ -974,10 +1016,14 @@ sp<IOProfile> AudioPolicyManager::getProfileForOutput(
             if (!curProfile->devicesSupportEncodedFormats(devices.types())) {
                 continue;
             }
            if (!directOnly) return curProfile;
             if (!directOnly) {
                return curProfile;
             }

             // when searching for direct outputs, if several profiles are compatible, give priority
             // to one with offload capability
            if (profile != 0 && ((curProfile->getFlags() & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) == 0)) {
             if (profile != 0 && 
                 ((curProfile->getFlags() & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) == 0)) {
                continue;
             }
             profile = curProfile;
@@ -3820,7 +3866,22 @@ bool AudioPolicyManager::isDirectOutputSupported(const audio_config_base_t& conf
        __FUNCTION__, profile != 0 ? "" : "NOT ",
        (profile != 0 ? profile->getTagName().c_str() : "null"),
        config.sample_rate, config.format, config.channel_mask, output_flags);
    return (profile != 0);

    // also try the MSD module if compatible profile not found
    if (profile == nullptr) {
        profile = getMsdProfileForOutput(outputDevices,
                                              config.sample_rate,
                                              config.format,
                                              config.channel_mask,
                                              output_flags,
                                              true /* directOnly */);
        ALOGV("%s() MSD profile %sfound with name: %s, "
            "sample rate: %u, format: 0x%x, channel_mask: 0x%x, output flags: 0x%x",
            __FUNCTION__, profile != 0 ? "" : "NOT ",
            (profile != 0 ? profile->getTagName().c_str() : "null"),
            config.sample_rate, config.format, config.channel_mask, output_flags);
    }
    return (profile != nullptr);
}

bool AudioPolicyManager::isOffloadPossible(const audio_offload_info_t &offloadInfo,
+24 −0
Original line number Diff line number Diff line
@@ -768,6 +768,15 @@ protected:
                                          audio_channel_mask_t channelMask,
                                          audio_output_flags_t flags,
                                          bool directOnly);
        /**
        * Same as getProfileForOutput, but it looks for an MSD profile
        */
        sp<IOProfile> getMsdProfileForOutput(const DeviceVector &devices,
                                           uint32_t samplingRate,
                                           audio_format_t format,
                                           audio_channel_mask_t channelMask,
                                           audio_output_flags_t flags,
                                           bool directOnly);

        audio_io_handle_t selectOutputForMusicEffects();

@@ -1201,6 +1210,21 @@ private:
        // without duplicating them if already present
        void addPortProfilesToVector(sp<IOProfile> outputProfile,
                                    AudioProfileVector& audioProfilesVector);

        // Searches for a compatible profile with the sample rate, audio format and channel mask
        // in the list of passed HwModule(s).
        // returns a compatible profile if found, nullptr otherwise
        sp<IOProfile> searchCompatibleProfileHwModules (
                                            const HwModuleCollection& hwModules,
                                            const DeviceVector& devices,
                                            uint32_t samplingRate,
                                            audio_format_t format,
                                            audio_channel_mask_t channelMask,
                                            audio_output_flags_t flags,
                                            bool directOnly);

        // Filters only the relevant flags for getProfileForOutput
        audio_output_flags_t getRelevantFlags (audio_output_flags_t flags, bool directOnly);
};

};
+67 −0
Original line number Diff line number Diff line
@@ -699,6 +699,73 @@ TEST_P(AudioPolicyManagerTestMsd, GetDirectProfilesForAttributesWithMsd) {
    ASSERT_EQ(countDirectProfilesPrimary, getDirectProfilesForAttributes(attr).size());
}

TEST_P(AudioPolicyManagerTestMsd, IsDirectPlaybackSupportedWithMsd) {
    const audio_attributes_t attr = {
        AUDIO_CONTENT_TYPE_UNKNOWN, AUDIO_USAGE_UNKNOWN,
        AUDIO_SOURCE_DEFAULT, AUDIO_FLAG_NONE, ""};

    audio_config_base_t directConfig = AUDIO_CONFIG_BASE_INITIALIZER;
    directConfig.format = AUDIO_FORMAT_DTS;
    directConfig.sample_rate = 48000;
    directConfig.channel_mask = AUDIO_CHANNEL_OUT_5POINT1;

    audio_config_base_t nonDirectConfig = AUDIO_CONFIG_BASE_INITIALIZER;
    nonDirectConfig.format = AUDIO_FORMAT_PCM_16_BIT;
    nonDirectConfig.sample_rate = 48000;
    nonDirectConfig.channel_mask = AUDIO_CHANNEL_OUT_STEREO;

    audio_config_base_t nonExistentConfig = AUDIO_CONFIG_BASE_INITIALIZER;
    nonExistentConfig.format = AUDIO_FORMAT_E_AC3;
    nonExistentConfig.sample_rate = 48000;
    nonExistentConfig.channel_mask = AUDIO_CHANNEL_OUT_STEREO;

    audio_config_base_t msdDirectConfig1 = AUDIO_CONFIG_BASE_INITIALIZER;
    msdDirectConfig1.format = AUDIO_FORMAT_AC3;
    msdDirectConfig1.sample_rate = 48000;
    msdDirectConfig1.channel_mask = AUDIO_CHANNEL_OUT_5POINT1;

    audio_config_base_t msdDirectConfig2 = AUDIO_CONFIG_BASE_INITIALIZER;
    msdDirectConfig2.format = AUDIO_FORMAT_IEC60958;
    msdDirectConfig2.sample_rate = 48000;
    msdDirectConfig2.channel_mask = AUDIO_CHANNEL_OUT_STEREO;

    audio_config_base_t msdNonDirectConfig = AUDIO_CONFIG_BASE_INITIALIZER;
    msdNonDirectConfig.format = AUDIO_FORMAT_PCM_16_BIT;
    msdNonDirectConfig.sample_rate = 96000;
    msdNonDirectConfig.channel_mask = AUDIO_CHANNEL_OUT_STEREO;

    ASSERT_TRUE(mManager->isDirectOutputSupported(directConfig, attr));
    ASSERT_FALSE(mManager->isDirectOutputSupported(nonDirectConfig, attr));
    ASSERT_FALSE(mManager->isDirectOutputSupported(nonExistentConfig, attr));
    // before setting MSD patches the direct MSD configs return false
    ASSERT_FALSE(mManager->isDirectOutputSupported(msdDirectConfig1, attr));
    ASSERT_FALSE(mManager->isDirectOutputSupported(msdDirectConfig2, attr));
    ASSERT_FALSE(mManager->isDirectOutputSupported(msdNonDirectConfig, attr));

    DeviceVector outputDevices = mManager->getAvailableOutputDevices();
    // Remove MSD output device to avoid patching to itself
    outputDevices.remove(mMsdOutputDevice);
    mManager->setMsdOutputPatches(&outputDevices);

    ASSERT_TRUE(mManager->isDirectOutputSupported(directConfig, attr));
    ASSERT_FALSE(mManager->isDirectOutputSupported(nonDirectConfig, attr));
    ASSERT_FALSE(mManager->isDirectOutputSupported(nonExistentConfig, attr));
    // after setting MSD patches the direct MSD configs return true
    ASSERT_TRUE(mManager->isDirectOutputSupported(msdDirectConfig1, attr));
    ASSERT_TRUE(mManager->isDirectOutputSupported(msdDirectConfig2, attr));
    ASSERT_FALSE(mManager->isDirectOutputSupported(msdNonDirectConfig, attr));

    mManager->releaseMsdOutputPatches(outputDevices);

    ASSERT_TRUE(mManager->isDirectOutputSupported(directConfig, attr));
    ASSERT_FALSE(mManager->isDirectOutputSupported(nonDirectConfig, attr));
    ASSERT_FALSE(mManager->isDirectOutputSupported(nonExistentConfig, attr));
    // AFTER releasing MSD patches the direct MSD configs return false
    ASSERT_FALSE(mManager->isDirectOutputSupported(msdDirectConfig1, attr));
    ASSERT_FALSE(mManager->isDirectOutputSupported(msdDirectConfig2, attr));
    ASSERT_FALSE(mManager->isDirectOutputSupported(msdNonDirectConfig, attr));
}

class AudioPolicyManagerTestWithConfigurationFile : public AudioPolicyManagerTest {
protected:
    void SetUpManagerConfig() override;