From f130ad79e6b2beff56a1fcd4f218872513da1070 Mon Sep 17 00:00:00 2001 From: Emilian Peev Date: Thu, 11 Oct 2018 11:03:07 +0100 Subject: [PATCH] Camera: Consider the currently acquired input buffers The maximum acquired count of the input buffer queue during surface sharing should be set considering the total maximum acquired count of individual registered outputs and also the current acquired count of the input buffer queue. The reason the two can be different is due to the fact that individual outputs can acquire and also block buffers from the input. The latter portion contains all buffers which are still queued but not acquired. This can happen in case some output acquires the maximum amount of buffers possible then stops consuming entirely and the camera client continues to reference it in subsequent capture requests. To handle this, track the number of acquired buffers in the input queue and expand (or contract) the maximum acquired count only if possible. The maximum shouldn't change otherwise because the blocked buffers could still be used by the unresponsive output at some later point in time. Bug: 117982710 Test: Camera CTS Change-Id: Ia4e743efdf59cb0c9baaea492f78c37d0f2c95b3 --- .../device3/Camera3StreamSplitter.cpp | 27 ++++++++++++++----- .../device3/Camera3StreamSplitter.h | 3 +++ 2 files changed, 23 insertions(+), 7 deletions(-) diff --git a/services/camera/libcameraservice/device3/Camera3StreamSplitter.cpp b/services/camera/libcameraservice/device3/Camera3StreamSplitter.cpp index 8bc208dfa7..6d088428bd 100644 --- a/services/camera/libcameraservice/device3/Camera3StreamSplitter.cpp +++ b/services/camera/libcameraservice/device3/Camera3StreamSplitter.cpp @@ -83,8 +83,8 @@ status_t Camera3StreamSplitter::connect(const std::unordered_map& o return res; } - res = mConsumer->setMaxAcquiredBufferCount(mMaxConsumerBuffers+1); + if (mMaxConsumerBuffers > mAcquiredInputBuffers) { + res = mConsumer->setMaxAcquiredBufferCount(mMaxConsumerBuffers); + } return res; } @@ -266,10 +270,12 @@ status_t Camera3StreamSplitter::removeOutput(size_t surfaceId) { return res; } - res = mConsumer->setMaxAcquiredBufferCount(mMaxConsumerBuffers+1); - if (res != OK) { - SP_LOGE("%s: setMaxAcquiredBufferCount failed %d", __FUNCTION__, res); - return res; + if (mAcquiredInputBuffers < mMaxConsumerBuffers) { + res = mConsumer->setMaxAcquiredBufferCount(mMaxConsumerBuffers); + if (res != OK) { + SP_LOGE("%s: setMaxAcquiredBufferCount failed %d", __FUNCTION__, res); + return res; + } } return res; @@ -497,6 +503,7 @@ void Camera3StreamSplitter::onFrameAvailable(const BufferItem& /*item*/) { return; } + mAcquiredInputBuffers++; SP_LOGV("acquired buffer %" PRId64 " from input at slot %d", bufferItem.mGraphicBuffer->getId(), bufferItem.mSlot); @@ -599,6 +606,12 @@ void Camera3StreamSplitter::decrementBufRefCountLocked(uint64_t id, size_t surfa } else { SP_LOGE("%s: releaseBuffer returns %d", __FUNCTION__, res); } + } else { + if (mAcquiredInputBuffers == 0) { + ALOGW("%s: Acquired input buffer count already at zero!", __FUNCTION__); + } else { + mAcquiredInputBuffers--; + } } } diff --git a/services/camera/libcameraservice/device3/Camera3StreamSplitter.h b/services/camera/libcameraservice/device3/Camera3StreamSplitter.h index fea1bdb3d6..1eaf2bda16 100644 --- a/services/camera/libcameraservice/device3/Camera3StreamSplitter.h +++ b/services/camera/libcameraservice/device3/Camera3StreamSplitter.h @@ -269,6 +269,9 @@ private: // Latest onFrameAvailable return value std::atomic mOnFrameAvailableRes{0}; + // Currently acquired input buffers + size_t mAcquiredInputBuffers; + String8 mConsumerName; };