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

Commit 01e0ee17 authored by Andy Hung's avatar Andy Hung Committed by android-build-merger
Browse files

Merge "VolumeShaper: Improve restore" into oc-dev am: abbb6772

am: 7dc9e283

Change-Id: If6df971ee7b860544e56ea90445fdfe650856b2f
parents c856d729 7dc9e283
Loading
Loading
Loading
Loading
+17 −5
Original line number Diff line number Diff line
@@ -528,6 +528,10 @@ public:
        mDelayXOffset = xOffset;
    }

    bool isStarted() const {
        return mStartFrame >= 0;
    }

    std::pair<T /* volume */, bool /* active */> getVolume(
            int64_t trackFrameCount, double trackSampleRate) {
        if ((getFlags() & VolumeShaper::Operation::FLAG_DELAY) != 0) {
@@ -752,6 +756,8 @@ public:
        return it->getState();
    }

    // getVolume() is not const, as it updates internal state.
    // Once called, any VolumeShapers not already started begin running.
    std::pair<T /* volume */, bool /* active */> getVolume(int64_t trackFrameCount) {
        AutoMutex _l(mLock);
        mLastFrame = trackFrameCount;
@@ -768,6 +774,14 @@ public:
        return mLastVolume;
    }

    // Used by a client side VolumeHandler to ensure all the VolumeShapers
    // indicate that they have been started.  Upon a change in audioserver
    // output sink, this information is used for restoration of the server side
    // VolumeHandler.
    void setStarted() {
        (void)getVolume(mLastFrame);  // getVolume() will start the individual VolumeShapers.
    }

    std::pair<T /* volume */, bool /* active */> getLastVolume() const {
        AutoMutex _l(mLock);
        return mLastVolume;
@@ -784,14 +798,12 @@ public:
        return ss.str();
    }

    void forall(const std::function<VolumeShaper::Status (
            const sp<VolumeShaper::Configuration> &configuration,
            const sp<VolumeShaper::Operation> &operation)> &lambda) {
    void forall(const std::function<VolumeShaper::Status (const VolumeShaper &)> &lambda) {
        AutoMutex _l(mLock);
        VS_LOG("forall: mVolumeShapers.size() %zu", mVolumeShapers.size());
        for (const auto &shaper : mVolumeShapers) {
            VS_LOG("forall applying lambda");
            (void)lambda(shaper.mConfiguration, shaper.mOperation);
            VolumeShaper::Status status = lambda(shaper);
            VS_LOG("forall applying lambda on shaper (%p): %d", &shaper, (int)status);
        }
    }

+32 −9
Original line number Diff line number Diff line
@@ -652,6 +652,9 @@ status_t AudioTrack::start()
            get_sched_policy(0, &mPreviousSchedulingGroup);
            androidSetThreadPriority(0, ANDROID_PRIORITY_AUDIO);
        }

        // Start our local VolumeHandler for restoration purposes.
        mVolumeHandler->setStarted();
    } else {
        ALOGE("start() status %d", status);
        mState = previousState;
@@ -2254,17 +2257,20 @@ status_t AudioTrack::restoreTrack_l(const char *from)
            }
        }
        // restore volume handler
        mVolumeHandler->forall([this](const sp<VolumeShaper::Configuration> &configuration,
                const sp<VolumeShaper::Operation> &operation) -> VolumeShaper::Status {
            sp<VolumeShaper::Operation> operationToEnd = new VolumeShaper::Operation(*operation);
        mVolumeHandler->forall([this](const VolumeShaper &shaper) -> VolumeShaper::Status {
            sp<VolumeShaper::Operation> operationToEnd =
                    new VolumeShaper::Operation(shaper.mOperation);
            // TODO: Ideally we would restore to the exact xOffset position
            // as returned by getVolumeShaperState(), but we don't have that
            // information when restoring at the client unless we periodically poll
            // the server or create shared memory state.
            //
            // For now, we simply advance to the end of the VolumeShaper effect.
            // For now, we simply advance to the end of the VolumeShaper effect
            // if it has been started.
            if (shaper.isStarted()) {
                operationToEnd->setXOffset(1.f);
            return mAudioTrack->applyVolumeShaper(configuration, operationToEnd);
            }
            return mAudioTrack->applyVolumeShaper(shaper.mConfiguration, operationToEnd);
        });

        if (mState == STATE_ACTIVE) {
@@ -2334,19 +2340,36 @@ VolumeShaper::Status AudioTrack::applyVolumeShaper(
    AutoMutex lock(mLock);
    mVolumeHandler->setIdIfNecessary(configuration);
    VolumeShaper::Status status = mAudioTrack->applyVolumeShaper(configuration, operation);

    if (status == DEAD_OBJECT) {
        if (restoreTrack_l("applyVolumeShaper") == OK) {
            status = mAudioTrack->applyVolumeShaper(configuration, operation);
        }
    }
    if (status >= 0) {
        // save VolumeShaper for restore
        mVolumeHandler->applyVolumeShaper(configuration, operation);
        if (mState == STATE_ACTIVE || mState == STATE_STOPPING) {
            mVolumeHandler->setStarted();
        }
    } else {
        // warn only if not an expected restore failure.
        ALOGW_IF(!((isOffloadedOrDirect_l() || mDoNotReconnect) && status == DEAD_OBJECT),
                "applyVolumeShaper failed: %d", status);
    }
    return status;
}

sp<VolumeShaper::State> AudioTrack::getVolumeShaperState(int id)
{
    // TODO: To properly restore the AudioTrack
    // we will need to save the last state in AudioTrackShared.
    AutoMutex lock(mLock);
    return mAudioTrack->getVolumeShaperState(id);
    sp<VolumeShaper::State> state = mAudioTrack->getVolumeShaperState(id);
    if (state.get() == nullptr && (mCblk->mFlags & CBLK_INVALID) != 0) {
        if (restoreTrack_l("getVolumeShaperState") == OK) {
            state = mAudioTrack->getVolumeShaperState(id);
        }
    }
    return state;
}

status_t AudioTrack::getTimestamp(ExtendedTimestamp *timestamp)
+31 −9
Original line number Diff line number Diff line
@@ -2029,12 +2029,23 @@ status_t MediaPlayerService::AudioOutput::open(
    ALOGV("setVolume");
    t->setVolume(mLeftVolume, mRightVolume);

    // Dispatch any queued VolumeShapers when the track was not open.
    mVolumeHandler->forall([&t](const sp<VolumeShaper::Configuration> &configuration,
            const sp<VolumeShaper::Operation> &operation) -> VolumeShaper::Status {
        return t->applyVolumeShaper(configuration, operation);
    // Restore VolumeShapers for the MediaPlayer in case the track was recreated
    // due to an output sink error (e.g. offload to non-offload switch).
    mVolumeHandler->forall([&t](const VolumeShaper &shaper) -> VolumeShaper::Status {
        sp<VolumeShaper::Operation> operationToEnd =
                new VolumeShaper::Operation(shaper.mOperation);
        // TODO: Ideally we would restore to the exact xOffset position
        // as returned by getVolumeShaperState(), but we don't have that
        // information when restoring at the client unless we periodically poll
        // the server or create shared memory state.
        //
        // For now, we simply advance to the end of the VolumeShaper effect
        // if it has been started.
        if (shaper.isStarted()) {
            operationToEnd->setXOffset(1.f);
        }
        return t->applyVolumeShaper(shaper.mConfiguration, operationToEnd);
    });
    mVolumeHandler->reset(); // After dispatching, clear VolumeShaper queue.

    mSampleRateHz = sampleRate;
    mFlags = flags;
@@ -2075,7 +2086,11 @@ status_t MediaPlayerService::AudioOutput::start()
    if (mTrack != 0) {
        mTrack->setVolume(mLeftVolume, mRightVolume);
        mTrack->setAuxEffectSendLevel(mSendLevel);
        return mTrack->start();
        status_t status = mTrack->start();
        if (status == NO_ERROR) {
            mVolumeHandler->setStarted();
        }
        return status;
    }
    return NO_INIT;
}
@@ -2279,13 +2294,20 @@ VolumeShaper::Status MediaPlayerService::AudioOutput::applyVolumeShaper(
    Mutex::Autolock lock(mLock);
    ALOGV("AudioOutput::applyVolumeShaper");

    // We take ownership of the VolumeShaper if set before the track is created.
    mVolumeHandler->setIdIfNecessary(configuration);

    VolumeShaper::Status status;
    if (mTrack != 0) {
        return mTrack->applyVolumeShaper(configuration, operation);
        status = mTrack->applyVolumeShaper(configuration, operation);
        if (status >= 0) {
            (void)mVolumeHandler->applyVolumeShaper(configuration, operation);
            // TODO: start on exact AudioTrack state (STATE_ACTIVE || STATE_STOPPING)
            mVolumeHandler->setStarted();
        }
    } else {
        return mVolumeHandler->applyVolumeShaper(configuration, operation);
        status = mVolumeHandler->applyVolumeShaper(configuration, operation);
    }
    return status;
}

sp<VolumeShaper::State> MediaPlayerService::AudioOutput::getVolumeShaperState(int id)