hardware: samsung_slsi: libcamera2: Add AF/CAF Feature
authorSungjoong Kang <sj3.kang@samsung.com>
Fri, 17 Aug 2012 22:43:12 +0000 (15:43 -0700)
committerRebecca Schultz Zavin <rebecca@android.com>
Wed, 22 Aug 2012 00:22:12 +0000 (17:22 -0700)
This patch enables AF/CAF of camera.
Requires camera 4th release.

Signed-off-by: Sungjoong Kang <sj3.kang@samsung.com>
Change-Id: I97547674ee115f7a00fd9ceeebbd0456a37c25e4

libcamera2/ExynosCamera2.cpp
libcamera2/ExynosCamera2.h
libcamera2/ExynosCameraHWInterface2.cpp
libcamera2/ExynosCameraHWInterface2.h
libcamera2/MetadataConverter.cpp

index 9fdf83b8e356bf50be070927d21fc3d97d6bb07a..9f2c2583ac2898449b343029ef5dbc0e5beae861 100644 (file)
@@ -137,6 +137,9 @@ ExynosCamera2InfoS5K4E5::ExynosCamera2InfoS5K4E5()
     scalerResolutions   = scalerResolutionS5K4E5;
     numJpegResolution   = ARRAY_SIZE(jpegResolutionS5K4E5)/2;
     jpegResolutions     = jpegResolutionS5K4E5;
+    minFocusDistance    = 0.1f;
+    focalLength         = 3.43f;
+    aperture            = 2.7f;
 }
 
 const int32_t scalerResolutionS5K6A3[] =
@@ -161,6 +164,9 @@ ExynosCamera2InfoS5K6A3::ExynosCamera2InfoS5K6A3()
     scalerResolutions   = scalerResolutionS5K6A3;
     numJpegResolution   = ARRAY_SIZE(jpegResolutionS5K6A3)/2;
     jpegResolutions     = jpegResolutionS5K6A3;
+    minFocusDistance    = 0.0f;
+    focalLength         = 2.73f;
+    aperture            = 2.8f;
 }
 
 ExynosCamera2::ExynosCamera2(int cameraId):
@@ -255,18 +261,16 @@ status_t ExynosCamera2::constructStaticInfo(camera_metadata_t **info,
 
     // android.lens
 
-    static const float minFocusDistance = 0;
     ADD_OR_SIZE(ANDROID_LENS_MINIMUM_FOCUS_DISTANCE,
-            &minFocusDistance, 1);
+            &(m_curCameraInfo->minFocusDistance), 1);
     ADD_OR_SIZE(ANDROID_LENS_HYPERFOCAL_DISTANCE,
-            &minFocusDistance, 1);
+            &(m_curCameraInfo->minFocusDistance), 1);
 
-    static const float focalLength = 3.30f; // mm
     ADD_OR_SIZE(ANDROID_LENS_AVAILABLE_FOCAL_LENGTHS,
-            &focalLength, 1);
-    static const float aperture = 2.8f;
+            &m_curCameraInfo->focalLength, 1);
     ADD_OR_SIZE(ANDROID_LENS_AVAILABLE_APERTURES,
-            &aperture, 1);
+            &m_curCameraInfo->aperture, 1);
+
     static const float filterDensity = 0;
     ADD_OR_SIZE(ANDROID_LENS_AVAILABLE_FILTER_DENSITY,
             &filterDensity, 1);
@@ -495,7 +499,11 @@ status_t ExynosCamera2::constructStaticInfo(camera_metadata_t **info,
             availableAwbModes, sizeof(availableAwbModes));
 
     static const uint8_t availableAfModes[] = {
-            ANDROID_CONTROL_AF_OFF
+            ANDROID_CONTROL_AF_OFF,
+            ANDROID_CONTROL_AF_AUTO,
+            ANDROID_CONTROL_AF_MACRO,
+            ANDROID_CONTROL_AF_CONTINUOUS_PICTURE,
+            ANDROID_CONTROL_AF_CONTINUOUS_VIDEO
     };
     ADD_OR_SIZE(ANDROID_CONTROL_AF_AVAILABLE_MODES,
             availableAfModes, sizeof(availableAfModes));
