diff options
author | Roman Kiryanov <rkir@google.com> | 2022-06-18 00:52:47 +0000 |
---|---|---|
committer | Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com> | 2022-06-18 00:52:47 +0000 |
commit | 9401b7b1c1b0c89c399b080dd4cf9fce97594fb6 (patch) | |
tree | cf7bc26180e10744b26612c46d9dd30e97b1c18d | |
parent | 917eccbc3c26ac8fd7966afc837234982e850fb8 (diff) | |
parent | 5357dcd409732bd94dd192a13b6e1826a47b3004 (diff) | |
download | goldfish-9401b7b1c1b0c89c399b080dd4cf9fce97594fb6.tar.gz |
Protect frame counters in device_port_source am: 5357dcd409
Original change: https://googleplex-android-review.googlesource.com/c/device/generic/goldfish/+/18971364
Change-Id: I153d0448e5d07f2b76442aa4eac4a796856354b8
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 40d03bce..000b9732 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 "device_port_source.h" @@ -72,8 +73,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; @@ -82,26 +85,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); @@ -142,8 +147,8 @@ struct TinyalsaSource : public DevicePortSource { const size_t nZeroBytes = nZeroFrames * mFrameSize; writer(zeroes, nZeroBytes); - mSentFrames += nZeroFrames; bytesToRead -= nZeroBytes; + mSentFrames += nZeroFrames; } break; } @@ -200,15 +205,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 { @@ -224,8 +230,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; @@ -233,15 +241,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(); @@ -251,7 +260,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; @@ -269,25 +278,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) { |