OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2016 The WebRTC project authors. All Rights Reserved. | 2 * Copyright 2016 The WebRTC project authors. All Rights Reserved. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license | 4 * Use of this source code is governed by a BSD-style license |
5 * that can be found in the LICENSE file in the root of the source | 5 * that can be found in the LICENSE file in the root of the source |
6 * tree. An additional intellectual property rights grant can be found | 6 * tree. An additional intellectual property rights grant can be found |
7 * in the file PATENTS. All contributing project authors may | 7 * in the file PATENTS. All contributing project authors may |
8 * be found in the AUTHORS file in the root of the source tree. | 8 * be found in the AUTHORS file in the root of the source tree. |
9 */ | 9 */ |
10 | 10 |
11 package org.webrtc; | 11 package org.webrtc; |
12 | 12 |
13 import android.annotation.TargetApi; | 13 import android.annotation.TargetApi; |
14 import android.content.Context; | 14 import android.content.Context; |
15 import android.graphics.SurfaceTexture; | 15 import android.graphics.SurfaceTexture; |
16 import android.hardware.camera2.CameraAccessException; | 16 import android.hardware.camera2.CameraAccessException; |
17 import android.hardware.camera2.CameraCaptureSession; | 17 import android.hardware.camera2.CameraCaptureSession; |
18 import android.hardware.camera2.CameraCharacteristics; | 18 import android.hardware.camera2.CameraCharacteristics; |
19 import android.hardware.camera2.CameraDevice; | 19 import android.hardware.camera2.CameraDevice; |
20 import android.hardware.camera2.CameraManager; | 20 import android.hardware.camera2.CameraManager; |
21 import android.hardware.camera2.CameraMetadata; | 21 import android.hardware.camera2.CameraMetadata; |
22 import android.hardware.camera2.CaptureFailure; | 22 import android.hardware.camera2.CaptureFailure; |
23 import android.hardware.camera2.CaptureRequest; | 23 import android.hardware.camera2.CaptureRequest; |
24 import android.media.MediaRecorder; | |
25 import android.os.Handler; | 24 import android.os.Handler; |
26 import android.util.Range; | 25 import android.util.Range; |
27 import android.view.Surface; | 26 import android.view.Surface; |
28 import android.view.WindowManager; | 27 import android.view.WindowManager; |
29 import java.util.ArrayList; | 28 import java.util.Arrays; |
30 import java.util.List; | 29 import java.util.List; |
31 import java.util.concurrent.TimeUnit; | 30 import java.util.concurrent.TimeUnit; |
32 import org.webrtc.CameraEnumerationAndroid.CaptureFormat; | 31 import org.webrtc.CameraEnumerationAndroid.CaptureFormat; |
33 | 32 |
34 @TargetApi(21) | 33 @TargetApi(21) |
35 class Camera2Session implements CameraSession { | 34 class Camera2Session implements CameraSession { |
36 private static final String TAG = "Camera2Session"; | 35 private static final String TAG = "Camera2Session"; |
37 | 36 |
38 private static final Histogram camera2StartTimeMsHistogram = | 37 private static final Histogram camera2StartTimeMsHistogram = |
39 Histogram.createCounts("WebRTC.Android.Camera2.StartTimeMs", 1, 10000, 50)
; | 38 Histogram.createCounts("WebRTC.Android.Camera2.StartTimeMs", 1, 10000, 50)
; |
40 private static final Histogram camera2StopTimeMsHistogram = | 39 private static final Histogram camera2StopTimeMsHistogram = |
41 Histogram.createCounts("WebRTC.Android.Camera2.StopTimeMs", 1, 10000, 50); | 40 Histogram.createCounts("WebRTC.Android.Camera2.StopTimeMs", 1, 10000, 50); |
42 private static final Histogram camera2ResolutionHistogram = Histogram.createEn
umeration( | 41 private static final Histogram camera2ResolutionHistogram = Histogram.createEn
umeration( |
43 "WebRTC.Android.Camera2.Resolution", CameraEnumerationAndroid.COMMON_RESOL
UTIONS.size()); | 42 "WebRTC.Android.Camera2.Resolution", CameraEnumerationAndroid.COMMON_RESOL
UTIONS.size()); |
44 | 43 |
45 private static enum SessionState { RUNNING, STOPPED } | 44 private static enum SessionState { RUNNING, STOPPED } |
46 | 45 |
47 private final Handler cameraThreadHandler; | 46 private final Handler cameraThreadHandler; |
48 private final CreateSessionCallback callback; | 47 private final CreateSessionCallback callback; |
49 private final Events events; | 48 private final Events events; |
50 private final Context applicationContext; | 49 private final Context applicationContext; |
51 private final CameraManager cameraManager; | 50 private final CameraManager cameraManager; |
52 private final SurfaceTextureHelper surfaceTextureHelper; | 51 private final SurfaceTextureHelper surfaceTextureHelper; |
53 private final Surface mediaRecorderSurface; | |
54 private final String cameraId; | 52 private final String cameraId; |
55 private final int width; | 53 private final int width; |
56 private final int height; | 54 private final int height; |
57 private final int framerate; | 55 private final int framerate; |
58 | 56 |
59 // Initialized at start | 57 // Initialized at start |
60 private CameraCharacteristics cameraCharacteristics; | 58 private CameraCharacteristics cameraCharacteristics; |
61 private int cameraOrientation; | 59 private int cameraOrientation; |
62 private boolean isCameraFrontFacing; | 60 private boolean isCameraFrontFacing; |
63 private int fpsUnitFactor; | 61 private int fpsUnitFactor; |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
118 @Override | 116 @Override |
119 public void onOpened(CameraDevice camera) { | 117 public void onOpened(CameraDevice camera) { |
120 checkIsOnCameraThread(); | 118 checkIsOnCameraThread(); |
121 | 119 |
122 Logging.d(TAG, "Camera opened."); | 120 Logging.d(TAG, "Camera opened."); |
123 cameraDevice = camera; | 121 cameraDevice = camera; |
124 | 122 |
125 final SurfaceTexture surfaceTexture = surfaceTextureHelper.getSurfaceTextu
re(); | 123 final SurfaceTexture surfaceTexture = surfaceTextureHelper.getSurfaceTextu
re(); |
126 surfaceTexture.setDefaultBufferSize(captureFormat.width, captureFormat.hei
ght); | 124 surfaceTexture.setDefaultBufferSize(captureFormat.width, captureFormat.hei
ght); |
127 surface = new Surface(surfaceTexture); | 125 surface = new Surface(surfaceTexture); |
128 List<Surface> surfaces = new ArrayList<Surface>(); | |
129 surfaces.add(surface); | |
130 if (mediaRecorderSurface != null) { | |
131 Logging.d(TAG, "Add MediaRecorder surface to capture session."); | |
132 surfaces.add(mediaRecorderSurface); | |
133 } | |
134 try { | 126 try { |
135 camera.createCaptureSession(surfaces, new CaptureSessionCallback(), came
raThreadHandler); | 127 camera.createCaptureSession( |
| 128 Arrays.asList(surface), new CaptureSessionCallback(), cameraThreadHa
ndler); |
136 } catch (CameraAccessException e) { | 129 } catch (CameraAccessException e) { |
137 reportError("Failed to create capture session. " + e); | 130 reportError("Failed to create capture session. " + e); |
138 return; | 131 return; |
139 } | 132 } |
140 } | 133 } |
141 | 134 |
142 @Override | 135 @Override |
143 public void onClosed(CameraDevice camera) { | 136 public void onClosed(CameraDevice camera) { |
144 checkIsOnCameraThread(); | 137 checkIsOnCameraThread(); |
145 | 138 |
(...skipping 29 matching lines...) Expand all Loading... |
175 captureRequestBuilder.set(CaptureRequest.CONTROL_AE_TARGET_FPS_RANGE, | 168 captureRequestBuilder.set(CaptureRequest.CONTROL_AE_TARGET_FPS_RANGE, |
176 new Range<Integer>(captureFormat.framerate.min / fpsUnitFactor, | 169 new Range<Integer>(captureFormat.framerate.min / fpsUnitFactor, |
177 captureFormat.framerate.max / fpsUnitFactor)); | 170 captureFormat.framerate.max / fpsUnitFactor)); |
178 captureRequestBuilder.set( | 171 captureRequestBuilder.set( |
179 CaptureRequest.CONTROL_AE_MODE, CaptureRequest.CONTROL_AE_MODE_ON); | 172 CaptureRequest.CONTROL_AE_MODE, CaptureRequest.CONTROL_AE_MODE_ON); |
180 captureRequestBuilder.set(CaptureRequest.CONTROL_AE_LOCK, false); | 173 captureRequestBuilder.set(CaptureRequest.CONTROL_AE_LOCK, false); |
181 chooseStabilizationMode(captureRequestBuilder); | 174 chooseStabilizationMode(captureRequestBuilder); |
182 chooseFocusMode(captureRequestBuilder); | 175 chooseFocusMode(captureRequestBuilder); |
183 | 176 |
184 captureRequestBuilder.addTarget(surface); | 177 captureRequestBuilder.addTarget(surface); |
185 if (mediaRecorderSurface != null) { | |
186 Logging.d(TAG, "Add MediaRecorder surface to CaptureRequest.Builder"); | |
187 captureRequestBuilder.addTarget(mediaRecorderSurface); | |
188 } | |
189 session.setRepeatingRequest( | 178 session.setRepeatingRequest( |
190 captureRequestBuilder.build(), new CameraCaptureCallback(), cameraTh
readHandler); | 179 captureRequestBuilder.build(), new CameraCaptureCallback(), cameraTh
readHandler); |
191 } catch (CameraAccessException e) { | 180 } catch (CameraAccessException e) { |
192 reportError("Failed to start capture request. " + e); | 181 reportError("Failed to start capture request. " + e); |
193 return; | 182 return; |
194 } | 183 } |
195 | 184 |
196 surfaceTextureHelper.startListening( | 185 surfaceTextureHelper.startListening( |
197 new SurfaceTextureHelper.OnTextureFrameAvailableListener() { | 186 new SurfaceTextureHelper.OnTextureFrameAvailableListener() { |
198 @Override | 187 @Override |
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
284 private class CameraCaptureCallback extends CameraCaptureSession.CaptureCallba
ck { | 273 private class CameraCaptureCallback extends CameraCaptureSession.CaptureCallba
ck { |
285 @Override | 274 @Override |
286 public void onCaptureFailed( | 275 public void onCaptureFailed( |
287 CameraCaptureSession session, CaptureRequest request, CaptureFailure fai
lure) { | 276 CameraCaptureSession session, CaptureRequest request, CaptureFailure fai
lure) { |
288 Logging.d(TAG, "Capture failed: " + failure); | 277 Logging.d(TAG, "Capture failed: " + failure); |
289 } | 278 } |
290 } | 279 } |
291 | 280 |
292 public static void create(CreateSessionCallback callback, Events events, | 281 public static void create(CreateSessionCallback callback, Events events, |
293 Context applicationContext, CameraManager cameraManager, | 282 Context applicationContext, CameraManager cameraManager, |
294 SurfaceTextureHelper surfaceTextureHelper, MediaRecorder mediaRecorder, St
ring cameraId, | 283 SurfaceTextureHelper surfaceTextureHelper, String cameraId, int width, int
height, |
295 int width, int height, int framerate) { | 284 int framerate) { |
296 new Camera2Session(callback, events, applicationContext, cameraManager, surf
aceTextureHelper, | 285 new Camera2Session(callback, events, applicationContext, cameraManager, surf
aceTextureHelper, |
297 mediaRecorder, cameraId, width, height, framerate); | 286 cameraId, width, height, framerate); |
298 } | 287 } |
299 | 288 |
300 private Camera2Session(CreateSessionCallback callback, Events events, Context
applicationContext, | 289 private Camera2Session(CreateSessionCallback callback, Events events, Context
applicationContext, |
301 CameraManager cameraManager, SurfaceTextureHelper surfaceTextureHelper, | 290 CameraManager cameraManager, SurfaceTextureHelper surfaceTextureHelper, St
ring cameraId, |
302 MediaRecorder mediaRecorder, String cameraId, int width, int height, int f
ramerate) { | 291 int width, int height, int framerate) { |
303 Logging.d(TAG, "Create new camera2 session on camera " + cameraId); | 292 Logging.d(TAG, "Create new camera2 session on camera " + cameraId); |
304 | 293 |
305 constructionTimeNs = System.nanoTime(); | 294 constructionTimeNs = System.nanoTime(); |
306 | 295 |
307 this.cameraThreadHandler = new Handler(); | 296 this.cameraThreadHandler = new Handler(); |
308 this.callback = callback; | 297 this.callback = callback; |
309 this.events = events; | 298 this.events = events; |
310 this.applicationContext = applicationContext; | 299 this.applicationContext = applicationContext; |
311 this.cameraManager = cameraManager; | 300 this.cameraManager = cameraManager; |
312 this.surfaceTextureHelper = surfaceTextureHelper; | 301 this.surfaceTextureHelper = surfaceTextureHelper; |
313 this.mediaRecorderSurface = (mediaRecorder != null) ? mediaRecorder.getSurfa
ce() : null; | |
314 this.cameraId = cameraId; | 302 this.cameraId = cameraId; |
315 this.width = width; | 303 this.width = width; |
316 this.height = height; | 304 this.height = height; |
317 this.framerate = framerate; | 305 this.framerate = framerate; |
318 | 306 |
319 start(); | 307 start(); |
320 } | 308 } |
321 | 309 |
322 private void start() { | 310 private void start() { |
323 checkIsOnCameraThread(); | 311 checkIsOnCameraThread(); |
(...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
456 } | 444 } |
457 return (cameraOrientation + rotation) % 360; | 445 return (cameraOrientation + rotation) % 360; |
458 } | 446 } |
459 | 447 |
460 private void checkIsOnCameraThread() { | 448 private void checkIsOnCameraThread() { |
461 if (Thread.currentThread() != cameraThreadHandler.getLooper().getThread()) { | 449 if (Thread.currentThread() != cameraThreadHandler.getLooper().getThread()) { |
462 throw new IllegalStateException("Wrong thread"); | 450 throw new IllegalStateException("Wrong thread"); |
463 } | 451 } |
464 } | 452 } |
465 } | 453 } |
OLD | NEW |