@@ -560,11 +568,9 @@ status_t ExynosCamera2::constructDefaultRequest(
     static const float focusDistance = 0;
     ADD_OR_SIZE(ANDROID_LENS_FOCUS_DISTANCE, &focusDistance, 1);
 
-    static const float aperture = 2.8f;
-    ADD_OR_SIZE(ANDROID_LENS_APERTURE, &aperture, 1);
+    ADD_OR_SIZE(ANDROID_LENS_APERTURE, &m_curCameraInfo->aperture, 1);
 
-    static const float focalLength = 5.0f;
-    ADD_OR_SIZE(ANDROID_LENS_FOCAL_LENGTH, &focalLength, 1);
+    ADD_OR_SIZE(ANDROID_LENS_FOCAL_LENGTH, &m_curCameraInfo->focalLength, 1);
 
     static const float filterDensity = 0;
     ADD_OR_SIZE(ANDROID_LENS_FILTER_DENSITY, &filterDensity, 1);
@@ -805,10 +811,10 @@ status_t ExynosCamera2::constructDefaultRequest(
     uint8_t afMode = 0;
     switch (request_template) {
       case CAMERA2_TEMPLATE_PREVIEW:
-        afMode = ANDROID_CONTROL_AF_AUTO;
+        afMode = ANDROID_CONTROL_AF_CONTINUOUS_PICTURE;
         break;
       case CAMERA2_TEMPLATE_STILL_CAPTURE:
-        afMode = ANDROID_CONTROL_AF_AUTO;
+        afMode = ANDROID_CONTROL_AF_CONTINUOUS_PICTURE;
         break;
       case CAMERA2_TEMPLATE_VIDEO_RECORD:
         afMode = ANDROID_CONTROL_AF_CONTINUOUS_VIDEO;
index b00a0641be6af23768f626e3cc62c214f83d212d..cbb817fe34953788d30fa52f09e9b9026d0b809e 100644 (file)
@@ -46,6 +46,9 @@ public:
     const int32_t     *scalerResolutions;
     int         numJpegResolution;
     const int32_t     *jpegResolutions;
+    float       minFocusDistance;
+    float       focalLength;
+    float       aperture;
 };
 
 struct ExynosCamera2InfoS5K4E5 : public ExynosCamera2Info
index 1be6cdcf37a7732020edcef906752b525e61dee7..b955c0a320c4df9a570413008f06ff9a39d45806 100644 (file)
@@ -366,7 +366,7 @@ void RequestManager::DeregisterRequest(camera_metadata_t ** deregistered_request
 }
 
 bool RequestManager::PrepareFrame(size_t* num_entries, size_t* frame_size,
-                camera_metadata_t ** prepared_frame)
+                camera_metadata_t ** prepared_frame, int afState)
 {
     ALOGV("DEBUG(%s):", __FUNCTION__);
     Mutex::Autolock lock(m_requestMutex);
@@ -383,6 +383,7 @@ bool RequestManager::PrepareFrame(size_t* num_entries, size_t* frame_size,
     }
     m_entryFrameOutputIndex = tempFrameOutputIndex;
     m_tempFrameMetadata = place_camera_metadata(m_tempFrameMetadataBuf, 2000, 15, 500); //estimated
+    add_camera_metadata_entry(m_tempFrameMetadata, ANDROID_CONTROL_AF_STATE, &afState, 1);
     res = m_metadataConverter->ToDynamicMetadata(&(currentEntry->internal_shot),
                 m_tempFrameMetadata);
     if (res!=NO_ERROR) {
@@ -398,7 +399,7 @@ bool RequestManager::PrepareFrame(size_t* num_entries, size_t* frame_size,
     return true;
 }
 
-int RequestManager::MarkProcessingRequest(ExynosBuffer* buf)
+int RequestManager::MarkProcessingRequest(ExynosBuffer* buf, int *afMode)
 {
 
     Mutex::Autolock lock(m_requestMutex);
@@ -406,6 +407,7 @@ int RequestManager::MarkProcessingRequest(ExynosBuffer* buf)
     struct camera2_shot_ext * request_shot;
     int targetStreamIndex = 0;
     request_manager_entry * newEntry = NULL;
+    static int count = 0;
 
     if (m_numOfEntries == 0)  {
         ALOGD("DEBUG(%s): Request Manager Empty ", __FUNCTION__);
@@ -424,6 +426,7 @@ int RequestManager::MarkProcessingRequest(ExynosBuffer* buf)
 
     newEntry = &(entries[newProcessingIndex]);
     request_shot = &(newEntry->internal_shot);
+    *afMode = (int)(newEntry->internal_shot.shot.ctl.aa.afMode);
     if (newEntry->status != REGISTERED) {
         ALOGD("DEBUG(%s)(%d): Circular buffer abnormal ", __FUNCTION__, newProcessingIndex);
         return -1;
@@ -462,7 +465,12 @@ int RequestManager::MarkProcessingRequest(ExynosBuffer* buf)
         }
     }
 
-    shot_ext->shot.ctl.aa.mode = AA_CONTROL_AUTO;
+    if (count == 0){
+        shot_ext->shot.ctl.aa.mode = AA_CONTROL_AUTO;
+    } else
+        shot_ext->shot.ctl.aa.mode = AA_CONTROL_NONE;
+
+    count++;
     shot_ext->shot.ctl.request.metadataMode = METADATA_MODE_FULL;
     shot_ext->shot.ctl.stats.faceDetectMode = FACEDETECT_MODE_FULL;
     shot_ext->shot.magicNumber = 0x23456789;
@@ -564,7 +572,7 @@ void RequestManager::DumpInfoWithIndex(int index)
         ALOGV("####   OutputStream num (%d) abnormal ", currMetadata->shot.ctl.request.outputStreams[15]);
 }
 
-void    RequestManager::UpdateIspParameters(struct camera2_shot_ext *shot_ext, int frameCnt)
+void    RequestManager::UpdateIspParameters(struct camera2_shot_ext *shot_ext, int frameCnt, bool afTrigger)
 {
     int index, targetStreamIndex;
     struct camera2_shot_ext * request_shot;
@@ -595,6 +603,17 @@ void    RequestManager::UpdateIspParameters(struct camera2_shot_ext *shot_ext, i
     shot_ext->shot.ctl.request.outputStreams[2] = 0;
 
 
+    if (afTrigger) {
+        ALOGE("### AF Trigger ");
+        shot_ext->shot.ctl.aa.afTrigger = 1;
+        shot_ext->shot.ctl.aa.afRegions[0] = 0;
+        shot_ext->shot.ctl.aa.afRegions[1] = 0;
+        shot_ext->shot.ctl.aa.afRegions[2] = 0;
+        shot_ext->shot.ctl.aa.afRegions[3] = 0;
+        shot_ext->shot.ctl.aa.afRegions[4] = 0;
+    }
+    else
+        shot_ext->shot.ctl.aa.afTrigger = 0;
     for (int i = 0; i < newEntry->output_stream_count; i++) {
        targetStreamIndex = newEntry->internal_shot.shot.ctl.request.outputStreams[i];
 
@@ -742,6 +761,13 @@ ExynosCameraHWInterface2::ExynosCameraHWInterface2(int cameraId, camera2_device_
             lastFrameCnt(-1),
             m_scp_closing(false),
             m_scp_closed(false),
+            m_afState(HAL_AFSTATE_INACTIVE),
+            m_afMode(NO_CHANGE),
+            m_afMode2(NO_CHANGE),
+            m_IsAfModeUpdateRequired(false),
+            m_IsAfTriggerRequired(false),
+            m_IsAfLockRequired(false),
+            m_afTriggerId(0),
             m_halDevice(dev),
             m_need_streamoff(0),
             m_cameraId(cameraId)
@@ -1136,6 +1162,8 @@ int ExynosCameraHWInterface2::notifyRequestQueueNotEmpty()
         return 0;
     }
     m_isRequestQueueNull = false;
+    if (m_requestManager->GetNumEntries() == 0)
+        m_requestManager->SetInitialSkip(5);
     m_mainThread->SetSignal(SIGNAL_MAIN_REQ_Q_NOT_EMPTY);
     return 0;
 }
@@ -1618,13 +1646,27 @@ int ExynosCameraHWInterface2::releaseReprocessStream(uint32_t stream_id)
 
 int ExynosCameraHWInterface2::triggerAction(uint32_t trigger_id, int ext1, int ext2)
 {
-    ALOGV("DEBUG(%s):", __FUNCTION__);
+    ALOGV("DEBUG(%s): id(%x), %d, %d", __FUNCTION__, trigger_id, ext1, ext2);
+
+    switch (trigger_id) {
+    case CAMERA2_TRIGGER_AUTOFOCUS:
+        ALOGV("DEBUG(%s):TRIGGER_AUTOFOCUS id(%d)", __FUNCTION__, ext1);
+        OnAfTrigger(ext1);
+        break;
+
+    case CAMERA2_TRIGGER_CANCEL_AUTOFOCUS:
+        ALOGV("DEBUG(%s):CANCEL_AUTOFOCUS id(%d)", __FUNCTION__, ext1);
+        OnAfCancel(ext1);
+        break;
+    default:
+        break;
+    }
     return 0;
 }
 
 int ExynosCameraHWInterface2::setNotifyCallback(camera2_notify_callback notify_cb, void *user)
 {
-    ALOGV("DEBUG(%s):", __FUNCTION__);
+    ALOGV("DEBUG(%s): cb_addr(%x)", __FUNCTION__, (unsigned int)notify_cb);
     m_notifyCb = notify_cb;
     m_callbackCookie = user;
     return 0;
@@ -2000,7 +2042,7 @@ void ExynosCameraHWInterface2::m_mainThreadFunc(SignalDrivenThread * self)
     if (currentSignal & SIGNAL_MAIN_STREAM_OUTPUT_DONE) {
         ALOGV("DEBUG(%s): MainThread processing SIGNAL_MAIN_STREAM_OUTPUT_DONE", __FUNCTION__);
         /*while (1)*/ {
-            ret = m_requestManager->PrepareFrame(&numEntries, &frameSize, &preparedFrame);
+            ret = m_requestManager->PrepareFrame(&numEntries, &frameSize, &preparedFrame, GetAfStateForService());
             if (ret == false)
                 ALOGD("++++++ PrepareFrame ret = %d", ret);
 
@@ -2129,6 +2171,8 @@ void ExynosCameraHWInterface2::m_sensorThreadFunc(SignalDrivenThread * self)
         int matchedFrameCnt = -1, processingReqIndex;
         struct camera2_shot_ext *shot_ext;
         struct camera2_shot_ext *shot_ext_capture;
+        bool triggered = false;
+        int afMode;
 
         /* dqbuf from sensor */
         ALOGV("Sensor DQbuf start");
@@ -2142,7 +2186,46 @@ void ExynosCameraHWInterface2::m_sensorThreadFunc(SignalDrivenThread * self)
         if (matchedFrameCnt != -1) {
                 frameTime = systemTime();
         m_requestManager->RegisterTimestamp(matchedFrameCnt, &frameTime);
-            m_requestManager->UpdateIspParameters(shot_ext, matchedFrameCnt);
+            if (m_IsAfModeUpdateRequired) {
+                ALOGE("### AF Mode change(Mode %d) ", m_afMode);
+                shot_ext->shot.ctl.aa.afMode = m_afMode;
+                if (m_afMode == AA_AFMODE_CONTINUOUS_VIDEO || m_afMode == AA_AFMODE_CONTINUOUS_PICTURE) {
+                    ALOGE("### With Automatic triger for continuous modes");
+                    m_afState = HAL_AFSTATE_STARTED;
+                    shot_ext->shot.ctl.aa.afTrigger = 1;
+                    triggered = true;
+                }
+                m_IsAfModeUpdateRequired = false;
+                if (m_afMode2 != NO_CHANGE) {
+                    enum aa_afmode tempAfMode = m_afMode2;
+                    m_afMode2 = NO_CHANGE;
+                    SetAfMode(tempAfMode);
+                }
+            }
+            else {
+                shot_ext->shot.ctl.aa.afMode = NO_CHANGE;
+            }
+            if (m_IsAfTriggerRequired) {
+                ALOGE("### AF Triggering with mode (%d)", m_afMode);
+                if (m_afState != HAL_AFSTATE_NEEDS_COMMAND)
+                    ALOGE("(%s): wrong trigger state %d", __FUNCTION__, m_afState);
+                else
+                    m_afState = HAL_AFSTATE_STARTED;
+                m_requestManager->UpdateIspParameters(shot_ext, matchedFrameCnt, true);
+                shot_ext->shot.ctl.aa.afMode = m_afMode;
+                m_IsAfTriggerRequired = false;
+            }
+            else {
+                m_requestManager->UpdateIspParameters(shot_ext, matchedFrameCnt, false);
+            }
+            if (triggered)
+                shot_ext->shot.ctl.aa.afTrigger = 1;
+
+            // TODO : check collision with AFMode Update
+            if (m_IsAfLockRequired) {
+                shot_ext->shot.ctl.aa.afMode = AA_AFMODE_OFF;
+                m_IsAfLockRequired = false;
+            }
             ALOGD("### Isp Qbuf start(%d) count (%d), SCP(%d) SCC(%d) DIS(%d) shot_size(%d)",
                 index,
                 shot_ext->shot.ctl.request.frameCount,
@@ -2229,13 +2312,17 @@ void ExynosCameraHWInterface2::m_sensorThreadFunc(SignalDrivenThread * self)
                 m_scp_closed = false;
 
             m_requestManager->ApplyDynamicMetadata(shot_ext);
+            OnAfNotification(shot_ext->shot.dm.aa.afState);
         }
 
-        processingReqIndex = m_requestManager->MarkProcessingRequest(&(m_camera_info.sensor.buffer[index]));
+        processingReqIndex = m_requestManager->MarkProcessingRequest(&(m_camera_info.sensor.buffer[index]), &afMode);
         if (processingReqIndex == -1)
         {
             ALOGE("DEBUG(%s) req underrun => inserting bubble to BayerIndex(%d)", __FUNCTION__, index);
         }
+        else {
+            SetAfMode((enum aa_afmode)afMode);
+        }
 
         shot_ext = (struct camera2_shot_ext *)(m_camera_info.sensor.buffer[index].virt.extP[1]);
         if (m_scp_closing || m_scp_closed) {
@@ -2901,6 +2988,676 @@ jpeg_encode_done:
 }
 
 
+void ExynosCameraHWInterface2::OnAfTrigger(int id)
+{
+    switch (m_afMode) {
+    case AA_AFMODE_AUTO:
+    case AA_AFMODE_MACRO:
+        OnAfTriggerAutoMacro(id);
+        break;
+    case AA_AFMODE_CONTINUOUS_VIDEO:
+        OnAfTriggerCAFVideo(id);
+        break;
+    case AA_AFMODE_CONTINUOUS_PICTURE:
+        OnAfTriggerCAFPicture(id);
+        break;
+    case AA_AFMODE_OFF:
+    default:
+        break;
+    }
+}
+
+void ExynosCameraHWInterface2::OnAfTriggerAutoMacro(int id)
+{
+    int nextState = NO_TRANSITION;
+    m_afTriggerId = id;
+
+    switch (m_afState) {
+    case HAL_AFSTATE_INACTIVE:
+        nextState = HAL_AFSTATE_NEEDS_COMMAND;
+        m_IsAfTriggerRequired = true;
+        break;
+    case HAL_AFSTATE_NEEDS_COMMAND:
+        nextState = NO_TRANSITION;
+        break;
+    case HAL_AFSTATE_STARTED:
+        nextState = NO_TRANSITION;
+        break;
+    case HAL_AFSTATE_SCANNING:
+        nextState = NO_TRANSITION;
+        break;
+    case HAL_AFSTATE_LOCKED:
+        nextState = HAL_AFSTATE_NEEDS_COMMAND;
+        m_IsAfTriggerRequired = true;
+        break;
+    case HAL_AFSTATE_FAILED:
+        nextState = HAL_AFSTATE_NEEDS_COMMAND;
+        m_IsAfTriggerRequired = true;
+        break;
+    default:
+        break;
+    }
+    ALOGV("(%s): State (%d) -> (%d)", __FUNCTION__, m_afState, nextState);
+    if (nextState != NO_TRANSITION)
+        m_afState = nextState;
+}
+
+void ExynosCameraHWInterface2::OnAfTriggerCAFPicture(int id)
+{
+    int nextState = NO_TRANSITION;
+    m_afTriggerId = id;
+
+    switch (m_afState) {
+    case HAL_AFSTATE_INACTIVE:
+        nextState = HAL_AFSTATE_FAILED;
+        SetAfStateForService(ANDROID_CONTROL_AF_STATE_NOT_FOCUSED_LOCKED);
+        break;
+    case HAL_AFSTATE_NEEDS_COMMAND:
+        // not used
+        break;
+    case HAL_AFSTATE_STARTED:
+        nextState = HAL_AFSTATE_NEEDS_DETERMINATION;
+        break;
+    case HAL_AFSTATE_SCANNING:
+        nextState = HAL_AFSTATE_NEEDS_DETERMINATION;
+        break;
+    case HAL_AFSTATE_NEEDS_DETERMINATION:
+        nextState = NO_TRANSITION;
+        break;
+    case HAL_AFSTATE_PASSIVE_FOCUSED:
+        m_IsAfLockRequired = true;
+        SetAfStateForService(ANDROID_CONTROL_AF_STATE_FOCUSED_LOCKED);
+        nextState = HAL_AFSTATE_LOCKED;
+        break;
+    case HAL_AFSTATE_LOCKED:
+        nextState = NO_TRANSITION;
+        break;
+    case HAL_AFSTATE_FAILED:
+        nextState = NO_TRANSITION;
+        break;
+    default:
+        break;
+    }
+    ALOGV("(%s): State (%d) -> (%d)", __FUNCTION__, m_afState, nextState);
+    if (nextState != NO_TRANSITION)
+        m_afState = nextState;
+}
+
+
+void ExynosCameraHWInterface2::OnAfTriggerCAFVideo(int id)
+{
+    int nextState = NO_TRANSITION;
+    m_afTriggerId = id;
+
+    switch (m_afState) {
+    case HAL_AFSTATE_INACTIVE:
+        nextState = HAL_AFSTATE_FAILED;
+        SetAfStateForService(ANDROID_CONTROL_AF_STATE_NOT_FOCUSED_LOCKED);
+        break;
+    case HAL_AFSTATE_NEEDS_COMMAND:
+        // not used
+        break;
+    case HAL_AFSTATE_STARTED:
+        m_IsAfLockRequired = true;
+        nextState = HAL_AFSTATE_FAILED;
+        SetAfStateForService(ANDROID_CONTROL_AF_STATE_NOT_FOCUSED_LOCKED);
+        break;
+    case HAL_AFSTATE_SCANNING:
+        m_IsAfLockRequired = true;
+        nextState = HAL_AFSTATE_FAILED;
+        SetAfStateForService(ANDROID_CONTROL_AF_STATE_NOT_FOCUSED_LOCKED);
+        break;
+    case HAL_AFSTATE_NEEDS_DETERMINATION:
+        // not used
+        break;
+    case HAL_AFSTATE_PASSIVE_FOCUSED:
+        m_IsAfLockRequired = true;
+        SetAfStateForService(ANDROID_CONTROL_AF_STATE_FOCUSED_LOCKED);
+        nextState = HAL_AFSTATE_LOCKED;
+        break;
+    case HAL_AFSTATE_LOCKED:
+        nextState = NO_TRANSITION;
+        break;
+    case HAL_AFSTATE_FAILED:
+        nextState = NO_TRANSITION;
+        break;
+    default:
+        break;
+    }
+    ALOGV("(%s): State (%d) -> (%d)", __FUNCTION__, m_afState, nextState);
+    if (nextState != NO_TRANSITION)
+        m_afState = nextState;
+}
+
+void ExynosCameraHWInterface2::OnAfNotification(enum aa_afstate noti)
+{
+    switch (m_afMode) {
+    case AA_AFMODE_AUTO:
+    case AA_AFMODE_MACRO:
+        OnAfNotificationAutoMacro(noti);
+        break;
+    case AA_AFMODE_CONTINUOUS_VIDEO:
+        OnAfNotificationCAFVideo(noti);
+        break;
+    case AA_AFMODE_CONTINUOUS_PICTURE:
+        OnAfNotificationCAFPicture(noti);
+        break;
+    case AA_AFMODE_OFF:
+    default:
+        break;
+    }
+}
+
+void ExynosCameraHWInterface2::OnAfNotificationAutoMacro(enum aa_afstate noti)
+{
+    int nextState = NO_TRANSITION;
+    bool bWrongTransition = false;
+
+    if (m_afState == HAL_AFSTATE_INACTIVE || m_afState == HAL_AFSTATE_NEEDS_COMMAND) {
+        switch (noti) {
+        case AA_AFSTATE_INACTIVE:
+        case AA_AFSTATE_ACTIVE_SCAN:
+        case AA_AFSTATE_AF_ACQUIRED_FOCUS:
+        case AA_AFSTATE_AF_FAILED_FOCUS:
+        default:
+            nextState = NO_TRANSITION;
+            break;
+        }
+    }
+    else if (m_afState == HAL_AFSTATE_STARTED) {
+        switch (noti) {
+        case AA_AFSTATE_INACTIVE:
+            nextState = NO_TRANSITION;
+            break;
+        case AA_AFSTATE_ACTIVE_SCAN:
+            nextState = HAL_AFSTATE_SCANNING;
+            SetAfStateForService(ANDROID_CONTROL_AF_STATE_ACTIVE_SCAN);
+            break;
+        case AA_AFSTATE_AF_ACQUIRED_FOCUS:
+            nextState = NO_TRANSITION;
+            break;
+        case AA_AFSTATE_AF_FAILED_FOCUS:
+            nextState = NO_TRANSITION;
+            break;
+        default:
+            bWrongTransition = true;
+            break;
+        }
+    }
+    else if (m_afState == HAL_AFSTATE_SCANNING) {
+        switch (noti) {
+        case AA_AFSTATE_INACTIVE:
+            bWrongTransition = true;
+            break;
+        case AA_AFSTATE_ACTIVE_SCAN:
+            nextState = NO_TRANSITION;
+            break;
+        case AA_AFSTATE_AF_ACQUIRED_FOCUS:
+            nextState = HAL_AFSTATE_LOCKED;
+            SetAfStateForService(ANDROID_CONTROL_AF_STATE_FOCUSED_LOCKED);
+            break;
+        case AA_AFSTATE_AF_FAILED_FOCUS:
+            nextState = HAL_AFSTATE_FAILED;
+            SetAfStateForService(ANDROID_CONTROL_AF_STATE_NOT_FOCUSED_LOCKED);
+            break;
+        default:
+            bWrongTransition = true;
+            break;
+        }
+    }
+    else if (m_afState == HAL_AFSTATE_LOCKED) {
+        switch (noti) {
+            case AA_AFSTATE_INACTIVE:
+            case AA_AFSTATE_ACTIVE_SCAN:
+                bWrongTransition = true;
+                break;
+            case AA_AFSTATE_AF_ACQUIRED_FOCUS:
+                nextState = NO_TRANSITION;
+                break;
+            case AA_AFSTATE_AF_FAILED_FOCUS:
+            default:
+                bWrongTransition = true;
+                break;
+        }
+    }
+    else if (m_afState == HAL_AFSTATE_FAILED) {
+        switch (noti) {
+            case AA_AFSTATE_INACTIVE:
+            case AA_AFSTATE_ACTIVE_SCAN:
+            case AA_AFSTATE_AF_ACQUIRED_FOCUS:
+                bWrongTransition = true;
+                break;
+            case AA_AFSTATE_AF_FAILED_FOCUS:
+                nextState = NO_TRANSITION;
+                break;
+            default:
+                bWrongTransition = true;
+                break;
+        }
+    }
+    if (bWrongTransition) {
+        ALOGV("(%s): Wrong Transition state(%d) noti(%d)", __FUNCTION__, m_afState, noti);
+        return;
+    }
+    ALOGV("(%s): State (%d) -> (%d) by (%d)", __FUNCTION__, m_afState, nextState, noti);
+    if (nextState != NO_TRANSITION)
+        m_afState = nextState;
+}
+
+void ExynosCameraHWInterface2::OnAfNotificationCAFPicture(enum aa_afstate noti)
+{
+    int nextState = NO_TRANSITION;
+    bool bWrongTransition = false;
+
+    if (m_afState == HAL_AFSTATE_INACTIVE) {
+        switch (noti) {
+        case AA_AFSTATE_INACTIVE:
+        case AA_AFSTATE_ACTIVE_SCAN:
+        case AA_AFSTATE_AF_ACQUIRED_FOCUS:
+        case AA_AFSTATE_AF_FAILED_FOCUS:
+        default:
+            nextState = NO_TRANSITION;
+            break;
+        }
+    }
+    else if (m_afState == HAL_AFSTATE_STARTED) {
+        switch (noti) {
+        case AA_AFSTATE_INACTIVE:
+            nextState = NO_TRANSITION;
+            break;
+        case AA_AFSTATE_ACTIVE_SCAN:
+            nextState = HAL_AFSTATE_SCANNING;
+            SetAfStateForService(ANDROID_CONTROL_AF_STATE_PASSIVE_SCAN);
+            break;
+        case AA_AFSTATE_AF_ACQUIRED_FOCUS:
+            nextState = HAL_AFSTATE_PASSIVE_FOCUSED;
+            SetAfStateForService(ANDROID_CONTROL_AF_STATE_PASSIVE_FOCUSED);
+            break;
+        case AA_AFSTATE_AF_FAILED_FOCUS:
+            nextState = HAL_AFSTATE_FAILED;
+            SetAfStateForService(ANDROID_CONTROL_AF_STATE_NOT_FOCUSED_LOCKED);
+            break;
+        default:
+            bWrongTransition = true;
+            break;
+        }
+    }
+    else if (m_afState == HAL_AFSTATE_SCANNING) {
+        switch (noti) {
+        case AA_AFSTATE_INACTIVE:
+            bWrongTransition = true;
+            break;
+        case AA_AFSTATE_ACTIVE_SCAN:
+            nextState = NO_TRANSITION;
+            break;
+        case AA_AFSTATE_AF_ACQUIRED_FOCUS:
+            nextState = HAL_AFSTATE_PASSIVE_FOCUSED;
+            SetAfStateForService(ANDROID_CONTROL_AF_STATE_PASSIVE_FOCUSED);
+            break;
+        case AA_AFSTATE_AF_FAILED_FOCUS:
+            nextState = NO_TRANSITION;
+            break;
+        default:
+            bWrongTransition = true;
+            break;
+        }
+    }
+    else if (m_afState == HAL_AFSTATE_PASSIVE_FOCUSED) {
+        switch (noti) {
+        case AA_AFSTATE_INACTIVE:
+            bWrongTransition = true;
+            break;
+        case AA_AFSTATE_ACTIVE_SCAN:
+            nextState = HAL_AFSTATE_SCANNING;
+            SetAfStateForService(ANDROID_CONTROL_AF_STATE_PASSIVE_SCAN);
+            break;
+        case AA_AFSTATE_AF_ACQUIRED_FOCUS:
+            nextState = NO_TRANSITION;
+            break;
+        case AA_AFSTATE_AF_FAILED_FOCUS:
+            nextState = HAL_AFSTATE_FAILED;
+            SetAfStateForService(ANDROID_CONTROL_AF_STATE_NOT_FOCUSED_LOCKED);
+            break;
+        default:
+            bWrongTransition = true;
+            break;
+        }
+    }
+    else if (m_afState == HAL_AFSTATE_NEEDS_DETERMINATION) {
+        switch (noti) {
+        case AA_AFSTATE_INACTIVE:
+            bWrongTransition = true;
+            break;
+        case AA_AFSTATE_ACTIVE_SCAN:
+            nextState = NO_TRANSITION;
+            break;
+        case AA_AFSTATE_AF_ACQUIRED_FOCUS:
+            m_IsAfLockRequired = true;
+            nextState = HAL_AFSTATE_LOCKED;
+            SetAfStateForService(ANDROID_CONTROL_AF_STATE_FOCUSED_LOCKED);
+            break;
+        case AA_AFSTATE_AF_FAILED_FOCUS:
+            m_IsAfLockRequired = true;
+            nextState = HAL_AFSTATE_FAILED;
+            SetAfStateForService(ANDROID_CONTROL_AF_STATE_NOT_FOCUSED_LOCKED);
+            break;
+        default:
+            bWrongTransition = true;
+            break;
+        }
+    }
+    else if (m_afState == HAL_AFSTATE_LOCKED) {
+        switch (noti) {
+            case AA_AFSTATE_INACTIVE:
+                nextState = NO_TRANSITION;
+                break;
+            case AA_AFSTATE_ACTIVE_SCAN:
+                bWrongTransition = true;
+                break;
+            case AA_AFSTATE_AF_ACQUIRED_FOCUS:
+                nextState = NO_TRANSITION;
+                break;
+            case AA_AFSTATE_AF_FAILED_FOCUS:
+            default:
+                bWrongTransition = true;
+                break;
+        }
+    }
+    else if (m_afState == HAL_AFSTATE_FAILED) {
+        switch (noti) {
+            case AA_AFSTATE_INACTIVE:
+            case AA_AFSTATE_ACTIVE_SCAN:
+            case AA_AFSTATE_AF_ACQUIRED_FOCUS:
+                bWrongTransition = true;
+                break;
+            case AA_AFSTATE_AF_FAILED_FOCUS:
+                nextState = NO_TRANSITION;
+                break;
+            default:
+                bWrongTransition = true;
+                break;
+        }
+    }
+    if (bWrongTransition) {
+        ALOGV("(%s): Wrong Transition state(%d) noti(%d)", __FUNCTION__, m_afState, noti);
+        return;
+    }
+    ALOGV("(%s): State (%d) -> (%d) by (%d)", __FUNCTION__, m_afState, nextState, noti);
+    if (nextState != NO_TRANSITION)
+        m_afState = nextState;
+}
+
+void ExynosCameraHWInterface2::OnAfNotificationCAFVideo(enum aa_afstate noti)
+{
+    int nextState = NO_TRANSITION;
+    bool bWrongTransition = false;
+
+    if (m_afState == HAL_AFSTATE_INACTIVE) {
+        switch (noti) {
+        case AA_AFSTATE_INACTIVE:
+        case AA_AFSTATE_ACTIVE_SCAN:
+        case AA_AFSTATE_AF_ACQUIRED_FOCUS:
+        case AA_AFSTATE_AF_FAILED_FOCUS:
+        default:
+            nextState = NO_TRANSITION;
+            break;
+        }
+    }
+    else if (m_afState == HAL_AFSTATE_STARTED) {
+        switch (noti) {
+        case AA_AFSTATE_INACTIVE:
+            nextState = NO_TRANSITION;
+            break;
+        case AA_AFSTATE_ACTIVE_SCAN:
+            nextState = HAL_AFSTATE_SCANNING;
+            SetAfStateForService(ANDROID_CONTROL_AF_STATE_PASSIVE_SCAN);
+            break;
+        case AA_AFSTATE_AF_ACQUIRED_FOCUS:
+            nextState = HAL_AFSTATE_PASSIVE_FOCUSED;
+            SetAfStateForService(ANDROID_CONTROL_AF_STATE_PASSIVE_FOCUSED);
+            break;
+        case AA_AFSTATE_AF_FAILED_FOCUS:
+            nextState = HAL_AFSTATE_FAILED;
+            SetAfStateForService(ANDROID_CONTROL_AF_STATE_NOT_FOCUSED_LOCKED);
+            break;
+        default:
+            bWrongTransition = true;
+            break;
+        }
+    }
+    else if (m_afState == HAL_AFSTATE_SCANNING) {
+        switch (noti) {
+        case AA_AFSTATE_INACTIVE:
+            bWrongTransition = true;
+            break;
+        case AA_AFSTATE_ACTIVE_SCAN:
+            nextState = NO_TRANSITION;
+            break;
+        case AA_AFSTATE_AF_ACQUIRED_FOCUS:
+            nextState = HAL_AFSTATE_PASSIVE_FOCUSED;
+            SetAfStateForService(ANDROID_CONTROL_AF_STATE_PASSIVE_FOCUSED);
+            break;
+        case AA_AFSTATE_AF_FAILED_FOCUS:
+            nextState = NO_TRANSITION;
+            break;
+        default:
+            bWrongTransition = true;
+            break;
+        }
+    }
+    else if (m_afState == HAL_AFSTATE_PASSIVE_FOCUSED) {
+        switch (noti) {
+        case AA_AFSTATE_INACTIVE:
+            bWrongTransition = true;
+            break;
+        case AA_AFSTATE_ACTIVE_SCAN:
+            nextState = HAL_AFSTATE_SCANNING;
+            SetAfStateForService(ANDROID_CONTROL_AF_STATE_PASSIVE_SCAN);
+            break;
+        case AA_AFSTATE_AF_ACQUIRED_FOCUS:
+            nextState = NO_TRANSITION;
+            break;
+        case AA_AFSTATE_AF_FAILED_FOCUS:
+            nextState = HAL_AFSTATE_FAILED;
+            SetAfStateForService(ANDROID_CONTROL_AF_STATE_NOT_FOCUSED_LOCKED);
+            break;
+        default:
+            bWrongTransition = true;
+            break;
+        }
+    }
+    else if (m_afState == HAL_AFSTATE_NEEDS_DETERMINATION) {
+        switch (noti) {
+        case AA_AFSTATE_INACTIVE:
+            bWrongTransition = true;
+            break;
+        case AA_AFSTATE_ACTIVE_SCAN:
+            nextState = NO_TRANSITION;
+            break;
+        case AA_AFSTATE_AF_ACQUIRED_FOCUS:
+            m_IsAfLockRequired = true;
+            nextState = HAL_AFSTATE_LOCKED;
+            SetAfStateForService(ANDROID_CONTROL_AF_STATE_FOCUSED_LOCKED);
+            break;
+        case AA_AFSTATE_AF_FAILED_FOCUS:
+            nextState = HAL_AFSTATE_FAILED;
+            SetAfStateForService(ANDROID_CONTROL_AF_STATE_NOT_FOCUSED_LOCKED);
+            break;
+        default:
+            bWrongTransition = true;
+            break;
+        }
+    }
+    else if (m_afState == HAL_AFSTATE_LOCKED) {
+        switch (noti) {
+            case AA_AFSTATE_INACTIVE:
+                nextState = NO_TRANSITION;
+                break;
+            case AA_AFSTATE_ACTIVE_SCAN:
+                bWrongTransition = true;
+                break;
+            case AA_AFSTATE_AF_ACQUIRED_FOCUS:
+                nextState = NO_TRANSITION;
+                break;
+            case AA_AFSTATE_AF_FAILED_FOCUS:
+            default:
+                bWrongTransition = true;
+                break;
+        }
+    }
+    else if (m_afState == HAL_AFSTATE_FAILED) {
+        switch (noti) {
+            case AA_AFSTATE_INACTIVE:
+            case AA_AFSTATE_ACTIVE_SCAN:
+            case AA_AFSTATE_AF_ACQUIRED_FOCUS:
+                bWrongTransition = true;
+                break;
+            case AA_AFSTATE_AF_FAILED_FOCUS:
+                nextState = NO_TRANSITION;
+                break;
+            default:
+                bWrongTransition = true;
+                break;
+        }
+    }
+    if (bWrongTransition) {
+        ALOGV("(%s): Wrong Transition state(%d) noti(%d)", __FUNCTION__, m_afState, noti);
+        return;
+    }
+    ALOGV("(%s): State (%d) -> (%d) by (%d)", __FUNCTION__, m_afState, nextState, noti);
+    if (nextState != NO_TRANSITION)
+        m_afState = nextState;
+}
+
+void ExynosCameraHWInterface2::OnAfCancel(int id)
+{
+    switch (m_afMode) {
+    case AA_AFMODE_AUTO:
+    case AA_AFMODE_MACRO:
+        OnAfCancelAutoMacro(id);
+        break;
+    case AA_AFMODE_CONTINUOUS_VIDEO:
+        OnAfCancelCAFVideo(id);
+        break;
+    case AA_AFMODE_CONTINUOUS_PICTURE:
+        OnAfCancelCAFPicture(id);
+        break;
+    case AA_AFMODE_OFF:
+    default:
+        break;
+    }
+}
+
+void ExynosCameraHWInterface2::OnAfCancelAutoMacro(int id)
+{
+    int nextState = NO_TRANSITION;
+    m_afTriggerId = id;
+
+    switch (m_afState) {
+    case HAL_AFSTATE_INACTIVE:
+        nextState = NO_TRANSITION;
+        break;
+    case HAL_AFSTATE_NEEDS_COMMAND:
+    case HAL_AFSTATE_STARTED:
+    case HAL_AFSTATE_SCANNING:
+    case HAL_AFSTATE_LOCKED:
+    case HAL_AFSTATE_FAILED:
+        SetAfMode(AA_AFMODE_OFF);
+        SetAfStateForService(ANDROID_CONTROL_AF_STATE_INACTIVE);
+        nextState = HAL_AFSTATE_INACTIVE;
+        break;
+    default:
+        break;
+    }
+    ALOGV("(%s): State (%d) -> (%d)", __FUNCTION__, m_afState, nextState);
+    if (nextState != NO_TRANSITION)
+        m_afState = nextState;
+}
+
+void ExynosCameraHWInterface2::OnAfCancelCAFPicture(int id)
+{
+    int nextState = NO_TRANSITION;
+    m_afTriggerId = id;
+
+    switch (m_afState) {
+    case HAL_AFSTATE_INACTIVE:
+        nextState = NO_TRANSITION;
+        break;
+    case HAL_AFSTATE_NEEDS_COMMAND:
+    case HAL_AFSTATE_STARTED:
+    case HAL_AFSTATE_SCANNING:
+    case HAL_AFSTATE_LOCKED:
+    case HAL_AFSTATE_FAILED:
+    case HAL_AFSTATE_NEEDS_DETERMINATION:
+    case HAL_AFSTATE_PASSIVE_FOCUSED:
+        SetAfMode(AA_AFMODE_OFF);
+        SetAfStateForService(ANDROID_CONTROL_AF_STATE_INACTIVE);
+        SetAfMode(AA_AFMODE_CONTINUOUS_PICTURE);
+        nextState = HAL_AFSTATE_INACTIVE;
+        break;
+    default:
+        break;
+    }
+    ALOGV("(%s): State (%d) -> (%d)", __FUNCTION__, m_afState, nextState);
+    if (nextState != NO_TRANSITION)
+        m_afState = nextState;
+}
+
+void ExynosCameraHWInterface2::OnAfCancelCAFVideo(int id)
+{
+    int nextState = NO_TRANSITION;
+    m_afTriggerId = id;
+
+    switch (m_afState) {
+    case HAL_AFSTATE_INACTIVE:
+        nextState = NO_TRANSITION;
+        break;
+    case HAL_AFSTATE_NEEDS_COMMAND:
+    case HAL_AFSTATE_STARTED:
+    case HAL_AFSTATE_SCANNING:
+    case HAL_AFSTATE_LOCKED:
+    case HAL_AFSTATE_FAILED:
+    case HAL_AFSTATE_NEEDS_DETERMINATION:
+    case HAL_AFSTATE_PASSIVE_FOCUSED:
+        SetAfMode(AA_AFMODE_OFF);
+        SetAfStateForService(ANDROID_CONTROL_AF_STATE_INACTIVE);
+        SetAfMode(AA_AFMODE_CONTINUOUS_VIDEO);
+        nextState = HAL_AFSTATE_INACTIVE;
+        break;
+    default:
+        break;
+    }
+    ALOGV("(%s): State (%d) -> (%d)", __FUNCTION__, m_afState, nextState);
+    if (nextState != NO_TRANSITION)
+        m_afState = nextState;
+}
+
+void ExynosCameraHWInterface2::SetAfStateForService(int newState)
+{
+    m_serviceAfState = newState;
+    m_notifyCb(CAMERA2_MSG_AUTOFOCUS, newState, m_afTriggerId, 0, m_callbackCookie);
+}
+
+int ExynosCameraHWInterface2::GetAfStateForService()
+{
+   return m_serviceAfState;
+}
+
+void ExynosCameraHWInterface2::SetAfMode(enum aa_afmode afMode)
+{
+    if (m_afMode != afMode) {
+        if (m_IsAfModeUpdateRequired) {
+            m_afMode2 = afMode;
+            ALOGV("(%s): pending(%d) and new(%d)", __FUNCTION__, m_afMode, afMode);
+        }
+        else {
+            ALOGV("(%s): current(%d) new(%d)", __FUNCTION__, m_afMode, afMode);
+            m_IsAfModeUpdateRequired = true;
+            m_afMode = afMode;
+        }
+    }
+}
+
 ExynosCameraHWInterface2::MainThread::~MainThread()
 {
     ALOGV("(%s):", __FUNCTION__);
index c09f0ea559f03aa821c43b70a530fcfc55d75e0c..a1490d2ca39fefc35338fe37adcbe4435deb5b04 100644 (file)
@@ -84,7 +84,15 @@ namespace android {
 
 #define SIGNAL_STREAM_DATA_COMING               (SIGNAL_THREAD_COMMON_LAST<<15)
 
-
+#define NO_TRANSITION                   (0)
+#define HAL_AFSTATE_INACTIVE            (1)
+#define HAL_AFSTATE_NEEDS_COMMAND       (2)
+#define HAL_AFSTATE_STARTED             (3)
+#define HAL_AFSTATE_SCANNING            (4)
+#define HAL_AFSTATE_LOCKED              (5)
+#define HAL_AFSTATE_FAILED              (6)
+#define HAL_AFSTATE_NEEDS_DETERMINATION (7)
+#define HAL_AFSTATE_PASSIVE_FOCUSED     (8)
 
 enum sensor_name {
     SENSOR_NAME_S5K3H2  = 1,
@@ -147,13 +155,13 @@ public:
     void    RegisterRequest(camera_metadata_t *new_request);
     void    DeregisterRequest(camera_metadata_t **deregistered_request);
     bool    PrepareFrame(size_t *num_entries, size_t *frame_size,
-                camera_metadata_t **prepared_frame);
-    int   MarkProcessingRequest(ExynosBuffer *buf);
+                camera_metadata_t **prepared_frame, int afState);
+    int     MarkProcessingRequest(ExynosBuffer * buf, int *afMode);
     void      NotifyStreamOutput(int frameCnt, int stream_id);
     void    DumpInfoWithIndex(int index);
     void    ApplyDynamicMetadata(struct camera2_shot_ext *shot_ext);
     void    CheckCompleted(int index);
-    void    UpdateIspParameters(struct camera2_shot_ext *shot_ext, int frameCnt);
+    void    UpdateIspParameters(struct camera2_shot_ext *shot_ext, int frameCnt, bool afTrigger);
     void    RegisterTimestamp(int frameCnt, nsecs_t *frameTime);
     uint64_t  GetTimestamp(int frameCnt);
     int     FindFrameCnt(struct camera2_shot_ext * shot_ext);
@@ -446,6 +454,22 @@ class MainThread : public SignalDrivenThread {
                             ExynosRect *rect);
     void            InitializeISPChain();
     void            StartISP();
+    int             GetAfState();
+    void            SetAfMode(enum aa_afmode afMode);
+    void            OnAfTrigger(int id);
+    void            OnAfTriggerAutoMacro(int id);
+    void            OnAfTriggerCAFPicture(int id);
+    void            OnAfTriggerCAFVideo(int id);
+    void            OnAfCancel(int id);
+    void            OnAfCancelAutoMacro(int id);
+    void            OnAfCancelCAFPicture(int id);
+    void            OnAfCancelCAFVideo(int id);
+    void            OnAfNotification(enum aa_afstate noti);
+    void            OnAfNotificationAutoMacro(enum aa_afstate noti);
+    void            OnAfNotificationCAFPicture(enum aa_afstate noti);
+    void            OnAfNotificationCAFVideo(enum aa_afstate noti);
+    void            SetAfStateForService(int newState);
+    int             GetAfStateForService();
     exif_attribute_t    mExifInfo;
     void               *m_exynosPictureCSC;
     void               *m_exynosVideoCSC;
@@ -495,6 +519,14 @@ class MainThread : public SignalDrivenThread {
 
     mutable Mutex    m_qbufLock;
 
+    int                                 m_afState;
+    int                                 m_afTriggerId;
+    enum aa_afmode                      m_afMode;
+    enum aa_afmode                      m_afMode2;
+    bool                                m_IsAfModeUpdateRequired;
+    bool                                m_IsAfTriggerRequired;
+    bool                                m_IsAfLockRequired;
+    int                                 m_serviceAfState;
 };
 
 }; // namespace android
index 42bdf6f7f950d63dc504991857c4b1a4ab7e2878..2110bbbc9c3ec493298fe2831997619b717e3f35 100644 (file)
@@ -80,7 +80,6 @@ status_t MetadataConverter::ToInternalShot(camera_metadata_t * request, struct c
     camera_metadata_entry_t curr_entry;
     struct camera2_shot * dst = NULL;
 
-    ALOGV("DEBUG(%s):", __FUNCTION__);
     if (request == NULL || dst_ext == NULL)
         return BAD_VALUE;
 
@@ -92,7 +91,6 @@ status_t MetadataConverter::ToInternalShot(camera_metadata_t * request, struct c
     for (index = 0 ; index < num_entry ; index++) {
 
         if (get_camera_metadata_entry(request, index, &curr_entry)==0) {
-            //ALOGV("### MetadataConverter.ToInternalCtl. tag(%x)", curr_entry.tag);
             switch (curr_entry.tag) {
 
             case ANDROID_LENS_FOCUS_DISTANCE:
@@ -415,7 +413,7 @@ status_t MetadataConverter::ToInternalShot(camera_metadata_t * request, struct c
             case ANDROID_CONTROL_AF_MODE:
                 if (NO_ERROR != CheckEntryTypeMismatch(&curr_entry, TYPE_BYTE, 1))
                     break;
-                dst->ctl.aa.afMode = (enum aa_afmode)curr_entry.data.u8[0];
+                dst->ctl.aa.afMode = (enum aa_afmode)(curr_entry.data.u8[0] + 1);
                 break;
 
             case ANDROID_CONTROL_AF_REGIONS: