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
gugelfrei
Emilian Peev 6 years ago
parent efd99ec863
commit f130ad79e6

@ -83,8 +83,8 @@ status_t Camera3StreamSplitter::connect(const std::unordered_map<size_t, sp<Surf
// from input, and attached to the outputs. In this case, the input queue's
// dequeueBuffer can still allocate 1 extra buffer before being blocked by
// the output's attachBuffer().
mBufferItemConsumer = new BufferItemConsumer(mConsumer, consumerUsage,
mMaxConsumerBuffers+1);
mMaxConsumerBuffers++;
mBufferItemConsumer = new BufferItemConsumer(mConsumer, consumerUsage, mMaxConsumerBuffers);
if (mBufferItemConsumer == nullptr) {
return NO_MEMORY;
}
@ -108,6 +108,7 @@ status_t Camera3StreamSplitter::connect(const std::unordered_map<size_t, sp<Surf
mHeight = height;
mFormat = format;
mProducerUsage = producerUsage;
mAcquiredInputBuffers = 0;
SP_LOGV("%s: connected", __FUNCTION__);
return res;
@ -147,6 +148,7 @@ void Camera3StreamSplitter::disconnect() {
mMaxHalBuffers = 0;
mMaxConsumerBuffers = 0;
mAcquiredInputBuffers = 0;
SP_LOGV("%s: Disconnected", __FUNCTION__);
}
@ -165,7 +167,9 @@ status_t Camera3StreamSplitter::addOutput(size_t surfaceId, const sp<Surface>& 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--;
}
}
}

@ -269,6 +269,9 @@ private:
// Latest onFrameAvailable return value
std::atomic<status_t> mOnFrameAvailableRes{0};
// Currently acquired input buffers
size_t mAcquiredInputBuffers;
String8 mConsumerName;
};

Loading…
Cancel
Save