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

Commit 813e2a74 authored by Eric Laurent's avatar Eric Laurent
Browse files

audioflinger: no effects on offloaded tracks

Invalidate offloaded tracks when an effect is enabled
so that the track is recreated in PCM mode and the effect
can be applied.
This is temporary until effect offloading is implemented.

Bug: 8174034.

Change-Id: I77b8b54a10db6cb8334be76d863ea7e720eaad09
parent 84b7fb0c
Loading
Loading
Loading
Loading
+39 −1
Original line number Diff line number Diff line
@@ -98,6 +98,11 @@ size_t AudioFlinger::mTeeSinkOutputFrames = kTeeSinkOutputFramesDefault;
size_t AudioFlinger::mTeeSinkTrackFrames = kTeeSinkTrackFramesDefault;
#endif

//TODO: remove when effect offload is implemented
// In order to avoid invalidating offloaded tracks each time a Visualizer is turned on and off
// we define a minimum time during which a global effect is considered enabled.
static const nsecs_t kMinGlobalEffectEnabletimeNs = seconds(7200);

// ----------------------------------------------------------------------------

static int load_audio_interface(const char *if_name, audio_hw_device_t **dev)
@@ -141,7 +146,8 @@ AudioFlinger::AudioFlinger()
      mMode(AUDIO_MODE_INVALID),
      mBtNrecIsOff(false),
      mIsLowRamDevice(true),
      mIsDeviceTypeKnown(false)
      mIsDeviceTypeKnown(false),
      mGlobalEffectEnableTime(0)
{
    getpid_cached = getpid();
    char value[PROPERTY_VALUE_MAX];
@@ -2314,6 +2320,38 @@ status_t AudioFlinger::moveEffectChain_l(int sessionId,
    return NO_ERROR;
}

bool AudioFlinger::isGlobalEffectEnabled_l()
{
    if (mGlobalEffectEnableTime != 0 &&
            ((systemTime() - mGlobalEffectEnableTime) < kMinGlobalEffectEnabletimeNs)) {
        return true;
    }

    for (size_t i = 0; i < mPlaybackThreads.size(); i++) {
        sp<EffectChain> ec =
                mPlaybackThreads.valueAt(i)->getEffectChain_l(AUDIO_SESSION_OUTPUT_MIX);
        if (ec != 0 && ec->isEnabled()) {
            return true;
        }
    }
    return false;
}

void AudioFlinger::onGlobalEffectEnable()
{
    Mutex::Autolock _l(mLock);

    mGlobalEffectEnableTime = systemTime();

    for (size_t i = 0; i < mPlaybackThreads.size(); i++) {
        sp<PlaybackThread> t = mPlaybackThreads.valueAt(i);
        if (t->mType == ThreadBase::OFFLOAD) {
            t->invalidateTracks(AUDIO_STREAM_MUSIC);
        }
    }

}

struct Entry {
#define MAX_NAME 32     // %Y%m%d%H%M%S_%d.wav
    char mName[MAX_NAME];
+6 −0
Original line number Diff line number Diff line
@@ -466,6 +466,10 @@ private:
                void        removeClient_l(pid_t pid);
                void        removeNotificationClient(pid_t pid);

                //TODO: remove when effect offload is implemented
                bool isGlobalEffectEnabled_l();
                void onGlobalEffectEnable();

    class AudioHwDevice {
    public:
        enum Flags {
@@ -641,6 +645,8 @@ public:
private:
    bool    mIsLowRamDevice;
    bool    mIsDeviceTypeKnown;
    //TODO: remove when effect offload is implemented
    nsecs_t mGlobalEffectEnableTime;  // when a global effect was last enabled
};

#undef INCLUDING_FROM_AUDIOFLINGER_H
+23 −11
Original line number Diff line number Diff line
@@ -593,17 +593,6 @@ status_t AudioFlinger::EffectModule::setEnabled_l(bool enabled)
                h->setEnabled(enabled);
            }
        }
//EL_FIXME not sure why this is needed?
//        sp<ThreadBase> thread = mThread.promote();
//        if (thread == 0) {
//            return NO_ERROR;
//        }
//
//        if ((thread->type() == ThreadBase::OFFLOAD) && (enabled)) {
//            PlaybackThread *p = (PlaybackThread *)thread.get();
//            ALOGV("setEnabled: Offload, invalidate tracks");
//            p->invalidateTracks(AUDIO_STREAM_MUSIC);
//        }
    }
    return NO_ERROR;
}
@@ -942,6 +931,17 @@ status_t AudioFlinger::EffectHandle::enable()
            thread->checkSuspendOnEffectEnabled(mEffect, false, mEffect->sessionId());
        }
        mEnabled = false;
    } else {
        //TODO: remove when effect offload is implemented
        if (thread != 0) {
            if ((thread->type() == ThreadBase::OFFLOAD)) {
                PlaybackThread *t = (PlaybackThread *)thread.get();
                t->invalidateTracks(AUDIO_STREAM_MUSIC);
            }
            if (mEffect->sessionId() == AUDIO_SESSION_OUTPUT_MIX) {
                thread->mAudioFlinger->onGlobalEffectEnable();
            }
        }
    }
    return status;
}
@@ -1728,4 +1728,16 @@ void AudioFlinger::EffectChain::checkSuspendOnEffectEnabled(const sp<EffectModul
    }
}

bool AudioFlinger::EffectChain::isEnabled()
{
    Mutex::Autolock _l(mLock);
    size_t size = mEffects.size();
    for (size_t i = 0; i < size; i++) {
        if (mEffects[i]->isEnabled()) {
            return true;
        }
    }
    return false;
}

}; // namespace android
+4 −0
Original line number Diff line number Diff line
@@ -303,6 +303,10 @@ public:

    void clearInputBuffer();

    // At least one effect in the chain is enabled
    bool isEnabled();


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

protected:
+11 −1
Original line number Diff line number Diff line
@@ -543,7 +543,17 @@ status_t AudioFlinger::PlaybackThread::Track::start(AudioSystem::sync_event_t ev

    sp<ThreadBase> thread = mThread.promote();
    if (thread != 0) {
        Mutex::Autolock _l(thread->mLock);
        //TODO: remove when effect offload is implemented
        if (isOffloaded()) {
            Mutex::Autolock _laf(thread->mAudioFlinger->mLock);
            Mutex::Autolock _lth(thread->mLock);
            sp<EffectChain> ec = thread->getEffectChain_l(mSessionId);
            if (thread->mAudioFlinger->isGlobalEffectEnabled_l() || (ec != 0 && ec->isEnabled())) {
                invalidate();
                return PERMISSION_DENIED;
            }
        }
        Mutex::Autolock _lth(thread->mLock);
        track_state state = mState;
        // here the track could be either new, or restarted
        // in both cases "unstop" the track