• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
AndroidCamera2Capabilities(CameraCharacteristics p)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 
buildSceneModes(CameraCharacteristics p)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 
buildFlashModes(CameraCharacteristics p)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 
buildFocusModes(CameraCharacteristics p)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 
buildWhiteBalances(CameraCharacteristics p)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      */
focusModeFromInt(int fm)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      */
sceneModeFromInt(int sm)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      */
whiteBalanceFromInt(int wb)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