Merge "PatchPanel: Fix crash when tearing down "pass thru" software patch"

am: f27d1e474b

Change-Id: I45c0bd9b3efee1d02f8cf92eb468e4ca8ce7982d
gugelfrei
Mikhail Naganov 5 years ago committed by android-build-merger
commit 8a56a515b3

@ -496,10 +496,12 @@ status_t AudioFlinger::PatchPanel::Patch::createConnections(PatchPanel *panel)
}
sp<RecordThread::PatchRecord> tempRecordTrack;
const bool usePassthruPatchRecord =
(inputFlags & AUDIO_INPUT_FLAG_DIRECT) && (outputFlags & AUDIO_OUTPUT_FLAG_DIRECT);
const size_t playbackFrameCount = mPlayback.thread()->frameCount();
const size_t recordFrameCount = mRecord.thread()->frameCount();
size_t frameCount = 0;
if ((inputFlags & AUDIO_INPUT_FLAG_DIRECT) && (outputFlags & AUDIO_OUTPUT_FLAG_DIRECT)) {
if (usePassthruPatchRecord) {
// PassthruPatchRecord producesBufferOnDemand, so use
// maximum of playback and record thread framecounts
frameCount = std::max(playbackFrameCount, recordFrameCount);
@ -556,8 +558,14 @@ status_t AudioFlinger::PatchPanel::Patch::createConnections(PatchPanel *panel)
}
// tie playback and record tracks together
mRecord.setTrackAndPeer(tempRecordTrack, tempPatchTrack);
mPlayback.setTrackAndPeer(tempPatchTrack, tempRecordTrack);
// In the case of PassthruPatchRecord no I/O activity happens on RecordThread,
// everything is driven from PlaybackThread. Thus AudioBufferProvider methods
// of PassthruPatchRecord can only be called if the corresponding PatchTrack
// is alive. There is no need to hold a reference, and there is no need
// to clear it. In fact, since playback stopping is asynchronous, there is
// no proper time when clearing could be done.
mRecord.setTrackAndPeer(tempRecordTrack, tempPatchTrack, !usePassthruPatchRecord);
mPlayback.setTrackAndPeer(tempPatchTrack, tempRecordTrack, true /*holdReference*/);
// start capture and playback
mRecord.track()->start(AudioSystem::SYNC_EVENT_NONE, AUDIO_SESSION_NONE);

@ -128,18 +128,20 @@ public:
mCloseThread = closeThread;
}
template <typename T>
void setTrackAndPeer(const sp<TrackType>& track, const sp<T> &peer) {
void setTrackAndPeer(const sp<TrackType>& track, const sp<T> &peer, bool holdReference) {
mTrack = track;
mThread->addPatchTrack(mTrack);
mTrack->setPeerProxy(peer, true /* holdReference */);
mTrack->setPeerProxy(peer, holdReference);
mClearPeerProxy = holdReference;
}
void clearTrackPeer() { if (mTrack) mTrack->clearPeerProxy(); }
void clearTrackPeer() { if (mClearPeerProxy && mTrack) mTrack->clearPeerProxy(); }
void stopTrack() { if (mTrack) mTrack->stop(); }
void swap(Endpoint &other) noexcept {
using std::swap;
swap(mThread, other.mThread);
swap(mCloseThread, other.mCloseThread);
swap(mClearPeerProxy, other.mClearPeerProxy);
swap(mHandle, other.mHandle);
swap(mTrack, other.mTrack);
}
@ -151,6 +153,7 @@ public:
private:
sp<ThreadType> mThread;
bool mCloseThread = true;
bool mClearPeerProxy = true;
audio_patch_handle_t mHandle = AUDIO_PATCH_HANDLE_NONE;
sp<TrackType> mTrack;
};

Loading…
Cancel
Save