Camera2: Synchronize mode changes and triggers
Make sure that changes to various parameters have reached the HAL
before triggering asynchronous events like autofocus or precapture
metering.
Bug: 7107220
Change-Id: I3c50038de1671968eb32004ce538435121934e7e
diff --git a/services/camera/libcameraservice/Camera2Device.cpp b/services/camera/libcameraservice/Camera2Device.cpp
index 25b7a58..d6445c1 100644
--- a/services/camera/libcameraservice/Camera2Device.cpp
+++ b/services/camera/libcameraservice/Camera2Device.cpp
@@ -27,6 +27,7 @@
#include <utils/Log.h>
#include <utils/Trace.h>
+#include <utils/Timers.h>
#include "Camera2Device.h"
namespace android {
@@ -228,6 +229,11 @@
return mRequestQueue.setStreamSlot(NULL);
}
+status_t Camera2Device::waitUntilRequestReceived(int32_t requestId, nsecs_t timeout) {
+ ATRACE_CALL();
+ return mRequestQueue.waitForDequeue(requestId, timeout);
+}
+
status_t Camera2Device::createStream(sp<ANativeWindow> consumer,
uint32_t width, uint32_t height, int format, size_t size, int *id) {
ATRACE_CALL();
@@ -567,6 +573,7 @@
Camera2Device::MetadataQueue::MetadataQueue():
mDevice(NULL),
mFrameCount(0),
+ mLatestRequestId(0),
mCount(0),
mStreamSlotCount(0),
mSignalConsumer(true)
@@ -678,6 +685,16 @@
mFrameCount++;
}
+ // Check for request ID, and if present, signal waiters.
+ camera_metadata_entry_t requestId;
+ res = find_camera_metadata_entry(b,
+ ANDROID_REQUEST_ID,
+ &requestId);
+ if (res == OK) {
+ mLatestRequestId = requestId.data.i32[0];
+ mNewRequestId.signal();
+ }
+
*buf = b;
mCount--;
@@ -695,6 +712,22 @@
return OK;
}
+status_t Camera2Device::MetadataQueue::waitForDequeue(int32_t id,
+ nsecs_t timeout) {
+ Mutex::Autolock l(mMutex);
+ status_t res;
+ while (mLatestRequestId != id) {
+ nsecs_t startTime = systemTime();
+
+ res = mNewRequestId.waitRelative(mMutex, timeout);
+ if (res != OK) return res;
+
+ timeout -= (systemTime() - startTime);
+ }
+
+ return OK;
+}
+
status_t Camera2Device::MetadataQueue::setStreamSlot(camera_metadata_t *buf)
{
ATRACE_CALL();