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

Commit fb47684b authored by Jiabin Huang's avatar Jiabin Huang
Browse files

Update tee patches in the thread loop.

When secondary output is updated, the tee patches need to
be updated. However, the mixer can access the tee patches
without any lock. In that case, updating tee patches in the
threadloop, which is before mixing, can help avoid race
condition.

Bug: 276314585
Test: manually
Test: atest AudioPlaybackCaptureTest
Change-Id: I36b5ae3777526942a31c7a3122a05477fce0b6df
Merged-In: I36b5ae3777526942a31c7a3122a05477fce0b6df
(cherry picked from commit bad75e93)
parent d8b8e3e9
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -3952,7 +3952,7 @@ void AudioFlinger::updateSecondaryOutputsForTrack_l(
        patchTrack->setPeerProxy(patchRecord, true /* holdReference */);
        patchRecord->setPeerProxy(patchTrack, false /* holdReference */);
    }
    track->setTeePatches(std::move(teePatches));
    track->setTeePatchesToUpdate(std::move(teePatches));
}

sp<AudioFlinger::SyncEvent> AudioFlinger::createSyncEvent(AudioSystem::sync_event_t type,
+4 −1
Original line number Diff line number Diff line
@@ -186,7 +186,9 @@ public:
            }
            sp<os::ExternalVibration> getExternalVibration() const { return mExternalVibration; }

            void    setTeePatches(TeePatches teePatches);
            // This function should be called with holding thread lock.
            void    updateTeePatches();
            void    setTeePatchesToUpdate(TeePatches teePatchesToUpdate);

    void tallyUnderrunFrames(size_t frames) override {
       if (isOut()) { // we expect this from output tracks only
@@ -369,6 +371,7 @@ private:
    bool                mPauseHwPending = false; // direct/offload track request for thread pause
    audio_output_flags_t mFlags;
    TeePatches  mTeePatches;
    std::optional<TeePatches> mTeePatchesToUpdate;
    const float         mSpeed;
    const bool          mIsSpatialized;
    const bool          mIsBitPerfect;
+4 −0
Original line number Diff line number Diff line
@@ -4104,6 +4104,10 @@ NO_THREAD_SAFETY_ANALYSIS // manual locking of AudioFlinger

            setHalLatencyMode_l();

            for (const auto &track : mActiveTracks ) {
                track->updateTeePatches();
            }

            // signal actual start of output stream when the render position reported by the kernel
            // starts moving.
            if (!mStandby && !mHalStarted && mKernelPositionOnStandby !=
+15 −6
Original line number Diff line number Diff line
@@ -1491,13 +1491,22 @@ void AudioFlinger::PlaybackThread::Track::copyMetadataTo(MetadataInserter& backI
    *backInserter++ = metadata;
}

void AudioFlinger::PlaybackThread::Track::setTeePatches(TeePatches teePatches) {
void AudioFlinger::PlaybackThread::Track::updateTeePatches() {
    if (mTeePatchesToUpdate.has_value()) {
        forEachTeePatchTrack([](auto patchTrack) { patchTrack->destroy(); });
    mTeePatches = std::move(teePatches);
        mTeePatches = mTeePatchesToUpdate.value();
        if (mState == TrackBase::ACTIVE || mState == TrackBase::RESUMING ||
                mState == TrackBase::STOPPING_1) {
            forEachTeePatchTrack([](auto patchTrack) { patchTrack->start(); });
        }
        mTeePatchesToUpdate.reset();
    }
}

void AudioFlinger::PlaybackThread::Track::setTeePatchesToUpdate(TeePatches teePatchesToUpdate) {
    ALOGW_IF(mTeePatchesToUpdate.has_value(),
             "%s, existing tee patches to update will be ignored", __func__);
    mTeePatchesToUpdate = std::move(teePatchesToUpdate);
}

// must be called with player thread lock held