diff options
Diffstat (limited to 'camera/OMXCameraAdapter/OMXFocus.cpp')
-rw-r--r-- | camera/OMXCameraAdapter/OMXFocus.cpp | 221 |
1 files changed, 132 insertions, 89 deletions
diff --git a/camera/OMXCameraAdapter/OMXFocus.cpp b/camera/OMXCameraAdapter/OMXFocus.cpp index be1dfc5..386fff3 100644 --- a/camera/OMXCameraAdapter/OMXFocus.cpp +++ b/camera/OMXCameraAdapter/OMXFocus.cpp @@ -22,10 +22,6 @@ * */ -#undef LOG_TAG - -#define LOG_TAG "CameraHAL" - #include "CameraHal.h" #include "OMXCameraAdapter.h" #include "ErrorUtils.h" @@ -34,23 +30,26 @@ #define AF_IMAGE_CALLBACK_TIMEOUT 5000000 //5 seconds timeout #define AF_VIDEO_CALLBACK_TIMEOUT 2800000 //2.8 seconds timeout -namespace android { +namespace Ti { +namespace Camera { -status_t OMXCameraAdapter::setParametersFocus(const CameraParameters ¶ms, +const nsecs_t OMXCameraAdapter::CANCEL_AF_TIMEOUT = seconds_to_nanoseconds(1); + +status_t OMXCameraAdapter::setParametersFocus(const android::CameraParameters ¶ms, BaseCameraAdapter::AdapterState state) { status_t ret = NO_ERROR; const char *str = NULL; - Vector< sp<CameraArea> > tempAreas; + android::Vector<android::sp<CameraArea> > tempAreas; size_t MAX_FOCUS_AREAS; LOG_FUNCTION_NAME; - Mutex::Autolock lock(mFocusAreasLock); + android::AutoMutex lock(mFocusAreasLock); - str = params.get(CameraParameters::KEY_FOCUS_AREAS); + str = params.get(android::CameraParameters::KEY_FOCUS_AREAS); - MAX_FOCUS_AREAS = atoi(params.get(CameraParameters::KEY_MAX_NUM_FOCUS_AREAS)); + MAX_FOCUS_AREAS = atoi(params.get(android::CameraParameters::KEY_MAX_NUM_FOCUS_AREAS)); if ( NULL != str ) { ret = CameraArea::parseAreas(str, ( strlen(str) + 1 ), tempAreas); @@ -72,7 +71,7 @@ status_t OMXCameraAdapter::setParametersFocus(const CameraParameters ¶ms, } } - LOG_FUNCTION_NAME; + LOG_FUNCTION_NAME_EXIT; return ret; } @@ -84,6 +83,7 @@ status_t OMXCameraAdapter::doAutoFocus() OMX_IMAGE_CONFIG_FOCUSCONTROLTYPE focusControl; OMX_PARAM_FOCUSSTATUSTYPE focusStatus; OMX_CONFIG_BOOLEANTYPE bOMX; + CameraAdapter::AdapterState state; nsecs_t timeout = 0; LOG_FUNCTION_NAME; @@ -102,12 +102,19 @@ status_t OMXCameraAdapter::doAutoFocus() return NO_ERROR; } - if( ((AF_ACTIVE & getState()) != AF_ACTIVE) && ((AF_ACTIVE & getNextState()) != AF_ACTIVE) ) { CAMHAL_LOGDA("Auto focus got canceled before doAutoFocus could be called"); 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. @@ -152,8 +159,7 @@ status_t OMXCameraAdapter::doAutoFocus() ( focusStatus.eFocusStatus == OMX_FocusStatusRequest || focusStatus.eFocusStatus == OMX_FocusStatusUnableToReach || focusStatus.eFocusStatus == OMX_FocusStatusLost ) ) || - (mParameters3A.Focus != (OMX_IMAGE_FOCUSCONTROLTYPE)OMX_IMAGE_FocusControlAuto) ) - { + (mParameters3A.Focus != (OMX_IMAGE_FOCUSCONTROLTYPE)OMX_IMAGE_FocusControlAuto) ) { OMX_INIT_STRUCT_PTR (&bOMX, OMX_CONFIG_BOOLEANTYPE); bOMX.bEnabled = OMX_TRUE; @@ -161,6 +167,12 @@ status_t OMXCameraAdapter::doAutoFocus() eError = OMX_SetConfig(mCameraAdapterParameters.mHandleComp, (OMX_INDEXTYPE)OMX_TI_IndexConfigAutofocusEnable, &bOMX); + if ( OMX_ErrorNone != eError ) { + return Utils::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 @@ -170,29 +182,31 @@ status_t OMXCameraAdapter::doAutoFocus() focusControl.eFocusControl = OMX_IMAGE_FocusControlAutoLock; } - if ( focusControl.eFocusControl != OMX_IMAGE_FocusControlAuto ) - { 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"); - } + // No need to wait if preview is about to stop + getNextState(state); + if ( ( PREVIEW_ACTIVE & state ) != PREVIEW_ACTIVE ) { + return NO_ERROR; + } + + // configure focus timeout based on capture mode + timeout = (mCapMode == VIDEO_MODE) || (mCapMode == VIDEO_MODE_HQ) ? + ( ( nsecs_t ) AF_VIDEO_CALLBACK_TIMEOUT * 1000 ) : + ( ( nsecs_t ) AF_IMAGE_CALLBACK_TIMEOUT * 1000 ); - // 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); - } + } //If somethiing bad happened while we wait if (mComponentState == OMX_StateInvalid) { @@ -204,6 +218,7 @@ status_t OMXCameraAdapter::doAutoFocus() CAMHAL_LOGEA("Autofocus callback timeout expired"); ret = returnFocusStatus(true); } else { + CAMHAL_LOGDA("Autofocus callback received"); ret = returnFocusStatus(false); } } else { // Focus mode in continuous @@ -225,18 +240,16 @@ status_t OMXCameraAdapter::stopAutoFocus() LOG_FUNCTION_NAME; - if ( OMX_StateInvalid == mComponentState ) - { + if ( OMX_StateInvalid == mComponentState ) { CAMHAL_LOGEA("OMX component in Invalid state"); returnFocusStatus(false); return -EINVAL; - } + } - if ( OMX_StateExecuting != mComponentState ) - { + if ( OMX_StateExecuting != mComponentState ) { CAMHAL_LOGEA("OMX component not in executing state"); return NO_ERROR; - } + } if ( mParameters3A.Focus == OMX_IMAGE_FocusControlAutoInfinity ) { // No need to stop focus if we are in infinity mode. Nothing to stop. @@ -249,19 +262,20 @@ status_t OMXCameraAdapter::stopAutoFocus() eError = OMX_SetConfig(mCameraAdapterParameters.mHandleComp, OMX_IndexConfigFocusControl, &focusControl); - if ( OMX_ErrorNone != eError ) - { + if ( OMX_ErrorNone != eError ) { CAMHAL_LOGEB("Error while stopping focus 0x%x", eError); - return ErrorUtils::omxToAndroidError(eError); - } else { + return Utils::ErrorUtils::omxToAndroidError(eError); + } +#ifdef CAMERAHAL_TUNA + 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); + android::AutoMutex lock(mDoAFMutex); mDoAFCond.broadcast(); } - +#endif LOG_FUNCTION_NAME_EXIT; @@ -292,7 +306,7 @@ status_t OMXCameraAdapter::getFocusMode(OMX_IMAGE_CONFIG_FOCUSCONTROLTYPE &focus LOG_FUNCTION_NAME_EXIT; - return ErrorUtils::omxToAndroidError(eError); + return Utils::ErrorUtils::omxToAndroidError(eError); } status_t OMXCameraAdapter::cancelAutoFocus() @@ -308,17 +322,30 @@ status_t OMXCameraAdapter::cancelAutoFocus() return ret; } - //Stop the AF only for modes other than CAF or Inifinity + //Stop the AF only for modes other than CAF, Inifinity or Off 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_LOGE("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); @@ -345,7 +372,7 @@ status_t OMXCameraAdapter::setFocusCallback(bool enabled) if ( OMX_StateExecuting != mComponentState ) { CAMHAL_LOGEA("OMX component not in executing state"); - ret = NO_ERROR; + return NO_ERROR; } if ( NO_ERROR == ret ) @@ -450,9 +477,9 @@ status_t OMXCameraAdapter::returnFocusStatus(bool timeoutReached) } else { CAMHAL_LOGDA("Focus locked. Applied focus locks successfully"); } + stopAutoFocus(); } - //Query current focus distance after AF is complete updateFocusDistances(mParameters); } @@ -508,6 +535,7 @@ status_t OMXCameraAdapter::checkFocus(OMX_PARAM_FOCUSSTATUSTYPE *eFocusStatus) if ( NO_ERROR == ret ) { OMX_INIT_STRUCT_PTR (eFocusStatus, OMX_PARAM_FOCUSSTATUSTYPE); + eError = OMX_GetConfig(mCameraAdapterParameters.mHandleComp, OMX_IndexConfigCommonFocusStatus, eFocusStatus); @@ -528,7 +556,7 @@ status_t OMXCameraAdapter::checkFocus(OMX_PARAM_FOCUSSTATUSTYPE *eFocusStatus) return ret; } -status_t OMXCameraAdapter::updateFocusDistances(CameraParameters ¶ms) +status_t OMXCameraAdapter::updateFocusDistances(android::CameraParameters ¶ms) { OMX_U32 focusNear, focusOptimal, focusFar; status_t ret = NO_ERROR; @@ -614,7 +642,7 @@ status_t OMXCameraAdapter::encodeFocusDistance(OMX_U32 dist, char *buffer, size_ { if ( 0 == dist ) { - strncpy(buffer, CameraParameters::FOCUS_DISTANCE_INFINITY, ( length - 1 )); + strncpy(buffer, android::CameraParameters::FOCUS_DISTANCE_INFINITY, ( length - 1 )); } else { @@ -632,7 +660,7 @@ status_t OMXCameraAdapter::encodeFocusDistance(OMX_U32 dist, char *buffer, size_ status_t OMXCameraAdapter::addFocusDistances(OMX_U32 &near, OMX_U32 &optimal, OMX_U32 &far, - CameraParameters& params) + android::CameraParameters& params) { status_t ret = NO_ERROR; @@ -671,7 +699,7 @@ status_t OMXCameraAdapter::addFocusDistances(OMX_U32 &near, mFocusDistOptimal, mFocusDistFar); - params.set(CameraParameters::KEY_FOCUS_DISTANCES, mFocusDistBuffer); + params.set(android::CameraParameters::KEY_FOCUS_DISTANCES, mFocusDistBuffer); } LOG_FUNCTION_NAME_EXIT; @@ -684,9 +712,9 @@ status_t OMXCameraAdapter::setTouchFocus() status_t ret = NO_ERROR; OMX_ERRORTYPE eError = OMX_ErrorNone; - OMX_ALGOAREASTYPE **focusAreas; + OMX_ALGOAREASTYPE *focusAreas; OMX_TI_CONFIG_SHAREDBUFFER sharedBuffer; - MemoryManager memMgr; + CameraBuffer *bufferlist; int areasSize = 0; LOG_FUNCTION_NAME; @@ -701,7 +729,8 @@ status_t OMXCameraAdapter::setTouchFocus() { areasSize = ((sizeof(OMX_ALGOAREASTYPE)+4095)/4096)*4096; - focusAreas = (OMX_ALGOAREASTYPE**) memMgr.allocateBuffer(0, 0, NULL, areasSize, 1); + bufferlist = mMemMgr.allocateBufferList(0, 0, NULL, areasSize, 1); + focusAreas = (OMX_ALGOAREASTYPE*) bufferlist[0].opaque; OMXCameraPortParameters * mPreviewData = NULL; mPreviewData = &mCameraAdapterParameters.mCameraPortParams[mCameraAdapterParameters.mPrevPortIndex]; @@ -712,51 +741,60 @@ status_t OMXCameraAdapter::setTouchFocus() return -ENOMEM; } - OMX_INIT_STRUCT_PTR (focusAreas[0], OMX_ALGOAREASTYPE); + OMX_INIT_STRUCT_PTR (focusAreas, OMX_ALGOAREASTYPE); - focusAreas[0]->nPortIndex = OMX_ALL; - focusAreas[0]->nNumAreas = mFocusAreas.size(); - focusAreas[0]->nAlgoAreaPurpose = OMX_AlgoAreaFocus; + focusAreas->nPortIndex = OMX_ALL; + focusAreas->nNumAreas = mFocusAreas.size(); + focusAreas->nAlgoAreaPurpose = OMX_AlgoAreaFocus; // If the area is the special case of (0, 0, 0, 0, 0), then // the algorithm needs nNumAreas to be set to 0, // in order to automatically choose the best fitting areas. if ( mFocusAreas.itemAt(0)->isZeroArea() ) { - focusAreas[0]->nNumAreas = 0; + focusAreas->nNumAreas = 0; + } + + for ( unsigned int n = 0; n < mFocusAreas.size(); n++) { + int widthDivisor = 1; + int heightDivisor = 1; + + if (mPreviewData->mFrameLayoutType == OMX_TI_StereoFrameLayoutTopBottom) { + heightDivisor = 2; + } + if (mPreviewData->mFrameLayoutType == OMX_TI_StereoFrameLayoutLeftRight) { + widthDivisor = 2; } - for ( unsigned int n = 0; n < mFocusAreas.size(); n++) - { // transform the coordinates to 3A-type coordinates - mFocusAreas.itemAt(n)->transfrom((size_t)mPreviewData->mWidth, - (size_t)mPreviewData->mHeight, - (size_t&)focusAreas[0]->tAlgoAreas[n].nTop, - (size_t&)focusAreas[0]->tAlgoAreas[n].nLeft, - (size_t&)focusAreas[0]->tAlgoAreas[n].nWidth, - (size_t&)focusAreas[0]->tAlgoAreas[n].nHeight); - - focusAreas[0]->tAlgoAreas[n].nLeft = - ( focusAreas[0]->tAlgoAreas[n].nLeft * TOUCH_FOCUS_RANGE ) / mPreviewData->mWidth; - focusAreas[0]->tAlgoAreas[n].nTop = - ( focusAreas[0]->tAlgoAreas[n].nTop* TOUCH_FOCUS_RANGE ) / mPreviewData->mHeight; - focusAreas[0]->tAlgoAreas[n].nWidth = - ( focusAreas[0]->tAlgoAreas[n].nWidth * TOUCH_FOCUS_RANGE ) / mPreviewData->mWidth; - focusAreas[0]->tAlgoAreas[n].nHeight = - ( focusAreas[0]->tAlgoAreas[n].nHeight * TOUCH_FOCUS_RANGE ) / mPreviewData->mHeight; - focusAreas[0]->tAlgoAreas[n].nPriority = mFocusAreas.itemAt(n)->getWeight(); + mFocusAreas.itemAt(n)->transfrom((size_t)mPreviewData->mWidth/widthDivisor, + (size_t)mPreviewData->mHeight/heightDivisor, + (size_t&)focusAreas->tAlgoAreas[n].nTop, + (size_t&)focusAreas->tAlgoAreas[n].nLeft, + (size_t&)focusAreas->tAlgoAreas[n].nWidth, + (size_t&)focusAreas->tAlgoAreas[n].nHeight); + + focusAreas->tAlgoAreas[n].nLeft = + ( focusAreas->tAlgoAreas[n].nLeft * TOUCH_FOCUS_RANGE ) / mPreviewData->mWidth; + focusAreas->tAlgoAreas[n].nTop = + ( focusAreas->tAlgoAreas[n].nTop* TOUCH_FOCUS_RANGE ) / mPreviewData->mHeight; + focusAreas->tAlgoAreas[n].nWidth = + ( focusAreas->tAlgoAreas[n].nWidth * TOUCH_FOCUS_RANGE ) / mPreviewData->mWidth; + focusAreas->tAlgoAreas[n].nHeight = + ( focusAreas->tAlgoAreas[n].nHeight * TOUCH_FOCUS_RANGE ) / mPreviewData->mHeight; + focusAreas->tAlgoAreas[n].nPriority = mFocusAreas.itemAt(n)->getWeight(); CAMHAL_LOGDB("Focus area %d : top = %d left = %d width = %d height = %d prio = %d", - n, (int)focusAreas[0]->tAlgoAreas[n].nTop, (int)focusAreas[0]->tAlgoAreas[n].nLeft, - (int)focusAreas[0]->tAlgoAreas[n].nWidth, (int)focusAreas[0]->tAlgoAreas[n].nHeight, - (int)focusAreas[0]->tAlgoAreas[n].nPriority); - } + n, (int)focusAreas->tAlgoAreas[n].nTop, (int)focusAreas->tAlgoAreas[n].nLeft, + (int)focusAreas->tAlgoAreas[n].nWidth, (int)focusAreas->tAlgoAreas[n].nHeight, + (int)focusAreas->tAlgoAreas[n].nPriority); + } OMX_INIT_STRUCT_PTR (&sharedBuffer, OMX_TI_CONFIG_SHAREDBUFFER); sharedBuffer.nPortIndex = OMX_ALL; sharedBuffer.nSharedBuffSize = areasSize; - sharedBuffer.pSharedBuff = (OMX_U8 *) focusAreas[0]; + sharedBuffer.pSharedBuff = (OMX_U8 *) camera_buffer_get_omx_ptr (&bufferlist[0]); if ( NULL == sharedBuffer.pSharedBuff ) { @@ -775,10 +813,9 @@ status_t OMXCameraAdapter::setTouchFocus() } EXIT: - if (NULL != focusAreas) + if (NULL != bufferlist) { - memMgr.freeBuffer((void*) focusAreas); - focusAreas = NULL; + mMemMgr.freeBufferList (bufferlist); } } @@ -802,17 +839,22 @@ void OMXCameraAdapter::handleFocusCallback() { CAMHAL_LOGEA("Focus status check failed!"); // signal and unblock doAutoFocus if (AF_ACTIVE & nextState) { - Mutex::Autolock lock(mDoAFMutex); + android::AutoMutex lock(mDoAFMutex); mDoAFCond.broadcast(); } 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); + android::AutoMutex lock(mDoAFMutex); mDoAFCond.broadcast(); } @@ -837,4 +879,5 @@ void OMXCameraAdapter::handleFocusCallback() { notifyFocusSubscribers(focusStatus); } -}; +} // namespace Camera +} // namespace Ti |