-rw-r--r--[-rwxr-xr-x] | media/codec2/sfplugin/CCodecBufferChannel.cpp | 6 | ||||
-rw-r--r-- | media/codec2/sfplugin/CCodecBuffers.cpp | 36 | ||||
-rw-r--r-- | media/codec2/sfplugin/CCodecBuffers.h | 29 | ||||
-rw-r--r-- | services/oboeservice/AAudioServiceStreamBase.cpp | 20 |
diff --git a/media/codec2/sfplugin/CCodecBufferChannel.cpp b/media/codec2/sfplugin/CCodecBufferChannel.cpp index 9000467..d41a554 100755..100644 --- a/media/codec2/sfplugin/CCodecBufferChannel.cpp +++ b/media/codec2/sfplugin/CCodecBufferChannel.cpp @@ -672,6 +672,12 @@ void CCodecBufferChannel::feedInputBufferIfAvailableInternal() { if (numActiveSlots >= input->numSlots) { break; } + if (pipelineRoom <= input->buffers->numClientBuffers()) { + ALOGI("pipelineRoom(%zu) is <= numClientBuffers(%zu). " + "Not signalling any more buffers to client", + pipelineRoom, input->buffers->numClientBuffers()); + break; + } if (!input->buffers->requestNewBuffer(&index, &inBuffer)) { ALOGV("[%s] no new buffer available", mName); break; diff --git a/media/codec2/sfplugin/CCodecBuffers.cpp b/media/codec2/sfplugin/CCodecBuffers.cpp index bddaa9f..7a705b7 100644 --- a/media/codec2/sfplugin/CCodecBuffers.cpp +++ b/media/codec2/sfplugin/CCodecBuffers.cpp @@ -510,6 +510,14 @@ size_t FlexBuffersImpl::numComponentBuffers() const { }); } +size_t FlexBuffersImpl::numClientBuffers() const { + return std::count_if( + mBuffers.begin(), mBuffers.end(), + [](const Entry &entry) { + return entry.clientBuffer != nullptr; + }); +} + // BuffersArrayImpl void BuffersArrayImpl::initialize( @@ -656,6 +664,14 @@ size_t BuffersArrayImpl::arraySize() const { return mBuffers.size(); } +size_t BuffersArrayImpl::numClientBuffers() const { + return std::count_if( + mBuffers.begin(), mBuffers.end(), + [](const Entry &entry) { + return entry.ownedByClient; + }); +} + // InputBuffersArray void InputBuffersArray::initialize( @@ -702,6 +718,10 @@ size_t InputBuffersArray::numActiveSlots() const { return mImpl.numActiveSlots(); } +size_t InputBuffersArray::numClientBuffers() const { + return mImpl.numClientBuffers(); +} + sp<Codec2Buffer> InputBuffersArray::createNewBuffer() { return mAllocate(); } @@ -740,6 +760,10 @@ size_t SlotInputBuffers::numActiveSlots() const { return mImpl.numActiveSlots(); } +size_t SlotInputBuffers::numClientBuffers() const { + return mImpl.numClientBuffers(); +} + sp<Codec2Buffer> SlotInputBuffers::createNewBuffer() { return new DummyContainerBuffer{mFormat, nullptr}; } @@ -792,6 +816,10 @@ size_t LinearInputBuffers::numActiveSlots() const { return mImpl.numActiveSlots(); } +size_t LinearInputBuffers::numClientBuffers() const { + return mImpl.numClientBuffers(); +} + // static sp<Codec2Buffer> LinearInputBuffers::Alloc( const std::shared_ptr<C2BlockPool> &pool, const sp<AMessage> &format) { @@ -969,6 +997,10 @@ size_t GraphicMetadataInputBuffers::numActiveSlots() const { return mImpl.numActiveSlots(); } +size_t GraphicMetadataInputBuffers::numClientBuffers() const { + return mImpl.numClientBuffers(); +} + sp<Codec2Buffer> GraphicMetadataInputBuffers::createNewBuffer() { std::shared_ptr<C2Allocator> alloc; c2_status_t err = mStore->fetchAllocator(mPool->getAllocatorId(), &alloc); @@ -1034,6 +1066,10 @@ size_t GraphicInputBuffers::numActiveSlots() const { return mImpl.numActiveSlots(); } +size_t GraphicInputBuffers::numClientBuffers() const { + return mImpl.numClientBuffers(); +} + sp<Codec2Buffer> GraphicInputBuffers::createNewBuffer() { // TODO: read usage from intf C2MemoryUsage usage = { C2MemoryUsage::CPU_READ, C2MemoryUsage::CPU_WRITE }; diff --git a/media/codec2/sfplugin/CCodecBuffers.h b/media/codec2/sfplugin/CCodecBuffers.h index 4772ab5..8d3c6ab 100644 --- a/media/codec2/sfplugin/CCodecBuffers.h +++ b/media/codec2/sfplugin/CCodecBuffers.h @@ -146,6 +146,11 @@ public: */ sp<Codec2Buffer> cloneAndReleaseBuffer(const sp<MediaCodecBuffer> &buffer); + /** + * Return number of buffers are given to client but have not yet queued back. + */ + virtual size_t numClientBuffers() const = 0; + protected: virtual sp<Codec2Buffer> createNewBuffer() = 0; @@ -587,6 +592,11 @@ public: size_t numActiveSlots() const; /** + * Return number of buffers are given to client but have not yet queued back. + */ + size_t numClientBuffers() const; + + /** * Return the number of buffers that are sent to the component but not * returned back yet. */ @@ -712,6 +722,11 @@ public: */ size_t arraySize() const; + /** + * Return number of buffers are given to client but have not yet queued back. + */ + size_t numClientBuffers() const; + private: std::string mImplName; ///< name for debugging const char *mName; ///< C-string version of name @@ -767,6 +782,8 @@ public: size_t numActiveSlots() const final; + size_t numClientBuffers() const final; + protected: sp<Codec2Buffer> createNewBuffer() override; @@ -798,6 +815,8 @@ public: size_t numActiveSlots() const final; + size_t numClientBuffers() const final; + protected: sp<Codec2Buffer> createNewBuffer() final; @@ -828,6 +847,8 @@ public: size_t numActiveSlots() const final; + size_t numClientBuffers() const final; + protected: sp<Codec2Buffer> createNewBuffer() override; @@ -896,6 +917,8 @@ public: size_t numActiveSlots() const final; + size_t numClientBuffers() const final; + protected: sp<Codec2Buffer> createNewBuffer() override; @@ -926,6 +949,8 @@ public: size_t numActiveSlots() const final; + size_t numClientBuffers() const final; + protected: sp<Codec2Buffer> createNewBuffer() override; @@ -969,6 +994,10 @@ public: return 0u; } + size_t numClientBuffers() const final { + return 0u; + } + protected: sp<Codec2Buffer> createNewBuffer() override { return nullptr; diff --git a/services/oboeservice/AAudioServiceStreamBase.cpp b/services/oboeservice/AAudioServiceStreamBase.cpp index 663dae2..30deb5d 100644 --- a/services/oboeservice/AAudioServiceStreamBase.cpp +++ b/services/oboeservice/AAudioServiceStreamBase.cpp @@ -293,10 +293,6 @@ aaudio_result_t AAudioServiceStreamBase::pause_l() { .set(AMEDIAMETRICS_PROP_STATUS, (int32_t)result) .record(); }); - // Send it now because the timestamp gets rounded up when stopStream() is called below. - // Also we don't need the timestamps while we are shutting down. - sendCurrentTimestamp(); - result = stopTimestampThread(); if (result != AAUDIO_OK) { disconnect_l(); @@ -342,10 +338,12 @@ aaudio_result_t AAudioServiceStreamBase::stop_l() { setState(AAUDIO_STREAM_STATE_STOPPING); - // Send it now because the timestamp gets rounded up when stopStream() is called below. - // Also we don't need the timestamps while we are shutting down. - sendCurrentTimestamp(); // warning - this calls a virtual function + // Temporarily unlock because we are joining the timestamp thread and it may try + // to acquire mLock. + mLock.unlock(); result = stopTimestampThread(); + mLock.lock(); + if (result != AAUDIO_OK) { disconnect_l(); return result; @@ -410,10 +408,11 @@ void AAudioServiceStreamBase::run() { timestampScheduler.start(AudioClock::getNanoseconds()); int64_t nextTime = timestampScheduler.nextAbsoluteTime(); int32_t loopCount = 0; + aaudio_result_t result = AAUDIO_OK; while(mThreadEnabled.load()) { loopCount++; if (AudioClock::getNanoseconds() >= nextTime) { - aaudio_result_t result = sendCurrentTimestamp(); + result = sendCurrentTimestamp(); if (result != AAUDIO_OK) { ALOGE("%s() timestamp thread got result = %d", __func__, result); break; @@ -425,6 +424,11 @@ void AAudioServiceStreamBase::run() { AudioClock::sleepUntilNanoTime(nextTime); } } + // This was moved from the calls in stop_l() and pause_l(), which could cause a deadlock + // if it resulted in a call to disconnect. + if (result == AAUDIO_OK) { + (void) sendCurrentTimestamp(); + } ALOGD("%s() %s exiting after %d loops <<<<<<<<<<<<<< TIMESTAMPS", __func__, getTypeText(), loopCount); } |