CameraCapabilities.java revision 8097973089420749dcd1ab4974a629c2466b31cc
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 com.android.ex.camera2.portability.debug.Log;
20
21import java.util.ArrayList;
22import java.util.EnumSet;
23import java.util.HashSet;
24import java.util.List;
25import java.util.Set;
26import java.util.TreeSet;
27
28/**
29 * This class holds all the static information of a camera's capabilities.
30 * <p>
31 * The design of this class is thread-safe and can be passed around regardless
32 * of which thread using it.
33 * </p>
34 */
35public class CameraCapabilities {
36
37    private static Log.Tag TAG = new Log.Tag("CamCapabilities");
38
39    /* All internal states are declared final and should be thread-safe. */
40
41    protected final ArrayList<int[]> mSupportedPreviewFpsRange = new ArrayList<int[]>();
42    protected final ArrayList<Size> mSupportedPreviewSizes = new ArrayList<Size>();
43    protected final TreeSet<Integer> mSupportedPreviewFormats = new TreeSet<Integer>();
44    protected final ArrayList<Size> mSupportedVideoSizes = new ArrayList<Size>();
45    protected final ArrayList<Size> mSupportedPhotoSizes = new ArrayList<Size>();
46    protected final TreeSet<Integer> mSupportedPhotoFormats = new TreeSet<Integer>();
47    protected final EnumSet<SceneMode> mSupportedSceneModes = EnumSet.noneOf(SceneMode.class);
48    protected final EnumSet<FlashMode> mSupportedFlashModes = EnumSet.noneOf(FlashMode.class);
49    protected final EnumSet<FocusMode> mSupportedFocusModes = EnumSet.noneOf(FocusMode.class);
50    protected final EnumSet<WhiteBalance> mSupportedWhiteBalances =
51            EnumSet.noneOf(WhiteBalance.class);
52    protected final EnumSet<Feature> mSupportedFeatures = EnumSet.noneOf(Feature.class);
53    protected Size mPreferredPreviewSizeForVideo;
54    protected int mMinExposureCompensation;
55    protected int mMaxExposureCompensation;
56    protected float mExposureCompensationStep;
57    protected int mMaxNumOfFacesSupported;
58    protected int mMaxNumOfFocusAreas;
59    protected int mMaxNumOfMeteringArea;
60    protected int mMaxZoomRatio;
61    private final Stringifier mStringifier;
62    protected final ArrayList<Integer> mZoomRatioList = new ArrayList<Integer>();
63    protected int mMaxZoomIndex;
64
65    /**
66     * Focus modes.
67     */
68    public enum FocusMode {
69        /**
70         * Continuous auto focus mode intended for taking pictures.
71         * @see {@link android.hardware.Camera.Parameters#FOCUS_MODE_AUTO}.
72         */
73        AUTO,
74        /**
75         * Continuous auto focus mode intended for taking pictures.
76         * @see {@link android.hardware.Camera.Parameters#FOCUS_MODE_CONTINUOUS_PICTURE}.
77         */
78        CONTINUOUS_PICTURE,
79        /**
80         * Continuous auto focus mode intended for video recording.
81         * @see {@link android.hardware.Camera.Parameters#FOCUS_MODE_CONTINUOUS_VIDEO}.
82         */
83        CONTINUOUS_VIDEO,
84        /**
85         * Extended depth of field (EDOF).
86         * @see {@link android.hardware.Camera.Parameters#FOCUS_MODE_EDOF}.
87         */
88        EXTENDED_DOF,
89        /**
90         * Focus is fixed.
91         * @see {@link android.hardware.Camera.Parameters#FOCUS_MODE_FIXED}.
92         */
93        FIXED,
94        /**
95         * Focus is set at infinity.
96         * @see {@link android.hardware.Camera.Parameters#FOCUS_MODE_INFINITY}.
97         */
98        INFINITY,
99        /**
100         * Macro (close-up) focus mode.
101         * @see {@link android.hardware.Camera.Parameters#FOCUS_MODE_MACRO}.
102         */
103        MACRO,
104    }
105
106    /**
107     * Flash modes.
108     */
109    public enum FlashMode {
110        /**
111         * No flash.
112         */
113        NO_FLASH,
114        /**
115         * Flash will be fired automatically when required.
116         * @see {@link android.hardware.Camera.Parameters#FLASH_MODE_OFF}.
117         */
118        AUTO,
119        /**
120         * Flash will not be fired.
121         * @see {@link android.hardware.Camera.Parameters#FLASH_MODE_OFF}.
122         */
123        OFF,
124        /**
125         * Flash will always be fired during snapshot.
126         * @see {@link android.hardware.Camera.Parameters#FLASH_MODE_ON}.
127         */
128        ON,
129        /**
130         * Constant emission of light during preview, auto-focus and snapshot.
131         * @see {@link android.hardware.Camera.Parameters#FLASH_MODE_TORCH}.
132         */
133        TORCH,
134        /**
135         * Flash will be fired in red-eye reduction mode.
136         * @see {@link android.hardware.Camera.Parameters#FLASH_MODE_RED_EYE}.
137         */
138        RED_EYE,
139    }
140
141    /**
142     * Scene modes.
143     */
144    public enum SceneMode {
145        /**
146         * No supported scene mode.
147         */
148        NO_SCENE_MODE,
149        /**
150         * Scene mode is off.
151         * @see {@link android.hardware.Camera.Parameters#SCENE_MODE_AUTO}.
152         */
153        AUTO,
154        /**
155         * Take photos of fast moving objects.
156         * @see {@link android.hardware.Camera.Parameters#SCENE_MODE_ACTION}.
157         */
158        ACTION,
159        /**
160         * Applications are looking for a barcode.
161         * @see {@link android.hardware.Camera.Parameters#SCENE_MODE_BARCODE}.
162         */
163        BARCODE,
164        /**
165         * Take pictures on the beach.
166         * @see {@link android.hardware.Camera.Parameters#SCENE_MODE_BEACH}.
167         */
168        BEACH,
169        /**
170         * Capture the naturally warm color of scenes lit by candles.
171         * @see {@link android.hardware.Camera.Parameters#SCENE_MODE_CANDLELIGHT}.
172         */
173        CANDLELIGHT,
174        /**
175         * For shooting firework displays.
176         * @see {@link android.hardware.Camera.Parameters#SCENE_MODE_FIREWORKS}.
177         */
178        FIREWORKS,
179        /**
180         * Capture a scene using high dynamic range imaging techniques.
181         * @see {@link android.hardware.Camera.Parameters#SCENE_MODE_HDR}.
182         */
183        HDR,
184        /**
185         * Take pictures on distant objects.
186         * @see {@link android.hardware.Camera.Parameters#SCENE_MODE_LANDSCAPE}.
187         */
188        LANDSCAPE,
189        /**
190         * Take photos at night.
191         * @see {@link android.hardware.Camera.Parameters#SCENE_MODE_NIGHT}.
192         */
193        NIGHT,
194        /**
195         * Take people pictures at night.
196         * @see {@link android.hardware.Camera.Parameters#SCENE_MODE_NIGHT_PORTRAIT}.
197         */
198        NIGHT_PORTRAIT,
199        /**
200         * Take indoor low-light shot.
201         * @see {@link android.hardware.Camera.Parameters#SCENE_MODE_PARTY}.
202         */
203        PARTY,
204        /**
205         * Take people pictures.
206         * @see {@link android.hardware.Camera.Parameters#SCENE_MODE_PORTRAIT}.
207         */
208        PORTRAIT,
209        /**
210         * Take pictures on the snow.
211         * @see {@link android.hardware.Camera.Parameters#SCENE_MODE_SNOW}.
212         */
213        SNOW,
214        /**
215         * Take photos of fast moving objects.
216         * @see {@link android.hardware.Camera.Parameters#SCENE_MODE_SPORTS}.
217         */
218        SPORTS,
219        /**
220         * Avoid blurry pictures (for example, due to hand shake).
221         * @see {@link android.hardware.Camera.Parameters#SCENE_MODE_STEADYPHOTO}.
222         */
223        STEADYPHOTO,
224        /**
225         * Take sunset photos.
226         * @see {@link android.hardware.Camera.Parameters#SCENE_MODE_SUNSET}.
227         */
228        SUNSET,
229        /**
230         * Take photos in a theater.
231         * @see {@link android.hardware.Camera.Parameters#SCENE_MODE_THEATRE}.
232         */
233        THEATRE,
234    }
235
236    /**
237     * White blances.
238     */
239    public enum WhiteBalance {
240        /**
241         * @see {@link android.hardware.Camera.Parameters#WHITE_BALANCE_AUTO}.
242         */
243        AUTO,
244        /**
245         * @see {@link android.hardware.Camera.Parameters#WHITE_BALANCE_CLOUDY_DAYLIGHT}.
246         */
247        CLOUDY_DAYLIGHT,
248        /**
249         * @see {@link android.hardware.Camera.Parameters#WHITE_BALANCE_DAYLIGHT}.
250         */
251        DAYLIGHT,
252        /**
253         * @see {@link android.hardware.Camera.Parameters#WHITE_BALANCE_FLUORESCENT}.
254         */
255        FLUORESCENT,
256        /**
257         * @see {@link android.hardware.Camera.Parameters#WHITE_BALANCE_INCANDESCENT}.
258         */
259        INCANDESCENT,
260        /**
261         * @see {@link android.hardware.Camera.Parameters#WHITE_BALANCE_SHADE}.
262         */
263        SHADE,
264        /**
265         * @see {@link android.hardware.Camera.Parameters#WHITE_BALANCE_TWILIGHT}.
266         */
267        TWILIGHT,
268        /**
269         * @see {@link android.hardware.Camera.Parameters#WHITE_BALANCE_WARM_FLUORESCENT}.
270         */
271        WARM_FLUORESCENT,
272    }
273
274    /**
275     * Features.
276     */
277    public enum Feature {
278        /**
279         * Support zoom-related methods.
280         */
281        ZOOM,
282        /**
283         * Support for photo capturing during video recording.
284         */
285        VIDEO_SNAPSHOT,
286        /**
287         * Support for focus area settings.
288         */
289        FOCUS_AREA,
290        /**
291         * Support for metering area settings.
292         */
293        METERING_AREA,
294        /**
295         * Support for automatic exposure lock.
296         */
297        AUTO_EXPOSURE_LOCK,
298        /**
299         * Support for automatic white balance lock.
300         */
301        AUTO_WHITE_BALANCE_LOCK,
302        /**
303         * Support for video stabilization.
304         */
305        VIDEO_STABILIZATION,
306    }
307
308    /**
309     * A interface stringifier to convert abstract representations to API
310     * related string representation.
311     */
312    public interface Stringifier {
313        /**
314         * Converts the focus mode to API-related string representation.
315         *
316         * @param focus The focus mode to convert.
317         * @return The string used by the camera framework API to represent the
318         * focus mode.
319         */
320        String stringify(FocusMode focus);
321
322        /**
323         * Converts the API-related string representation of the focus mode to the
324         * abstract representation.
325         *
326         * @param val The string representation.
327         * @return The focus mode represented by the input string.
328         */
329        FocusMode focusModeFromString(String val);
330
331        /**
332         * Converts the flash mode to API-related string representation.
333         *
334         * @param flash The focus mode to convert.
335         * @return The string used by the camera framework API to represent the
336         * flash mode.
337         */
338        String stringify(FlashMode flash);
339
340        /**
341         * Converts the API-related string representation of the flash mode to the
342         * abstract representation.
343         *
344         * @param val The string representation.
345         * @return The flash mode represented by the input string. Can be
346         *         {@code null}.
347         */
348        FlashMode flashModeFromString(String val);
349
350        /**
351         * Converts the scene mode to API-related string representation.
352         *
353         * @param scene The focus mode to convert.
354         * @return The string used by the camera framework API to represent the
355         * scene mode.
356         */
357        String stringify(SceneMode scene);
358
359        /**
360         * Converts the API-related string representation of the scene mode to the
361         * abstract representation.
362         *
363         * @param val The string representation.
364         * @return The scene mode represented by the input string.
365         */
366        SceneMode sceneModeFromString(String val);
367
368        /**
369         * Converts the white balance to API-related string representation.
370         *
371         * @param wb The focus mode to convert.
372         * @return The string used by the camera framework API to represent the
373         * white balance.
374         */
375        String stringify(WhiteBalance wb);
376
377        /**
378         * Converts the API-related string representation of the white balance to
379         * the abstract representation.
380         *
381         * @param val The string representation.
382         * @return The white balance represented by the input string.
383         */
384        WhiteBalance whiteBalanceFromString(String val);
385    }
386
387    /**
388     * Constructor.
389     * @param stringifier The API-specific stringifier for this instance.
390     */
391    CameraCapabilities(Stringifier stringifier) {
392        mStringifier = stringifier;
393    }
394
395    /**
396     * Copy constructor.
397     * @param src The source instance.
398     */
399    public CameraCapabilities(CameraCapabilities src) {
400        mSupportedPreviewFpsRange.addAll(src.mSupportedPreviewFpsRange);
401        mSupportedPreviewSizes.addAll(src.mSupportedPreviewSizes);
402        mSupportedPreviewFormats.addAll(src.mSupportedPreviewFormats);
403        mSupportedVideoSizes.addAll(src.mSupportedVideoSizes);
404        mSupportedPhotoSizes.addAll(src.mSupportedPhotoSizes);
405        mSupportedPhotoFormats.addAll(src.mSupportedPhotoFormats);
406        mSupportedSceneModes.addAll(src.mSupportedSceneModes);
407        mSupportedFlashModes.addAll(src.mSupportedFlashModes);
408        mSupportedFocusModes.addAll(src.mSupportedFocusModes);
409        mSupportedWhiteBalances.addAll(src.mSupportedWhiteBalances);
410        mSupportedFeatures.addAll(src.mSupportedFeatures);
411        mPreferredPreviewSizeForVideo = src.mPreferredPreviewSizeForVideo;
412        mMaxExposureCompensation = src.mMaxExposureCompensation;
413        mMinExposureCompensation = src.mMinExposureCompensation;
414        mExposureCompensationStep = src.mExposureCompensationStep;
415        mMaxNumOfFacesSupported = src.mMaxNumOfFacesSupported;
416        mMaxNumOfFocusAreas = src.mMaxNumOfFocusAreas;
417        mMaxNumOfMeteringArea = src.mMaxNumOfMeteringArea;
418        mMaxZoomRatio = src.mMaxZoomRatio;
419        mStringifier = src.mStringifier;
420    }
421
422    /**
423     * @return the supported picture formats. See {@link android.graphics.ImageFormat}.
424     */
425    public Set<Integer> getSupportedPhotoFormats() {
426        return new TreeSet<Integer>(mSupportedPhotoFormats);
427    }
428
429    /**
430     * Gets the supported preview formats.
431     * @return The supported preview {@link android.graphics.ImageFormat}s.
432     */
433    public Set<Integer> getSupportedPreviewFormats() {
434        return new TreeSet<Integer>(mSupportedPreviewFormats);
435    }
436
437    /**
438     * Gets the supported picture sizes.
439     */
440    public List<Size> getSupportedPhotoSizes() {
441        return new ArrayList<Size>(mSupportedPhotoSizes);
442    }
443
444
445    /**
446     * @return The supported preview fps (frame-per-second) ranges. The returned
447     * list is sorted by maximum fps then minimum fps in a descending order.
448     * The values are multiplied by 1000.
449     */
450    public final List<int[]> getSupportedPreviewFpsRange() {
451        return new ArrayList<int[]>(mSupportedPreviewFpsRange);
452    }
453
454    /**
455     * @return The supported preview sizes. The list is sorted by width then
456     * height in a descending order.
457     */
458    public final List<Size> getSupportedPreviewSizes() {
459        return new ArrayList<Size>(mSupportedPreviewSizes);
460    }
461
462    public final Size getPreferredPreviewSizeForVideo() {
463        return new Size(mPreferredPreviewSizeForVideo);
464    }
465
466    /**
467     * @return The supported video frame sizes that can be used by MediaRecorder.
468     *         The list is sorted by width then height in a descending order.
469     */
470    public final List<Size> getSupportedVideoSizes() {
471        return new ArrayList<Size>(mSupportedVideoSizes);
472    }
473
474    /**
475     * @return The supported scene modes.
476     */
477    public final Set<SceneMode> getSupportedSceneModes() {
478        return new HashSet<SceneMode>(mSupportedSceneModes);
479    }
480
481    /**
482     * @return Whether the scene mode is supported.
483     */
484    public final boolean supports(SceneMode scene) {
485        return (scene != null && mSupportedSceneModes.contains(scene));
486    }
487
488    public boolean supports(final CameraSettings settings) {
489        if (zoomCheck(settings) && exposureCheck(settings) && focusCheck(settings) &&
490                flashCheck(settings) && photoSizeCheck(settings) && previewSizeCheck(settings) &&
491                videoStabilizationCheck(settings)) {
492            return true;
493        }
494        return false;
495    }
496
497    /**
498     * @return The supported flash modes.
499     */
500    public final Set<FlashMode> getSupportedFlashModes() {
501        return new HashSet<FlashMode>(mSupportedFlashModes);
502    }
503
504    /**
505     * @return Whether the flash mode is supported.
506     */
507    public final boolean supports(FlashMode flash) {
508        return (flash != null && mSupportedFlashModes.contains(flash));
509    }
510
511    /**
512     * @return The supported focus modes.
513     */
514    public final Set<FocusMode> getSupportedFocusModes() {
515        return new HashSet<FocusMode>(mSupportedFocusModes);
516    }
517
518    /**
519     * @return Whether the focus mode is supported.
520     */
521    public final boolean supports(FocusMode focus) {
522        return (focus != null && mSupportedFocusModes.contains(focus));
523    }
524
525    /**
526     * @return The supported white balanceas.
527     */
528    public final Set<WhiteBalance> getSupportedWhiteBalance() {
529        return new HashSet<WhiteBalance>(mSupportedWhiteBalances);
530    }
531
532    /**
533     * @return Whether the white balance is supported.
534     */
535    public boolean supports(WhiteBalance wb) {
536        return (wb != null && mSupportedWhiteBalances.contains(wb));
537    }
538
539    public final Set<Feature> getSupportedFeature() {
540        return new HashSet<Feature>(mSupportedFeatures);
541    }
542
543    public boolean supports(Feature ft) {
544        return (ft != null && mSupportedFeatures.contains(ft));
545    }
546
547    /**
548     * @return The maximal supported zoom ratio.
549     */
550    public float getMaxZoomRatio() {
551        return mMaxZoomRatio;
552    }
553
554    // We'll replace these old style methods with new ones.
555    @Deprecated
556    public int getMaxZoomIndex() {
557        return mMaxZoomIndex;
558    }
559
560    @Deprecated
561    public List<Integer> getZoomRatioList() {
562        return new ArrayList<Integer>(mZoomRatioList);
563    }
564
565    /**
566     * @return The min exposure compensation index. The EV is the compensation
567     * index multiplied by the step value. If unsupported, both this method and
568     * {@link #getMaxExposureCompensation()} return 0.
569     */
570    public final int getMinExposureCompensation() {
571        return mMinExposureCompensation;
572    }
573
574    /**
575     * @return The max exposure compensation index. The EV is the compensation
576     * index multiplied by the step value. If unsupported, both this method and
577     * {@link #getMinExposureCompensation()} return 0.
578     */
579    public final int getMaxExposureCompensation() {
580        return mMaxExposureCompensation;
581    }
582
583    /**
584     * @return The exposure compensation step. The EV is the compensation index
585     * multiplied by the step value.
586     */
587    public final float getExposureCompensationStep() {
588        return mExposureCompensationStep;
589    }
590
591    /**
592     * @return The max number of faces supported by the face detection. 0 if
593     * unsupported.
594     */
595    public final int getMaxNumOfFacesSupported() {
596        return mMaxNumOfFacesSupported;
597    }
598
599    /**
600     * @return The stringifier used by this instance.
601     */
602    public Stringifier getStringifier() {
603        return mStringifier;
604    }
605
606    private boolean zoomCheck(final CameraSettings settings) {
607        final float ratio = settings.getCurrentZoomRatio();
608        final int index = settings.getCurrentZoomIndex();
609        if (!supports(Feature.ZOOM)) {
610            if (ratio != 1.0f || index != 0) {
611                Log.v(TAG, "Zoom is not supported");
612                return false;
613            }
614        } else {
615            if (settings.getCurrentZoomRatio() > getMaxZoomRatio() ||
616                    index > getMaxZoomIndex()) {
617                Log.v(TAG, "Zoom ratio is not supported: ratio = " +
618                        settings.getCurrentZoomRatio() + ", index = " + index);
619                return false;
620            }
621        }
622        return true;
623    }
624
625    private boolean exposureCheck(final CameraSettings settings) {
626        final int index = settings.getExposureCompensationIndex();
627        if (index > getMaxExposureCompensation() || index < getMinExposureCompensation()) {
628            Log.v(TAG, "Exposure compensation index is not supported. Min = " +
629                    getMinExposureCompensation() + ", max = " + getMaxExposureCompensation() + "," +
630                    " setting = " + index);
631            return false;
632        }
633        return true;
634    }
635
636    private boolean focusCheck(final CameraSettings settings) {
637        FocusMode focusMode = settings.getCurrentFocusMode();
638        if (!supports(focusMode)) {
639            Log.v(TAG,
640                    "Focus mode not supported:" + (focusMode != null ? focusMode.name() : "null"));
641            return false;
642        }
643        return true;
644    }
645
646    private boolean flashCheck(final CameraSettings settings) {
647        FlashMode flashMode = settings.getCurrentFlashMode();
648        if (!supports(flashMode)) {
649            Log.v(TAG,
650                    "Flash mode not supported:" + (flashMode != null ? flashMode.name() : "null"));
651            return false;
652        }
653        return true;
654    }
655
656    private boolean photoSizeCheck(final CameraSettings settings) {
657        Size photoSize = settings.getCurrentPhotoSize();
658        if (mSupportedPhotoSizes.contains(photoSize)) {
659            return true;
660        }
661        Log.v(TAG, "Unsupported photo size:" + photoSize);
662        return false;
663    }
664
665    private boolean previewSizeCheck(final CameraSettings settings) {
666        final Size previewSize = settings.getCurrentPreviewSize();
667        if (mSupportedPreviewSizes.contains(previewSize)) {
668            return true;
669        }
670        Log.v(TAG, "Unsupported preview size:" + previewSize);
671        return false;
672    }
673
674    private boolean videoStabilizationCheck(final CameraSettings settings) {
675        if (!settings.isVideoStabilizationEnabled() || supports(Feature.VIDEO_STABILIZATION)) {
676            return true;
677        }
678        Log.v(TAG, "Video stabilization is not supported");
679        return false;
680    }
681}
682