From d196d6165aa1ac0dd7c0ad6cc5ada3a2f8e4b49d Mon Sep 17 00:00:00 2001 From: Chien-Yu Chen Date: Mon, 22 Jun 2015 19:49:01 -0700 Subject: Camera3: Support AE precapture trigger CANCEL Support AE precapture trigger CANCEL for devices <= API version 3.2. Bug: 20494782 Change-Id: I6003ba8057ca4ec9e8dfda47b8411ae6be913d22 --- .../libcameraservice/device3/Camera3Device.cpp | 93 ++++++++++++++++++++-- .../libcameraservice/device3/Camera3Device.h | 62 +++++++++------ 2 files changed, 124 insertions(+), 31 deletions(-) (limited to 'services/camera') diff --git a/services/camera/libcameraservice/device3/Camera3Device.cpp b/services/camera/libcameraservice/device3/Camera3Device.cpp index c28a57e..f64a9f0 100644 --- a/services/camera/libcameraservice/device3/Camera3Device.cpp +++ b/services/camera/libcameraservice/device3/Camera3Device.cpp @@ -1783,12 +1783,14 @@ void Camera3Device::setErrorStateLockedV(const char *fmt, va_list args) { */ status_t Camera3Device::registerInFlight(uint32_t frameNumber, - int32_t numBuffers, CaptureResultExtras resultExtras, bool hasInput) { + int32_t numBuffers, CaptureResultExtras resultExtras, bool hasInput, + const AeTriggerCancelOverride_t &aeTriggerCancelOverride) { ATRACE_CALL(); Mutex::Autolock l(mInFlightLock); ssize_t res; - res = mInFlightMap.add(frameNumber, InFlightRequest(numBuffers, resultExtras, hasInput)); + res = mInFlightMap.add(frameNumber, InFlightRequest(numBuffers, resultExtras, hasInput, + aeTriggerCancelOverride)); if (res < 0) return res; return OK; @@ -2032,7 +2034,8 @@ void Camera3Device::sendCaptureResult(CameraMetadata &pendingMetadata, CaptureResultExtras &resultExtras, CameraMetadata &collectedPartialResult, uint32_t frameNumber, - bool reprocess) { + bool reprocess, + const AeTriggerCancelOverride_t &aeTriggerCancelOverride) { if (pendingMetadata.isEmpty()) return; @@ -2087,6 +2090,8 @@ void Camera3Device::sendCaptureResult(CameraMetadata &pendingMetadata, return; } + overrideResultForPrecaptureCancel(&captureResult.mMetadata, aeTriggerCancelOverride); + // Valid result, insert into queue List::iterator queuedResult = mResultQueue.insert(mResultQueue.end(), CaptureResult(captureResult)); @@ -2265,7 +2270,8 @@ void Camera3Device::processCaptureResult(const camera3_capture_result *result) { CameraMetadata metadata; metadata = result->result; sendCaptureResult(metadata, request.resultExtras, - collectedPartialResult, frameNumber, hasInputBufferInRequest); + collectedPartialResult, frameNumber, hasInputBufferInRequest, + request.aeTriggerCancelOverride); } } @@ -2428,7 +2434,7 @@ void Camera3Device::notifyShutter(const camera3_shutter_msg_t &msg, // send pending result and buffers sendCaptureResult(r.pendingMetadata, r.resultExtras, r.partialResult.collectedResult, msg.frame_number, - r.hasInputBuffer); + r.hasInputBuffer, r.aeTriggerCancelOverride); returnOutputBuffers(r.pendingOutputBuffers.array(), r.pendingOutputBuffers.size(), r.shutterTimestamp); r.pendingOutputBuffers.clear(); @@ -2477,6 +2483,17 @@ Camera3Device::RequestThread::RequestThread(wp parent, mCurrentPreCaptureTriggerId(0), mRepeatingLastFrameNumber(NO_IN_FLIGHT_REPEATING_FRAMES) { mStatusId = statusTracker->addComponent(); + + mAeLockAvailable = false; + sp p = parent.promote(); + if (p != NULL) { + camera_metadata_ro_entry aeLockAvailable = + p->info().find(ANDROID_CONTROL_AE_LOCK_AVAILABLE); + if (aeLockAvailable.count > 0) { + mAeLockAvailable = (aeLockAvailable.data.u8[0] == + ANDROID_CONTROL_AE_LOCK_AVAILABLE_TRUE); + } + } } void Camera3Device::RequestThread::setNotificationListener( @@ -2683,6 +2700,65 @@ void Camera3Device::RequestThread::requestExit() { mRequestSignal.signal(); } + +/** + * For devices <= CAMERA_DEVICE_API_VERSION_3_2, AE_PRECAPTURE_TRIGGER_CANCEL is not supported so + * we need to override AE_PRECAPTURE_TRIGGER_CANCEL to AE_PRECAPTURE_TRIGGER_IDLE and AE_LOCK_OFF + * to AE_LOCK_ON to start cancelling AE precapture. If AE lock is not available, it still overrides + * AE_PRECAPTURE_TRIGGER_CANCEL to AE_PRECAPTURE_TRIGGER_IDLE but doesn't add AE_LOCK_ON to the + * request. + */ +void Camera3Device::RequestThread::handleAePrecaptureCancelRequest(sp request) { + request->mAeTriggerCancelOverride.applyAeLock = false; + request->mAeTriggerCancelOverride.applyAePrecaptureTrigger = false; + + if (mHal3Device->common.version > CAMERA_DEVICE_API_VERSION_3_2) { + return; + } + + camera_metadata_entry_t aePrecaptureTrigger = + request->mSettings.find(ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER); + if (aePrecaptureTrigger.count > 0 && + aePrecaptureTrigger.data.u8[0] == ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER_CANCEL) { + // Always override CANCEL to IDLE + uint8_t aePrecaptureTrigger = ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER_IDLE; + request->mSettings.update(ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER, &aePrecaptureTrigger, 1); + request->mAeTriggerCancelOverride.applyAePrecaptureTrigger = true; + request->mAeTriggerCancelOverride.aePrecaptureTrigger = + ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER_CANCEL; + + if (mAeLockAvailable == true) { + camera_metadata_entry_t aeLock = request->mSettings.find(ANDROID_CONTROL_AE_LOCK); + if (aeLock.count == 0 || aeLock.data.u8[0] == ANDROID_CONTROL_AE_LOCK_OFF) { + uint8_t aeLock = ANDROID_CONTROL_AE_LOCK_ON; + request->mSettings.update(ANDROID_CONTROL_AE_LOCK, &aeLock, 1); + request->mAeTriggerCancelOverride.applyAeLock = true; + request->mAeTriggerCancelOverride.aeLock = ANDROID_CONTROL_AE_LOCK_OFF; + } + } + } +} + +/** + * Override result metadata for cancelling AE precapture trigger applied in + * handleAePrecaptureCancelRequest(). + */ +void Camera3Device::overrideResultForPrecaptureCancel( + CameraMetadata *result, const AeTriggerCancelOverride_t &aeTriggerCancelOverride) { + if (aeTriggerCancelOverride.applyAeLock) { + // Only devices <= v3.2 should have this override + assert(mDeviceVersion <= CAMERA_DEVICE_API_VERSION_3_2); + result->update(ANDROID_CONTROL_AE_LOCK, &aeTriggerCancelOverride.aeLock, 1); + } + + if (aeTriggerCancelOverride.applyAePrecaptureTrigger) { + // Only devices <= v3.2 should have this override + assert(mDeviceVersion <= CAMERA_DEVICE_API_VERSION_3_2); + result->update(ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER, + &aeTriggerCancelOverride.aePrecaptureTrigger, 1); + } +} + bool Camera3Device::RequestThread::threadLoop() { status_t res; @@ -2822,7 +2898,8 @@ bool Camera3Device::RequestThread::threadLoop() { res = parent->registerInFlight(request.frame_number, totalNumBuffers, nextRequest->mResultExtras, - /*hasInput*/request.input_buffer != NULL); + /*hasInput*/request.input_buffer != NULL, + nextRequest->mAeTriggerCancelOverride); ALOGVV("%s: registered in flight requestId = %" PRId32 ", frameNumber = %" PRId64 ", burstId = %" PRId32 ".", __FUNCTION__, @@ -3048,6 +3125,9 @@ sp } } } + + handleAePrecaptureCancelRequest(nextRequest); + mNextRequest = nextRequest; return nextRequest; @@ -3437,6 +3517,7 @@ void Camera3Device::sProcessCaptureResult(const camera3_callback_ops *cb, const camera3_capture_result *result) { Camera3Device *d = const_cast(static_cast(cb)); + d->processCaptureResult(result); } diff --git a/services/camera/libcameraservice/device3/Camera3Device.h b/services/camera/libcameraservice/device3/Camera3Device.h index e2fd8d4..bb4bcc4 100644 --- a/services/camera/libcameraservice/device3/Camera3Device.h +++ b/services/camera/libcameraservice/device3/Camera3Device.h @@ -234,6 +234,13 @@ class Camera3Device : /**** End scope for mLock ****/ + typedef struct AeTriggerCancelOverride { + bool applyAeLock; + uint8_t aeLock; + bool applyAePrecaptureTrigger; + uint8_t aePrecaptureTrigger; + } AeTriggerCancelOverride_t; + class CaptureRequest : public LightRefBase { public: CameraMetadata mSettings; @@ -242,6 +249,9 @@ class Camera3Device : Vector > mOutputStreams; CaptureResultExtras mResultExtras; + // Used to cancel AE precapture trigger for devices doesn't support + // CONTROL_AE_PRECAPTURE_TRIGGER_CANCEL + AeTriggerCancelOverride_t mAeTriggerCancelOverride; }; typedef List > RequestList; @@ -492,6 +502,9 @@ class Camera3Device : // If the input request is in mRepeatingRequests. Must be called with mRequestLock hold bool isRepeatingRequestLocked(const sp); + // Handle AE precapture trigger cancel for devices <= CAMERA_DEVICE_API_VERSION_3_2. + void handleAePrecaptureCancelRequest(sp request); + wp mParent; wp mStatusTracker; camera3_device_t *mHal3Device; @@ -540,6 +553,9 @@ class Camera3Device : uint32_t mCurrentPreCaptureTriggerId; int64_t mRepeatingLastFrameNumber; + + // Whether the device supports AE lock + bool mAeLockAvailable; }; sp mRequestThread; @@ -562,7 +578,6 @@ class Camera3Device : // If this request has any input buffer bool hasInputBuffer; - // The last metadata that framework receives from HAL and // not yet send out because the shutter event hasn't arrived. // It's added by process_capture_result and sent when framework @@ -575,6 +590,10 @@ class Camera3Device : // the shutter event. Vector pendingOutputBuffers; + // Used to cancel AE precapture trigger for devices doesn't support + // CONTROL_AE_PRECAPTURE_TRIGGER_CANCEL + AeTriggerCancelOverride_t aeTriggerCancelOverride; + // Fields used by the partial result only struct PartialResultInFlight { @@ -595,36 +614,20 @@ class Camera3Device : requestStatus(OK), haveResultMetadata(false), numBuffersLeft(0), - hasInputBuffer(false){ - } - - InFlightRequest(int numBuffers) : - shutterTimestamp(0), - sensorTimestamp(0), - requestStatus(OK), - haveResultMetadata(false), - numBuffersLeft(numBuffers), - hasInputBuffer(false){ + hasInputBuffer(false), + aeTriggerCancelOverride({false, 0, false, 0}){ } - InFlightRequest(int numBuffers, CaptureResultExtras extras) : + InFlightRequest(int numBuffers, CaptureResultExtras extras, bool hasInput, + AeTriggerCancelOverride aeTriggerCancelOverride) : shutterTimestamp(0), sensorTimestamp(0), requestStatus(OK), haveResultMetadata(false), numBuffersLeft(numBuffers), resultExtras(extras), - hasInputBuffer(false){ - } - - InFlightRequest(int numBuffers, CaptureResultExtras extras, bool hasInput) : - shutterTimestamp(0), - sensorTimestamp(0), - requestStatus(OK), - haveResultMetadata(false), - numBuffersLeft(numBuffers), - resultExtras(extras), - hasInputBuffer(hasInput){ + hasInputBuffer(hasInput), + aeTriggerCancelOverride(aeTriggerCancelOverride){ } }; @@ -635,7 +638,8 @@ class Camera3Device : InFlightMap mInFlightMap; status_t registerInFlight(uint32_t frameNumber, - int32_t numBuffers, CaptureResultExtras resultExtras, bool hasInput); + int32_t numBuffers, CaptureResultExtras resultExtras, bool hasInput, + const AeTriggerCancelOverride_t &aeTriggerCancelOverride); /** * For the partial result, check if all 3A state fields are available @@ -653,6 +657,14 @@ class Camera3Device : template bool insert3AResult(CameraMetadata &result, int32_t tag, const T* value, uint32_t frameNumber); + + /** + * Override result metadata for cancelling AE precapture trigger applied in + * handleAePrecaptureCancelRequest(). + */ + void overrideResultForPrecaptureCancel(CameraMetadata* result, + const AeTriggerCancelOverride_t &aeTriggerCancelOverride); + /** * Tracking for idle detection */ @@ -738,7 +750,7 @@ class Camera3Device : void sendCaptureResult(CameraMetadata &pendingMetadata, CaptureResultExtras &resultExtras, CameraMetadata &collectedPartialResult, uint32_t frameNumber, - bool reprocess); + bool reprocess, const AeTriggerCancelOverride_t &aeTriggerCancelOverride); /**** Scope for mInFlightLock ****/ -- cgit v1.1