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);