hardware: samsung_slsi: libcamera2: Enabled Face Detection
authorSungjoong Kang <sj3.kang@samsung.com>
Mon, 27 Aug 2012 00:44:25 +0000 (17:44 -0700)
committerRebecca Schultz Zavin <rebecca@android.com>
Wed, 29 Aug 2012 00:26:54 +0000 (17:26 -0700)
Face Detaction is enabled.

Change-Id: I3e004a10252cc2a4514951439203a1aae08e492b
Signed-off-by: Sungjoong Kang <sj3.kang@samsung.com>
libcamera2/ExynosCamera2.cpp
libcamera2/ExynosCamera2.h
libcamera2/ExynosCameraHWInterface2.cpp
libcamera2/MetadataConverter.cpp

index aea8970bffebd4512388d37f55d7e9f7965bdcc6..e62e3ce0e6b7d0df18b3a6bf8c5a8596c7d83ab4 100644 (file)
@@ -356,7 +356,7 @@ status_t ExynosCamera2::constructStaticInfo(camera_metadata_t **info,
     //TODO: sensor color calibration fields
 
     // android.flash
-    static const uint8_t flashAvailable = 0;
+    static const uint8_t flashAvailable = 1;
     ADD_OR_SIZE(ANDROID_FLASH_AVAILABLE, &flashAvailable, 1);
 
     static const int64_t flashChargeDuration = 0;
@@ -419,15 +419,16 @@ status_t ExynosCamera2::constructStaticInfo(camera_metadata_t **info,
     // android.stats
 
     static const uint8_t availableFaceDetectModes[] = {
-            ANDROID_STATS_FACE_DETECTION_OFF
+            ANDROID_STATS_FACE_DETECTION_OFF,
+            ANDROID_STATS_FACE_DETECTION_FULL
     };
     ADD_OR_SIZE(ANDROID_STATS_AVAILABLE_FACE_DETECT_MODES,
             availableFaceDetectModes,
             sizeof(availableFaceDetectModes));
 
-    static const int32_t maxFaceCount = 0;
+    m_curCameraInfo->maxFaceCount = 16;
     ADD_OR_SIZE(ANDROID_STATS_MAX_FACE_COUNT,
-            &maxFaceCount, 1);
+            &(m_curCameraInfo->maxFaceCount), 1);
 
     static const int32_t histogramSize = 64;
     ADD_OR_SIZE(ANDROID_STATS_HISTOGRAM_BUCKET_COUNT,
@@ -468,7 +469,8 @@ status_t ExynosCamera2::constructStaticInfo(camera_metadata_t **info,
 
     static const uint8_t availableAeModes[] = {
             ANDROID_CONTROL_AE_OFF,
-            ANDROID_CONTROL_AE_ON
+            ANDROID_CONTROL_AE_ON,
+            ANDROID_CONTROL_AE_ON_AUTO_FLASH
     };
     ADD_OR_SIZE(ANDROID_CONTROL_AE_AVAILABLE_MODES,
             availableAeModes, sizeof(availableAeModes));
@@ -749,7 +751,7 @@ status_t ExynosCamera2::constructDefaultRequest(
 
     /** android.stats */
 
-    static const uint8_t faceDetectMode = ANDROID_STATS_FACE_DETECTION_OFF;
+    static const uint8_t faceDetectMode = ANDROID_STATS_FACE_DETECTION_FULL;
     ADD_OR_SIZE(ANDROID_STATS_FACE_DETECT_MODE, &faceDetectMode, 1);
 
     static const uint8_t histogramMode = ANDROID_STATS_OFF;
index cbb817fe34953788d30fa52f09e9b9026d0b809e..68ac531325d763743053680eb9cc7adaedd16d79 100644 (file)
@@ -49,6 +49,9 @@ public:
     float       minFocusDistance;
     float       focalLength;
     float       aperture;
+
+    /* FD information */
+    int32_t    maxFaceCount;
 };
 
 struct ExynosCamera2InfoS5K4E5 : public ExynosCamera2Info
index 82756bb22eed2ba2037c5d7de56bc0e1b46afca7..52790328c80463b44481ebfd9878e638c2be0d01 100644 (file)
@@ -392,7 +392,7 @@ bool RequestManager::PrepareFrame(size_t* num_entries, size_t* frame_size,
         return false;
     }
     m_entryFrameOutputIndex = tempFrameOutputIndex;
-    m_tempFrameMetadata = place_camera_metadata(m_tempFrameMetadataBuf, 2000, 15, 500); //estimated
+    m_tempFrameMetadata = place_camera_metadata(m_tempFrameMetadataBuf, 2000, 20, 500); //estimated
     add_camera_metadata_entry(m_tempFrameMetadata, ANDROID_CONTROL_AF_STATE, &afState, 1);
     res = m_metadataConverter->ToDynamicMetadata(&(currentEntry->internal_shot),
                 m_tempFrameMetadata);
@@ -460,6 +460,8 @@ int RequestManager::MarkProcessingRequest(ExynosBuffer* buf, int *afMode)
         if (targetStreamIndex==0) {
             ALOGV("DEBUG(%s): outputstreams(%d) is for scalerP", __FUNCTION__, i);
             shot_ext->request_scp = 1;
+             if (shot_ext->shot.ctl.stats.faceDetectMode != FACEDETECT_MODE_OFF)
+                shot_ext->fd_bypass = 0;
         }
         else if (targetStreamIndex == 1) {
             ALOGV("DEBUG(%s): outputstreams(%d) is for scalerC", __FUNCTION__, i);
@@ -469,6 +471,8 @@ int RequestManager::MarkProcessingRequest(ExynosBuffer* buf, int *afMode)
             ALOGV("DEBUG(%s): outputstreams(%d) is for scalerP (record)", __FUNCTION__, i);
             shot_ext->request_scp = 1;
             shot_ext->shot.ctl.request.outputStreams[2] = 1;
+            if (shot_ext->shot.ctl.stats.faceDetectMode != FACEDETECT_MODE_OFF)
+                shot_ext->fd_bypass = 0;
         }
         else {
             ALOGV("DEBUG(%s): outputstreams(%d) has abnormal value(%d)", __FUNCTION__, i, targetStreamIndex);
@@ -658,10 +662,14 @@ void    RequestManager::UpdateIspParameters(struct camera2_shot_ext *shot_ext, i
         if (targetStreamIndex==0) {
             ALOGV("DEBUG(%s): outputstreams(%d) is for scalerP", __FUNCTION__, i);
             shot_ext->request_scp = 1;
+            if (shot_ext->shot.ctl.stats.faceDetectMode != FACEDETECT_MODE_OFF)
+                shot_ext->fd_bypass = 0;
         }
         else if (targetStreamIndex == 1) {
             ALOGV("DEBUG(%s): outputstreams(%d) is for scalerC", __FUNCTION__, i);
             shot_ext->request_scc = 1;
+            if (shot_ext->shot.ctl.stats.faceDetectMode != FACEDETECT_MODE_OFF)
+                shot_ext->fd_bypass = 0;
         }
         else if (targetStreamIndex == 2) {
             ALOGV("DEBUG(%s): outputstreams(%d) is for scalerP (record)", __FUNCTION__, i);
@@ -669,6 +677,8 @@ void    RequestManager::UpdateIspParameters(struct camera2_shot_ext *shot_ext, i
             shot_ext->shot.ctl.request.outputStreams[2] = 1;
             shot_ext->shot.ctl.aa.aeTargetFpsRange[0] = 30;
             shot_ext->shot.ctl.aa.aeTargetFpsRange[1] = 30;
+            if (shot_ext->shot.ctl.stats.faceDetectMode != FACEDETECT_MODE_OFF)
+                shot_ext->fd_bypass = 0;
         }
         else {
             ALOGV("DEBUG(%s): outputstreams(%d) has abnormal value(%d)", __FUNCTION__, i, targetStreamIndex);
@@ -2451,6 +2461,28 @@ void ExynosCameraHWInterface2::m_sensorThreadFunc(SignalDrivenThread * self)
             else
                 m_scp_closed = false;
 
+            if (!shot_ext->fd_bypass) {
+                /* FD orientation axis transformation */
+                for (int i=0; i < CAMERA2_MAX_FACES; i++) {
+                    if (shot_ext->shot.dm.stats.faceRectangles[i][0] > 0)
+                        shot_ext->shot.dm.stats.faceRectangles[i][0] = (m_camera2->m_curCameraInfo->sensorW
+                                                                                                       * shot_ext->shot.dm.stats.faceRectangles[i][0])
+                                                                                                       / m_streamThreads[0].get()->m_parameters.outputWidth;
+                    if (shot_ext->shot.dm.stats.faceRectangles[i][1] > 0)
+                        shot_ext->shot.dm.stats.faceRectangles[i][1] = (m_camera2->m_curCameraInfo->sensorH
+                                                                                                       * shot_ext->shot.dm.stats.faceRectangles[i][1])
+                                                                                                       / m_streamThreads[0].get()->m_parameters.outputHeight;
+                    if (shot_ext->shot.dm.stats.faceRectangles[i][2] > 0)
+                        shot_ext->shot.dm.stats.faceRectangles[i][2] = (m_camera2->m_curCameraInfo->sensorW
+                                                                                                       * shot_ext->shot.dm.stats.faceRectangles[i][2])
+                                                                                                       / m_streamThreads[0].get()->m_parameters.outputWidth;
+                    if (shot_ext->shot.dm.stats.faceRectangles[i][3] > 0)
+                        shot_ext->shot.dm.stats.faceRectangles[i][3] = (m_camera2->m_curCameraInfo->sensorH
+                                                                                                       * shot_ext->shot.dm.stats.faceRectangles[i][3])
+                                                                                                       / m_streamThreads[0].get()->m_parameters.outputHeight;
+                }
+            }
+
             m_requestManager->ApplyDynamicMetadata(shot_ext);
             OnAfNotification(shot_ext->shot.dm.aa.afState);
         }
index 869fae32e2bf61676b2ef9635af341a7b8512369..bc069aa4724b9ed7cf70dc5775cedebcb4544a91 100644 (file)
@@ -485,11 +485,33 @@ status_t MetadataConverter::ToDynamicMetadata(struct camera2_shot_ext * metadata
                 &intData, 1))
         return NO_MEMORY;
 
-    byteData = ANDROID_STATS_FACE_DETECTION_OFF;
+    byteData = metadata->dm.stats.faceDetectMode - 1;
     if (0 != add_camera_metadata_entry(dst, ANDROID_STATS_FACE_DETECT_MODE,
                 &byteData, 1))
         return NO_MEMORY;
 
+    int maxFacecount = 16;
+    if (0 != add_camera_metadata_entry(dst, ANDROID_STATS_MAX_FACE_COUNT,
+                &maxFacecount, 1))
+        return NO_MEMORY;
+
+    if (0 != add_camera_metadata_entry(dst, ANDROID_STATS_FACE_RECTANGLES,
+                &metadata->dm.stats.faceRectangles, 4 * maxFacecount))
+        return NO_MEMORY;
+
+    if (0 != add_camera_metadata_entry(dst, ANDROID_STATS_FACE_LANDMARKS,
+                &metadata->dm.stats.faceLandmarks, 6 * maxFacecount))
+        return NO_MEMORY;
+
+    if (0 != add_camera_metadata_entry(dst, ANDROID_STATS_FACE_IDS,
+                &metadata->dm.stats.faceIds, maxFacecount))
+        return NO_MEMORY;
+
+    if (0 != add_camera_metadata_entry(dst, ANDROID_STATS_FACE_SCORES,
+                &metadata->dm.stats.faceScores, maxFacecount))
+        return NO_MEMORY;
+
+
     ALOGV("(%s): AWB(%d) AE(%d) SCENE(%d)  AEComp(%d)", __FUNCTION__,
        metadata->dm.aa.awbMode - 1, metadata->dm.aa.aeMode - 1, metadata->ctl.aa.sceneMode - 1,
        metadata->ctl.aa.aeExpCompensation );