diff options
author | Roman Kiryanov <rkir@google.com> | 2022-06-18 01:17:28 +0000 |
---|---|---|
committer | Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com> | 2022-06-18 01:17:28 +0000 |
commit | 995f6354f7b87acd584b8b6a9807a4250ae27168 (patch) | |
tree | 28188e7025941bbffccc96bea081f237ef83502b | |
parent | c912b35a53e069bc8fdf809587e8db3a4f37d472 (diff) | |
parent | ec2dbaffc57fc7262c5fd10b97eac2a2d2d6449f (diff) | |
download | goldfish-995f6354f7b87acd584b8b6a9807a4250ae27168.tar.gz |
Protect frame counters in device_port_source am: 5357dcd409 am: ec2dbaffc5
Original change: https://googleplex-android-review.googlesource.com/c/device/generic/goldfish/+/18971364
Change-Id: I3ded2af8c3712048d850556ee0f1ffa683e11722
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
-rw-r--r-- | audio/device_port_source.cpp | 55 |
1 files changed, 33 insertions, 22 deletions
diff --git a/audio/device_port_source.cpp b/audio/device_port_source.cpp index 0d51efd1..e4c4528b 100644 --- a/audio/device_port_source.cpp +++ b/audio/device_port_source.cpp @@ -22,6 +22,7 @@ #include <audio_utils/channels.h> #include <audio_utils/format.h> #include <log/log.h> +#include <utils/Mutex.h> #include <utils/ThreadDefs.h> #include <utils/Timers.h> #include PATH(APM_XSD_ENUMS_H_FILENAME) @@ -77,8 +78,10 @@ struct TinyalsaSource : public DevicePortSource { } Result getCapturePosition(uint64_t &frames, uint64_t &time) override { + const AutoMutex lock(mFrameCountersMutex); + const nsecs_t nowNs = systemTime(SYSTEM_TIME_MONOTONIC); - const uint64_t nowFrames = getCaptureFrames(nowNs); + const uint64_t nowFrames = getCaptureFramesLocked(nowNs); mFrames += (nowFrames - mPreviousFrames); mPreviousFrames = nowFrames; @@ -87,26 +90,28 @@ struct TinyalsaSource : public DevicePortSource { return Result::OK; } - uint64_t getCaptureFrames(const nsecs_t nowNs) const { + uint64_t getCaptureFramesLocked(const nsecs_t nowNs) const { return uint64_t(mSampleRateHz) * ns2us(nowNs - mStartNs) / 1000000; } - uint64_t getAvailableFrames(const nsecs_t nowNs) const { - return getCaptureFrames(nowNs) - mSentFrames; + uint64_t getAvailableFramesLocked(const nsecs_t nowNs) const { + return getCaptureFramesLocked(nowNs) - mSentFrames; } - uint64_t getAvailableFramesNow() const { - return getAvailableFrames(systemTime(SYSTEM_TIME_MONOTONIC)); + uint64_t getAvailableFramesNowLocked() const { + return getAvailableFramesLocked(systemTime(SYSTEM_TIME_MONOTONIC)); } - size_t getWaitFramesNow(const size_t requestedFrames) const { - const size_t availableFrames = getAvailableFramesNow(); + size_t getWaitFramesNowLocked(const size_t requestedFrames) const { + const size_t availableFrames = getAvailableFramesNowLocked(); return (requestedFrames > availableFrames) ? (requestedFrames - availableFrames) : 0; } size_t read(float volume, size_t bytesToRead, IWriter &writer) override { - const size_t waitFrames = getWaitFramesNow(bytesToRead / mFrameSize); + const AutoMutex lock(mFrameCountersMutex); + + const size_t waitFrames = getWaitFramesNowLocked(bytesToRead / mFrameSize); const auto blockUntil = std::chrono::high_resolution_clock::now() + + std::chrono::microseconds(waitFrames * 1000000 / mSampleRateHz); @@ -147,8 +152,8 @@ struct TinyalsaSource : public DevicePortSource { const size_t nZeroBytes = nZeroFrames * mFrameSize; writer(zeroes, nZeroBytes); - mSentFrames += nZeroFrames; bytesToRead -= nZeroBytes; + mSentFrames += nZeroFrames; } break; } @@ -205,15 +210,16 @@ private: const unsigned mSampleRateHz; const unsigned mFrameSize; const unsigned mReadSizeFrames; - uint64_t &mFrames; - uint64_t mPreviousFrames = 0; - uint64_t mSentFrames = 0; + uint64_t &mFrames GUARDED_BY(mFrameCountersMutex); + uint64_t mPreviousFrames GUARDED_BY(mFrameCountersMutex) = 0; + uint64_t mSentFrames GUARDED_BY(mFrameCountersMutex) = 0; std::atomic<uint32_t> mFramesLost = 0; RingBuffer mRingBuffer; talsa::Mixer mMixer; talsa::PcmPtr mPcm; std::thread mProduceThread; std::atomic<bool> mProduceThreadRunning = true; + mutable Mutex mFrameCountersMutex; }; template <class G> struct GeneratedSource : public DevicePortSource { @@ -229,8 +235,10 @@ template <class G> struct GeneratedSource : public DevicePortSource { , mGenerator(std::move(generator)) {} Result getCapturePosition(uint64_t &frames, uint64_t &time) override { + const AutoMutex lock(mFrameCountersMutex); + const nsecs_t nowNs = systemTime(SYSTEM_TIME_MONOTONIC); - const uint64_t nowFrames = getCaptureFrames(nowNs); + const uint64_t nowFrames = getCaptureFramesLocked(nowNs); mFrames += (nowFrames - mPreviousFrames); mPreviousFrames = nowFrames; frames = mFrames; @@ -238,15 +246,16 @@ template <class G> struct GeneratedSource : public DevicePortSource { return Result::OK; } - uint64_t getCaptureFrames(const nsecs_t nowNs) const { + uint64_t getCaptureFramesLocked(const nsecs_t nowNs) const { return uint64_t(mSampleRateHz) * ns2us(nowNs - mStartNs) / 1000000; } - uint64_t getAvailableFrames(const nsecs_t nowNs) const { - return getCaptureFrames(nowNs) - mSentFrames; + uint64_t getAvailableFramesLocked(const nsecs_t nowNs) const { + return getCaptureFramesLocked(nowNs) - mSentFrames; } size_t read(float volume, size_t bytesToRead, IWriter &writer) override { + const AutoMutex lock(mFrameCountersMutex); mWriteBuffer.resize(bytesToRead / sizeof(int16_t)); int16_t *samples = mWriteBuffer.data(); @@ -256,7 +265,7 @@ template <class G> struct GeneratedSource : public DevicePortSource { unsigned availableFrames; while (true) { const nsecs_t nowNs = systemTime(SYSTEM_TIME_MONOTONIC); - availableFrames = getAvailableFrames(nowNs); + availableFrames = getAvailableFramesLocked(nowNs); if (availableFrames < requestedFrames / 2) { const unsigned neededMoreFrames = requestedFrames / 2 - availableFrames; @@ -274,25 +283,27 @@ template <class G> struct GeneratedSource : public DevicePortSource { adjust_channels(samples, 1, samples, nChannels, sizeof(*samples), nFrames * sizeof(*samples)); } - mSentFrames += nFrames; aops::multiplyByVolume(volume, mWriteBuffer.data(), nSamples); writer(mWriteBuffer.data(), nSamples * sizeof(*samples)); + mSentFrames += nFrames; + return 0; } private: std::vector<int16_t> mWriteBuffer; - uint64_t &mFrames; + uint64_t &mFrames GUARDED_BY(mFrameCountersMutex); const nsecs_t mStartNs; const unsigned mSampleRateHz; const unsigned mNChannels; - uint64_t mPreviousFrames = 0; - uint64_t mSentFrames = 0; + uint64_t mPreviousFrames GUARDED_BY(mFrameCountersMutex) = 0; + uint64_t mSentFrames GUARDED_BY(mFrameCountersMutex) = 0; G mGenerator; + mutable Mutex mFrameCountersMutex; }; std::vector<int16_t> convertFloatsToInt16(const std::vector<float> &pcmFloat) { |