EmulatedFakeCamera2: Add autofocus management
- Add skeleton ControlThread for 3A processing
- Add fake autofocus management into ControlThread
- Support AUTO, MACRO, CONTINUOUS_PICTURE, CONTINUOUS_VIDEO
Bug: 6243944
Change-Id: Ic47f5be642d4705db86021b94aaba8dcc7f32cf0
diff --git a/tools/emulator/system/camera/EmulatedCamera2.cpp b/tools/emulator/system/camera/EmulatedCamera2.cpp
index 599bd16..fa7ee4d 100644
--- a/tools/emulator/system/camera/EmulatedCamera2.cpp
+++ b/tools/emulator/system/camera/EmulatedCamera2.cpp
@@ -305,6 +305,7 @@
int EmulatedCamera2::set_notify_callback(const camera2_device_t *d,
camera2_notify_callback notify_cb, void* user) {
EmulatedCamera2* ec = getInstance(d);
+ Mutex::Autolock l(ec->mMutex);
ec->mNotifyCb = notify_cb;
ec->mNotifyUserPtr = user;
return NO_ERROR;
@@ -355,6 +356,18 @@
return ec->closeCamera();
}
+void EmulatedCamera2::sendNotification(int32_t msgType,
+ int32_t ext1, int32_t ext2, int32_t ext3) {
+ camera2_notify_callback notifyCb;
+ {
+ Mutex::Autolock l(mMutex);
+ notifyCb = mNotifyCb;
+ }
+ if (notifyCb != NULL) {
+ notifyCb(msgType, ext1, ext2, ext3, mNotifyUserPtr);
+ }
+}
+
camera2_device_ops_t EmulatedCamera2::sDeviceOps = {
EmulatedCamera2::set_request_queue_src_ops,
EmulatedCamera2::notify_request_queue_not_empty,
diff --git a/tools/emulator/system/camera/EmulatedCamera2.h b/tools/emulator/system/camera/EmulatedCamera2.h
index 2c813a4..a294454 100644
--- a/tools/emulator/system/camera/EmulatedCamera2.h
+++ b/tools/emulator/system/camera/EmulatedCamera2.h
@@ -28,6 +28,8 @@
#include "hardware/camera2.h"
#include "system/camera_metadata.h"
#include "EmulatedBaseCamera.h"
+#include <utils/Thread.h>
+#include <utils/Mutex.h>
namespace android {
@@ -128,7 +130,7 @@
/** 3A action triggering */
virtual int triggerAction(uint32_t trigger_id,
- int ext1, int ext2);
+ int32_t ext1, int32_t ext2);
/** Custom tag definitions */
virtual const char* getVendorSectionName(uint32_t tag);
@@ -232,21 +234,27 @@
* Data members shared with implementations
***************************************************************************/
protected:
+ /** Mutex for calls through camera2 device interface */
+ Mutex mMutex;
+
const camera2_request_queue_src_ops *mRequestQueueSrc;
const camera2_frame_queue_dst_ops *mFrameQueueDst;
- camera2_notify_callback mNotifyCb;
- void* mNotifyUserPtr;
struct TagOps : public vendor_tag_query_ops {
EmulatedCamera2 *parent;
};
TagOps mVendorTagOps;
+ void sendNotification(int32_t msgType,
+ int32_t ext1, int32_t ext2, int32_t ext3);
+
/****************************************************************************
* Data members
***************************************************************************/
private:
static camera2_device_ops_t sDeviceOps;
+ camera2_notify_callback mNotifyCb;
+ void* mNotifyUserPtr;
};
}; /* namespace android */
diff --git a/tools/emulator/system/camera/EmulatedFakeCamera2.cpp b/tools/emulator/system/camera/EmulatedFakeCamera2.cpp
index f614f1d..70297c6 100644
--- a/tools/emulator/system/camera/EmulatedFakeCamera2.cpp
+++ b/tools/emulator/system/camera/EmulatedFakeCamera2.cpp
@@ -133,6 +133,7 @@
mConfigureThread = new ConfigureThread(this);
mReadoutThread = new ReadoutThread(this);
+ mControlThread = new ControlThread(this);
mSensor = new Sensor(this);
mJpegCompressor = new JpegCompressor(this);
@@ -147,6 +148,9 @@
res = mReadoutThread->run("EmulatedFakeCamera2::readoutThread");
if (res != NO_ERROR) return res;
+ res = mControlThread->run("EmulatedFakeCamera2::controlThread");
+ if (res != NO_ERROR) return res;
+
return EmulatedCamera2::connectCamera(device);
}
@@ -164,11 +168,12 @@
mConfigureThread->requestExit();
mReadoutThread->requestExit();
+ mControlThread->requestExit();
mJpegCompressor->cancel();
mConfigureThread->join();
mReadoutThread->join();
-
+ mControlThread->join();
ALOGV("%s exit", __FUNCTION__);
return NO_ERROR;
@@ -431,6 +436,14 @@
return NO_ERROR;
}
+int EmulatedFakeCamera2::triggerAction(uint32_t trigger_id,
+ int32_t ext1,
+ int32_t ext2) {
+ Mutex::Autolock l(mMutex);
+ return mControlThread->triggerAction(trigger_id,
+ ext1, ext2);
+}
+
/** Custom tag definitions */
// Emulator camera metadata sections
@@ -535,8 +548,8 @@
EmulatedFakeCamera2::ConfigureThread::ConfigureThread(EmulatedFakeCamera2 *parent):
Thread(false),
mParent(parent),
- mNextBuffers(NULL),
- mRequestCount(0) {
+ mRequestCount(0),
+ mNextBuffers(NULL) {
mRunning = false;
}
@@ -635,7 +648,7 @@
}
// Get necessary parameters for sensor config
- sort_camera_metadata(mRequest);
+ mParent->mControlThread->processRequest(mRequest);
camera_metadata_entry_t streams;
res = find_camera_metadata_entry(mRequest,
@@ -803,10 +816,9 @@
mParent(parent),
mRunning(false),
mActive(false),
+ mRequestCount(0),
mRequest(NULL),
- mBuffers(NULL),
- mRequestCount(0)
-{
+ mBuffers(NULL) {
mInFlightQueue = new InFlightQueue[kInFlightQueueSize];
mInFlightHead = 0;
mInFlightTail = 0;
@@ -1046,6 +1058,343 @@
return true;
}
+EmulatedFakeCamera2::ControlThread::ControlThread(EmulatedFakeCamera2 *parent):
+ Thread(false),
+ mParent(parent) {
+ mRunning = false;
+}
+
+EmulatedFakeCamera2::ControlThread::~ControlThread() {
+}
+
+status_t EmulatedFakeCamera2::ControlThread::readyToRun() {
+ Mutex::Autolock lock(mInputMutex);
+
+ ALOGV("Starting up ControlThread");
+ mRunning = true;
+ mStartAf = false;
+ mCancelAf = false;
+ mStartPrecapture = false;
+
+ mControlMode = ANDROID_CONTROL_AUTO;
+
+ mEffectMode = ANDROID_CONTROL_EFFECT_OFF;
+ mSceneMode = ANDROID_CONTROL_SCENE_MODE_FACE_PRIORITY;
+
+ mAfMode = ANDROID_CONTROL_AF_AUTO;
+ mAfModeChange = false;
+
+ mAeMode = ANDROID_CONTROL_AE_ON;
+ mAwbMode = ANDROID_CONTROL_AWB_AUTO;
+
+ mAfTriggerId = 0;
+ mPrecaptureTriggerId = 0;
+
+ mAfState = ANDROID_CONTROL_AF_STATE_INACTIVE;
+ mAeState = ANDROID_CONTROL_AE_STATE_INACTIVE;
+ mAwbState = ANDROID_CONTROL_AWB_STATE_INACTIVE;
+
+ mInputSignal.signal();
+ return NO_ERROR;
+}
+
+status_t EmulatedFakeCamera2::ControlThread::waitUntilRunning() {
+ Mutex::Autolock lock(mInputMutex);
+ if (!mRunning) {
+ ALOGV("Waiting for control thread to start");
+ mInputSignal.wait(mInputMutex);
+ }
+ return OK;
+}
+
+status_t EmulatedFakeCamera2::ControlThread::processRequest(camera_metadata_t *request) {
+ Mutex::Autolock lock(mInputMutex);
+ // TODO: Add handling for all android.control.* fields here
+ camera_metadata_entry_t mode;
+ status_t res;
+
+ res = find_camera_metadata_entry(request,
+ ANDROID_CONTROL_MODE,
+ &mode);
+ mControlMode = mode.data.u8[0];
+
+ res = find_camera_metadata_entry(request,
+ ANDROID_CONTROL_EFFECT_MODE,
+ &mode);
+ mEffectMode = mode.data.u8[0];
+
+ res = find_camera_metadata_entry(request,
+ ANDROID_CONTROL_SCENE_MODE,
+ &mode);
+ mSceneMode = mode.data.u8[0];
+
+ res = find_camera_metadata_entry(request,
+ ANDROID_CONTROL_AF_MODE,
+ &mode);
+ if (mAfMode != mode.data.u8[0]) {
+ ALOGV("AF new mode: %d, old mode %d", mode.data.u8[0], mAfMode);
+ mAfMode = mode.data.u8[0];
+ mAfModeChange = true;
+ mStartAf = false;
+ mCancelAf = false;
+ }
+
+ res = find_camera_metadata_entry(request,
+ ANDROID_CONTROL_AE_MODE,
+ &mode);
+ mAeMode = mode.data.u8[0];
+
+ res = find_camera_metadata_entry(request,
+ ANDROID_CONTROL_AWB_MODE,
+ &mode);
+ mAwbMode = mode.data.u8[0];
+
+ // TODO: Override control fields
+
+ return OK;
+}
+
+status_t EmulatedFakeCamera2::ControlThread::triggerAction(uint32_t msgType,
+ int32_t ext1, int32_t ext2) {
+ Mutex::Autolock lock(mInputMutex);
+ switch (msgType) {
+ case CAMERA2_TRIGGER_AUTOFOCUS:
+ mAfTriggerId = ext1;
+ mStartAf = true;
+ mCancelAf = false;
+ break;
+ case CAMERA2_TRIGGER_CANCEL_AUTOFOCUS:
+ mAfTriggerId = ext1;
+ mStartAf = false;
+ mCancelAf = true;
+ break;
+ case CAMERA2_TRIGGER_PRECAPTURE_METERING:
+ mPrecaptureTriggerId = ext1;
+ mStartPrecapture = true;
+ break;
+ default:
+ ALOGE("%s: Unknown action triggered: %d (arguments %d %d)",
+ __FUNCTION__, msgType, ext1, ext2);
+ return BAD_VALUE;
+ }
+ return OK;
+}
+
+const nsecs_t EmulatedFakeCamera2::ControlThread::kControlCycleDelay = 100000000;
+const nsecs_t EmulatedFakeCamera2::ControlThread::kMinAfDuration = 500000000;
+const nsecs_t EmulatedFakeCamera2::ControlThread::kMaxAfDuration = 900000000;
+const float EmulatedFakeCamera2::ControlThread::kAfSuccessRate = 0.9;
+const float EmulatedFakeCamera2::ControlThread::kContinuousAfStartRate =
+ kControlCycleDelay / 5000000000.0; // Once every 5 seconds
+
+bool EmulatedFakeCamera2::ControlThread::threadLoop() {
+ bool afModeChange = false;
+ bool afTriggered = false;
+ bool afCancelled = false;
+ uint8_t afState;
+ uint8_t afMode;
+ int32_t afTriggerId;
+ nsecs_t nextSleep = kControlCycleDelay;
+
+ {
+ Mutex::Autolock lock(mInputMutex);
+ if (mStartAf) {
+ afTriggered = true;
+ mStartAf = false;
+ } else if (mCancelAf) {
+ afCancelled = true;
+ mCancelAf = false;
+ }
+ afState = mAfState;
+ afMode = mAfMode;
+ afModeChange = mAfModeChange;
+ mAfModeChange = false;
+
+ afTriggerId = mAfTriggerId;
+ }
+
+ if (afCancelled || afModeChange) {
+ ALOGV("Resetting AF state due to cancel/mode change");
+ afState = ANDROID_CONTROL_AF_STATE_INACTIVE;
+ updateAfState(afState, afTriggerId);
+ mAfScanDuration = 0;
+ mLockAfterPassiveScan = false;
+ }
+
+ uint8_t oldAfState = afState;
+
+ if (afTriggered) {
+ afState = processAfTrigger(afMode, afState);
+ }
+
+ afState = maybeStartAfScan(afMode, afState);
+
+ afState = updateAfScan(afMode, afState, &nextSleep);
+
+ updateAfState(afState, afTriggerId);
+
+ int ret;
+ timespec t;
+ t.tv_sec = 0;
+ t.tv_nsec = nextSleep;
+ do {
+ ret = nanosleep(&t, &t);
+ } while (ret != 0);
+
+ return true;
+}
+
+int EmulatedFakeCamera2::ControlThread::processAfTrigger(uint8_t afMode,
+ uint8_t afState) {
+ switch (afMode) {
+ case ANDROID_CONTROL_AF_OFF:
+ case ANDROID_CONTROL_AF_EDOF:
+ // Do nothing
+ break;
+ case ANDROID_CONTROL_AF_MACRO:
+ case ANDROID_CONTROL_AF_AUTO:
+ switch (afState) {
+ case ANDROID_CONTROL_AF_STATE_INACTIVE:
+ case ANDROID_CONTROL_AF_STATE_FOCUSED_LOCKED:
+ case ANDROID_CONTROL_AF_STATE_NOT_FOCUSED_LOCKED:
+ // Start new focusing cycle
+ mAfScanDuration = ((double)rand() / RAND_MAX) *
+ (kMaxAfDuration - kMinAfDuration) + kMinAfDuration;
+ afState = ANDROID_CONTROL_AF_STATE_ACTIVE_SCAN;
+ ALOGV("%s: AF scan start, duration %lld ms",
+ __FUNCTION__, mAfScanDuration / 1000000);
+ break;
+ case ANDROID_CONTROL_AF_STATE_ACTIVE_SCAN:
+ // Ignore new request, already scanning
+ break;
+ default:
+ ALOGE("Unexpected AF state in AUTO/MACRO AF mode: %d",
+ afState);
+ }
+ break;
+ case ANDROID_CONTROL_AF_CONTINUOUS_PICTURE:
+ switch (afState) {
+ // Picture mode waits for passive scan to complete
+ case ANDROID_CONTROL_AF_STATE_PASSIVE_SCAN:
+ mLockAfterPassiveScan = true;
+ break;
+ case ANDROID_CONTROL_AF_STATE_INACTIVE:
+ afState = ANDROID_CONTROL_AF_STATE_NOT_FOCUSED_LOCKED;
+ break;
+ case ANDROID_CONTROL_AF_STATE_PASSIVE_FOCUSED:
+ afState = ANDROID_CONTROL_AF_STATE_FOCUSED_LOCKED;
+ break;
+ case ANDROID_CONTROL_AF_STATE_FOCUSED_LOCKED:
+ case ANDROID_CONTROL_AF_STATE_NOT_FOCUSED_LOCKED:
+ // Must cancel to get out of these states
+ break;
+ default:
+ ALOGE("Unexpected AF state in CONTINUOUS_PICTURE AF mode: %d",
+ afState);
+ }
+ break;
+ case ANDROID_CONTROL_AF_CONTINUOUS_VIDEO:
+ switch (afState) {
+ // Video mode does not wait for passive scan to complete
+ case ANDROID_CONTROL_AF_STATE_PASSIVE_SCAN:
+ case ANDROID_CONTROL_AF_STATE_INACTIVE:
+ afState = ANDROID_CONTROL_AF_STATE_NOT_FOCUSED_LOCKED;
+ break;
+ case ANDROID_CONTROL_AF_STATE_PASSIVE_FOCUSED:
+ afState = ANDROID_CONTROL_AF_STATE_FOCUSED_LOCKED;
+ break;
+ case ANDROID_CONTROL_AF_STATE_FOCUSED_LOCKED:
+ case ANDROID_CONTROL_AF_STATE_NOT_FOCUSED_LOCKED:
+ // Must cancel to get out of these states
+ break;
+ default:
+ ALOGE("Unexpected AF state in CONTINUOUS_VIDEO AF mode: %d",
+ afState);
+ }
+ break;
+ default:
+ break;
+ }
+ return afState;
+}
+
+int EmulatedFakeCamera2::ControlThread::maybeStartAfScan(uint8_t afMode,
+ uint8_t afState) {
+ if ((afMode == ANDROID_CONTROL_AF_CONTINUOUS_VIDEO ||
+ afMode == ANDROID_CONTROL_AF_CONTINUOUS_PICTURE) &&
+ (afState == ANDROID_CONTROL_AF_STATE_INACTIVE ||
+ afState == ANDROID_CONTROL_AF_STATE_PASSIVE_FOCUSED)) {
+
+ bool startScan = ((double)rand() / RAND_MAX) < kContinuousAfStartRate;
+ if (startScan) {
+ // Start new passive focusing cycle
+ mAfScanDuration = ((double)rand() / RAND_MAX) *
+ (kMaxAfDuration - kMinAfDuration) + kMinAfDuration;
+ afState = ANDROID_CONTROL_AF_STATE_PASSIVE_SCAN;
+ ALOGV("%s: AF passive scan start, duration %lld ms",
+ __FUNCTION__, mAfScanDuration / 1000000);
+ }
+ }
+ return afState;
+}
+
+int EmulatedFakeCamera2::ControlThread::updateAfScan(uint8_t afMode,
+ uint8_t afState, nsecs_t *maxSleep) {
+ if (! (afState == ANDROID_CONTROL_AF_STATE_ACTIVE_SCAN ||
+ afState == ANDROID_CONTROL_AF_STATE_PASSIVE_SCAN ) ) {
+ return afState;
+ }
+
+ if (mAfScanDuration == 0) {
+ ALOGV("%s: AF scan done", __FUNCTION__);
+ switch (afMode) {
+ case ANDROID_CONTROL_AF_MACRO:
+ case ANDROID_CONTROL_AF_AUTO: {
+ bool success = ((double)rand() / RAND_MAX) < kAfSuccessRate;
+ if (success) {
+ afState = ANDROID_CONTROL_AF_STATE_FOCUSED_LOCKED;
+ } else {
+ afState = ANDROID_CONTROL_AF_STATE_NOT_FOCUSED_LOCKED;
+ }
+ break;
+ }
+ case ANDROID_CONTROL_AF_CONTINUOUS_PICTURE:
+ if (mLockAfterPassiveScan) {
+ afState = ANDROID_CONTROL_AF_STATE_FOCUSED_LOCKED;
+ mLockAfterPassiveScan = false;
+ } else {
+ afState = ANDROID_CONTROL_AF_STATE_PASSIVE_FOCUSED;
+ }
+ break;
+ case ANDROID_CONTROL_AF_CONTINUOUS_VIDEO:
+ afState = ANDROID_CONTROL_AF_STATE_PASSIVE_FOCUSED;
+ break;
+ default:
+ ALOGE("Unexpected AF mode in scan state");
+ }
+ } else {
+ if (mAfScanDuration <= *maxSleep) {
+ *maxSleep = mAfScanDuration;
+ mAfScanDuration = 0;
+ } else {
+ mAfScanDuration -= *maxSleep;
+ }
+ }
+ return afState;
+}
+
+void EmulatedFakeCamera2::ControlThread::updateAfState(uint8_t newState,
+ int32_t triggerId) {
+ Mutex::Autolock lock(mInputMutex);
+ if (mAfState != newState) {
+ ALOGV("%s: Autofocus state now %d, id %d", __FUNCTION__,
+ newState, triggerId);
+ mAfState = newState;
+ mParent->sendNotification(CAMERA2_MSG_AUTOFOCUS,
+ newState, triggerId, 0);
+ }
+}
+
/** Private methods */
status_t EmulatedFakeCamera2::constructStaticInfo(
@@ -1062,9 +1411,12 @@
// android.lens
- static const float minFocusDistance = 0;
+ // 5 cm min focus distance for back camera, infinity (fixed focus) for front
+ const float minFocusDistance = mFacingBack ? 1.0/0.05 : 0.0;
ADD_OR_SIZE(ANDROID_LENS_MINIMUM_FOCUS_DISTANCE,
&minFocusDistance, 1);
+ // 5 m hyperfocal distance for back camera, infinity (fixed focus) for front
+ const float hyperFocalDistance = mFacingBack ? 1.0/5.0 : 0.0;
ADD_OR_SIZE(ANDROID_LENS_HYPERFOCAL_DISTANCE,
&minFocusDistance, 1);
@@ -1323,11 +1675,25 @@
ADD_OR_SIZE(ANDROID_CONTROL_AWB_AVAILABLE_MODES,
availableAwbModes, sizeof(availableAwbModes));
- static const uint8_t availableAfModes[] = {
+ static const uint8_t availableAfModesBack[] = {
+ ANDROID_CONTROL_AF_OFF,
+ ANDROID_CONTROL_AF_AUTO,
+ ANDROID_CONTROL_AF_MACRO,
+ ANDROID_CONTROL_AF_CONTINUOUS_VIDEO,
+ ANDROID_CONTROL_AF_CONTINUOUS_PICTURE
+ };
+
+ static const uint8_t availableAfModesFront[] = {
ANDROID_CONTROL_AF_OFF
};
- ADD_OR_SIZE(ANDROID_CONTROL_AF_AVAILABLE_MODES,
- availableAfModes, sizeof(availableAfModes));
+
+ if (mFacingBack) {
+ ADD_OR_SIZE(ANDROID_CONTROL_AF_AVAILABLE_MODES,
+ availableAfModesBack, sizeof(availableAfModesBack));
+ } else {
+ ADD_OR_SIZE(ANDROID_CONTROL_AF_AVAILABLE_MODES,
+ availableAfModesFront, sizeof(availableAfModesFront));
+ }
static const uint8_t availableVstabModes[] = {
ANDROID_CONTROL_VIDEO_STABILIZATION_OFF
diff --git a/tools/emulator/system/camera/EmulatedFakeCamera2.h b/tools/emulator/system/camera/EmulatedFakeCamera2.h
index 5563c1d..4621cec 100644
--- a/tools/emulator/system/camera/EmulatedFakeCamera2.h
+++ b/tools/emulator/system/camera/EmulatedFakeCamera2.h
@@ -31,7 +31,6 @@
#include <utils/KeyedVector.h>
#include <utils/String8.h>
#include <utils/String16.h>
-#include <utils/Thread.h>
namespace android {
@@ -113,9 +112,9 @@
// virtual int releaseReprocessStream(uint32_t stream_id);
- // virtual int triggerAction(uint32_t trigger_id,
- // int ext1,
- // int ext2);
+ virtual int triggerAction(uint32_t trigger_id,
+ int32_t ext1,
+ int32_t ext2);
/** Custom tag definitions */
virtual const char* getVendorSectionName(uint32_t tag);
@@ -245,6 +244,80 @@
};
+ // 3A management thread (auto-exposure, focus, white balance)
+ class ControlThread: public Thread {
+ public:
+ ControlThread(EmulatedFakeCamera2 *parent);
+ ~ControlThread();
+
+ status_t readyToRun();
+
+ status_t waitUntilRunning();
+
+ // Interpret request's control parameters and override
+ // capture settings as needed
+ status_t processRequest(camera_metadata_t *request);
+
+ status_t triggerAction(uint32_t msgType,
+ int32_t ext1, int32_t ext2);
+ private:
+ ControlThread(const ControlThread &t);
+ ControlThread& operator=(const ControlThread &t);
+
+ // Constants controlling fake 3A behavior
+ static const nsecs_t kControlCycleDelay;
+ static const nsecs_t kMinAfDuration;
+ static const nsecs_t kMaxAfDuration;
+ static const float kAfSuccessRate;
+ static const float kContinuousAfStartRate;
+
+ EmulatedFakeCamera2 *mParent;
+
+ bool mRunning;
+ bool threadLoop();
+
+ Mutex mInputMutex; // Protects input methods
+ Condition mInputSignal;
+
+ // Trigger notifications
+ bool mStartAf;
+ bool mCancelAf;
+ bool mStartPrecapture;
+
+ // Latest state for 3A request fields
+ uint8_t mControlMode;
+
+ uint8_t mEffectMode;
+ uint8_t mSceneMode;
+
+ uint8_t mAfMode;
+ bool mAfModeChange;
+
+ uint8_t mAwbMode;
+ uint8_t mAeMode;
+
+ // Latest trigger IDs
+ int32_t mAfTriggerId;
+ int32_t mPrecaptureTriggerId;
+
+ // Current state for 3A algorithms
+ uint8_t mAfState;
+ uint8_t mAeState;
+ uint8_t mAwbState;
+
+ // Private to threadLoop and its utility methods
+
+ nsecs_t mAfScanDuration;
+ bool mLockAfterPassiveScan;
+
+ // Utility methods
+ int processAfTrigger(uint8_t afMode, uint8_t afState);
+ int maybeStartAfScan(uint8_t afMode, uint8_t afState);
+ int updateAfScan(uint8_t afMode, uint8_t afState, nsecs_t *maxSleep);
+ void updateAfState(uint8_t newState, int32_t triggerId);
+
+ };
+
/****************************************************************************
* Static configuration information
***************************************************************************/
@@ -271,9 +344,6 @@
bool mFacingBack;
private:
- /** Mutex for calls through camera2 device interface */
- Mutex mMutex;
-
/** Stream manipulation */
uint32_t mNextStreamId;
uint32_t mRawStreamCount;
@@ -289,6 +359,7 @@
/** Pipeline control threads */
sp<ConfigureThread> mConfigureThread;
sp<ReadoutThread> mReadoutThread;
+ sp<ControlThread> mControlThread;
};
}; /* namespace android */