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