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

Commit 10b464cf authored by Eric Laurent's avatar Eric Laurent Committed by Android Git Automerger
Browse files

am 2b217bb3: Merge "audioflinger: fix pre processing transfer between record threads." into lmp-dev

* commit '2b217bb3':
  audioflinger: fix pre processing transfer between record threads.
parents c4fd8b3b 2b217bb3
Loading
Loading
Loading
Loading
+43 −5
Original line number Diff line number Diff line
@@ -1436,6 +1436,16 @@ sp<IAudioRecord> AudioFlinger::openRecord(
                                                  IPCThreadState::self()->getCallingUid(),
                                                  flags, tid, &lStatus);
        LOG_ALWAYS_FATAL_IF((lStatus == NO_ERROR) && (recordTrack == 0));

        if (lStatus == NO_ERROR) {
            // Check if one effect chain was awaiting for an AudioRecord to be created on this
            // session and move it to this thread.
            sp<EffectChain> chain = getOrphanEffectChain_l((audio_session_t)lSessionId);
            if (chain != 0) {
                Mutex::Autolock _l(thread->mLock);
                thread->addEffectChain_l(chain);
            }
        }
    }

    if (lStatus != NO_ERROR) {
@@ -2034,14 +2044,41 @@ status_t AudioFlinger::closeInput_nonvirtual(audio_io_handle_t input)
        }

        ALOGV("closeInput() %d", input);
        {

        // If we still have effect chains, it means that a client still holds a handle
            // on at least one effect. We must keep the chain alive in case a new record
            // thread is opened for a new capture on the same session
        // on at least one effect. We must either move the chain to an existing thread with the
        // same session ID or put it aside in case a new record thread is opened for a
        // new capture on the same session
        sp<EffectChain> chain;
        {
            Mutex::Autolock _sl(thread->mLock);
            Vector< sp<EffectChain> > effectChains = thread->getEffectChains_l();
            for (size_t i = 0; i < effectChains.size(); i++) {
                putOrphanEffectChain_l(effectChains[i]);
            // Note: maximum one chain per record thread
            if (effectChains.size() != 0) {
                chain = effectChains[0];
            }
        }
        if (chain != 0) {
            // first check if a record thread is already opened with a client on the same session.
            // This should only happen in case of overlap between one thread tear down and the
            // creation of its replacement
            size_t i;
            for (i = 0; i < mRecordThreads.size(); i++) {
                sp<RecordThread> t = mRecordThreads.valueAt(i);
                if (t == thread) {
                    continue;
                }
                if (t->hasAudioSession(chain->sessionId()) != 0) {
                    Mutex::Autolock _l(t->mLock);
                    ALOGV("closeInput() found thread %d for effect session %d",
                          t->id(), chain->sessionId());
                    t->addEffectChain_l(chain);
                    break;
                }
            }
            // put the chain aside if we could not find a record thread with the same session id.
            if (i == mRecordThreads.size()) {
                putOrphanEffectChain_l(chain);
            }
        }
        audioConfigChanged(AudioSystem::INPUT_CLOSED, input, NULL);
@@ -2478,6 +2515,7 @@ sp<IEffect> AudioFlinger::createEffect(
            // session and used it instead of creating a new one.
            sp<EffectChain> chain = getOrphanEffectChain_l((audio_session_t)sessionId);
            if (chain != 0) {
                Mutex::Autolock _l(thread->mLock);
                thread->addEffectChain_l(chain);
            }
        }
+26 −10
Original line number Diff line number Diff line
@@ -440,6 +440,20 @@ status_t AudioFlinger::EffectModule::init()
    return status;
}

void AudioFlinger::EffectModule::addEffectToHal_l()
{
    if ((mDescriptor.flags & EFFECT_FLAG_TYPE_MASK) == EFFECT_FLAG_TYPE_PRE_PROC ||
         (mDescriptor.flags & EFFECT_FLAG_TYPE_MASK) == EFFECT_FLAG_TYPE_POST_PROC) {
        sp<ThreadBase> thread = mThread.promote();
        if (thread != 0) {
            audio_stream_t *stream = thread->stream();
            if (stream != NULL) {
                stream->add_audio_effect(stream, mEffectInterface);
            }
        }
    }
}

status_t AudioFlinger::EffectModule::start()
{
    Mutex::Autolock _l(mLock);
@@ -466,16 +480,7 @@ status_t AudioFlinger::EffectModule::start_l()
        status = cmdStatus;
    }
    if (status == 0) {
        if ((mDescriptor.flags & EFFECT_FLAG_TYPE_MASK) == EFFECT_FLAG_TYPE_PRE_PROC ||
             (mDescriptor.flags & EFFECT_FLAG_TYPE_MASK) == EFFECT_FLAG_TYPE_POST_PROC) {
            sp<ThreadBase> thread = mThread.promote();
            if (thread != 0) {
                audio_stream_t *stream = thread->stream();
                if (stream != NULL) {
                    stream->add_audio_effect(stream, mEffectInterface);
                }
            }
        }
        addEffectToHal_l();
        sp<EffectChain> chain = mChain.promote();
        if (chain != 0) {
            chain->forceVolume();
@@ -1696,6 +1701,17 @@ bool AudioFlinger::EffectChain::setVolume_l(uint32_t *left, uint32_t *right)
    return hasControl;
}

void AudioFlinger::EffectChain::syncHalEffectsState()
{
    Mutex::Autolock _l(mLock);
    for (size_t i = 0; i < mEffects.size(); i++) {
        if (mEffects[i]->state() == EffectModule::ACTIVE ||
                mEffects[i]->state() == EffectModule::STOPPING) {
            mEffects[i]->addEffectToHal_l();
        }
    }
}

void AudioFlinger::EffectChain::dump(int fd, const Vector<String16>& args)
{
    const size_t SIZE = 256;
+3 −0
Original line number Diff line number Diff line
@@ -119,6 +119,7 @@ public:
                        { return (mDescriptor.flags & EFFECT_FLAG_OFFLOAD_SUPPORTED) != 0; }
    status_t         setOffloaded(bool offloaded, audio_io_handle_t io);
    bool             isOffloaded() const;
    void             addEffectToHal_l();

    void             dump(int fd, const Vector<String16>& args);

@@ -325,6 +326,8 @@ public:
    // we are the only observers.
    bool isVolumeForced() { return (android_atomic_acquire_cas(true, false, &mForceVolume) == 0); }

    void syncHalEffectsState();

    void dump(int fd, const Vector<String16>& args);

protected:
+4 −0
Original line number Diff line number Diff line
@@ -6207,6 +6207,10 @@ status_t AudioFlinger::RecordThread::addEffectChain_l(const sp<EffectChain>& cha

    checkSuspendOnAddEffectChain_l(chain);

    // make sure enabled pre processing effects state is communicated to the HAL as we
    // just moved them to a new input stream.
    chain->syncHalEffectsState();

    mEffectChains.add(chain);

    return NO_ERROR;