Camera: Keep a list of outstanding buffers
Keep a list of outstanding buffers in Camera3Stream so that
it won't return invalid buffers or the same buffers twice back
to the buffer queue.
Bug: 27894484
Change-Id: I9f96629b4f531778433c2e1ec32a142f2040832b
diff --git a/services/camera/libcameraservice/device3/Camera3Stream.cpp b/services/camera/libcameraservice/device3/Camera3Stream.cpp
index a4714a7..80dce84 100644
--- a/services/camera/libcameraservice/device3/Camera3Stream.cpp
+++ b/services/camera/libcameraservice/device3/Camera3Stream.cpp
@@ -476,16 +476,51 @@
res = getBufferLocked(buffer);
if (res == OK) {
fireBufferListenersLocked(*buffer, /*acquired*/true, /*output*/true);
+ if (buffer->buffer) {
+ mOutstandingBuffers.push_back(*buffer->buffer);
+ }
}
return res;
}
+bool Camera3Stream::isOutstandingBuffer(const camera3_stream_buffer &buffer) {
+ if (buffer.buffer == nullptr) {
+ return false;
+ }
+
+ for (auto b : mOutstandingBuffers) {
+ if (b == *buffer.buffer) {
+ return true;
+ }
+ }
+ return false;
+}
+
+void Camera3Stream::removeOutstandingBuffer(const camera3_stream_buffer &buffer) {
+ if (buffer.buffer == nullptr) {
+ return;
+ }
+
+ for (auto b = mOutstandingBuffers.begin(); b != mOutstandingBuffers.end(); b++) {
+ if (*b == *buffer.buffer) {
+ mOutstandingBuffers.erase(b);
+ return;
+ }
+ }
+}
+
status_t Camera3Stream::returnBuffer(const camera3_stream_buffer &buffer,
nsecs_t timestamp) {
ATRACE_CALL();
Mutex::Autolock l(mLock);
+ // Check if this buffer is outstanding.
+ if (!isOutstandingBuffer(buffer)) {
+ ALOGE("%s: Stream %d: Returning an unknown buffer.", __FUNCTION__, mId);
+ return BAD_VALUE;
+ }
+
/**
* TODO: Check that the state is valid first.
*
@@ -503,6 +538,7 @@
// buffer to be returned.
mOutputBufferReturnedSignal.signal();
+ removeOutstandingBuffer(buffer);
return res;
}
@@ -535,6 +571,9 @@
res = getInputBufferLocked(buffer);
if (res == OK) {
fireBufferListenersLocked(*buffer, /*acquired*/true, /*output*/false);
+ if (buffer->buffer) {
+ mOutstandingBuffers.push_back(*buffer->buffer);
+ }
}
return res;
@@ -544,11 +583,19 @@
ATRACE_CALL();
Mutex::Autolock l(mLock);
+ // Check if this buffer is outstanding.
+ if (!isOutstandingBuffer(buffer)) {
+ ALOGE("%s: Stream %d: Returning an unknown buffer.", __FUNCTION__, mId);
+ return BAD_VALUE;
+ }
+
status_t res = returnInputBufferLocked(buffer);
if (res == OK) {
fireBufferListenersLocked(buffer, /*acquired*/false, /*output*/false);
mInputBufferReturnedSignal.signal();
}
+
+ removeOutstandingBuffer(buffer);
return res;
}