1 /*
2  * libjingle
3  * Copyright 2015 Google Inc.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are met:
7  *
8  *  1. Redistributions of source code must retain the above copyright notice,
9  *     this list of conditions and the following disclaimer.
10  *  2. Redistributions in binary form must reproduce the above copyright notice,
11  *     this list of conditions and the following disclaimer in the documentation
12  *     and/or other materials provided with the distribution.
13  *  3. The name of the author may not be used to endorse or promote products
14  *     derived from this software without specific prior written permission.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
17  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
18  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
19  * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
20  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
22  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
23  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
24  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
25  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26  */
27 
28 package org.webrtc;
29 
30 import android.os.SystemClock;
31 
32 import org.webrtc.CameraEnumerationAndroid.CaptureFormat;
33 import org.webrtc.Logging;
34 
35 import java.util.ArrayList;
36 import java.util.List;
37 
38 @SuppressWarnings("deprecation")
39 public class CameraEnumerator implements CameraEnumerationAndroid.Enumerator {
40   private final static String TAG = "CameraEnumerator";
41   // Each entry contains the supported formats for corresponding camera index. The formats for all
42   // cameras are enumerated on the first call to getSupportedFormats(), and cached for future
43   // reference.
44   private List<List<CaptureFormat>> cachedSupportedFormats;
45 
46   @Override
getSupportedFormats(int cameraId)47   public List<CaptureFormat> getSupportedFormats(int cameraId) {
48     synchronized (this) {
49       if (cachedSupportedFormats == null) {
50         cachedSupportedFormats = new ArrayList<List<CaptureFormat>>();
51         for (int i = 0; i < CameraEnumerationAndroid.getDeviceCount(); ++i) {
52           cachedSupportedFormats.add(enumerateFormats(i));
53         }
54       }
55     }
56     return cachedSupportedFormats.get(cameraId);
57   }
58 
enumerateFormats(int cameraId)59   private List<CaptureFormat> enumerateFormats(int cameraId) {
60     Logging.d(TAG, "Get supported formats for camera index " + cameraId + ".");
61     final long startTimeMs = SystemClock.elapsedRealtime();
62     final android.hardware.Camera.Parameters parameters;
63     android.hardware.Camera camera = null;
64     try {
65       Logging.d(TAG, "Opening camera with index " + cameraId);
66       camera = android.hardware.Camera.open(cameraId);
67       parameters = camera.getParameters();
68     } catch (RuntimeException e) {
69       Logging.e(TAG, "Open camera failed on camera index " + cameraId, e);
70       return new ArrayList<CaptureFormat>();
71     } finally {
72       if (camera != null) {
73         camera.release();
74       }
75     }
76 
77     final List<CaptureFormat> formatList = new ArrayList<CaptureFormat>();
78     try {
79       int minFps = 0;
80       int maxFps = 0;
81       final List<int[]> listFpsRange = parameters.getSupportedPreviewFpsRange();
82       if (listFpsRange != null) {
83         // getSupportedPreviewFpsRange() returns a sorted list. Take the fps range
84         // corresponding to the highest fps.
85         final int[] range = listFpsRange.get(listFpsRange.size() - 1);
86         minFps = range[android.hardware.Camera.Parameters.PREVIEW_FPS_MIN_INDEX];
87         maxFps = range[android.hardware.Camera.Parameters.PREVIEW_FPS_MAX_INDEX];
88       }
89       for (android.hardware.Camera.Size size : parameters.getSupportedPreviewSizes()) {
90         formatList.add(new CaptureFormat(size.width, size.height, minFps, maxFps));
91       }
92     } catch (Exception e) {
93       Logging.e(TAG, "getSupportedFormats() failed on camera index " + cameraId, e);
94     }
95 
96     final long endTimeMs = SystemClock.elapsedRealtime();
97     Logging.d(TAG, "Get supported formats for camera index " + cameraId + " done."
98         + " Time spent: " + (endTimeMs - startTimeMs) + " ms.");
99     return formatList;
100   }
101 }
102