Home | History | Annotate | Download | only in v2
      1 /*
      2  * Copyright (C) 2014 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package com.android.camera.one.v2;
     18 
     19 import android.graphics.PointF;
     20 import android.graphics.Rect;
     21 import android.hardware.camera2.CameraCharacteristics;
     22 import android.hardware.camera2.CaptureResult;
     23 import android.hardware.camera2.params.MeteringRectangle;
     24 
     25 import com.android.camera.debug.Log;
     26 import com.android.camera.one.OneCamera;
     27 import com.android.camera.one.Settings3A;
     28 import com.android.camera.util.CameraUtil;
     29 
     30 /**
     31  * Helper class to implement auto focus and 3A in camera2-based
     32  * {@link com.android.camera.one.OneCamera} implementations.
     33  */
     34 @Deprecated
     35 public class AutoFocusHelper {
     36     private static final Log.Tag TAG = new Log.Tag("OneCameraAFHelp");
     37 
     38     /** camera2 API metering region weight. */
     39     private static final int CAMERA2_REGION_WEIGHT = (int)
     40         (CameraUtil.lerp(MeteringRectangle.METERING_WEIGHT_MIN, MeteringRectangle.METERING_WEIGHT_MAX,
     41                         Settings3A.getGcamMeteringRegionFraction()));
     42 
     43     /** Zero weight 3A region, to reset regions per API. */
     44     private static final MeteringRectangle[] ZERO_WEIGHT_3A_REGION = new MeteringRectangle[]{
     45             new MeteringRectangle(0, 0, 0, 0, 0)
     46     };
     47 
     48     public static MeteringRectangle[] getZeroWeightRegion() {
     49         return ZERO_WEIGHT_3A_REGION;
     50     }
     51 
     52     /**
     53      * Convert reported camera2 AF state to OneCamera AutoFocusState.
     54      */
     55     public static OneCamera.AutoFocusState stateFromCamera2State(int state) {
     56         switch (state) {
     57             case CaptureResult.CONTROL_AF_STATE_ACTIVE_SCAN:
     58                 return OneCamera.AutoFocusState.ACTIVE_SCAN;
     59             case CaptureResult.CONTROL_AF_STATE_PASSIVE_SCAN:
     60                 return OneCamera.AutoFocusState.PASSIVE_SCAN;
     61             case CaptureResult.CONTROL_AF_STATE_PASSIVE_FOCUSED:
     62                 return OneCamera.AutoFocusState.PASSIVE_FOCUSED;
     63             case CaptureResult.CONTROL_AF_STATE_FOCUSED_LOCKED:
     64                 return OneCamera.AutoFocusState.ACTIVE_FOCUSED;
     65             case CaptureResult.CONTROL_AF_STATE_PASSIVE_UNFOCUSED:
     66                 return OneCamera.AutoFocusState.PASSIVE_UNFOCUSED;
     67             case CaptureResult.CONTROL_AF_STATE_NOT_FOCUSED_LOCKED:
     68                 return OneCamera.AutoFocusState.ACTIVE_UNFOCUSED;
     69             default:
     70                 return OneCamera.AutoFocusState.INACTIVE;
     71         }
     72     }
     73 
     74     /**
     75      * Complain if CONTROL_AF_STATE is not present in result.
     76      * Could indicate bug in API implementation.
     77      */
     78     public static boolean checkControlAfState(CaptureResult result) {
     79         boolean missing = result.get(CaptureResult.CONTROL_AF_STATE) == null;
     80         if (missing) {
     81             // throw new IllegalStateException("CaptureResult missing CONTROL_AF_STATE.");
     82             Log.e(TAG, "\n!!!! TotalCaptureResult missing CONTROL_AF_STATE. !!!!\n ");
     83         }
     84         return !missing;
     85     }
     86 
     87     /**
     88      * Complain if LENS_STATE is not present in result.
     89      * Could indicate bug in API implementation.
     90      */
     91     public static boolean checkLensState(CaptureResult result) {
     92         boolean missing = result.get(CaptureResult.LENS_STATE) == null;
     93         if (missing) {
     94             // throw new IllegalStateException("CaptureResult missing LENS_STATE.");
     95             Log.e(TAG, "\n!!!! TotalCaptureResult missing LENS_STATE. !!!!\n ");
     96         }
     97         return !missing;
     98     }
     99 
    100 
    101     public static void logExtraFocusInfo(CaptureResult result) {
    102         if(!checkControlAfState(result) || !checkLensState(result)) {
    103             return;
    104         }
    105 
    106         Object tag = result.getRequest().getTag();
    107 
    108         Log.v(TAG, String.format("af_state:%-17s  lens_foc_dist:%.3f  lens_state:%-10s  %s",
    109                 controlAFStateToString(result.get(CaptureResult.CONTROL_AF_STATE)),
    110                 result.get(CaptureResult.LENS_FOCUS_DISTANCE),
    111                 lensStateToString(result.get(CaptureResult.LENS_STATE)),
    112                 (tag == null) ? "" : "[" + tag +"]"
    113         ));
    114     }
    115 
    116     /** Compute 3A regions for a sensor-referenced touch coordinate.
    117      * Returns a MeteringRectangle[] with length 1.
    118      *
    119      * @param nx x coordinate of the touch point, in normalized portrait coordinates.
    120      * @param ny y coordinate of the touch point, in normalized portrait coordinates.
    121      * @param fraction Fraction in [0,1]. Multiplied by min(cropRegion.width(), cropRegion.height())
    122      *             to determine the side length of the square MeteringRectangle.
    123      * @param cropRegion Crop region of the image.
    124      * @param sensorOrientation sensor orientation as defined by
    125      *             CameraCharacteristics.get(CameraCharacteristics.SENSOR_ORIENTATION).
    126      */
    127     private static MeteringRectangle[] regionsForNormalizedCoord(float nx, float ny,
    128         float fraction, final Rect cropRegion, int sensorOrientation) {
    129         // Compute half side length in pixels.
    130         int minCropEdge = Math.min(cropRegion.width(), cropRegion.height());
    131         int halfSideLength = (int) (0.5f * fraction * minCropEdge);
    132 
    133         // Compute the output MeteringRectangle in sensor space.
    134         // nx, ny is normalized to the screen.
    135         // Crop region itself is specified in sensor coordinates.
    136 
    137         // Normalized coordinates, now rotated into sensor space.
    138         PointF nsc = CameraUtil.normalizedSensorCoordsForNormalizedDisplayCoords(
    139             nx, ny, sensorOrientation);
    140 
    141         int xCenterSensor = (int)(cropRegion.left + nsc.x * cropRegion.width());
    142         int yCenterSensor = (int)(cropRegion.top + nsc.y * cropRegion.height());
    143 
    144         Rect meteringRegion = new Rect(xCenterSensor - halfSideLength,
    145             yCenterSensor - halfSideLength,
    146             xCenterSensor + halfSideLength,
    147             yCenterSensor + halfSideLength);
    148 
    149         // Clamp meteringRegion to cropRegion.
    150         meteringRegion.left = CameraUtil.clamp(meteringRegion.left, cropRegion.left, cropRegion.right);
    151         meteringRegion.top = CameraUtil.clamp(meteringRegion.top, cropRegion.top, cropRegion.bottom);
    152         meteringRegion.right = CameraUtil.clamp(meteringRegion.right, cropRegion.left, cropRegion.right);
    153         meteringRegion.bottom = CameraUtil.clamp(meteringRegion.bottom, cropRegion.top, cropRegion.bottom);
    154 
    155         return new MeteringRectangle[]{new MeteringRectangle(meteringRegion, CAMERA2_REGION_WEIGHT)};
    156     }
    157 
    158     /**
    159      * Return AF region(s) for a sensor-referenced touch coordinate.
    160      *
    161      * <p>
    162      * Normalized coordinates are referenced to portrait preview window with
    163      * (0, 0) top left and (1, 1) bottom right. Rotation has no effect.
    164      * </p>
    165      *
    166      * @return AF region(s).
    167      */
    168     public static MeteringRectangle[] afRegionsForNormalizedCoord(float nx,
    169         float ny, final Rect cropRegion, int sensorOrientation) {
    170         return regionsForNormalizedCoord(nx, ny, Settings3A.getAutoFocusRegionWidth(),
    171             cropRegion, sensorOrientation);
    172     }
    173 
    174     /**
    175      * Return AE region(s) for a sensor-referenced touch coordinate.
    176      *
    177      * <p>
    178      * Normalized coordinates are referenced to portrait preview window with
    179      * (0, 0) top left and (1, 1) bottom right. Rotation has no effect.
    180      * </p>
    181      *
    182      * @return AE region(s).
    183      */
    184     public static MeteringRectangle[] aeRegionsForNormalizedCoord(float nx,
    185         float ny, final Rect cropRegion, int sensorOrientation) {
    186         return regionsForNormalizedCoord(nx, ny, Settings3A.getMeteringRegionWidth(),
    187             cropRegion, sensorOrientation);
    188     }
    189 
    190     /**
    191      * [Gcam mode only]: Return AE region(s) for a sensor-referenced touch coordinate.
    192      *
    193      * <p>
    194      * Normalized coordinates are referenced to portrait preview window with
    195      * (0, 0) top left and (1, 1) bottom right. Rotation has no effect.
    196      * </p>
    197      *
    198      * @return AE region(s).
    199      */
    200     public static MeteringRectangle[] gcamAERegionsForNormalizedCoord(float nx,
    201         float ny, final Rect cropRegion, int sensorOrientation) {
    202         return regionsForNormalizedCoord(nx, ny, Settings3A.getGcamMeteringRegionFraction(),
    203             cropRegion, sensorOrientation);
    204     }
    205 
    206     /**
    207      * Calculates sensor crop region for a zoom level (zoom >= 1.0).
    208      *
    209      * @return Crop region.
    210      */
    211     public static Rect cropRegionForZoom(CameraCharacteristics characteristics, float zoom) {
    212         Rect sensor = characteristics.get(CameraCharacteristics.SENSOR_INFO_ACTIVE_ARRAY_SIZE);
    213         int xCenter = sensor.width() / 2;
    214         int yCenter = sensor.height() / 2;
    215         int xDelta = (int) (0.5f * sensor.width() / zoom);
    216         int yDelta = (int) (0.5f * sensor.height() / zoom);
    217         return new Rect(xCenter - xDelta, yCenter - yDelta, xCenter + xDelta, yCenter + yDelta);
    218     }
    219 
    220     /**
    221      * Utility function: converts CaptureResult.CONTROL_AF_STATE to String.
    222      */
    223     private static String controlAFStateToString(int controlAFState) {
    224         switch (controlAFState) {
    225             case CaptureResult.CONTROL_AF_STATE_INACTIVE:
    226                 return "inactive";
    227             case CaptureResult.CONTROL_AF_STATE_PASSIVE_SCAN:
    228                 return "passive_scan";
    229             case CaptureResult.CONTROL_AF_STATE_PASSIVE_FOCUSED:
    230                 return "passive_focused";
    231             case CaptureResult.CONTROL_AF_STATE_ACTIVE_SCAN:
    232                 return "active_scan";
    233             case CaptureResult.CONTROL_AF_STATE_FOCUSED_LOCKED:
    234                 return "focus_locked";
    235             case CaptureResult.CONTROL_AF_STATE_NOT_FOCUSED_LOCKED:
    236                 return "not_focus_locked";
    237             case CaptureResult.CONTROL_AF_STATE_PASSIVE_UNFOCUSED:
    238                 return "passive_unfocused";
    239             default:
    240                 return "unknown";
    241         }
    242     }
    243 
    244     /**
    245      * Utility function: converts CaptureResult.LENS_STATE to String.
    246      */
    247     private static String lensStateToString(int lensState) {
    248         switch (lensState) {
    249             case CaptureResult.LENS_STATE_MOVING:
    250                 return "moving";
    251             case CaptureResult.LENS_STATE_STATIONARY:
    252                 return "stationary";
    253             default:
    254                 return "unknown";
    255         }
    256     }
    257 
    258 }
    259