From b96dffd40e25d29a61f9fbd7f2e5968b5335b957 Mon Sep 17 00:00:00 2001 From: Emilian Peev Date: Mon, 22 Oct 2012 10:53:12 +0300 Subject: CameraHal: Sync AF cancel with incoming OMX events - Cancel AF is made to wait on incoming OMX events when AF status changes. An AF timeout is introduced in order not to block this call indefinitely. - Additionally calls to 'autoFocus()' will immediately trigger AF callbacks if fixed modes are being used. Bug: 6949572 Change-Id: I5f240fb6fc7fe53aecaff76d75d608dd522c1e27 Signed-off-by: Emilian Peev --- camera/OMXCameraAdapter/OMXFocus.cpp | 72 ++++++++++++++++++-------- camera/inc/OMXCameraAdapter/OMXCameraAdapter.h | 4 ++ 2 files changed, 53 insertions(+), 23 deletions(-) (limited to 'camera') diff --git a/camera/OMXCameraAdapter/OMXFocus.cpp b/camera/OMXCameraAdapter/OMXFocus.cpp index be1dfc5..e50b005 100644 --- a/camera/OMXCameraAdapter/OMXFocus.cpp +++ b/camera/OMXCameraAdapter/OMXFocus.cpp @@ -36,6 +36,8 @@ namespace android { +const nsecs_t OMXCameraAdapter::CANCEL_AF_TIMEOUT = seconds_to_nanoseconds(1); + status_t OMXCameraAdapter::setParametersFocus(const CameraParameters ¶ms, BaseCameraAdapter::AdapterState state) { @@ -108,6 +110,14 @@ status_t OMXCameraAdapter::doAutoFocus() return NO_ERROR; } + // AF when fixed focus modes are set should be a no-op. + if ( ( mParameters3A.Focus == OMX_IMAGE_FocusControlOff ) || + ( mParameters3A.Focus == OMX_IMAGE_FocusControlAutoInfinity ) || + ( mParameters3A.Focus == OMX_IMAGE_FocusControlHyperfocal ) ) { + returnFocusStatus(true); + return NO_ERROR; + } + OMX_INIT_STRUCT_PTR (&focusStatus, OMX_PARAM_FOCUSSTATUSTYPE); // If the app calls autoFocus, the camera will stop sending face callbacks. @@ -161,6 +171,12 @@ status_t OMXCameraAdapter::doAutoFocus() eError = OMX_SetConfig(mCameraAdapterParameters.mHandleComp, (OMX_INDEXTYPE)OMX_TI_IndexConfigAutofocusEnable, &bOMX); + if ( OMX_ErrorNone != eError ) { + return ErrorUtils::omxToAndroidError(eError); + } + + { + android::AutoMutex lock(mDoAFMutex); // force AF, Ducati will take care of whether CAF // or AF will be performed, depending on light conditions @@ -175,24 +191,23 @@ status_t OMXCameraAdapter::doAutoFocus() eError = OMX_SetConfig(mCameraAdapterParameters.mHandleComp, OMX_IndexConfigFocusControl, &focusControl); - } - if ( OMX_ErrorNone != eError ) { - CAMHAL_LOGEB("Error while starting focus 0x%x", eError); - return INVALID_OPERATION; - } else { - CAMHAL_LOGDA("Autofocus started successfully"); - } + if ( OMX_ErrorNone != eError ) { + CAMHAL_LOGEB("Error while starting focus 0x%x", eError); + return INVALID_OPERATION; + } else { + CAMHAL_LOGDA("Autofocus started successfully"); + } - // configure focus timeout based on capture mode - timeout = (mCapMode == VIDEO_MODE) ? + // configure focus timeout based on capture mode + timeout = (mCapMode == VIDEO_MODE) ? ( ( nsecs_t ) AF_VIDEO_CALLBACK_TIMEOUT * 1000 ) : ( ( nsecs_t ) AF_IMAGE_CALLBACK_TIMEOUT * 1000 ); - { - Mutex::Autolock lock(mDoAFMutex); + ret = mDoAFCond.waitRelative(mDoAFMutex, timeout); } + } // mDoAFMutex lock ends here //If somethiing bad happened while we wait if (mComponentState == OMX_StateInvalid) { @@ -222,6 +237,7 @@ status_t OMXCameraAdapter::stopAutoFocus() { OMX_ERRORTYPE eError = OMX_ErrorNone; OMX_IMAGE_CONFIG_FOCUSCONTROLTYPE focusControl; + status_t ret = NO_ERROR; LOG_FUNCTION_NAME; @@ -253,19 +269,11 @@ status_t OMXCameraAdapter::stopAutoFocus() { CAMHAL_LOGEB("Error while stopping focus 0x%x", eError); return ErrorUtils::omxToAndroidError(eError); - } else { - // This is a WA. Usually the OMX Camera component should - // generate AF status change OMX event fairly quickly - // ( after one preview frame ) and this notification should - // actually come from 'handleFocusCallback()'. - Mutex::Autolock lock(mDoAFMutex); - mDoAFCond.broadcast(); } - LOG_FUNCTION_NAME_EXIT; - return NO_ERROR; + return ret; } status_t OMXCameraAdapter::getFocusMode(OMX_IMAGE_CONFIG_FOCUSCONTROLTYPE &focusMode) @@ -311,14 +319,27 @@ status_t OMXCameraAdapter::cancelAutoFocus() //Stop the AF only for modes other than CAF or Inifinity if ( ( focusMode.eFocusControl != OMX_IMAGE_FocusControlAuto ) && ( focusMode.eFocusControl != ( OMX_IMAGE_FOCUSCONTROLTYPE ) - OMX_IMAGE_FocusControlAutoInfinity ) ) { + OMX_IMAGE_FocusControlAutoInfinity ) && + ( focusMode.eFocusControl != OMX_IMAGE_FocusControlOff ) ) { + android::AutoMutex lock(mCancelAFMutex); stopAutoFocus(); + ret = mCancelAFCond.waitRelative(mCancelAFMutex, CANCEL_AF_TIMEOUT); + if ( NO_ERROR != ret ) { + CAMHAL_LOGEA("Cancel AF timeout!"); + } } else if (focusMode.eFocusControl == OMX_IMAGE_FocusControlAuto) { // This re-enabling of CAF doesn't seem to // be needed any more. // re-apply CAF after unlocking and canceling // mPending3Asettings |= SetFocus; } + + { + // Signal to 'doAutoFocus()' + android::AutoMutex lock(mDoAFMutex); + mDoAFCond.broadcast(); + } + // If the apps call #cancelAutoFocus()}, the face callbacks will also resume. pauseFaceDetection(false); @@ -808,8 +829,13 @@ void OMXCameraAdapter::handleFocusCallback() { return; } - if ( ( eFocusStatus.eFocusStatus != OMX_FocusStatusRequest ) && - ( eFocusStatus.eFocusStatus != OMX_FocusStatusOff ) ) { + if ( eFocusStatus.eFocusStatus == OMX_FocusStatusOff ) { + android::AutoMutex lock(mCancelAFMutex); + mCancelAFCond.signal(); + return; + } + + if (eFocusStatus.eFocusStatus != OMX_FocusStatusRequest) { // signal doAutoFocus when a end of scan message comes // ignore start of scan Mutex::Autolock lock(mDoAFMutex); diff --git a/camera/inc/OMXCameraAdapter/OMXCameraAdapter.h b/camera/inc/OMXCameraAdapter/OMXCameraAdapter.h index 59c5efc..1f1fd9f 100644 --- a/camera/inc/OMXCameraAdapter/OMXCameraAdapter.h +++ b/camera/inc/OMXCameraAdapter/OMXCameraAdapter.h @@ -939,6 +939,10 @@ private: Mutex mFrameCountMutex; Condition mFirstFrameCondition; + static const nsecs_t CANCEL_AF_TIMEOUT; + Mutex mCancelAFMutex; + Condition mCancelAFCond; + Mutex mDoAFMutex; Condition mDoAFCond; -- cgit v1.1