OLD | NEW |
| (Empty) |
1 /* | |
2 * Copyright 2016 The WebRTC project authors. All Rights Reserved. | |
3 * | |
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 | |
6 * tree. An additional intellectual property rights grant can be found | |
7 * in the file PATENTS. All contributing project authors may | |
8 * be found in the AUTHORS file in the root of the source tree. | |
9 */ | |
10 | |
11 package org.webrtc; | |
12 | |
13 /** | |
14 * Base interface for camera1 and camera2 implementations. Extends VideoCapturer
with a | |
15 * switchCamera() function. Also provides subinterfaces for handling camera even
ts, and a helper | |
16 * class for detecting camera freezes. | |
17 */ | |
18 public interface CameraVideoCapturer extends VideoCapturer { | |
19 /** | |
20 * Camera events handler - can be used to be notifed about camera events. The
callbacks are | |
21 * executed from an arbitrary thread. | |
22 */ | |
23 public interface CameraEventsHandler { | |
24 // Camera error handler - invoked when camera can not be opened | |
25 // or any camera exception happens on camera thread. | |
26 void onCameraError(String errorDescription); | |
27 | |
28 // Invoked when camera stops receiving frames. | |
29 void onCameraFreezed(String errorDescription); | |
30 | |
31 // Callback invoked when camera is opening. | |
32 void onCameraOpening(int cameraId); | |
33 | |
34 // Callback invoked when first camera frame is available after camera is sta
rted. | |
35 void onFirstFrameAvailable(); | |
36 | |
37 // Callback invoked when camera is closed. | |
38 void onCameraClosed(); | |
39 } | |
40 | |
41 /** | |
42 * Camera switch handler - one of these functions are invoked with the result
of switchCamera(). | |
43 * The callback may be called on an arbitrary thread. | |
44 */ | |
45 public interface CameraSwitchHandler { | |
46 // Invoked on success. |isFrontCamera| is true if the new camera is front fa
cing. | |
47 void onCameraSwitchDone(boolean isFrontCamera); | |
48 | |
49 // Invoked on failure, e.g. camera is stopped or only one camera available. | |
50 void onCameraSwitchError(String errorDescription); | |
51 } | |
52 | |
53 /** | |
54 * Switch camera to the next valid camera id. This can only be called while th
e camera is running. | |
55 * This function can be called from any thread. | |
56 */ | |
57 void switchCamera(CameraSwitchHandler switchEventsHandler); | |
58 | |
59 /** | |
60 * Helper class to log framerate and detect if the camera freezes. It will run
periodic callbacks | |
61 * on the SurfaceTextureHelper thread passed in the ctor, and should only be o
perated from that | |
62 * thread. | |
63 */ | |
64 public static class CameraStatistics { | |
65 private final static String TAG = "CameraStatistics"; | |
66 private final static int CAMERA_OBSERVER_PERIOD_MS = 2000; | |
67 private final static int CAMERA_FREEZE_REPORT_TIMOUT_MS = 4000; | |
68 | |
69 private final SurfaceTextureHelper surfaceTextureHelper; | |
70 private final CameraEventsHandler eventsHandler; | |
71 private int frameCount; | |
72 private int freezePeriodCount; | |
73 // Camera observer - monitors camera framerate. Observer is executed on came
ra thread. | |
74 private final Runnable cameraObserver = new Runnable() { | |
75 @Override | |
76 public void run() { | |
77 final int cameraFps = Math.round(frameCount * 1000.0f / CAMERA_OBSERVER_
PERIOD_MS); | |
78 Logging.d(TAG, "Camera fps: " + cameraFps +"."); | |
79 if (frameCount == 0) { | |
80 ++freezePeriodCount; | |
81 if (CAMERA_OBSERVER_PERIOD_MS * freezePeriodCount >= CAMERA_FREEZE_REP
ORT_TIMOUT_MS | |
82 && eventsHandler != null) { | |
83 Logging.e(TAG, "Camera freezed."); | |
84 if (surfaceTextureHelper.isTextureInUse()) { | |
85 // This can only happen if we are capturing to textures. | |
86 eventsHandler.onCameraFreezed("Camera failure. Client must return
video buffers."); | |
87 } else { | |
88 eventsHandler.onCameraFreezed("Camera failure."); | |
89 } | |
90 return; | |
91 } | |
92 } else { | |
93 freezePeriodCount = 0; | |
94 } | |
95 frameCount = 0; | |
96 surfaceTextureHelper.getHandler().postDelayed(this, CAMERA_OBSERVER_PERI
OD_MS); | |
97 } | |
98 }; | |
99 | |
100 public CameraStatistics( | |
101 SurfaceTextureHelper surfaceTextureHelper, CameraEventsHandler eventsHan
dler) { | |
102 if (surfaceTextureHelper == null) { | |
103 throw new IllegalArgumentException("SurfaceTextureHelper is null"); | |
104 } | |
105 this.surfaceTextureHelper = surfaceTextureHelper; | |
106 this.eventsHandler = eventsHandler; | |
107 this.frameCount = 0; | |
108 this.freezePeriodCount = 0; | |
109 surfaceTextureHelper.getHandler().postDelayed(cameraObserver, CAMERA_OBSER
VER_PERIOD_MS); | |
110 } | |
111 | |
112 private void checkThread() { | |
113 if (Thread.currentThread() != surfaceTextureHelper.getHandler().getLooper(
).getThread()) { | |
114 throw new IllegalStateException("Wrong thread"); | |
115 } | |
116 } | |
117 | |
118 public void addFrame() { | |
119 checkThread(); | |
120 ++frameCount; | |
121 } | |
122 | |
123 public void release() { | |
124 checkThread(); | |
125 surfaceTextureHelper.getHandler().removeCallbacks(cameraObserver); | |
126 } | |
127 } | |
128 } | |
OLD | NEW |