Home | History | Annotate | Download | only in portability
      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.ex.camera2.portability;
     18 
     19 import static android.hardware.camera2.CameraCharacteristics.*;
     20 
     21 import android.graphics.ImageFormat;
     22 import android.graphics.Point;
     23 import android.graphics.SurfaceTexture;
     24 import android.hardware.camera2.CameraCharacteristics;
     25 import android.hardware.camera2.params.StreamConfigurationMap;
     26 import android.media.MediaRecorder;
     27 import android.util.Range;
     28 import android.util.Rational;
     29 
     30 import com.android.ex.camera2.portability.debug.Log;
     31 
     32 import java.util.ArrayList;
     33 import java.util.Arrays;
     34 
     35 /**
     36  * The subclass of {@link CameraCapabilities} for Android Camera 2 API.
     37  */
     38 public class AndroidCamera2Capabilities extends CameraCapabilities {
     39     private static Log.Tag TAG = new Log.Tag("AndCam2Capabs");
     40 
     41     AndroidCamera2Capabilities(CameraCharacteristics p) {
     42         super(new Stringifier());
     43 
     44         StreamConfigurationMap s = p.get(SCALER_STREAM_CONFIGURATION_MAP);
     45 
     46         for (Range<Integer> fpsRange : p.get(CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES)) {
     47             mSupportedPreviewFpsRange.add(new int[] { fpsRange.getLower(), fpsRange.getUpper() });
     48         }
     49 
     50         // TODO: We only support TextureView preview rendering
     51         mSupportedPreviewSizes.addAll(Size.buildListFromAndroidSizes(Arrays.asList(
     52                 s.getOutputSizes(SurfaceTexture.class))));
     53         for (int format : s.getOutputFormats()) {
     54             mSupportedPreviewFormats.add(format);
     55         }
     56 
     57         // TODO: We only support MediaRecorder video capture
     58         mSupportedVideoSizes.addAll(Size.buildListFromAndroidSizes(Arrays.asList(
     59                 s.getOutputSizes(MediaRecorder.class))));
     60 
     61         // TODO: We only support JPEG image capture
     62         mSupportedPhotoSizes.addAll(Size.buildListFromAndroidSizes(Arrays.asList(
     63                 s.getOutputSizes(ImageFormat.JPEG))));
     64         mSupportedPhotoFormats.addAll(mSupportedPreviewFormats);
     65 
     66         buildSceneModes(p);
     67         buildFlashModes(p);
     68         buildFocusModes(p);
     69         buildWhiteBalances(p);
     70         // TODO: Populate mSupportedFeatures
     71 
     72         // TODO: Populate mPreferredPreviewSizeForVideo
     73 
     74         Range<Integer> ecRange = p.get(CONTROL_AE_COMPENSATION_RANGE);
     75         mMinExposureCompensation = ecRange.getLower();
     76         mMaxExposureCompensation = ecRange.getUpper();
     77 
     78         Rational ecStep = p.get(CONTROL_AE_COMPENSATION_STEP);
     79         mExposureCompensationStep = (float) ecStep.getNumerator() / ecStep.getDenominator();
     80 
     81         mMaxNumOfFacesSupported = p.get(STATISTICS_INFO_MAX_FACE_COUNT);
     82         mMaxNumOfMeteringArea = p.get(CONTROL_MAX_REGIONS_AE);
     83 
     84         mMaxZoomRatio = p.get(SCALER_AVAILABLE_MAX_DIGITAL_ZOOM);
     85         // TODO: Populate mHorizontalViewAngle
     86         // TODO: Populate mVerticalViewAngle
     87         // TODO: Populate mZoomRatioList
     88         // TODO: Populate mMaxZoomIndex
     89 
     90         if (supports(FocusMode.AUTO)) {
     91             mMaxNumOfFocusAreas = p.get(CONTROL_MAX_REGIONS_AF);
     92             if (mMaxNumOfFocusAreas > 0) {
     93                 mSupportedFeatures.add(Feature.FOCUS_AREA);
     94             }
     95         }
     96         if (mMaxNumOfMeteringArea > 0) {
     97             mSupportedFeatures.add(Feature.METERING_AREA);
     98         }
     99 
    100         if (mMaxZoomRatio > CameraCapabilities.ZOOM_RATIO_UNZOOMED) {
    101             mSupportedFeatures.add(Feature.ZOOM);
    102         }
    103 
    104         // TODO: Detect other features
    105     }
    106 
    107     private void buildSceneModes(CameraCharacteristics p) {
    108         int[] scenes = p.get(CONTROL_AVAILABLE_SCENE_MODES);
    109         if (scenes != null) {
    110             for (int scene : scenes) {
    111                 SceneMode equiv = sceneModeFromInt(scene);
    112                 if (equiv != null) {
    113                     mSupportedSceneModes.add(equiv);
    114                 }
    115             }
    116         }
    117     }
    118 
    119     private void buildFlashModes(CameraCharacteristics p) {
    120         mSupportedFlashModes.add(FlashMode.OFF);
    121         if (p.get(FLASH_INFO_AVAILABLE)) {
    122             mSupportedFlashModes.add(FlashMode.AUTO);
    123             mSupportedFlashModes.add(FlashMode.ON);
    124             mSupportedFlashModes.add(FlashMode.TORCH);
    125             for (int expose : p.get(CONTROL_AE_AVAILABLE_MODES)) {
    126                 if (expose == CONTROL_AE_MODE_ON_AUTO_FLASH_REDEYE) {
    127                     mSupportedFlashModes.add(FlashMode.RED_EYE);
    128                 }
    129             }
    130         }
    131     }
    132 
    133     private void buildFocusModes(CameraCharacteristics p) {
    134         int[] focuses = p.get(CONTROL_AF_AVAILABLE_MODES);
    135         if (focuses != null) {
    136             for (int focus : focuses) {
    137                 FocusMode equiv = focusModeFromInt(focus);
    138                 if (equiv != null) {
    139                     mSupportedFocusModes.add(equiv);
    140                 }
    141             }
    142         }
    143     }
    144 
    145     private void buildWhiteBalances(CameraCharacteristics p) {
    146         int[] bals = p.get(CONTROL_AWB_AVAILABLE_MODES);
    147         if (bals != null) {
    148             for (int bal : bals) {
    149                 WhiteBalance equiv = whiteBalanceFromInt(bal);
    150                 if (equiv != null) {
    151                     mSupportedWhiteBalances.add(equiv);
    152                 }
    153             }
    154         }
    155     }
    156 
    157     /**
    158      * Converts the API-related integer representation of the focus mode to the
    159      * abstract representation.
    160      *
    161      * @param fm The integral representation.
    162      * @return The mode represented by the input integer, or {@code null} if it
    163      *         cannot be converted.
    164      */
    165     public static FocusMode focusModeFromInt(int fm) {
    166         switch (fm) {
    167             case CONTROL_AF_MODE_AUTO:
    168                 return FocusMode.AUTO;
    169             case CONTROL_AF_MODE_CONTINUOUS_PICTURE:
    170                 return FocusMode.CONTINUOUS_PICTURE;
    171             case CONTROL_AF_MODE_CONTINUOUS_VIDEO:
    172                 return FocusMode.CONTINUOUS_VIDEO;
    173             case CONTROL_AF_MODE_EDOF:
    174                 return FocusMode.EXTENDED_DOF;
    175             case CONTROL_AF_MODE_OFF:
    176                 return FocusMode.FIXED;
    177             // TODO: We cannot support INFINITY
    178             case CONTROL_AF_MODE_MACRO:
    179                 return FocusMode.MACRO;
    180         }
    181         Log.w(TAG, "Unable to convert from API 2 focus mode: " + fm);
    182         return null;
    183     }
    184 
    185     /**
    186      * Converts the API-related integer representation of the scene mode to the
    187      * abstract representation.
    188      *
    189      * @param sm The integral representation.
    190      * @return The mode represented by the input integer, or {@code null} if it
    191      *         cannot be converted.
    192      */
    193     public static SceneMode sceneModeFromInt(int sm) {
    194         switch (sm) {
    195             case CONTROL_SCENE_MODE_DISABLED:
    196                 return SceneMode.AUTO;
    197             case CONTROL_SCENE_MODE_ACTION:
    198                 return SceneMode.ACTION;
    199             case CONTROL_SCENE_MODE_BARCODE:
    200                 return SceneMode.BARCODE;
    201             case CONTROL_SCENE_MODE_BEACH:
    202                 return SceneMode.BEACH;
    203             case CONTROL_SCENE_MODE_CANDLELIGHT:
    204                 return SceneMode.CANDLELIGHT;
    205             case CONTROL_SCENE_MODE_FIREWORKS:
    206                 return SceneMode.FIREWORKS;
    207             case CONTROL_SCENE_MODE_LANDSCAPE:
    208                 return SceneMode.LANDSCAPE;
    209             case CONTROL_SCENE_MODE_NIGHT:
    210                 return SceneMode.NIGHT;
    211             // TODO: We cannot support NIGHT_PORTRAIT
    212             case CONTROL_SCENE_MODE_PARTY:
    213                 return SceneMode.PARTY;
    214             case CONTROL_SCENE_MODE_PORTRAIT:
    215                 return SceneMode.PORTRAIT;
    216             case CONTROL_SCENE_MODE_SNOW:
    217                 return SceneMode.SNOW;
    218             case CONTROL_SCENE_MODE_SPORTS:
    219                 return SceneMode.SPORTS;
    220             case CONTROL_SCENE_MODE_STEADYPHOTO:
    221                 return SceneMode.STEADYPHOTO;
    222             case CONTROL_SCENE_MODE_SUNSET:
    223                 return SceneMode.SUNSET;
    224             case CONTROL_SCENE_MODE_THEATRE:
    225                 return SceneMode.THEATRE;
    226             case CONTROL_SCENE_MODE_HDR:
    227                 return SceneMode.HDR;
    228             // TODO: We cannot expose FACE_PRIORITY, or HIGH_SPEED_VIDEO
    229         }
    230 
    231         Log.w(TAG, "Unable to convert from API 2 scene mode: " + sm);
    232         return null;
    233     }
    234 
    235     /**
    236      * Converts the API-related integer representation of the white balance to
    237      * the abstract representation.
    238      *
    239      * @param wb The integral representation.
    240      * @return The balance represented by the input integer, or {@code null} if
    241      *         it cannot be converted.
    242      */
    243     public static WhiteBalance whiteBalanceFromInt(int wb) {
    244         switch (wb) {
    245             case CONTROL_AWB_MODE_AUTO:
    246                 return WhiteBalance.AUTO;
    247             case CONTROL_AWB_MODE_CLOUDY_DAYLIGHT:
    248                 return WhiteBalance.CLOUDY_DAYLIGHT;
    249             case CONTROL_AWB_MODE_DAYLIGHT:
    250                 return WhiteBalance.DAYLIGHT;
    251             case CONTROL_AWB_MODE_FLUORESCENT:
    252                 return WhiteBalance.FLUORESCENT;
    253             case CONTROL_AWB_MODE_INCANDESCENT:
    254                 return WhiteBalance.INCANDESCENT;
    255             case CONTROL_AWB_MODE_SHADE:
    256                 return WhiteBalance.SHADE;
    257             case CONTROL_AWB_MODE_TWILIGHT:
    258                 return WhiteBalance.TWILIGHT;
    259             case CONTROL_AWB_MODE_WARM_FLUORESCENT:
    260                 return WhiteBalance.WARM_FLUORESCENT;
    261         }
    262         Log.w(TAG, "Unable to convert from API 2 white balance: " + wb);
    263         return null;
    264     }
    265 }
    266