AndroidCameraCapabilities.java revision 01e7c02174ef268b6d6daaa5a5bb4f752d55964c
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 android.hardware.Camera;
20
21import com.android.ex.camera2.portability.debug.Log;
22
23import java.util.Collections;
24import java.util.Comparator;
25import java.util.List;
26
27/**
28 * The subclass of {@link CameraCapabilities} for Android Camera 1 API.
29 */
30class AndroidCameraCapabilities extends CameraCapabilities {
31
32    private static Log.Tag TAG = new Log.Tag("AndroidCameraCapabilities");
33
34    private FpsComparator mFpsComparator = new FpsComparator();
35    private SizeComparator mSizeComparator = new SizeComparator();
36
37    AndroidCameraCapabilities(Camera.Parameters p) {
38        super(new AndroidCameraCapabilityStringifier());
39        mMaxExposureCompensation = p.getMaxExposureCompensation();
40        mMinExposureCompensation = p.getMinExposureCompensation();
41        mExposureCompensationStep = p.getExposureCompensationStep();
42        mMaxNumOfFacesSupported = p.getMaxNumDetectedFaces();
43        mMaxNumOfMeteringArea = p.getMaxNumMeteringAreas();
44        mPreferredPreviewSizeForVideo = new Size(p.getPreferredPreviewSizeForVideo());
45        mSupportedPreviewFormats.addAll(p.getSupportedPreviewFormats());
46        mSupportedPhotoFormats.addAll(p.getSupportedPictureFormats());
47        mMaxZoomIndex = p.getMaxZoom();
48        mZoomRatioList.addAll(p.getZoomRatios());
49        mMaxZoomRatio = mZoomRatioList.get(mMaxZoomIndex);
50        mHorizontalViewAngle = p.getHorizontalViewAngle();
51        mVerticalViewAngle = p.getVerticalViewAngle();
52        buildPreviewFpsRange(p);
53        buildPreviewSizes(p);
54        buildVideoSizes(p);
55        buildPictureSizes(p);
56        buildSceneModes(p);
57        buildFlashModes(p);
58        buildFocusModes(p);
59        buildWhiteBalances(p);
60
61        if (p.isZoomSupported()) {
62            mSupportedFeatures.add(Feature.ZOOM);
63        }
64        if (p.isVideoSnapshotSupported()) {
65            mSupportedFeatures.add(Feature.VIDEO_SNAPSHOT);
66        }
67        if (p.isAutoExposureLockSupported()) {
68            mSupportedFeatures.add(Feature.AUTO_EXPOSURE_LOCK);
69        }
70        if (p.isAutoWhiteBalanceLockSupported()) {
71            mSupportedFeatures.add(Feature.AUTO_WHITE_BALANCE_LOCK);
72        }
73        if (supports(FocusMode.AUTO)) {
74            mMaxNumOfFocusAreas = p.getMaxNumFocusAreas();
75            if (mMaxNumOfFocusAreas > 0) {
76                mSupportedFeatures.add(Feature.FOCUS_AREA);
77            }
78        }
79        if (mMaxNumOfMeteringArea > 0) {
80            mSupportedFeatures.add(Feature.METERING_AREA);
81        }
82    }
83
84    AndroidCameraCapabilities(AndroidCameraCapabilities src) {
85        super(src);
86    }
87
88    private void buildPreviewFpsRange(Camera.Parameters p) {
89        List<int[]> supportedPreviewFpsRange = p.getSupportedPreviewFpsRange();
90        if (supportedPreviewFpsRange != null) {
91            mSupportedPreviewFpsRange.addAll(supportedPreviewFpsRange);
92        }
93        Collections.sort(mSupportedPreviewFpsRange, mFpsComparator);
94    }
95
96    private void buildPreviewSizes(Camera.Parameters p) {
97        List<Camera.Size> supportedPreviewSizes = p.getSupportedPreviewSizes();
98        if (supportedPreviewSizes != null) {
99            for (Camera.Size s : supportedPreviewSizes) {
100                mSupportedPreviewSizes.add(new Size(s.width, s.height));
101            }
102        }
103        Collections.sort(mSupportedPreviewSizes, mSizeComparator);
104    }
105
106    private void buildVideoSizes(Camera.Parameters p) {
107        List<Camera.Size> supportedVideoSizes = p.getSupportedVideoSizes();
108        if (supportedVideoSizes != null) {
109            for (Camera.Size s : supportedVideoSizes) {
110                mSupportedVideoSizes.add(new Size(s.width, s.height));
111            }
112        }
113        Collections.sort(mSupportedVideoSizes, mSizeComparator);
114    }
115
116    private void buildPictureSizes(Camera.Parameters p) {
117        List<Camera.Size> supportedPictureSizes = p.getSupportedPictureSizes();
118        if (supportedPictureSizes != null) {
119            for (Camera.Size s : supportedPictureSizes) {
120                mSupportedPhotoSizes.add(new Size(s.width, s.height));
121            }
122        }
123        Collections.sort(mSupportedPhotoSizes, mSizeComparator);
124
125    }
126
127    private void buildSceneModes(Camera.Parameters p) {
128        List<String> supportedSceneModes = p.getSupportedSceneModes();
129        if (supportedSceneModes != null) {
130            for (String scene : supportedSceneModes) {
131                if (Camera.Parameters.SCENE_MODE_AUTO.equals(scene)) {
132                    mSupportedSceneModes.add(SceneMode.AUTO);
133                } else if (Camera.Parameters.SCENE_MODE_ACTION.equals(scene)) {
134                    mSupportedSceneModes.add(SceneMode.ACTION);
135                } else if (Camera.Parameters.SCENE_MODE_BARCODE.equals(scene)) {
136                    mSupportedSceneModes.add(SceneMode.BARCODE);
137                } else if (Camera.Parameters.SCENE_MODE_BEACH.equals(scene)) {
138                    mSupportedSceneModes.add(SceneMode.BEACH);
139                } else if (Camera.Parameters.SCENE_MODE_CANDLELIGHT.equals(scene)) {
140                    mSupportedSceneModes.add(SceneMode.CANDLELIGHT);
141                } else if (Camera.Parameters.SCENE_MODE_FIREWORKS.equals(scene)) {
142                    mSupportedSceneModes.add(SceneMode.FIREWORKS);
143                } else if (Camera.Parameters.SCENE_MODE_HDR.equals(scene)) {
144                    mSupportedSceneModes.add(SceneMode.HDR);
145                } else if (Camera.Parameters.SCENE_MODE_LANDSCAPE.equals(scene)) {
146                    mSupportedSceneModes.add(SceneMode.LANDSCAPE);
147                } else if (Camera.Parameters.SCENE_MODE_NIGHT.equals(scene)) {
148                    mSupportedSceneModes.add(SceneMode.NIGHT);
149                } else if (Camera.Parameters.SCENE_MODE_NIGHT_PORTRAIT.equals(scene)) {
150                    mSupportedSceneModes.add(SceneMode.NIGHT_PORTRAIT);
151                } else if (Camera.Parameters.SCENE_MODE_PARTY.equals(scene)) {
152                    mSupportedSceneModes.add(SceneMode.PARTY);
153                } else if (Camera.Parameters.SCENE_MODE_PORTRAIT.equals(scene)) {
154                    mSupportedSceneModes.add(SceneMode.PORTRAIT);
155                } else if (Camera.Parameters.SCENE_MODE_SNOW.equals(scene)) {
156                    mSupportedSceneModes.add(SceneMode.SNOW);
157                } else if (Camera.Parameters.SCENE_MODE_SPORTS.equals(scene)) {
158                    mSupportedSceneModes.add(SceneMode.SPORTS);
159                } else if (Camera.Parameters.SCENE_MODE_STEADYPHOTO.equals(scene)) {
160                    mSupportedSceneModes.add(SceneMode.STEADYPHOTO);
161                } else if (Camera.Parameters.SCENE_MODE_SUNSET.equals(scene)) {
162                    mSupportedSceneModes.add(SceneMode.SUNSET);
163                } else if (Camera.Parameters.SCENE_MODE_THEATRE.equals(scene)) {
164                    mSupportedSceneModes.add(SceneMode.THEATRE);
165                }
166            }
167        }
168    }
169
170    private void buildFlashModes(Camera.Parameters p) {
171        List<String> supportedFlashModes = p.getSupportedFlashModes();
172        if (supportedFlashModes == null) {
173            // Camera 1 will return NULL if no flash mode is supported.
174            mSupportedFlashModes.add(FlashMode.NO_FLASH);
175        } else {
176            for (String flash : supportedFlashModes) {
177                if (Camera.Parameters.FLASH_MODE_AUTO.equals(flash)) {
178                    mSupportedFlashModes.add(FlashMode.AUTO);
179                } else if (Camera.Parameters.FLASH_MODE_OFF.equals(flash)) {
180                    mSupportedFlashModes.add(FlashMode.OFF);
181                } else if (Camera.Parameters.FLASH_MODE_ON.equals(flash)) {
182                    mSupportedFlashModes.add(FlashMode.ON);
183                } else if (Camera.Parameters.FLASH_MODE_RED_EYE.equals(flash)) {
184                    mSupportedFlashModes.add(FlashMode.RED_EYE);
185                }
186            }
187        }
188    }
189
190    private void buildFocusModes(Camera.Parameters p) {
191        List<String> supportedFocusModes = p.getSupportedFocusModes();
192        if (supportedFocusModes != null) {
193            for (String focus : supportedFocusModes) {
194                if (Camera.Parameters.FOCUS_MODE_AUTO.equals(focus)) {
195                    mSupportedFocusModes.add(FocusMode.AUTO);
196                } else if (Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE.equals(focus)) {
197                    mSupportedFocusModes.add(FocusMode.CONTINUOUS_PICTURE);
198                } else if (Camera.Parameters.FOCUS_MODE_CONTINUOUS_VIDEO.equals(focus)) {
199                    mSupportedFocusModes.add(FocusMode.CONTINUOUS_VIDEO);
200                } else if (Camera.Parameters.FOCUS_MODE_EDOF.equals(focus)) {
201                    mSupportedFocusModes.add(FocusMode.EXTENDED_DOF);
202                } else if (Camera.Parameters.FOCUS_MODE_FIXED.equals(focus)) {
203                    mSupportedFocusModes.add(FocusMode.FIXED);
204                } else if (Camera.Parameters.FOCUS_MODE_INFINITY.equals(focus)) {
205                    mSupportedFocusModes.add(FocusMode.INFINITY);
206                } else if (Camera.Parameters.FOCUS_MODE_MACRO.equals(focus)) {
207                    mSupportedFocusModes.add(FocusMode.MACRO);
208                }
209            }
210        }
211    }
212
213    private void buildWhiteBalances(Camera.Parameters p) {
214        List<String> supportedWhiteBalances = p.getSupportedFocusModes();
215        if (supportedWhiteBalances != null) {
216            for (String wb : supportedWhiteBalances) {
217                if (Camera.Parameters.WHITE_BALANCE_AUTO.equals(wb)) {
218                    mSupportedWhiteBalances.add(WhiteBalance.AUTO);
219                } else if (Camera.Parameters.WHITE_BALANCE_CLOUDY_DAYLIGHT.equals(wb)) {
220                    mSupportedWhiteBalances.add(WhiteBalance.CLOUDY_DAYLIGHT);
221                } else if (Camera.Parameters.WHITE_BALANCE_DAYLIGHT.equals(wb)) {
222                    mSupportedWhiteBalances.add(WhiteBalance.DAYLIGHT);
223                } else if (Camera.Parameters.WHITE_BALANCE_FLUORESCENT.equals(wb)) {
224                    mSupportedWhiteBalances.add(WhiteBalance.FLUORESCENT);
225                } else if (Camera.Parameters.WHITE_BALANCE_INCANDESCENT.equals(wb)) {
226                    mSupportedWhiteBalances.add(WhiteBalance.INCANDESCENT);
227                } else if (Camera.Parameters.WHITE_BALANCE_SHADE.equals(wb)) {
228                    mSupportedWhiteBalances.add(WhiteBalance.SHADE);
229                } else if (Camera.Parameters.WHITE_BALANCE_TWILIGHT.equals(wb)) {
230                    mSupportedWhiteBalances.add(WhiteBalance.TWILIGHT);
231                } else if (Camera.Parameters.WHITE_BALANCE_WARM_FLUORESCENT.equals(wb)) {
232                    mSupportedWhiteBalances.add(WhiteBalance.WARM_FLUORESCENT);
233                }
234            }
235        }
236    }
237
238    private static class FpsComparator implements Comparator<int[]> {
239        @Override
240        public int compare(int[] fps1, int[] fps2) {
241            return (fps1[0] == fps2[0] ? fps1[1] - fps2[1] : fps1[0] - fps2[0]);
242        }
243    }
244
245    private static class SizeComparator implements Comparator<Size> {
246
247        @Override
248        public int compare(Size size1, Size size2) {
249            return (size1.width() == size2.width() ? size1.height() - size2.height() :
250                    size1.width() - size2.width());
251        }
252    }
253
254    private static class AndroidCameraCapabilityStringifier implements Stringifier {
255
256        @Override
257        public String stringify(FocusMode focus) {
258            if (focus == null) {
259                return null;
260            }
261
262            switch (focus) {
263                case AUTO:
264                    return Camera.Parameters.FOCUS_MODE_AUTO;
265                case CONTINUOUS_PICTURE:
266                    return Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE;
267                case CONTINUOUS_VIDEO:
268                    return Camera.Parameters.FOCUS_MODE_CONTINUOUS_VIDEO;
269                case EXTENDED_DOF:
270                    return Camera.Parameters.FOCUS_MODE_EDOF;
271                case FIXED:
272                    return Camera.Parameters.FOCUS_MODE_FIXED;
273                case INFINITY:
274                    return Camera.Parameters.FOCUS_MODE_INFINITY;
275                case MACRO:
276                    return Camera.Parameters.FOCUS_MODE_MACRO;
277            }
278            return null;
279        }
280
281        @Override
282        public FocusMode focusModeFromString(String val) {
283            if (val == null) {
284                return null;
285            }
286
287            if (Camera.Parameters.FOCUS_MODE_AUTO.equals(val)) {
288                return FocusMode.AUTO;
289            } else if (Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE.equals(val)) {
290                return FocusMode.CONTINUOUS_PICTURE;
291            } else if (Camera.Parameters.FOCUS_MODE_CONTINUOUS_VIDEO.equals(val)) {
292                return FocusMode.CONTINUOUS_VIDEO;
293            } else if (Camera.Parameters.FOCUS_MODE_EDOF.equals(val)) {
294                return FocusMode.EXTENDED_DOF;
295            } else if (Camera.Parameters.FOCUS_MODE_FIXED.equals(val)) {
296                return FocusMode.FIXED;
297            } else if (Camera.Parameters.FOCUS_MODE_INFINITY.equals(val)) {
298                return FocusMode.INFINITY;
299            } else if (Camera.Parameters.FOCUS_MODE_MACRO.equals(val)) {
300                return FocusMode.MACRO;
301            } else {
302                return null;
303            }
304        }
305
306        @Override
307        public String stringify(FlashMode flash) {
308            if (flash == null) {
309                return null;
310            }
311
312            switch (flash) {
313                case NO_FLASH:
314                    return null;
315                case AUTO:
316                    return Camera.Parameters.FLASH_MODE_AUTO;
317                case OFF:
318                    return Camera.Parameters.FLASH_MODE_OFF;
319                case ON:
320                    return Camera.Parameters.FLASH_MODE_ON;
321                case TORCH:
322                    return Camera.Parameters.FLASH_MODE_TORCH;
323                case RED_EYE:
324                    return Camera.Parameters.FLASH_MODE_RED_EYE;
325            }
326            return null;
327        }
328
329        @Override
330        public FlashMode flashModeFromString(String val) {
331            if (val == null) {
332                return FlashMode.NO_FLASH;
333            } else if (Camera.Parameters.FLASH_MODE_AUTO.equals(val)) {
334                return FlashMode.AUTO;
335            } else if (Camera.Parameters.FLASH_MODE_OFF.equals(val)) {
336                return FlashMode.OFF;
337            } else if (Camera.Parameters.FLASH_MODE_ON.equals(val)) {
338                return FlashMode.ON;
339            } else if (Camera.Parameters.FLASH_MODE_TORCH.equals(val)) {
340                return FlashMode.TORCH;
341            } else if (Camera.Parameters.FLASH_MODE_RED_EYE.equals(val)) {
342                return FlashMode.RED_EYE;
343            } else {
344                return null;
345            }
346        }
347
348        @Override
349        public String stringify(SceneMode scene) {
350            if (scene == null) {
351                return null;
352            }
353
354            switch (scene) {
355                case AUTO:
356                    return Camera.Parameters.SCENE_MODE_AUTO;
357                case ACTION:
358                    return Camera.Parameters.SCENE_MODE_ACTION;
359                case BARCODE:
360                    return Camera.Parameters.SCENE_MODE_BARCODE;
361                case BEACH:
362                    return Camera.Parameters.SCENE_MODE_BEACH;
363                case CANDLELIGHT:
364                    return Camera.Parameters.SCENE_MODE_CANDLELIGHT;
365                case FIREWORKS:
366                    return Camera.Parameters.SCENE_MODE_FIREWORKS;
367                case HDR:
368                    return Camera.Parameters.SCENE_MODE_HDR;
369                case LANDSCAPE:
370                    return Camera.Parameters.SCENE_MODE_LANDSCAPE;
371                case NIGHT:
372                    return Camera.Parameters.SCENE_MODE_NIGHT;
373                case NIGHT_PORTRAIT:
374                    return Camera.Parameters.SCENE_MODE_NIGHT_PORTRAIT;
375                case PARTY:
376                    return Camera.Parameters.SCENE_MODE_PARTY;
377                case PORTRAIT:
378                    return Camera.Parameters.SCENE_MODE_PORTRAIT;
379                case SNOW:
380                    return Camera.Parameters.SCENE_MODE_SNOW;
381                case SPORTS:
382                    return Camera.Parameters.SCENE_MODE_SPORTS;
383                case STEADYPHOTO:
384                    return Camera.Parameters.SCENE_MODE_STEADYPHOTO;
385                case SUNSET:
386                    return Camera.Parameters.SCENE_MODE_SUNSET;
387                case THEATRE:
388                    return Camera.Parameters.SCENE_MODE_THEATRE;
389            }
390            return null;
391        }
392
393        @Override
394        public SceneMode sceneModeFromString(String val) {
395            if (val == null) {
396                return SceneMode.NO_SCENE_MODE;
397            } else if (Camera.Parameters.SCENE_MODE_AUTO.equals(val)) {
398                return SceneMode.AUTO;
399            } else if (Camera.Parameters.SCENE_MODE_ACTION.equals(val)) {
400                return SceneMode.ACTION;
401            } else if (Camera.Parameters.SCENE_MODE_BARCODE.equals(val)) {
402                return SceneMode.BARCODE;
403            } else if (Camera.Parameters.SCENE_MODE_BEACH.equals(val)) {
404                return SceneMode.BEACH;
405            } else if (Camera.Parameters.SCENE_MODE_CANDLELIGHT.equals(val)) {
406                return SceneMode.CANDLELIGHT;
407            } else if (Camera.Parameters.SCENE_MODE_FIREWORKS.equals(val)) {
408                return SceneMode.FIREWORKS;
409            } else if (Camera.Parameters.SCENE_MODE_HDR.equals(val)) {
410                return SceneMode.HDR;
411            } else if (Camera.Parameters.SCENE_MODE_LANDSCAPE.equals(val)) {
412                return SceneMode.LANDSCAPE;
413            } else if (Camera.Parameters.SCENE_MODE_NIGHT.equals(val)) {
414                return SceneMode.NIGHT;
415            } else if (Camera.Parameters.SCENE_MODE_NIGHT_PORTRAIT.equals(val)) {
416                return SceneMode.NIGHT_PORTRAIT;
417            } else if (Camera.Parameters.SCENE_MODE_PARTY.equals(val)) {
418                return SceneMode.PARTY;
419            } else if (Camera.Parameters.SCENE_MODE_PORTRAIT.equals(val)) {
420                return SceneMode.PORTRAIT;
421            } else if (Camera.Parameters.SCENE_MODE_SNOW.equals(val)) {
422                return SceneMode.SNOW;
423            } else if (Camera.Parameters.SCENE_MODE_SPORTS.equals(val)) {
424                return SceneMode.SPORTS;
425            } else if (Camera.Parameters.SCENE_MODE_STEADYPHOTO.equals(val)) {
426                return SceneMode.STEADYPHOTO;
427            } else if (Camera.Parameters.SCENE_MODE_SUNSET.equals(val)) {
428                return SceneMode.SUNSET;
429            } else if (Camera.Parameters.SCENE_MODE_THEATRE.equals(val)) {
430                return SceneMode.THEATRE;
431            } else {
432                return null;
433            }
434        }
435
436        @Override
437        public String stringify(WhiteBalance wb) {
438            if (wb == null) {
439                return null;
440            }
441
442            switch (wb) {
443                case AUTO:
444                    return Camera.Parameters.WHITE_BALANCE_AUTO;
445                case CLOUDY_DAYLIGHT:
446                    return Camera.Parameters.WHITE_BALANCE_CLOUDY_DAYLIGHT;
447                case DAYLIGHT:
448                    return Camera.Parameters.WHITE_BALANCE_DAYLIGHT;
449                case FLUORESCENT:
450                    return Camera.Parameters.WHITE_BALANCE_FLUORESCENT;
451                case INCANDESCENT:
452                    return Camera.Parameters.WHITE_BALANCE_INCANDESCENT;
453                case SHADE:
454                    return Camera.Parameters.WHITE_BALANCE_SHADE;
455                case TWILIGHT:
456                    return Camera.Parameters.WHITE_BALANCE_TWILIGHT;
457                case WARM_FLUORESCENT:
458                    return Camera.Parameters.WHITE_BALANCE_WARM_FLUORESCENT;
459            }
460            return null;
461        }
462
463        @Override
464        public WhiteBalance whiteBalanceFromString(String val) {
465            if (val == null) {
466                return null;
467            }
468
469            if (Camera.Parameters.WHITE_BALANCE_AUTO.equals(val)) {
470                return WhiteBalance.AUTO;
471            } else if (Camera.Parameters.WHITE_BALANCE_CLOUDY_DAYLIGHT.equals(val)) {
472                return WhiteBalance.CLOUDY_DAYLIGHT;
473            } else if (Camera.Parameters.WHITE_BALANCE_DAYLIGHT.equals(val)) {
474                return WhiteBalance.DAYLIGHT;
475            } else if (Camera.Parameters.WHITE_BALANCE_FLUORESCENT.equals(val)) {
476                return WhiteBalance.FLUORESCENT;
477            } else if (Camera.Parameters.WHITE_BALANCE_INCANDESCENT.equals(val)) {
478                return WhiteBalance.INCANDESCENT;
479            } else if (Camera.Parameters.WHITE_BALANCE_SHADE.equals(val)) {
480                return WhiteBalance.SHADE;
481            } else if (Camera.Parameters.WHITE_BALANCE_TWILIGHT.equals(val)) {
482                return WhiteBalance.TWILIGHT;
483            } else if (Camera.Parameters.WHITE_BALANCE_WARM_FLUORESCENT.equals(val)) {
484                return WhiteBalance.WARM_FLUORESCENT;
485            } else {
486                return null;
487            }
488        }
489    }
490}
491