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.content.Context; | 13 import android.content.Context; |
14 import android.media.MediaRecorder; | |
15 import android.os.Handler; | 14 import android.os.Handler; |
16 import android.os.Looper; | 15 import android.os.Looper; |
17 import java.util.Arrays; | 16 import java.util.Arrays; |
18 | 17 |
19 @SuppressWarnings("deprecation") | 18 @SuppressWarnings("deprecation") |
20 abstract class CameraCapturer implements CameraVideoCapturer { | 19 abstract class CameraCapturer implements CameraVideoCapturer { |
21 enum SwitchState { | 20 enum SwitchState { |
22 IDLE, // No switch requested. | 21 IDLE, // No switch requested. |
23 PENDING, // Waiting for previous capture session to open. | 22 PENDING, // Waiting for previous capture session to open. |
24 IN_PROGRESS, // Waiting for new switched capture session to start. | 23 IN_PROGRESS, // Waiting for new switched capture session to start. |
25 } | 24 } |
26 | 25 |
27 enum MediaRecorderState { | |
28 IDLE, // No media recording update (add or remove) requested. | |
29 IDLE_TO_ACTIVE, // Waiting for new capture session with added MediaRecorder
surface to start. | |
30 ACTIVE_TO_IDLE, // Waiting for new capture session with removed MediaRecorde
r surface to start. | |
31 ACTIVE, // MediaRecorder was successfully added to camera pipeline. | |
32 } | |
33 | |
34 private static final String TAG = "CameraCapturer"; | 26 private static final String TAG = "CameraCapturer"; |
35 private final static int MAX_OPEN_CAMERA_ATTEMPTS = 3; | 27 private final static int MAX_OPEN_CAMERA_ATTEMPTS = 3; |
36 private final static int OPEN_CAMERA_DELAY_MS = 500; | 28 private final static int OPEN_CAMERA_DELAY_MS = 500; |
37 private final static int OPEN_CAMERA_TIMEOUT = 10000; | 29 private final static int OPEN_CAMERA_TIMEOUT = 10000; |
38 | 30 |
39 private final CameraEnumerator cameraEnumerator; | 31 private final CameraEnumerator cameraEnumerator; |
40 private final CameraEventsHandler eventsHandler; | 32 private final CameraEventsHandler eventsHandler; |
41 private final Handler uiThreadHandler; | 33 private final Handler uiThreadHandler; |
42 | 34 |
43 private final CameraSession.CreateSessionCallback createSessionCallback = | 35 private final CameraSession.CreateSessionCallback createSessionCallback = |
44 new CameraSession.CreateSessionCallback() { | 36 new CameraSession.CreateSessionCallback() { |
45 @Override | 37 @Override |
46 public void onDone(CameraSession session) { | 38 public void onDone(CameraSession session) { |
47 checkIsOnCameraThread(); | 39 checkIsOnCameraThread(); |
48 Logging.d(TAG, | 40 Logging.d(TAG, "Create session done"); |
49 "Create session done. Switch state: " + switchState | |
50 + ". MediaRecorder state: " + mediaRecorderState); | |
51 uiThreadHandler.removeCallbacks(openCameraTimeoutRunnable); | 41 uiThreadHandler.removeCallbacks(openCameraTimeoutRunnable); |
52 synchronized (stateLock) { | 42 synchronized (stateLock) { |
53 capturerObserver.onCapturerStarted(true /* success */); | 43 capturerObserver.onCapturerStarted(true /* success */); |
54 sessionOpening = false; | 44 sessionOpening = false; |
55 currentSession = session; | 45 currentSession = session; |
56 cameraStatistics = new CameraStatistics(surfaceHelper, eventsHandler
); | 46 cameraStatistics = new CameraStatistics(surfaceHelper, eventsHandler
); |
57 firstFrameObserved = false; | 47 firstFrameObserved = false; |
58 stateLock.notifyAll(); | 48 stateLock.notifyAll(); |
59 | 49 |
60 if (switchState == SwitchState.IN_PROGRESS) { | 50 if (switchState == SwitchState.IN_PROGRESS) { |
61 if (switchEventsHandler != null) { | 51 if (switchEventsHandler != null) { |
62 switchEventsHandler.onCameraSwitchDone(cameraEnumerator.isFrontF
acing(cameraName)); | 52 switchEventsHandler.onCameraSwitchDone(cameraEnumerator.isFrontF
acing(cameraName)); |
63 switchEventsHandler = null; | 53 switchEventsHandler = null; |
64 } | 54 } |
65 switchState = SwitchState.IDLE; | 55 switchState = SwitchState.IDLE; |
66 } else if (switchState == SwitchState.PENDING) { | 56 } else if (switchState == SwitchState.PENDING) { |
67 switchState = SwitchState.IDLE; | 57 switchState = SwitchState.IDLE; |
68 switchCameraInternal(switchEventsHandler); | 58 switchCameraInternal(switchEventsHandler); |
69 } | 59 } |
70 | |
71 if (mediaRecorderState == MediaRecorderState.IDLE_TO_ACTIVE | |
72 || mediaRecorderState == MediaRecorderState.ACTIVE_TO_IDLE) { | |
73 if (mediaRecorderEventsHandler != null) { | |
74 mediaRecorderEventsHandler.onMediaRecorderSuccess(); | |
75 mediaRecorderEventsHandler = null; | |
76 } | |
77 if (mediaRecorderState == MediaRecorderState.IDLE_TO_ACTIVE) { | |
78 mediaRecorderState = MediaRecorderState.ACTIVE; | |
79 } else { | |
80 mediaRecorderState = MediaRecorderState.IDLE; | |
81 } | |
82 } | |
83 } | 60 } |
84 } | 61 } |
85 | 62 |
86 @Override | 63 @Override |
87 public void onFailure(CameraSession.FailureType failureType, String erro
r) { | 64 public void onFailure(CameraSession.FailureType failureType, String erro
r) { |
88 checkIsOnCameraThread(); | 65 checkIsOnCameraThread(); |
89 uiThreadHandler.removeCallbacks(openCameraTimeoutRunnable); | 66 uiThreadHandler.removeCallbacks(openCameraTimeoutRunnable); |
90 synchronized (stateLock) { | 67 synchronized (stateLock) { |
91 capturerObserver.onCapturerStarted(false /* success */); | 68 capturerObserver.onCapturerStarted(false /* success */); |
92 openAttemptsRemaining--; | 69 openAttemptsRemaining--; |
93 | 70 |
94 if (openAttemptsRemaining <= 0) { | 71 if (openAttemptsRemaining <= 0) { |
95 Logging.w(TAG, "Opening camera failed, passing: " + error); | 72 Logging.w(TAG, "Opening camera failed, passing: " + error); |
96 sessionOpening = false; | 73 sessionOpening = false; |
97 stateLock.notifyAll(); | 74 stateLock.notifyAll(); |
98 | 75 |
99 if (switchState != SwitchState.IDLE) { | 76 if (switchState != SwitchState.IDLE) { |
100 if (switchEventsHandler != null) { | 77 if (switchEventsHandler != null) { |
101 switchEventsHandler.onCameraSwitchError(error); | 78 switchEventsHandler.onCameraSwitchError(error); |
102 switchEventsHandler = null; | 79 switchEventsHandler = null; |
103 } | 80 } |
104 switchState = SwitchState.IDLE; | 81 switchState = SwitchState.IDLE; |
105 } | 82 } |
106 | 83 |
107 if (mediaRecorderState != MediaRecorderState.IDLE) { | |
108 if (mediaRecorderEventsHandler != null) { | |
109 mediaRecorderEventsHandler.onMediaRecorderError(error); | |
110 mediaRecorderEventsHandler = null; | |
111 } | |
112 mediaRecorderState = MediaRecorderState.IDLE; | |
113 } | |
114 | |
115 if (failureType == CameraSession.FailureType.DISCONNECTED) { | 84 if (failureType == CameraSession.FailureType.DISCONNECTED) { |
116 eventsHandler.onCameraDisconnected(); | 85 eventsHandler.onCameraDisconnected(); |
117 } else { | 86 } else { |
118 eventsHandler.onCameraError(error); | 87 eventsHandler.onCameraError(error); |
119 } | 88 } |
120 } else { | 89 } else { |
121 Logging.w(TAG, "Opening camera failed, retry: " + error); | 90 Logging.w(TAG, "Opening camera failed, retry: " + error); |
122 createSessionInternal(OPEN_CAMERA_DELAY_MS, null /* mediaRecorder
*/); | 91 |
| 92 createSessionInternal(OPEN_CAMERA_DELAY_MS); |
123 } | 93 } |
124 } | 94 } |
125 } | 95 } |
126 }; | 96 }; |
127 | 97 |
128 private final CameraSession.Events cameraSessionEventsHandler = new CameraSess
ion.Events() { | 98 private final CameraSession.Events cameraSessionEventsHandler = new CameraSess
ion.Events() { |
129 @Override | 99 @Override |
130 public void onCameraOpening() { | 100 public void onCameraOpening() { |
131 checkIsOnCameraThread(); | 101 checkIsOnCameraThread(); |
132 synchronized (stateLock) { | 102 synchronized (stateLock) { |
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
236 private int width; /* guarded by stateLock */ | 206 private int width; /* guarded by stateLock */ |
237 private int height; /* guarded by stateLock */ | 207 private int height; /* guarded by stateLock */ |
238 private int framerate; /* guarded by stateLock */ | 208 private int framerate; /* guarded by stateLock */ |
239 private int openAttemptsRemaining; /* guarded by stateLock */ | 209 private int openAttemptsRemaining; /* guarded by stateLock */ |
240 private SwitchState switchState = SwitchState.IDLE; /* guarded by stateLock */ | 210 private SwitchState switchState = SwitchState.IDLE; /* guarded by stateLock */ |
241 private CameraSwitchHandler switchEventsHandler; /* guarded by stateLock */ | 211 private CameraSwitchHandler switchEventsHandler; /* guarded by stateLock */ |
242 // Valid from onDone call until stopCapture, otherwise null. | 212 // Valid from onDone call until stopCapture, otherwise null. |
243 private CameraStatistics cameraStatistics; /* guarded by stateLock */ | 213 private CameraStatistics cameraStatistics; /* guarded by stateLock */ |
244 private boolean firstFrameObserved; /* guarded by stateLock */ | 214 private boolean firstFrameObserved; /* guarded by stateLock */ |
245 | 215 |
246 // Variables used on camera thread - do not require stateLock synchronization. | |
247 private MediaRecorderState mediaRecorderState = MediaRecorderState.IDLE; | |
248 private MediaRecorderHandler mediaRecorderEventsHandler; | |
249 | |
250 public CameraCapturer( | 216 public CameraCapturer( |
251 String cameraName, CameraEventsHandler eventsHandler, CameraEnumerator cam
eraEnumerator) { | 217 String cameraName, CameraEventsHandler eventsHandler, CameraEnumerator cam
eraEnumerator) { |
252 if (eventsHandler == null) { | 218 if (eventsHandler == null) { |
253 eventsHandler = new CameraEventsHandler() { | 219 eventsHandler = new CameraEventsHandler() { |
254 @Override | 220 @Override |
255 public void onCameraError(String errorDescription) {} | 221 public void onCameraError(String errorDescription) {} |
256 @Override | 222 @Override |
257 public void onCameraDisconnected() {} | 223 public void onCameraDisconnected() {} |
258 @Override | 224 @Override |
259 public void onCameraFreezed(String errorDescription) {} | 225 public void onCameraFreezed(String errorDescription) {} |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
304 Logging.w(TAG, "Session already open"); | 270 Logging.w(TAG, "Session already open"); |
305 return; | 271 return; |
306 } | 272 } |
307 | 273 |
308 this.width = width; | 274 this.width = width; |
309 this.height = height; | 275 this.height = height; |
310 this.framerate = framerate; | 276 this.framerate = framerate; |
311 | 277 |
312 sessionOpening = true; | 278 sessionOpening = true; |
313 openAttemptsRemaining = MAX_OPEN_CAMERA_ATTEMPTS; | 279 openAttemptsRemaining = MAX_OPEN_CAMERA_ATTEMPTS; |
314 createSessionInternal(0, null /* mediaRecorder */); | 280 createSessionInternal(0); |
315 } | 281 } |
316 } | 282 } |
317 | 283 |
318 private void createSessionInternal(int delayMs, final MediaRecorder mediaRecor
der) { | 284 private void createSessionInternal(int delayMs) { |
319 uiThreadHandler.postDelayed(openCameraTimeoutRunnable, delayMs + OPEN_CAMERA
_TIMEOUT); | 285 uiThreadHandler.postDelayed(openCameraTimeoutRunnable, delayMs + OPEN_CAMERA
_TIMEOUT); |
320 cameraThreadHandler.postDelayed(new Runnable() { | 286 cameraThreadHandler.postDelayed(new Runnable() { |
321 @Override | 287 @Override |
322 public void run() { | 288 public void run() { |
323 createCameraSession(createSessionCallback, cameraSessionEventsHandler, a
pplicationContext, | 289 createCameraSession(createSessionCallback, cameraSessionEventsHandler, a
pplicationContext, |
324 surfaceHelper, mediaRecorder, cameraName, width, height, framerate); | 290 surfaceHelper, cameraName, width, height, framerate); |
325 } | 291 } |
326 }, delayMs); | 292 }, delayMs); |
327 } | 293 } |
328 | 294 |
329 @Override | 295 @Override |
330 public void stopCapture() { | 296 public void stopCapture() { |
331 Logging.d(TAG, "Stop capture"); | 297 Logging.d(TAG, "Stop capture"); |
332 | 298 |
333 synchronized (stateLock) { | 299 synchronized (stateLock) { |
334 while (sessionOpening) { | 300 while (sessionOpening) { |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
377 Logging.d(TAG, "switchCamera"); | 343 Logging.d(TAG, "switchCamera"); |
378 cameraThreadHandler.post(new Runnable() { | 344 cameraThreadHandler.post(new Runnable() { |
379 @Override | 345 @Override |
380 public void run() { | 346 public void run() { |
381 switchCameraInternal(switchEventsHandler); | 347 switchCameraInternal(switchEventsHandler); |
382 } | 348 } |
383 }); | 349 }); |
384 } | 350 } |
385 | 351 |
386 @Override | 352 @Override |
387 public void addMediaRecorderToCamera( | |
388 final MediaRecorder mediaRecorder, final MediaRecorderHandler mediaRecoder
EventsHandler) { | |
389 Logging.d(TAG, "addMediaRecorderToCamera"); | |
390 cameraThreadHandler.post(new Runnable() { | |
391 @Override | |
392 public void run() { | |
393 updateMediaRecorderInternal(mediaRecorder, mediaRecoderEventsHandler); | |
394 } | |
395 }); | |
396 } | |
397 | |
398 @Override | |
399 public void removeMediaRecorderFromCamera(final MediaRecorderHandler mediaReco
derEventsHandler) { | |
400 Logging.d(TAG, "removeMediaRecorderFromCamera"); | |
401 cameraThreadHandler.post(new Runnable() { | |
402 @Override | |
403 public void run() { | |
404 updateMediaRecorderInternal(null /* mediaRecorder */, mediaRecoderEvents
Handler); | |
405 } | |
406 }); | |
407 } | |
408 | |
409 @Override | |
410 public boolean isScreencast() { | 353 public boolean isScreencast() { |
411 return false; | 354 return false; |
412 } | 355 } |
413 | 356 |
414 public void printStackTrace() { | 357 public void printStackTrace() { |
415 Thread cameraThread = null; | 358 Thread cameraThread = null; |
416 if (cameraThreadHandler != null) { | 359 if (cameraThreadHandler != null) { |
417 cameraThread = cameraThreadHandler.getLooper().getThread(); | 360 cameraThread = cameraThreadHandler.getLooper().getThread(); |
418 } | 361 } |
419 if (cameraThread != null) { | 362 if (cameraThread != null) { |
420 StackTraceElement[] cameraStackTrace = cameraThread.getStackTrace(); | 363 StackTraceElement[] cameraStackTrace = cameraThread.getStackTrace(); |
421 if (cameraStackTrace.length > 0) { | 364 if (cameraStackTrace.length > 0) { |
422 Logging.d(TAG, "CameraCapturer stack trace:"); | 365 Logging.d(TAG, "CameraCapturer stack trace:"); |
423 for (StackTraceElement traceElem : cameraStackTrace) { | 366 for (StackTraceElement traceElem : cameraStackTrace) { |
424 Logging.d(TAG, traceElem.toString()); | 367 Logging.d(TAG, traceElem.toString()); |
425 } | 368 } |
426 } | 369 } |
427 } | 370 } |
428 } | 371 } |
429 | 372 |
430 private void reportCameraSwitchError(String error, CameraSwitchHandler switchE
ventsHandler) { | |
431 Logging.e(TAG, error); | |
432 if (switchEventsHandler != null) { | |
433 switchEventsHandler.onCameraSwitchError(error); | |
434 } | |
435 } | |
436 | |
437 private void switchCameraInternal(final CameraSwitchHandler switchEventsHandle
r) { | 373 private void switchCameraInternal(final CameraSwitchHandler switchEventsHandle
r) { |
438 Logging.d(TAG, "switchCamera internal"); | 374 Logging.d(TAG, "switchCamera internal"); |
439 | 375 |
440 final String[] deviceNames = cameraEnumerator.getDeviceNames(); | 376 final String[] deviceNames = cameraEnumerator.getDeviceNames(); |
441 | 377 |
442 if (deviceNames.length < 2) { | 378 if (deviceNames.length < 2) { |
443 if (switchEventsHandler != null) { | 379 if (switchEventsHandler != null) { |
444 switchEventsHandler.onCameraSwitchError("No camera to switch to."); | 380 switchEventsHandler.onCameraSwitchError("No camera to switch to."); |
445 } | 381 } |
446 return; | 382 return; |
447 } | 383 } |
448 | 384 |
449 synchronized (stateLock) { | 385 synchronized (stateLock) { |
450 if (switchState != SwitchState.IDLE) { | 386 if (switchState != SwitchState.IDLE) { |
451 reportCameraSwitchError("Camera switch already in progress.", switchEven
tsHandler); | 387 Logging.d(TAG, "switchCamera switchInProgress"); |
452 return; | 388 if (switchEventsHandler != null) { |
453 } | 389 switchEventsHandler.onCameraSwitchError("Camera switch already in prog
ress."); |
454 if (mediaRecorderState != MediaRecorderState.IDLE) { | 390 } |
455 reportCameraSwitchError("switchCamera: media recording is active", switc
hEventsHandler); | |
456 return; | |
457 } | |
458 if (!sessionOpening && currentSession == null) { | |
459 reportCameraSwitchError("switchCamera: camera is not running.", switchEv
entsHandler); | |
460 return; | 391 return; |
461 } | 392 } |
462 | 393 |
| 394 if (!sessionOpening && currentSession == null) { |
| 395 Logging.d(TAG, "switchCamera: No session open"); |
| 396 if (switchEventsHandler != null) { |
| 397 switchEventsHandler.onCameraSwitchError("Camera is not running."); |
| 398 } |
| 399 return; |
| 400 } |
| 401 |
463 this.switchEventsHandler = switchEventsHandler; | 402 this.switchEventsHandler = switchEventsHandler; |
464 if (sessionOpening) { | 403 if (sessionOpening) { |
465 switchState = SwitchState.PENDING; | 404 switchState = SwitchState.PENDING; |
466 return; | 405 return; |
467 } else { | 406 } else { |
468 switchState = SwitchState.IN_PROGRESS; | 407 switchState = SwitchState.IN_PROGRESS; |
469 } | 408 } |
470 | 409 |
471 Logging.d(TAG, "switchCamera: Stopping session"); | 410 Logging.d(TAG, "switchCamera: Stopping session"); |
472 cameraStatistics.release(); | 411 cameraStatistics.release(); |
473 cameraStatistics = null; | 412 cameraStatistics = null; |
474 final CameraSession oldSession = currentSession; | 413 final CameraSession oldSession = currentSession; |
475 cameraThreadHandler.post(new Runnable() { | 414 cameraThreadHandler.post(new Runnable() { |
476 @Override | 415 @Override |
477 public void run() { | 416 public void run() { |
478 oldSession.stop(); | 417 oldSession.stop(); |
479 } | 418 } |
480 }); | 419 }); |
481 currentSession = null; | 420 currentSession = null; |
482 | 421 |
483 int cameraNameIndex = Arrays.asList(deviceNames).indexOf(cameraName); | 422 int cameraNameIndex = Arrays.asList(deviceNames).indexOf(cameraName); |
484 cameraName = deviceNames[(cameraNameIndex + 1) % deviceNames.length]; | 423 cameraName = deviceNames[(cameraNameIndex + 1) % deviceNames.length]; |
485 | 424 |
486 sessionOpening = true; | 425 sessionOpening = true; |
487 openAttemptsRemaining = 1; | 426 openAttemptsRemaining = 1; |
488 createSessionInternal(0, null /* mediaRecorder */); | 427 createSessionInternal(0); |
489 } | 428 } |
490 Logging.d(TAG, "switchCamera done"); | 429 Logging.d(TAG, "switchCamera done"); |
491 } | 430 } |
492 | 431 |
493 private void reportUpdateMediaRecorderError( | |
494 String error, MediaRecorderHandler mediaRecoderEventsHandler) { | |
495 checkIsOnCameraThread(); | |
496 Logging.e(TAG, error); | |
497 if (mediaRecoderEventsHandler != null) { | |
498 mediaRecoderEventsHandler.onMediaRecorderError(error); | |
499 } | |
500 } | |
501 | |
502 private void updateMediaRecorderInternal( | |
503 MediaRecorder mediaRecorder, MediaRecorderHandler mediaRecoderEventsHandle
r) { | |
504 checkIsOnCameraThread(); | |
505 boolean addMediaRecorder = (mediaRecorder != null); | |
506 Logging.d(TAG, | |
507 "updateMediaRecoderInternal internal. State: " + mediaRecorderState | |
508 + ". Switch state: " + switchState + ". Add MediaRecorder: " + addMe
diaRecorder); | |
509 | |
510 synchronized (stateLock) { | |
511 if ((addMediaRecorder && mediaRecorderState != MediaRecorderState.IDLE) | |
512 || (!addMediaRecorder && mediaRecorderState != MediaRecorderState.ACTI
VE)) { | |
513 reportUpdateMediaRecorderError( | |
514 "Incorrect state for MediaRecorder update.", mediaRecoderEventsHandl
er); | |
515 return; | |
516 } | |
517 if (switchState != SwitchState.IDLE) { | |
518 reportUpdateMediaRecorderError( | |
519 "MediaRecorder update while camera is switching.", mediaRecoderEvent
sHandler); | |
520 return; | |
521 } | |
522 if (currentSession == null) { | |
523 reportUpdateMediaRecorderError( | |
524 "MediaRecorder update while camera is closed.", mediaRecoderEventsHa
ndler); | |
525 return; | |
526 } | |
527 if (sessionOpening) { | |
528 reportUpdateMediaRecorderError( | |
529 "MediaRecorder update while camera is still opening.", mediaRecoderE
ventsHandler); | |
530 return; | |
531 } | |
532 | |
533 this.mediaRecorderEventsHandler = mediaRecoderEventsHandler; | |
534 mediaRecorderState = | |
535 addMediaRecorder ? MediaRecorderState.IDLE_TO_ACTIVE : MediaRecorderSt
ate.ACTIVE_TO_IDLE; | |
536 | |
537 Logging.d(TAG, "updateMediaRecoder: Stopping session"); | |
538 cameraStatistics.release(); | |
539 cameraStatistics = null; | |
540 final CameraSession oldSession = currentSession; | |
541 cameraThreadHandler.post(new Runnable() { | |
542 @Override | |
543 public void run() { | |
544 oldSession.stop(); | |
545 } | |
546 }); | |
547 currentSession = null; | |
548 | |
549 sessionOpening = true; | |
550 openAttemptsRemaining = 1; | |
551 createSessionInternal(0, mediaRecorder); | |
552 } | |
553 Logging.d(TAG, "updateMediaRecoderInternal done"); | |
554 } | |
555 | |
556 private void checkIsOnCameraThread() { | 432 private void checkIsOnCameraThread() { |
557 if (Thread.currentThread() != cameraThreadHandler.getLooper().getThread()) { | 433 if (Thread.currentThread() != cameraThreadHandler.getLooper().getThread()) { |
558 Logging.e(TAG, "Check is on camera thread failed."); | 434 Logging.e(TAG, "Check is on camera thread failed."); |
559 throw new RuntimeException("Not on camera thread."); | 435 throw new RuntimeException("Not on camera thread."); |
560 } | 436 } |
561 } | 437 } |
562 | 438 |
563 protected String getCameraName() { | 439 protected String getCameraName() { |
564 synchronized (stateLock) { | 440 synchronized (stateLock) { |
565 return cameraName; | 441 return cameraName; |
566 } | 442 } |
567 } | 443 } |
568 | 444 |
569 abstract protected void createCameraSession( | 445 abstract protected void createCameraSession( |
570 CameraSession.CreateSessionCallback createSessionCallback, CameraSession.E
vents events, | 446 CameraSession.CreateSessionCallback createSessionCallback, CameraSession.E
vents events, |
571 Context applicationContext, SurfaceTextureHelper surfaceTextureHelper, | 447 Context applicationContext, SurfaceTextureHelper surfaceTextureHelper, Str
ing cameraName, |
572 MediaRecorder mediaRecoder, String cameraName, int width, int height, int
framerate); | 448 int width, int height, int framerate); |
573 } | 449 } |
OLD | NEW |