AndroidCamera2Capabilities.java revision c6344faeff899655abd60b3bf4cd638e58bcc3d7
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
17package com.android.ex.camera2.portability;
18
19import static android.hardware.camera2.CameraCharacteristics.*;
20
21import android.graphics.ImageFormat;
22import android.graphics.Point;
23import android.graphics.SurfaceTexture;
24import android.hardware.camera2.CameraCharacteristics;
25import android.hardware.camera2.params.StreamConfigurationMap;
26import android.media.MediaRecorder;
27import android.util.Range;
28import android.util.Rational;
29
30import com.android.ex.camera2.portability.debug.Log;
31
32import java.util.ArrayList;
33import java.util.Arrays;
34
35/**
36 * The subclass of {@link CameraCapabilities} for Android Camera 2 API.
37 */
38public 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        // TODO: Populate mMaxZoomRatio
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        // TODO: Detect other features
101    }
102
103    private void buildSceneModes(CameraCharacteristics p) {
104        int[] scenes = p.get(CONTROL_AVAILABLE_SCENE_MODES);
105        if (scenes != null) {
106            for (int scene : scenes) {
107                SceneMode equiv = sceneModeFromInt(scene);
108                if (equiv != null) {
109                    mSupportedSceneModes.add(equiv);
110                }
111            }
112        }
113    }
114
115    private void buildFlashModes(CameraCharacteristics p) {
116        mSupportedFlashModes.add(FlashMode.OFF);
117        if (p.get(FLASH_INFO_AVAILABLE)) {
118            mSupportedFlashModes.add(FlashMode.AUTO);
119            mSupportedFlashModes.add(FlashMode.ON);
120            mSupportedFlashModes.add(FlashMode.TORCH);
121            for (int expose : p.get(CONTROL_AE_AVAILABLE_MODES)) {
122                if (expose == CONTROL_AE_MODE_ON_AUTO_FLASH_REDEYE) {
123                    mSupportedFlashModes.add(FlashMode.RED_EYE);
124                }
125            }
126        }
127    }
128
129    private void buildFocusModes(CameraCharacteristics p) {
130        int[] focuses = p.get(CONTROL_AF_AVAILABLE_MODES);
131        if (focuses != null) {
132            for (int focus : focuses) {
133                FocusMode equiv = focusModeFromInt(focus);
134                if (equiv != null) {
135                    mSupportedFocusModes.add(equiv);
136                }
137            }
138        }
139    }
140
141    private void buildWhiteBalances(CameraCharacteristics p) {
142        int[] bals = p.get(CONTROL_AWB_AVAILABLE_MODES);
143        if (bals != null) {
144            for (int bal : bals) {
145                WhiteBalance equiv = whiteBalanceFromInt(bal);
146                if (equiv != null) {
147                    mSupportedWhiteBalances.add(equiv);
148                }
149            }
150        }
151    }
152
153    /**
154     * Converts the API-related integer representation of the focus mode to the
155     * abstract representation.
156     *
157     * @param fm The integral representation.
158     * @return The mode represented by the input integer, or {@code null} if it
159     *         cannot be converted.
160     */
161    public static FocusMode focusModeFromInt(int fm) {
162        switch (fm) {
163            case CONTROL_AF_MODE_AUTO:
164                return FocusMode.AUTO;
165            case CONTROL_AF_MODE_CONTINUOUS_PICTURE:
166                return FocusMode.CONTINUOUS_PICTURE;
167            case CONTROL_AF_MODE_CONTINUOUS_VIDEO:
168                return FocusMode.CONTINUOUS_VIDEO;
169            case CONTROL_AF_MODE_EDOF:
170                return FocusMode.EXTENDED_DOF;
171            case CONTROL_AF_MODE_OFF:
172                return FocusMode.FIXED;
173            // TODO: We cannot support INFINITY
174            case CONTROL_AF_MODE_MACRO:
175                return FocusMode.MACRO;
176        }
177        Log.w(TAG, "Unable to convert from API 2 focus mode: " + fm);
178        return null;
179    }
180
181    /**
182     * Converts the API-related integer representation of the scene mode to the
183     * abstract representation.
184     *
185     * @param sm The integral representation.
186     * @return The mode represented by the input integer, or {@code null} if it
187     *         cannot be converted.
188     */
189    public static SceneMode sceneModeFromInt(int sm) {
190        switch (sm) {
191            case CONTROL_SCENE_MODE_DISABLED:
192                return SceneMode.AUTO;
193            case CONTROL_SCENE_MODE_ACTION:
194                return SceneMode.ACTION;
195            case CONTROL_SCENE_MODE_BARCODE:
196                return SceneMode.BARCODE;
197            case CONTROL_SCENE_MODE_BEACH:
198                return SceneMode.BEACH;
199            case CONTROL_SCENE_MODE_CANDLELIGHT:
200                return SceneMode.CANDLELIGHT;
201            case CONTROL_SCENE_MODE_FIREWORKS:
202                return SceneMode.FIREWORKS;
203            // TODO: We cannot support HDR
204            case CONTROL_SCENE_MODE_LANDSCAPE:
205                return SceneMode.LANDSCAPE;
206            case CONTROL_SCENE_MODE_NIGHT:
207                return SceneMode.NIGHT;
208            // TODO: We cannot support NIGHT_PORTRAIT
209            case CONTROL_SCENE_MODE_PARTY:
210                return SceneMode.PARTY;
211            case CONTROL_SCENE_MODE_PORTRAIT:
212                return SceneMode.PORTRAIT;
213            case CONTROL_SCENE_MODE_SNOW:
214                return SceneMode.SNOW;
215            case CONTROL_SCENE_MODE_SPORTS:
216                return SceneMode.SPORTS;
217            case CONTROL_SCENE_MODE_STEADYPHOTO:
218                return SceneMode.STEADYPHOTO;
219            case CONTROL_SCENE_MODE_SUNSET:
220                return SceneMode.SUNSET;
221            case CONTROL_SCENE_MODE_THEATRE:
222                return SceneMode.THEATRE;
223            // TODO: We cannot expose FACE_PRIORITY, or HIGH_SPEED_VIDEO
224        }
225        Log.w(TAG, "Unable to convert from API 2 scene mode: " + sm);
226        return null;
227    }
228
229    /**
230     * Converts the API-related integer representation of the white balance to
231     * the abstract representation.
232     *
233     * @param wb The integral representation.
234     * @return The balance represented by the input integer, or {@code null} if
235     *         it cannot be converted.
236     */
237    public static WhiteBalance whiteBalanceFromInt(int wb) {
238        switch (wb) {
239            case CONTROL_AWB_MODE_AUTO:
240                return WhiteBalance.AUTO;
241            case CONTROL_AWB_MODE_CLOUDY_DAYLIGHT:
242                return WhiteBalance.CLOUDY_DAYLIGHT;
243            case CONTROL_AWB_MODE_DAYLIGHT:
244                return WhiteBalance.DAYLIGHT;
245            case CONTROL_AWB_MODE_FLUORESCENT:
246                return WhiteBalance.FLUORESCENT;
247            case CONTROL_AWB_MODE_INCANDESCENT:
248                return WhiteBalance.INCANDESCENT;
249            case CONTROL_AWB_MODE_SHADE:
250                return WhiteBalance.SHADE;
251            case CONTROL_AWB_MODE_TWILIGHT:
252                return WhiteBalance.TWILIGHT;
253            case CONTROL_AWB_MODE_WARM_FLUORESCENT:
254                return WhiteBalance.WARM_FLUORESCENT;
255        }
256        Log.w(TAG, "Unable to convert from API 2 white balance: " + wb);
257        return null;
258    }
259}
260