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; | |
24 import android.os.Handler; | 25 import android.os.Handler; |
25 import android.util.Range; | 26 import android.util.Range; |
26 import android.view.Surface; | 27 import android.view.Surface; |
27 import android.view.WindowManager; | 28 import android.view.WindowManager; |
28 import java.util.Arrays; | 29 import java.util.ArrayList; |
29 import java.util.List; | 30 import java.util.List; |
30 import java.util.concurrent.TimeUnit; | 31 import java.util.concurrent.TimeUnit; |
31 import org.webrtc.CameraEnumerationAndroid.CaptureFormat; | 32 import org.webrtc.CameraEnumerationAndroid.CaptureFormat; |
32 | 33 |
33 @TargetApi(21) | 34 @TargetApi(21) |
34 class Camera2Session implements CameraSession { | 35 class Camera2Session implements CameraSession { |
35 private static final String TAG = "Camera2Session"; | 36 private static final String TAG = "Camera2Session"; |
36 | 37 |
37 private static final Histogram camera2StartTimeMsHistogram = | 38 private static final Histogram camera2StartTimeMsHistogram = |
38 Histogram.createCounts("WebRTC.Android.Camera2.StartTimeMs", 1, 10000, 50) ; | 39 Histogram.createCounts("WebRTC.Android.Camera2.StartTimeMs", 1, 10000, 50) ; |
(...skipping 18 matching lines...) Expand all Loading... | |
57 // Initialized at start | 58 // Initialized at start |
58 private CameraCharacteristics cameraCharacteristics; | 59 private CameraCharacteristics cameraCharacteristics; |
59 private int cameraOrientation; | 60 private int cameraOrientation; |
60 private boolean isCameraFrontFacing; | 61 private boolean isCameraFrontFacing; |
61 private int fpsUnitFactor; | 62 private int fpsUnitFactor; |
62 private CaptureFormat captureFormat; | 63 private CaptureFormat captureFormat; |
63 | 64 |
64 // Initialized when camera opens | 65 // Initialized when camera opens |
65 private CameraDevice cameraDevice; | 66 private CameraDevice cameraDevice; |
66 private Surface surface; | 67 private Surface surface; |
68 private Surface mediaRecorderSurface; | |
sakal
2017/04/21 07:56:48
move below surfaceTextureHelper and make final
AlexG
2017/04/21 19:38:11
Done.
| |
67 | 69 |
68 // Initialized when capture session is created | 70 // Initialized when capture session is created |
69 private CameraCaptureSession captureSession; | 71 private CameraCaptureSession captureSession; |
70 | 72 |
71 // State | 73 // State |
72 private SessionState state = SessionState.RUNNING; | 74 private SessionState state = SessionState.RUNNING; |
73 private boolean firstFrameReported = false; | 75 private boolean firstFrameReported = false; |
74 | 76 |
75 // Used only for stats. Only used on the camera thread. | 77 // Used only for stats. Only used on the camera thread. |
76 private final long constructionTimeNs; // Construction time of this class. | 78 private final long constructionTimeNs; // Construction time of this class. |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
116 @Override | 118 @Override |
117 public void onOpened(CameraDevice camera) { | 119 public void onOpened(CameraDevice camera) { |
118 checkIsOnCameraThread(); | 120 checkIsOnCameraThread(); |
119 | 121 |
120 Logging.d(TAG, "Camera opened."); | 122 Logging.d(TAG, "Camera opened."); |
121 cameraDevice = camera; | 123 cameraDevice = camera; |
122 | 124 |
123 final SurfaceTexture surfaceTexture = surfaceTextureHelper.getSurfaceTextu re(); | 125 final SurfaceTexture surfaceTexture = surfaceTextureHelper.getSurfaceTextu re(); |
124 surfaceTexture.setDefaultBufferSize(captureFormat.width, captureFormat.hei ght); | 126 surfaceTexture.setDefaultBufferSize(captureFormat.width, captureFormat.hei ght); |
125 surface = new Surface(surfaceTexture); | 127 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 } | |
126 try { | 134 try { |
127 camera.createCaptureSession( | 135 camera.createCaptureSession(surfaces, new CaptureSessionCallback(), came raThreadHandler); |
128 Arrays.asList(surface), new CaptureSessionCallback(), cameraThreadHa ndler); | |
129 } catch (CameraAccessException e) { | 136 } catch (CameraAccessException e) { |
130 reportError("Failed to create capture session. " + e); | 137 reportError("Failed to create capture session. " + e); |
131 return; | 138 return; |
132 } | 139 } |
133 } | 140 } |
134 | 141 |
135 @Override | 142 @Override |
136 public void onClosed(CameraDevice camera) { | 143 public void onClosed(CameraDevice camera) { |
137 checkIsOnCameraThread(); | 144 checkIsOnCameraThread(); |
138 | 145 |
(...skipping 29 matching lines...) Expand all Loading... | |
168 captureRequestBuilder.set(CaptureRequest.CONTROL_AE_TARGET_FPS_RANGE, | 175 captureRequestBuilder.set(CaptureRequest.CONTROL_AE_TARGET_FPS_RANGE, |
169 new Range<Integer>(captureFormat.framerate.min / fpsUnitFactor, | 176 new Range<Integer>(captureFormat.framerate.min / fpsUnitFactor, |
170 captureFormat.framerate.max / fpsUnitFactor)); | 177 captureFormat.framerate.max / fpsUnitFactor)); |
171 captureRequestBuilder.set( | 178 captureRequestBuilder.set( |
172 CaptureRequest.CONTROL_AE_MODE, CaptureRequest.CONTROL_AE_MODE_ON); | 179 CaptureRequest.CONTROL_AE_MODE, CaptureRequest.CONTROL_AE_MODE_ON); |
173 captureRequestBuilder.set(CaptureRequest.CONTROL_AE_LOCK, false); | 180 captureRequestBuilder.set(CaptureRequest.CONTROL_AE_LOCK, false); |
174 chooseStabilizationMode(captureRequestBuilder); | 181 chooseStabilizationMode(captureRequestBuilder); |
175 chooseFocusMode(captureRequestBuilder); | 182 chooseFocusMode(captureRequestBuilder); |
176 | 183 |
177 captureRequestBuilder.addTarget(surface); | 184 captureRequestBuilder.addTarget(surface); |
185 if (mediaRecorderSurface != null) { | |
186 Logging.d(TAG, "Add MediaRecorder surface to CaptureRequest.Builder"); | |
187 captureRequestBuilder.addTarget(mediaRecorderSurface); | |
188 } | |
178 session.setRepeatingRequest( | 189 session.setRepeatingRequest( |
179 captureRequestBuilder.build(), new CameraCaptureCallback(), cameraTh readHandler); | 190 captureRequestBuilder.build(), new CameraCaptureCallback(), cameraTh readHandler); |
180 } catch (CameraAccessException e) { | 191 } catch (CameraAccessException e) { |
181 reportError("Failed to start capture request. " + e); | 192 reportError("Failed to start capture request. " + e); |
182 return; | 193 return; |
183 } | 194 } |
184 | 195 |
185 surfaceTextureHelper.startListening( | 196 surfaceTextureHelper.startListening( |
186 new SurfaceTextureHelper.OnTextureFrameAvailableListener() { | 197 new SurfaceTextureHelper.OnTextureFrameAvailableListener() { |
187 @Override | 198 @Override |
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
273 private class CameraCaptureCallback extends CameraCaptureSession.CaptureCallba ck { | 284 private class CameraCaptureCallback extends CameraCaptureSession.CaptureCallba ck { |
274 @Override | 285 @Override |
275 public void onCaptureFailed( | 286 public void onCaptureFailed( |
276 CameraCaptureSession session, CaptureRequest request, CaptureFailure fai lure) { | 287 CameraCaptureSession session, CaptureRequest request, CaptureFailure fai lure) { |
277 Logging.d(TAG, "Capture failed: " + failure); | 288 Logging.d(TAG, "Capture failed: " + failure); |
278 } | 289 } |
279 } | 290 } |
280 | 291 |
281 public static void create(CreateSessionCallback callback, Events events, | 292 public static void create(CreateSessionCallback callback, Events events, |
282 Context applicationContext, CameraManager cameraManager, | 293 Context applicationContext, CameraManager cameraManager, |
283 SurfaceTextureHelper surfaceTextureHelper, String cameraId, int width, int height, | 294 SurfaceTextureHelper surfaceTextureHelper, MediaRecorder mediaRecorder, St ring cameraId, |
284 int framerate) { | 295 int width, int height, int framerate) { |
285 new Camera2Session(callback, events, applicationContext, cameraManager, surf aceTextureHelper, | 296 new Camera2Session(callback, events, applicationContext, cameraManager, surf aceTextureHelper, |
286 cameraId, width, height, framerate); | 297 mediaRecorder, cameraId, width, height, framerate); |
287 } | 298 } |
288 | 299 |
289 private Camera2Session(CreateSessionCallback callback, Events events, Context applicationContext, | 300 private Camera2Session(CreateSessionCallback callback, Events events, Context applicationContext, |
290 CameraManager cameraManager, SurfaceTextureHelper surfaceTextureHelper, St ring cameraId, | 301 CameraManager cameraManager, SurfaceTextureHelper surfaceTextureHelper, |
291 int width, int height, int framerate) { | 302 MediaRecorder mediaRecorder, String cameraId, int width, int height, int f ramerate) { |
292 Logging.d(TAG, "Create new camera2 session on camera " + cameraId); | 303 Logging.d(TAG, "Create new camera2 session on camera " + cameraId); |
293 | 304 |
294 constructionTimeNs = System.nanoTime(); | 305 constructionTimeNs = System.nanoTime(); |
295 | 306 |
296 this.cameraThreadHandler = new Handler(); | 307 this.cameraThreadHandler = new Handler(); |
297 this.callback = callback; | 308 this.callback = callback; |
298 this.events = events; | 309 this.events = events; |
299 this.applicationContext = applicationContext; | 310 this.applicationContext = applicationContext; |
300 this.cameraManager = cameraManager; | 311 this.cameraManager = cameraManager; |
301 this.surfaceTextureHelper = surfaceTextureHelper; | 312 this.surfaceTextureHelper = surfaceTextureHelper; |
313 this.mediaRecorderSurface = (mediaRecorder != null) ? mediaRecorder.getSurfa ce() : null; | |
302 this.cameraId = cameraId; | 314 this.cameraId = cameraId; |
303 this.width = width; | 315 this.width = width; |
304 this.height = height; | 316 this.height = height; |
305 this.framerate = framerate; | 317 this.framerate = framerate; |
306 | 318 |
307 start(); | 319 start(); |
308 } | 320 } |
309 | 321 |
310 private void start() { | 322 private void start() { |
311 checkIsOnCameraThread(); | 323 checkIsOnCameraThread(); |
(...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
444 } | 456 } |
445 return (cameraOrientation + rotation) % 360; | 457 return (cameraOrientation + rotation) % 360; |
446 } | 458 } |
447 | 459 |
448 private void checkIsOnCameraThread() { | 460 private void checkIsOnCameraThread() { |
449 if (Thread.currentThread() != cameraThreadHandler.getLooper().getThread()) { | 461 if (Thread.currentThread() != cameraThreadHandler.getLooper().getThread()) { |
450 throw new IllegalStateException("Wrong thread"); | 462 throw new IllegalStateException("Wrong thread"); |
451 } | 463 } |
452 } | 464 } |
453 } | 465 } |
OLD | NEW |