ProCamera: Fix waitForFrameBuffer not handling multiple outstanding frames
If the CpuConsumer triggered multiple onFrameAvailable callbacks in between
a single waitForFrameBuffer call, the old code would only handle 1 callback.
This meant on two subsequent waitForFrameBuffer calls the second would always
timeout when two buffers were already available to be unlocked.
Bug: 8238112
Change-Id: Ibefca35005ac5c408e5ada97ec4a4344a9e3e497
diff --git a/camera/ProCamera.cpp b/camera/ProCamera.cpp
index d4a9556..7c66d62 100644
--- a/camera/ProCamera.cpp
+++ b/camera/ProCamera.cpp
@@ -432,20 +432,21 @@
// Unblock waitForFrame(id) callers
{
Mutex::Autolock al(mWaitMutex);
- getStreamInfo(streamId).frameReady = true;
+ getStreamInfo(streamId).frameReady++;
mWaitCondition.broadcast();
}
}
-status_t ProCamera::waitForFrameBuffer(int streamId) {
+int ProCamera::waitForFrameBuffer(int streamId) {
status_t stat = BAD_VALUE;
Mutex::Autolock al(mWaitMutex);
StreamInfo& si = getStreamInfo(streamId);
- if (si.frameReady) {
- si.frameReady = false;
- return OK;
+ if (si.frameReady > 0) {
+ int numFrames = si.frameReady;
+ si.frameReady = 0;
+ return numFrames;
} else {
while (true) {
stat = mWaitCondition.waitRelative(mWaitMutex,
@@ -456,9 +457,10 @@
return stat;
}
- if (si.frameReady) {
- si.frameReady = false;
- return OK;
+ if (si.frameReady > 0) {
+ int numFrames = si.frameReady;
+ si.frameReady = 0;
+ return numFrames;
}
// else it was some other stream that got unblocked
}
@@ -467,6 +469,29 @@
return stat;
}
+int ProCamera::dropFrameBuffer(int streamId, int count) {
+ StreamInfo& si = getStreamInfo(streamId);
+
+ if (!si.cpuStream) {
+ return BAD_VALUE;
+ } else if (count < 0) {
+ return BAD_VALUE;
+ }
+
+ int numDropped = 0;
+ for (int i = 0; i < count; ++i) {
+ CpuConsumer::LockedBuffer buffer;
+ if (si.cpuConsumer->lockNextBuffer(&buffer) != OK) {
+ break;
+ }
+
+ si.cpuConsumer->unlockBuffer(buffer);
+ numDropped++;
+ }
+
+ return numDropped;
+}
+
status_t ProCamera::waitForFrameMetadata() {
status_t stat = BAD_VALUE;
Mutex::Autolock al(mWaitMutex);