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

Commit 72eb7878 authored by Andy Hung's avatar Andy Hung Committed by Android (Google) Code Review
Browse files

Merge "AudioFlinger: Improve effect compatibility with RAW and FAST" into nyc-mr1-dev

parents 9dfbcea2 d3bb0adf
Loading
Loading
Loading
Loading
+39 −5
Original line number Diff line number Diff line
@@ -2032,16 +2032,50 @@ void AudioFlinger::EffectChain::setThread(const sp<ThreadBase>& thread)
    }
}

bool AudioFlinger::EffectChain::hasSoftwareEffect() const
void AudioFlinger::EffectChain::checkOutputFlagCompatibility(audio_output_flags_t *flags) const
{
    if ((*flags & AUDIO_OUTPUT_FLAG_RAW) != 0 && !isRawCompatible()) {
        *flags = (audio_output_flags_t)(*flags & ~AUDIO_OUTPUT_FLAG_RAW);
    }
    if ((*flags & AUDIO_OUTPUT_FLAG_FAST) != 0 && !isFastCompatible()) {
        *flags = (audio_output_flags_t)(*flags & ~AUDIO_OUTPUT_FLAG_FAST);
    }
}

void AudioFlinger::EffectChain::checkInputFlagCompatibility(audio_input_flags_t *flags) const
{
    if ((*flags & AUDIO_INPUT_FLAG_RAW) != 0 && !isRawCompatible()) {
        *flags = (audio_input_flags_t)(*flags & ~AUDIO_INPUT_FLAG_RAW);
    }
    if ((*flags & AUDIO_INPUT_FLAG_FAST) != 0 && !isFastCompatible()) {
        *flags = (audio_input_flags_t)(*flags & ~AUDIO_INPUT_FLAG_FAST);
    }
}

bool AudioFlinger::EffectChain::isRawCompatible() const
{
    Mutex::Autolock _l(mLock);
    for (size_t i = 0; i < mEffects.size(); i++) {
        if (mEffects[i]->isImplementationSoftware()) {
            return true;
    for (const auto &effect : mEffects) {
        if (effect->isProcessImplemented()) {
            return false;
        }
    }
    // Allow effects without processing.
    return true;
}

bool AudioFlinger::EffectChain::isFastCompatible() const
{
    Mutex::Autolock _l(mLock);
    for (const auto &effect : mEffects) {
        if (effect->isProcessImplemented()
                && effect->isImplementationSoftware()) {
            return false;
        }
    }
    // Allow effects without processing or hw accelerated effects.
    return true;
}

// isCompatibleWithThread_l() must be called with thread->mLock held
bool AudioFlinger::EffectChain::isCompatibleWithThread_l(const sp<ThreadBase>& thread) const
+11 −1
Original line number Diff line number Diff line
@@ -328,7 +328,17 @@ public:

    void syncHalEffectsState();

    bool hasSoftwareEffect() const;
    // flags is an ORed set of audio_output_flags_t which is updated on return.
    void checkOutputFlagCompatibility(audio_output_flags_t *flags) const;

    // flags is an ORed set of audio_input_flags_t which is updated on return.
    void checkInputFlagCompatibility(audio_input_flags_t *flags) const;

    // Is this EffectChain compatible with the RAW audio flag.
    bool isRawCompatible() const;

    // Is this EffectChain compatible with the FAST audio flag.
    bool isFastCompatible() const;

    // isCompatibleWithThread_l() must be called with thread->mLock held
    bool isCompatibleWithThread_l(const sp<ThreadBase>& thread) const;
+18 −34
Original line number Diff line number Diff line
@@ -1918,34 +1918,19 @@ sp<AudioFlinger::PlaybackThread::Track> AudioFlinger::PlaybackThread::createTrac
        // check compatibility with audio effects.
        { // scope for mLock
            Mutex::Autolock _l(mLock);
            // do not accept RAW flag if post processing are present. Note that post processing on
            // a fast mixer are necessarily hardware
            sp<EffectChain> chain = getEffectChain_l(AUDIO_SESSION_OUTPUT_STAGE);
            if (chain != 0) {
                ALOGV_IF((*flags & AUDIO_OUTPUT_FLAG_RAW) != 0,
                        "AUDIO_OUTPUT_FLAG_RAW denied: post processing effect present");
                *flags = (audio_output_flags_t)(*flags & ~AUDIO_OUTPUT_FLAG_RAW);
            }
            // Do not accept FAST flag if software global effects are present
            chain = getEffectChain_l(AUDIO_SESSION_OUTPUT_MIX);
            if (chain != 0) {
                ALOGV_IF((*flags & AUDIO_OUTPUT_FLAG_RAW) != 0,
                        "AUDIO_OUTPUT_FLAG_RAW denied: global effect present");
                *flags = (audio_output_flags_t)(*flags & ~AUDIO_OUTPUT_FLAG_RAW);
                if (chain->hasSoftwareEffect()) {
                    ALOGV("AUDIO_OUTPUT_FLAG_FAST denied: software global effect present");
                    *flags = (audio_output_flags_t)(*flags & ~AUDIO_OUTPUT_FLAG_FAST);
                }
            for (audio_session_t session : {
                    AUDIO_SESSION_OUTPUT_STAGE,
                    AUDIO_SESSION_OUTPUT_MIX,
                    sessionId,
                }) {
                sp<EffectChain> chain = getEffectChain_l(session);
                if (chain.get() != nullptr) {
                    audio_output_flags_t old = *flags;
                    chain->checkOutputFlagCompatibility(flags);
                    if (old != *flags) {
                        ALOGV("AUDIO_OUTPUT_FLAGS denied by effect, session=%d old=%#x new=%#x",
                                (int)session, (int)old, (int)*flags);
                    }
            // Do not accept FAST flag if the session has software effects
            chain = getEffectChain_l(sessionId);
            if (chain != 0) {
                ALOGV_IF((*flags & AUDIO_OUTPUT_FLAG_RAW) != 0,
                        "AUDIO_OUTPUT_FLAG_RAW denied: effect present on session");
                *flags = (audio_output_flags_t)(*flags & ~AUDIO_OUTPUT_FLAG_RAW);
                if (chain->hasSoftwareEffect()) {
                    ALOGV("AUDIO_OUTPUT_FLAG_FAST denied: software effect present on session");
                    *flags = (audio_output_flags_t)(*flags & ~AUDIO_OUTPUT_FLAG_FAST);
                }
            }
        }
@@ -6594,12 +6579,11 @@ sp<AudioFlinger::RecordThread::RecordTrack> AudioFlinger::RecordThread::createRe
          // Do not accept FAST flag if the session has software effects
          sp<EffectChain> chain = getEffectChain_l(sessionId);
          if (chain != 0) {
              ALOGV_IF((*flags & AUDIO_INPUT_FLAG_RAW) != 0,
                      "AUDIO_INPUT_FLAG_RAW denied: effect present on session");
              *flags = (audio_input_flags_t)(*flags & ~AUDIO_INPUT_FLAG_RAW);
              if (chain->hasSoftwareEffect()) {
                  ALOGV("AUDIO_INPUT_FLAG_FAST denied: software effect present on session");
                  *flags = (audio_input_flags_t)(*flags & ~AUDIO_INPUT_FLAG_FAST);
              audio_input_flags_t old = *flags;
              chain->checkInputFlagCompatibility(flags);
              if (old != *flags) {
                  ALOGV("AUDIO_INPUT_FLAGS denied by effect old=%#x new=%#x",
                          (int)old, (int)*flags);
              }
          }
          ALOGV_IF((*flags & AUDIO_INPUT_FLAG_FAST) != 0,