From 7142df6eb369d2c3d1a8c12e6df2861ed1bd8c36 Mon Sep 17 00:00:00 2001 From: Emilian Peev Date: Fri, 8 Jun 2018 15:01:57 +0100 Subject: [PATCH] Camera: Skip gathering complete 3A state FrameProcessor will always gather the complete 3A state before notifying clients. This could introduce unnecessary delays for camera devices that support partial results. To avoid this check the pending 3A state for each algorithm individually and notify about state changes as soon as possible. Bug: 110058858 Test: Manual using application, Camera CTS Change-Id: Ie197b2adcd884f1296f621f62cef8d53c9dc99c1 --- .../api1/client2/FrameProcessor.cpp | 94 ++++++++++++------- .../api1/client2/FrameProcessor.h | 3 +- 2 files changed, 59 insertions(+), 38 deletions(-) diff --git a/services/camera/libcameraservice/api1/client2/FrameProcessor.cpp b/services/camera/libcameraservice/api1/client2/FrameProcessor.cpp index 0c738e7324..683e84daee 100644 --- a/services/camera/libcameraservice/api1/client2/FrameProcessor.cpp +++ b/services/camera/libcameraservice/api1/client2/FrameProcessor.cpp @@ -33,7 +33,10 @@ FrameProcessor::FrameProcessor(wp device, FrameProcessorBase(device), mClient(client), mLastFrameNumberOfFaces(0), - mLast3AFrameNumber(-1) { + mLast3AFrameNumber(-1), + mLastAEFrameNumber(-1), + mLastAFrameNumber(-1), + mLastAWBFrameNumber(-1) { sp d = device.promote(); mSynthesize3ANotify = !(d->willNotify3A()); @@ -262,24 +265,73 @@ status_t FrameProcessor::process3aState(const CaptureResult &frame, bool gotAllStates = true; // TODO: Also use AE mode, AE trigger ID - gotAllStates &= updatePendingState(metadata, ANDROID_CONTROL_AF_MODE, + bool gotAFState = updatePendingState(metadata, ANDROID_CONTROL_AF_MODE, &pendingState.afMode, frameNumber, cameraId); - gotAllStates &= updatePendingState(metadata, ANDROID_CONTROL_AWB_MODE, + bool gotAWBState = updatePendingState(metadata, ANDROID_CONTROL_AWB_MODE, &pendingState.awbMode, frameNumber, cameraId); - gotAllStates &= updatePendingState(metadata, ANDROID_CONTROL_AE_STATE, + bool gotAEState = updatePendingState(metadata, ANDROID_CONTROL_AE_STATE, &pendingState.aeState, frameNumber, cameraId); - gotAllStates &= updatePendingState(metadata, ANDROID_CONTROL_AF_STATE, + gotAFState &= updatePendingState(metadata, ANDROID_CONTROL_AF_STATE, &pendingState.afState, frameNumber, cameraId); - gotAllStates &= updatePendingState(metadata, ANDROID_CONTROL_AWB_STATE, + gotAWBState &= updatePendingState(metadata, ANDROID_CONTROL_AWB_STATE, &pendingState.awbState, frameNumber, cameraId); pendingState.afTriggerId = frame.mResultExtras.afTriggerId; pendingState.aeTriggerId = frame.mResultExtras.precaptureTriggerId; + if (gotAEState && (frameNumber > mLastAEFrameNumber)) { + if (pendingState.aeState != m3aState.aeState || + pendingState.aeTriggerId > m3aState.aeTriggerId) { + ALOGV("%s: Camera %d: AE state %d->%d", + __FUNCTION__, cameraId, + m3aState.aeState, pendingState.aeState); + client->notifyAutoExposure(pendingState.aeState, pendingState.aeTriggerId); + + m3aState.aeState = pendingState.aeState; + m3aState.aeTriggerId = pendingState.aeTriggerId; + mLastAEFrameNumber = frameNumber; + } + } + + if (gotAFState && (frameNumber > mLastAFrameNumber)) { + if (pendingState.afState != m3aState.afState || + pendingState.afMode != m3aState.afMode || + pendingState.afTriggerId != m3aState.afTriggerId) { + ALOGV("%s: Camera %d: AF state %d->%d. AF mode %d->%d. Trigger %d->%d", + __FUNCTION__, cameraId, + m3aState.afState, pendingState.afState, + m3aState.afMode, pendingState.afMode, + m3aState.afTriggerId, pendingState.afTriggerId); + client->notifyAutoFocus(pendingState.afState, pendingState.afTriggerId); + + m3aState.afState = pendingState.afState; + m3aState.afMode = pendingState.afMode; + m3aState.afTriggerId = pendingState.afTriggerId; + mLastAFrameNumber = frameNumber; + } + } + + if (gotAWBState && (frameNumber > mLastAWBFrameNumber)) { + if (pendingState.awbState != m3aState.awbState || + pendingState.awbMode != m3aState.awbMode) { + ALOGV("%s: Camera %d: AWB state %d->%d. AWB mode %d->%d", + __FUNCTION__, cameraId, + m3aState.awbState, pendingState.awbState, + m3aState.awbMode, pendingState.awbMode); + client->notifyAutoWhitebalance(pendingState.awbState, + pendingState.aeTriggerId); + + m3aState.awbMode = pendingState.awbMode; + m3aState.awbState = pendingState.awbState; + mLastAWBFrameNumber = frameNumber; + } + } + + gotAllStates &= gotAEState & gotAFState & gotAWBState; if (!gotAllStates) { // If not all states are received, put the pending state to mPending3AStates. if (index == NAME_NOT_FOUND) { @@ -290,40 +342,10 @@ status_t FrameProcessor::process3aState(const CaptureResult &frame, return NOT_ENOUGH_DATA; } - // Once all 3A states are received, notify the client about 3A changes. - if (pendingState.aeState != m3aState.aeState || - pendingState.aeTriggerId > m3aState.aeTriggerId) { - ALOGV("%s: Camera %d: AE state %d->%d", - __FUNCTION__, cameraId, - m3aState.aeState, pendingState.aeState); - client->notifyAutoExposure(pendingState.aeState, pendingState.aeTriggerId); - } - - if (pendingState.afState != m3aState.afState || - pendingState.afMode != m3aState.afMode || - pendingState.afTriggerId != m3aState.afTriggerId) { - ALOGV("%s: Camera %d: AF state %d->%d. AF mode %d->%d. Trigger %d->%d", - __FUNCTION__, cameraId, - m3aState.afState, pendingState.afState, - m3aState.afMode, pendingState.afMode, - m3aState.afTriggerId, pendingState.afTriggerId); - client->notifyAutoFocus(pendingState.afState, pendingState.afTriggerId); - } - if (pendingState.awbState != m3aState.awbState || - pendingState.awbMode != m3aState.awbMode) { - ALOGV("%s: Camera %d: AWB state %d->%d. AWB mode %d->%d", - __FUNCTION__, cameraId, - m3aState.awbState, pendingState.awbState, - m3aState.awbMode, pendingState.awbMode); - client->notifyAutoWhitebalance(pendingState.awbState, - pendingState.aeTriggerId); - } - if (index != NAME_NOT_FOUND) { mPending3AStates.removeItemsAt(index); } - m3aState = pendingState; mLast3AFrameNumber = frameNumber; return OK; diff --git a/services/camera/libcameraservice/api1/client2/FrameProcessor.h b/services/camera/libcameraservice/api1/client2/FrameProcessor.h index 62a4e91dff..8183c1284d 100644 --- a/services/camera/libcameraservice/api1/client2/FrameProcessor.h +++ b/services/camera/libcameraservice/api1/client2/FrameProcessor.h @@ -104,8 +104,7 @@ class FrameProcessor : public FrameProcessorBase { // Track most recent frame number for which 3A notifications were sent for. // Used to filter against sending 3A notifications for the same frame // several times. - int32_t mLast3AFrameNumber; - + int32_t mLast3AFrameNumber, mLastAEFrameNumber, mLastAFrameNumber, mLastAWBFrameNumber; // Emit FaceDetection event to java if faces changed void callbackFaceDetection(const sp& client, const camera_frame_metadata &metadata);