hardware: samsung_slsi: libcamera2: Add SceneMode support
authorSungjoong Kang <sj3.kang@samsung.com>
Fri, 17 Aug 2012 22:47:56 +0000 (15:47 -0700)
committerRebecca Schultz Zavin <rebecca@android.com>
Wed, 22 Aug 2012 00:22:22 +0000 (17:22 -0700)
This patch enables SceneMode feature.
Requires camera 4th release.

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

index 9f2c2583ac2898449b343029ef5dbc0e5beae861..cbdea7e967a476ebb24f03f72cf1e600789aaf43 100644 (file)
@@ -288,21 +288,6 @@ status_t ExynosCamera2::constructStaticInfo(camera_metadata_t **info,
     ADD_OR_SIZE(ANDROID_LENS_SHADING_MAP, lensShadingMap,
             sizeof(lensShadingMap)/sizeof(float));
 
-    // Identity transform
-    static const int32_t geometricCorrectionMapSize[] = {2, 2};
-    ADD_OR_SIZE(ANDROID_LENS_GEOMETRIC_CORRECTION_MAP_SIZE,
-            geometricCorrectionMapSize,
-            sizeof(geometricCorrectionMapSize)/sizeof(int32_t));
-
-    static const float geometricCorrectionMap[2 * 3 * 2 * 2] = {
-            0.f, 0.f,  0.f, 0.f,  0.f, 0.f,
-            1.f, 0.f,  1.f, 0.f,  1.f, 0.f,
-            0.f, 1.f,  0.f, 1.f,  0.f, 1.f,
-            1.f, 1.f,  1.f, 1.f,  1.f, 1.f};
-    ADD_OR_SIZE(ANDROID_LENS_GEOMETRIC_CORRECTION_MAP,
-            geometricCorrectionMap,
-            sizeof(geometricCorrectionMap)/sizeof(float));
-
     int32_t lensFacing = cameraId ?
             ANDROID_LENS_FACING_FRONT : ANDROID_LENS_FACING_BACK;
     ADD_OR_SIZE(ANDROID_LENS_FACING, &lensFacing, 1);
@@ -388,7 +373,7 @@ status_t ExynosCamera2::constructStaticInfo(camera_metadata_t **info,
             kAvailableJpegMinDurations,
             sizeof(kAvailableJpegMinDurations)/sizeof(uint64_t));
 
-    static const float maxZoom = 3.5;
+    static const float maxZoom = 1;
     ADD_OR_SIZE(ANDROID_SCALER_AVAILABLE_MAX_ZOOM, &maxZoom, 1);
 
     // android.jpeg
@@ -437,10 +422,10 @@ status_t ExynosCamera2::constructStaticInfo(camera_metadata_t **info,
     // android.control
 
     static const uint8_t availableSceneModes[] = {
-            ANDROID_CONTROL_SCENE_MODE_PARTY,
-            ANDROID_CONTROL_SCENE_MODE_SPORTS,
+            ANDROID_CONTROL_SCENE_MODE_ACTION,
             ANDROID_CONTROL_SCENE_MODE_NIGHT,
-            ANDROID_CONTROL_SCENE_MODE_BEACH
+            ANDROID_CONTROL_SCENE_MODE_SUNSET,
+            ANDROID_CONTROL_SCENE_MODE_PARTY
     };
     ADD_OR_SIZE(ANDROID_CONTROL_AVAILABLE_SCENE_MODES,
             availableSceneModes, sizeof(availableSceneModes));
@@ -463,12 +448,12 @@ status_t ExynosCamera2::constructStaticInfo(camera_metadata_t **info,
             availableAeModes, sizeof(availableAeModes));
 
     static const camera_metadata_rational exposureCompensationStep = {
-            1, 3
+            1, 1
     };
     ADD_OR_SIZE(ANDROID_CONTROL_AE_EXP_COMPENSATION_STEP,
             &exposureCompensationStep, 1);
 
-    int32_t exposureCompensationRange[] = {-9, 9};
+    int32_t exposureCompensationRange[] = {-3, 3};
     ADD_OR_SIZE(ANDROID_CONTROL_AE_EXP_COMPENSATION_RANGE,
             exposureCompensationRange,
             sizeof(exposureCompensationRange)/sizeof(int32_t));
@@ -493,7 +478,7 @@ status_t ExynosCamera2::constructStaticInfo(camera_metadata_t **info,
             ANDROID_CONTROL_AWB_INCANDESCENT,
             ANDROID_CONTROL_AWB_FLUORESCENT,
             ANDROID_CONTROL_AWB_DAYLIGHT,
-            ANDROID_CONTROL_AWB_SHADE
+            ANDROID_CONTROL_AWB_CLOUDY_DAYLIGHT
     };
     ADD_OR_SIZE(ANDROID_CONTROL_AWB_AVAILABLE_MODES,
             availableAwbModes, sizeof(availableAwbModes));
index b955c0a320c4df9a570413008f06ff9a39d45806..e1765f2b5cc089d0632e5613189cd485b6ef59aa 100644 (file)
@@ -268,6 +268,10 @@ RequestManager::RequestManager(SignalDrivenThread* main_thread):
     m_entryInsertionIndex(-1),
     m_entryProcessingIndex(-1),
     m_entryFrameOutputIndex(-1),
+    m_lastAeMode(0),
+    m_lastAaMode(0),
+    m_lastAwbMode(0),
+    m_lastAeComp(0),
     m_frameIndex(-1)
 {
     m_metadataConverter = new MetadataConverter;
@@ -589,6 +593,7 @@ void    RequestManager::UpdateIspParameters(struct camera2_shot_ext *shot_ext, i
 
     request_manager_entry * newEntry = &(entries[index]);
     request_shot = &(newEntry->internal_shot);
+    memcpy(&(shot_ext->shot.ctl), &(request_shot->shot.ctl), sizeof(struct camera2_ctl));
     shot_ext->request_sensor = 1;
     shot_ext->dis_bypass = 1;
     shot_ext->dnr_bypass = 1;
@@ -602,7 +607,34 @@ void    RequestManager::UpdateIspParameters(struct camera2_shot_ext *shot_ext, i
     shot_ext->shot.ctl.request.outputStreams[1] = 0;
     shot_ext->shot.ctl.request.outputStreams[2] = 0;
 
-
+    if (m_lastAaMode == request_shot->shot.ctl.aa.mode) {
+        shot_ext->shot.ctl.aa.mode = (enum aa_mode)(0);
+    }
+    else {
+        shot_ext->shot.ctl.aa.mode = request_shot->shot.ctl.aa.mode;
+        m_lastAaMode = (int)(shot_ext->shot.ctl.aa.mode);
+    }
+    if (m_lastAeMode == request_shot->shot.ctl.aa.aeMode) {
+        shot_ext->shot.ctl.aa.aeMode = (enum aa_aemode)(0);
+    }
+    else {
+        shot_ext->shot.ctl.aa.aeMode = request_shot->shot.ctl.aa.aeMode;
+        m_lastAeMode = (int)(shot_ext->shot.ctl.aa.aeMode);
+    }
+    if (m_lastAwbMode == request_shot->shot.ctl.aa.awbMode) {
+        shot_ext->shot.ctl.aa.awbMode = (enum aa_awbmode)(0);
+    }
+    else {
+        shot_ext->shot.ctl.aa.awbMode = request_shot->shot.ctl.aa.awbMode;
+        m_lastAwbMode = (int)(shot_ext->shot.ctl.aa.awbMode);
+    }
+    if (m_lastAeComp == request_shot->shot.ctl.aa.aeExpCompensation) {
+        shot_ext->shot.ctl.aa.aeExpCompensation = 0;
+    }
+    else {
+        shot_ext->shot.ctl.aa.aeExpCompensation = request_shot->shot.ctl.aa.aeExpCompensation;
+        m_lastAeComp = (int)(shot_ext->shot.ctl.aa.aeExpCompensation);
+    }
     if (afTrigger) {
         ALOGE("### AF Trigger ");
         shot_ext->shot.ctl.aa.afTrigger = 1;
@@ -629,12 +661,17 @@ void    RequestManager::UpdateIspParameters(struct camera2_shot_ext *shot_ext, i
             ALOGV("DEBUG(%s): outputstreams(%d) is for scalerP (record)", __FUNCTION__, i);
             shot_ext->request_scp = 1;
             shot_ext->shot.ctl.request.outputStreams[2] = 1;
+            shot_ext->shot.ctl.aa.aeTargetFpsRange[0] = 30;
+            shot_ext->shot.ctl.aa.aeTargetFpsRange[1] = 30;
         }
         else {
             ALOGV("DEBUG(%s): outputstreams(%d) has abnormal value(%d)", __FUNCTION__, i, targetStreamIndex);
         }
     }
-
+        ALOGV("(%s): applied aa(%d) aemode(%d) expComp(%d), awb(%d) afmode(%d), ", __FUNCTION__,
+        (int)(shot_ext->shot.ctl.aa.mode), (int)(shot_ext->shot.ctl.aa.aeMode),
+        (int)(shot_ext->shot.ctl.aa.aeExpCompensation), (int)(shot_ext->shot.ctl.aa.awbMode),
+        (int)(shot_ext->shot.ctl.aa.afMode));
 }
 
 int     RequestManager::FindEntryIndexByFrameCnt(int frameCnt)
index a1490d2ca39fefc35338fe37adcbe4435deb5b04..44e143662734cb9a05c5e4e13403a52229b143e6 100644 (file)
@@ -193,6 +193,10 @@ private:
     int                             m_sensorPipelineSkipCnt;
     int                             m_cropX;
     int                         m_frameIndex;
+    int                             m_lastAeMode;
+    int                             m_lastAaMode;
+    int                             m_lastAwbMode;
+    int                             m_lastAeComp;
 };
 
 
index 2110bbbc9c3ec493298fe2831997619b717e3f35..38c9ea7b3ce61a0829568401d668ab39e24bf1c0 100644 (file)
@@ -87,6 +87,10 @@ status_t MetadataConverter::ToInternalShot(camera_metadata_t * request, struct c
     dst = &dst_ext->shot;
 
     dst->magicNumber = 0x23456789;
+    dst->ctl.aa.aeTargetFpsRange[0] = 15;
+    dst->ctl.aa.aeTargetFpsRange[1] = 30;
+    dst->ctl.aa.aeExpCompensation = 5;
+
     num_entry = (uint32_t)get_camera_metadata_data_count(request);
     for (index = 0 ; index < num_entry ; index++) {
 
@@ -126,25 +130,6 @@ status_t MetadataConverter::ToInternalShot(camera_metadata_t * request, struct c
 
 
 
-            case ANDROID_SENSOR_EXPOSURE_TIME:
-                if (NO_ERROR != CheckEntryTypeMismatch(&curr_entry, TYPE_INT64, 1))
-                    break;
-                dst->ctl.sensor.exposureTime =  curr_entry.data.i64[0];
-                break;
-
-            case ANDROID_SENSOR_FRAME_DURATION:
-                if (NO_ERROR != CheckEntryTypeMismatch(&curr_entry, TYPE_INT64, 1))
-                    break;
-                dst->ctl.sensor.frameDuration = curr_entry.data.i64[0];
-                break;
-
-            case ANDROID_SENSOR_SENSITIVITY:
-                if (NO_ERROR != CheckEntryTypeMismatch(&curr_entry, TYPE_INT32, 1))
-                    break;
-                dst->ctl.sensor.sensitivity = curr_entry.data.i32[0];
-                break;
-
-
 
             case ANDROID_FLASH_MODE:
                 if (NO_ERROR != CheckEntryTypeMismatch(&curr_entry, TYPE_BYTE, 1))
@@ -182,20 +167,6 @@ status_t MetadataConverter::ToInternalShot(camera_metadata_t * request, struct c
 
 
 
-            case ANDROID_NOISE_MODE:
-                if (NO_ERROR != CheckEntryTypeMismatch(&curr_entry, TYPE_BYTE, 1))
-                    break;
-                dst->ctl.noise.mode = (enum processing_mode)curr_entry.data.u8[0];
-                break;
-
-            case ANDROID_NOISE_STRENGTH:
-                if (NO_ERROR != CheckEntryTypeMismatch(&curr_entry, TYPE_BYTE, 1))
-                    break;
-                dst->ctl.noise.strength= curr_entry.data.u8[0];
-                break;
-
-
-
             case ANDROID_SHADING_MODE:
                 if (NO_ERROR != CheckEntryTypeMismatch(&curr_entry, TYPE_BYTE, 1))
                     break;
@@ -256,19 +227,6 @@ status_t MetadataConverter::ToInternalShot(camera_metadata_t * request, struct c
 
 
 
-            case ANDROID_EDGE_MODE:
-                if (NO_ERROR != CheckEntryTypeMismatch(&curr_entry, TYPE_BYTE, 1))
-                    break;
-                dst->ctl.edge.mode = (enum processing_mode)curr_entry.data.u8[0];
-                break;
-
-            case ANDROID_EDGE_STRENGTH:
-                if (NO_ERROR != CheckEntryTypeMismatch(&curr_entry, TYPE_BYTE, 1))
-                    break;
-                dst->ctl.edge.strength = curr_entry.data.u8[0];
-                break;
-
-
 
             case ANDROID_SCALER_CROP_REGION:
                 if (NO_ERROR != CheckEntryTypeMismatch(&curr_entry, TYPE_INT32, 3))
@@ -369,27 +327,16 @@ status_t MetadataConverter::ToInternalShot(camera_metadata_t * request, struct c
                 if (NO_ERROR != CheckEntryTypeMismatch(&curr_entry, TYPE_BYTE, 1))
                     break;
                 dst->ctl.aa.aeMode = (enum aa_aemode)(curr_entry.data.u8[0] + 1);
+                ALOGV("DEBUG(%s): ANDROID_CONTROL_AE_MODE (%d)",  __FUNCTION__, dst->ctl.aa.aeMode);
                 break;
 
-            case ANDROID_CONTROL_AE_REGIONS:
-                if (NO_ERROR != CheckEntryTypeMismatch(&curr_entry, TYPE_INT32, 5))
-                    break;
-                for (i=0 ; i<curr_entry.count ; i++)
-                    dst->ctl.aa.aeRegions[i] = curr_entry.data.i32[i];
-                break;
 
             case ANDROID_CONTROL_AE_EXP_COMPENSATION:
                 if (NO_ERROR != CheckEntryTypeMismatch(&curr_entry, TYPE_INT32, 1))
                     break;
-                dst->ctl.aa.aeExpCompensation = curr_entry.data.i32[0];
+                dst->ctl.aa.aeExpCompensation = curr_entry.data.i32[0] + 5;
                 break;
 
-            case ANDROID_CONTROL_AE_TARGET_FPS_RANGE:
-                if (NO_ERROR != CheckEntryTypeMismatch(&curr_entry, TYPE_INT32, 2))
-                    break;
-                for (i=0 ; i<curr_entry.count ; i++)
-                    dst->ctl.aa.aeTargetFpsRange[i] = curr_entry.data.i32[i];
-                break;
 
             case ANDROID_CONTROL_AE_ANTIBANDING_MODE:
                 if (NO_ERROR != CheckEntryTypeMismatch(&curr_entry, TYPE_BYTE, 1))
@@ -458,17 +405,133 @@ status_t MetadataConverter::ToInternalShot(camera_metadata_t * request, struct c
                 ALOGV("DEBUG(%s): ANDROID_REQUEST_FRAME_COUNT (%d)",  __FUNCTION__, dst->ctl.request.frameCount);
                 break;
 
+            case ANDROID_CONTROL_SCENE_MODE:
+                if (NO_ERROR != CheckEntryTypeMismatch(&curr_entry, TYPE_BYTE, 1))
+                    break;
+                dst->ctl.aa.sceneMode = (enum aa_scene_mode)(curr_entry.data.u8[0] + 1);
+                ALOGV("DEBUG(%s): converted ANDROID_CONTROL_SCENE_MODE (%d)",  __FUNCTION__, dst->ctl.aa.sceneMode);
+                break;
+
             default:
                 ALOGV("DEBUG(%s):Bad Metadata tag (%d)",  __FUNCTION__, curr_entry.tag);
                 break;
             }
         }
     }
-
+    if (dst->ctl.aa.mode != ANDROID_CONTROL_USE_SCENE_MODE)
+        dst->ctl.aa.sceneMode = AA_SCENE_MODE_UNSUPPORTED;
+    ApplySceneModeParameters(request, dst_ext);
     return NO_ERROR;
 }
 
+status_t MetadataConverter::ApplySceneModeParameters(camera_metadata_t * request, struct camera2_shot_ext * dst_ext)
+{
+    camera_metadata_entry_t curr_entry;
+    struct camera2_shot * dst = NULL;
 
+    ALOGV("DEBUG(%s):", __FUNCTION__);
+
+    dst = &(dst_ext->shot);
+
+    switch (dst->ctl.aa.sceneMode) {
+
+    case AA_SCENE_MODE_ACTION:
+        dst->ctl.aa.mode = AA_CONTROL_USE_SCENE_MODE;
+        if (dst->ctl.aa.aeMode != AA_AEMODE_LOCKED)
+            dst->ctl.aa.aeMode = AA_AEMODE_ON;
+        dst->ctl.aa.awbMode = AA_AWBMODE_WB_AUTO;
+        dst->ctl.aa.isoMode = AA_ISOMODE_AUTO;
+        dst->ctl.aa.isoValue = 0;
+        dst->ctl.aa.aeTargetFpsRange[0] = 30;
+        dst->ctl.aa.aeTargetFpsRange[1] = 30;
+
+        dst->ctl.noise.mode = PROCESSING_MODE_FAST;
+        dst->ctl.noise.strength = 0;
+        dst->ctl.edge.mode = PROCESSING_MODE_FAST;
+        dst->ctl.edge.strength = 0;
+
+        dst->ctl.color.saturation = 3; // means '0'
+        // FLASH
+        // METERING
+        break;
+
+    case AA_SCENE_MODE_PARTY:
+        dst->ctl.aa.mode = AA_CONTROL_USE_SCENE_MODE;
+        if (dst->ctl.aa.aeMode != AA_AEMODE_LOCKED)
+            dst->ctl.aa.aeMode = AA_AEMODE_ON;
+        dst->ctl.aa.awbMode = AA_AWBMODE_WB_AUTO;
+        dst->ctl.aa.isoMode = AA_ISOMODE_MANUAL;
+        dst->ctl.aa.isoValue = 200;
+        dst->ctl.aa.aeTargetFpsRange[0] = 15;
+        dst->ctl.aa.aeTargetFpsRange[1] = 30;
+
+        dst->ctl.noise.mode = PROCESSING_MODE_FAST;
+        dst->ctl.noise.strength = 0;
+        dst->ctl.edge.mode = PROCESSING_MODE_FAST;
+        dst->ctl.edge.strength = 0;
+
+        dst->ctl.color.saturation = 4; // means '+1'
+        // FLASH
+        // METERING
+        break;
+
+    case AA_SCENE_MODE_SUNSET:
+        dst->ctl.aa.mode = AA_CONTROL_USE_SCENE_MODE;
+        if (dst->ctl.aa.aeMode != AA_AEMODE_LOCKED)
+            dst->ctl.aa.aeMode = AA_AEMODE_ON;
+        dst->ctl.aa.awbMode = AA_AWBMODE_WB_DAYLIGHT;
+        dst->ctl.aa.isoMode = AA_ISOMODE_AUTO;
+        dst->ctl.aa.isoValue = 0;
+        dst->ctl.aa.aeTargetFpsRange[0] = 15;
+        dst->ctl.aa.aeTargetFpsRange[1] = 30;
+
+        dst->ctl.noise.mode = PROCESSING_MODE_FAST;
+        dst->ctl.noise.strength = 0;
+        dst->ctl.edge.mode = PROCESSING_MODE_FAST;
+        dst->ctl.edge.strength = 0;
+
+        dst->ctl.color.saturation = 3; // means '0'
+        // FLASH
+        // METERING
+        break;
+
+    case AA_SCENE_MODE_NIGHT:
+        dst->ctl.aa.mode = AA_CONTROL_USE_SCENE_MODE;
+        if (dst->ctl.aa.aeMode != AA_AEMODE_LOCKED)
+            dst->ctl.aa.aeMode = AA_AEMODE_ON;
+        dst->ctl.aa.awbMode = AA_AWBMODE_WB_AUTO;
+        dst->ctl.aa.isoMode = AA_ISOMODE_AUTO;
+        dst->ctl.aa.isoValue = 0;
+        dst->ctl.aa.aeTargetFpsRange[0] = 2;
+        dst->ctl.aa.aeTargetFpsRange[1] = 30;
+
+        dst->ctl.noise.mode = PROCESSING_MODE_FAST;
+        dst->ctl.noise.strength = 0;
+        dst->ctl.edge.mode = PROCESSING_MODE_FAST;
+        dst->ctl.edge.strength = 0;
+
+        dst->ctl.color.saturation = 3; // means '0'
+        // FLASH
+        // METERING
+        break;
+
+    default:
+        dst->ctl.aa.mode = AA_CONTROL_AUTO;
+        if (dst->ctl.aa.aeMode != AA_AEMODE_LOCKED)
+            dst->ctl.aa.aeMode = AA_AEMODE_ON;
+        dst->ctl.aa.sceneMode = AA_SCENE_MODE_UNSUPPORTED;
+        dst->ctl.aa.isoMode = AA_ISOMODE_AUTO;
+        dst->ctl.aa.isoValue = 0;
+        dst->ctl.noise.mode = PROCESSING_MODE_OFF;
+        dst->ctl.noise.strength = 0;
+        dst->ctl.edge.mode = PROCESSING_MODE_OFF;
+        dst->ctl.edge.strength = 0;
+        dst->ctl.color.saturation = 3; // means '0'
+        break;
+    }
+
+    return NO_ERROR;
+}
 
 
 status_t MetadataConverter::ToDynamicMetadata(struct camera2_shot_ext * metadata_ext, camera_metadata_t * dst)
@@ -606,7 +669,7 @@ status_t MetadataConverter::ToDynamicMetadata(camera2_ctl_metadata_t * metadata,
         return NO_MEMORY;
 
     if (0 != add_camera_metadata_entry(dst, ANDROID_SENSOR_SENSITIVITY,
-                &(metadata->dm.sensor.sensitivity), 1))
+                &(metadata->dm.aa.isoValue), 1))
         return NO_MEMORY;
 
     if (0 != add_camera_metadata_entry(dst, ANDROID_SENSOR_TIMESTAMP,
index 6bf30cff7598490d30a18aa6e1aba1c524905113..077860978a2e0f02a8fccfb004a9fd839176c8aa 100644 (file)
@@ -52,6 +52,7 @@ public:
 private:
     status_t CheckEntryTypeMismatch(camera_metadata_entry_t * entry, uint8_t type);    
     status_t CheckEntryTypeMismatch(camera_metadata_entry_t * entry, uint8_t type, size_t count);
+    status_t ApplySceneModeParameters(camera_metadata_t * request, struct camera2_shot_ext * dst_ext);
   
 };