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 mediaRecorder = null; | |
83 } | |
60 } | 84 } |
61 } | 85 } |
62 | 86 |
63 @Override | 87 @Override |
64 public void onFailure(CameraSession.FailureType failureType, String erro r) { | 88 public void onFailure(CameraSession.FailureType failureType, String erro r) { |
65 checkIsOnCameraThread(); | 89 checkIsOnCameraThread(); |
66 uiThreadHandler.removeCallbacks(openCameraTimeoutRunnable); | 90 uiThreadHandler.removeCallbacks(openCameraTimeoutRunnable); |
67 synchronized (stateLock) { | 91 synchronized (stateLock) { |
68 capturerObserver.onCapturerStarted(false /* success */); | 92 capturerObserver.onCapturerStarted(false /* success */); |
69 openAttemptsRemaining--; | 93 openAttemptsRemaining--; |
70 | 94 |
71 if (openAttemptsRemaining <= 0) { | 95 if (openAttemptsRemaining <= 0) { |
72 Logging.w(TAG, "Opening camera failed, passing: " + error); | 96 Logging.w(TAG, "Opening camera failed, passing: " + error); |
73 sessionOpening = false; | 97 sessionOpening = false; |
74 stateLock.notifyAll(); | 98 stateLock.notifyAll(); |
75 | 99 |
76 if (switchState != SwitchState.IDLE) { | 100 if (switchState != SwitchState.IDLE) { |
77 if (switchEventsHandler != null) { | 101 if (switchEventsHandler != null) { |
78 switchEventsHandler.onCameraSwitchError(error); | 102 switchEventsHandler.onCameraSwitchError(error); |
79 switchEventsHandler = null; | 103 switchEventsHandler = null; |
80 } | 104 } |
81 switchState = SwitchState.IDLE; | 105 switchState = SwitchState.IDLE; |
82 } | 106 } |
83 | 107 |
108 if (mediaRecorderState != MediaRecorderState.IDLE) { | |
109 if (mediaRecorderEventsHandler != null) { | |
110 mediaRecorderEventsHandler.onMediaRecorderError(error); | |
111 mediaRecorderEventsHandler = null; | |
112 } | |
113 mediaRecorderState = MediaRecorderState.IDLE; | |
114 mediaRecorder = null; | |
115 } | |
116 | |
84 if (failureType == CameraSession.FailureType.DISCONNECTED) { | 117 if (failureType == CameraSession.FailureType.DISCONNECTED) { |
85 eventsHandler.onCameraDisconnected(); | 118 eventsHandler.onCameraDisconnected(); |
86 } else { | 119 } else { |
87 eventsHandler.onCameraError(error); | 120 eventsHandler.onCameraError(error); |
88 } | 121 } |
89 } else { | 122 } else { |
90 Logging.w(TAG, "Opening camera failed, retry: " + error); | 123 Logging.w(TAG, "Opening camera failed, retry: " + error); |
91 | 124 |
92 createSessionInternal(OPEN_CAMERA_DELAY_MS); | 125 createSessionInternal(OPEN_CAMERA_DELAY_MS); |
93 } | 126 } |
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
191 eventsHandler.onCameraError("Camera failed to start within timeout."); | 224 eventsHandler.onCameraError("Camera failed to start within timeout."); |
192 } | 225 } |
193 }; | 226 }; |
194 | 227 |
195 // Initialized on initialize | 228 // Initialized on initialize |
196 // ------------------------- | 229 // ------------------------- |
197 private Handler cameraThreadHandler; | 230 private Handler cameraThreadHandler; |
198 private Context applicationContext; | 231 private Context applicationContext; |
199 private CapturerObserver capturerObserver; | 232 private CapturerObserver capturerObserver; |
200 private SurfaceTextureHelper surfaceHelper; | 233 private SurfaceTextureHelper surfaceHelper; |
234 private MediaRecorder mediaRecorder; | |
sakal
2017/04/24 09:17:32
I don't think this member variable is needed. It c
AlexG
2017/04/25 23:11:51
This is actually used during re attempting to open
sakal
2017/04/26 07:34:11
But you set openAttemptsRemaining = 1; in updateMe
| |
201 | 235 |
202 private final Object stateLock = new Object(); | 236 private final Object stateLock = new Object(); |
203 private boolean sessionOpening; /* guarded by stateLock */ | 237 private boolean sessionOpening; /* guarded by stateLock */ |
204 private CameraSession currentSession; /* guarded by stateLock */ | 238 private CameraSession currentSession; /* guarded by stateLock */ |
205 private String cameraName; /* guarded by stateLock */ | 239 private String cameraName; /* guarded by stateLock */ |
206 private int width; /* guarded by stateLock */ | 240 private int width; /* guarded by stateLock */ |
207 private int height; /* guarded by stateLock */ | 241 private int height; /* guarded by stateLock */ |
208 private int framerate; /* guarded by stateLock */ | 242 private int framerate; /* guarded by stateLock */ |
209 private int openAttemptsRemaining; /* guarded by stateLock */ | 243 private int openAttemptsRemaining; /* guarded by stateLock */ |
210 private SwitchState switchState = SwitchState.IDLE; /* guarded by stateLock */ | 244 private SwitchState switchState = SwitchState.IDLE; /* guarded by stateLock */ |
211 private CameraSwitchHandler switchEventsHandler; /* guarded by stateLock */ | 245 private CameraSwitchHandler switchEventsHandler; /* guarded by stateLock */ |
212 // Valid from onDone call until stopCapture, otherwise null. | 246 // Valid from onDone call until stopCapture, otherwise null. |
213 private CameraStatistics cameraStatistics; /* guarded by stateLock */ | 247 private CameraStatistics cameraStatistics; /* guarded by stateLock */ |
214 private boolean firstFrameObserved; /* guarded by stateLock */ | 248 private boolean firstFrameObserved; /* guarded by stateLock */ |
215 | 249 |
250 // Variables used on camera thread - do not require stateLock synchronization. | |
251 private MediaRecorderState mediaRecorderState = MediaRecorderState.IDLE; | |
252 private MediaRecorderHandler mediaRecorderEventsHandler; | |
253 | |
216 public CameraCapturer( | 254 public CameraCapturer( |
217 String cameraName, CameraEventsHandler eventsHandler, CameraEnumerator cam eraEnumerator) { | 255 String cameraName, CameraEventsHandler eventsHandler, CameraEnumerator cam eraEnumerator) { |
218 if (eventsHandler == null) { | 256 if (eventsHandler == null) { |
219 eventsHandler = new CameraEventsHandler() { | 257 eventsHandler = new CameraEventsHandler() { |
220 @Override | 258 @Override |
221 public void onCameraError(String errorDescription) {} | 259 public void onCameraError(String errorDescription) {} |
222 @Override | 260 @Override |
223 public void onCameraDisconnected() {} | 261 public void onCameraDisconnected() {} |
224 @Override | 262 @Override |
225 public void onCameraFreezed(String errorDescription) {} | 263 public void onCameraFreezed(String errorDescription) {} |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
280 createSessionInternal(0); | 318 createSessionInternal(0); |
281 } | 319 } |
282 } | 320 } |
283 | 321 |
284 private void createSessionInternal(int delayMs) { | 322 private void createSessionInternal(int delayMs) { |
285 uiThreadHandler.postDelayed(openCameraTimeoutRunnable, delayMs + OPEN_CAMERA _TIMEOUT); | 323 uiThreadHandler.postDelayed(openCameraTimeoutRunnable, delayMs + OPEN_CAMERA _TIMEOUT); |
286 cameraThreadHandler.postDelayed(new Runnable() { | 324 cameraThreadHandler.postDelayed(new Runnable() { |
287 @Override | 325 @Override |
288 public void run() { | 326 public void run() { |
289 createCameraSession(createSessionCallback, cameraSessionEventsHandler, a pplicationContext, | 327 createCameraSession(createSessionCallback, cameraSessionEventsHandler, a pplicationContext, |
290 surfaceHelper, cameraName, width, height, framerate); | 328 surfaceHelper, mediaRecorder, cameraName, width, height, framerate); |
291 } | 329 } |
292 }, delayMs); | 330 }, delayMs); |
293 } | 331 } |
294 | 332 |
295 @Override | 333 @Override |
296 public void stopCapture() { | 334 public void stopCapture() { |
297 Logging.d(TAG, "Stop capture"); | 335 Logging.d(TAG, "Stop capture"); |
298 | 336 |
299 synchronized (stateLock) { | 337 synchronized (stateLock) { |
300 while (sessionOpening) { | 338 while (sessionOpening) { |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
343 Logging.d(TAG, "switchCamera"); | 381 Logging.d(TAG, "switchCamera"); |
344 cameraThreadHandler.post(new Runnable() { | 382 cameraThreadHandler.post(new Runnable() { |
345 @Override | 383 @Override |
346 public void run() { | 384 public void run() { |
347 switchCameraInternal(switchEventsHandler); | 385 switchCameraInternal(switchEventsHandler); |
348 } | 386 } |
349 }); | 387 }); |
350 } | 388 } |
351 | 389 |
352 @Override | 390 @Override |
391 public void addMediaRecorderToCamera( | |
392 final MediaRecorder mediaRecorder, final MediaRecorderHandler mediaRecoder EventsHandler) { | |
393 Logging.d(TAG, "addMediaRecorderToCamera"); | |
394 cameraThreadHandler.post(new Runnable() { | |
395 @Override | |
396 public void run() { | |
397 updateMediaRecorderInternal( | |
398 true /* addMediaRecorder */, mediaRecorder, mediaRecoderEventsHandle r); | |
399 } | |
400 }); | |
401 } | |
402 | |
403 @Override | |
404 public void removeMediaRecorderFromCamera(final MediaRecorderHandler mediaReco derEventsHandler) { | |
405 Logging.d(TAG, "removeMediaRecorderFromCamera"); | |
406 cameraThreadHandler.post(new Runnable() { | |
407 @Override | |
408 public void run() { | |
409 updateMediaRecorderInternal( | |
410 false /* addMediaRecorder */, null /* mediaRecorder */, mediaRecoder EventsHandler); | |
411 } | |
412 }); | |
413 } | |
414 | |
415 @Override | |
353 public boolean isScreencast() { | 416 public boolean isScreencast() { |
354 return false; | 417 return false; |
355 } | 418 } |
356 | 419 |
357 public void printStackTrace() { | 420 public void printStackTrace() { |
358 Thread cameraThread = null; | 421 Thread cameraThread = null; |
359 if (cameraThreadHandler != null) { | 422 if (cameraThreadHandler != null) { |
360 cameraThread = cameraThreadHandler.getLooper().getThread(); | 423 cameraThread = cameraThreadHandler.getLooper().getThread(); |
361 } | 424 } |
362 if (cameraThread != null) { | 425 if (cameraThread != null) { |
363 StackTraceElement[] cameraStackTrace = cameraThread.getStackTrace(); | 426 StackTraceElement[] cameraStackTrace = cameraThread.getStackTrace(); |
364 if (cameraStackTrace.length > 0) { | 427 if (cameraStackTrace.length > 0) { |
365 Logging.d(TAG, "CameraCapturer stack trace:"); | 428 Logging.d(TAG, "CameraCapturer stack trace:"); |
366 for (StackTraceElement traceElem : cameraStackTrace) { | 429 for (StackTraceElement traceElem : cameraStackTrace) { |
367 Logging.d(TAG, traceElem.toString()); | 430 Logging.d(TAG, traceElem.toString()); |
368 } | 431 } |
369 } | 432 } |
370 } | 433 } |
371 } | 434 } |
372 | 435 |
436 private void reportCameraSwitchError(String error, CameraSwitchHandler switchE ventsHandler) { | |
437 Logging.e(TAG, error); | |
438 if (switchEventsHandler != null) { | |
439 switchEventsHandler.onCameraSwitchError(error); | |
440 } | |
441 } | |
442 | |
373 private void switchCameraInternal(final CameraSwitchHandler switchEventsHandle r) { | 443 private void switchCameraInternal(final CameraSwitchHandler switchEventsHandle r) { |
374 Logging.d(TAG, "switchCamera internal"); | 444 Logging.d(TAG, "switchCamera internal"); |
375 | 445 |
376 final String[] deviceNames = cameraEnumerator.getDeviceNames(); | 446 final String[] deviceNames = cameraEnumerator.getDeviceNames(); |
377 | 447 |
378 if (deviceNames.length < 2) { | 448 if (deviceNames.length < 2) { |
379 if (switchEventsHandler != null) { | 449 if (switchEventsHandler != null) { |
380 switchEventsHandler.onCameraSwitchError("No camera to switch to."); | 450 switchEventsHandler.onCameraSwitchError("No camera to switch to."); |
381 } | 451 } |
382 return; | 452 return; |
383 } | 453 } |
384 | 454 |
385 synchronized (stateLock) { | 455 synchronized (stateLock) { |
386 if (switchState != SwitchState.IDLE) { | 456 if (switchState != SwitchState.IDLE) { |
387 Logging.d(TAG, "switchCamera switchInProgress"); | 457 reportCameraSwitchError("Camera switch already in progress.", switchEven tsHandler); |
388 if (switchEventsHandler != null) { | 458 return; |
389 switchEventsHandler.onCameraSwitchError("Camera switch already in prog ress."); | 459 } |
390 } | 460 if (mediaRecorderState != MediaRecorderState.IDLE) { |
461 reportCameraSwitchError("switchCamera: media recording is active", switc hEventsHandler); | |
462 return; | |
463 } | |
464 if (!sessionOpening && currentSession == null) { | |
465 reportCameraSwitchError("switchCamera: camera is not running.", switchEv entsHandler); | |
391 return; | 466 return; |
392 } | 467 } |
393 | 468 |
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; | 469 this.switchEventsHandler = switchEventsHandler; |
403 if (sessionOpening) { | 470 if (sessionOpening) { |
404 switchState = SwitchState.PENDING; | 471 switchState = SwitchState.PENDING; |
405 return; | 472 return; |
406 } else { | 473 } else { |
407 switchState = SwitchState.IN_PROGRESS; | 474 switchState = SwitchState.IN_PROGRESS; |
408 } | 475 } |
409 | 476 |
410 Logging.d(TAG, "switchCamera: Stopping session"); | 477 Logging.d(TAG, "switchCamera: Stopping session"); |
411 cameraStatistics.release(); | 478 cameraStatistics.release(); |
(...skipping 10 matching lines...) Expand all Loading... | |
422 int cameraNameIndex = Arrays.asList(deviceNames).indexOf(cameraName); | 489 int cameraNameIndex = Arrays.asList(deviceNames).indexOf(cameraName); |
423 cameraName = deviceNames[(cameraNameIndex + 1) % deviceNames.length]; | 490 cameraName = deviceNames[(cameraNameIndex + 1) % deviceNames.length]; |
424 | 491 |
425 sessionOpening = true; | 492 sessionOpening = true; |
426 openAttemptsRemaining = 1; | 493 openAttemptsRemaining = 1; |
427 createSessionInternal(0); | 494 createSessionInternal(0); |
428 } | 495 } |
429 Logging.d(TAG, "switchCamera done"); | 496 Logging.d(TAG, "switchCamera done"); |
430 } | 497 } |
431 | 498 |
499 private void reportUpdateMediaRecorderError( | |
500 String error, MediaRecorderHandler mediaRecoderEventsHandler) { | |
501 checkIsOnCameraThread(); | |
502 Logging.e(TAG, error); | |
503 if (mediaRecoderEventsHandler != null) { | |
504 mediaRecoderEventsHandler.onMediaRecorderError(error); | |
505 } | |
506 } | |
507 | |
508 private void updateMediaRecorderInternal(boolean addMediaRecorder, MediaRecord er mediaRecorder, | |
magjed_webrtc
2017/04/22 08:41:52
I would prefer to not have |addMediaRecorder| as a
AlexG
2017/04/25 23:11:52
Done.
| |
509 MediaRecorderHandler mediaRecoderEventsHandler) { | |
510 checkIsOnCameraThread(); | |
511 Logging.d(TAG, | |
512 "updateMediaRecoderInternal internal. State: " + mediaRecorderState | |
513 + ". Switch state: " + switchState + ". Add MediaRecorder: " + addMe diaRecorder); | |
514 | |
515 synchronized (stateLock) { | |
516 if ((addMediaRecorder && mediaRecorderState != MediaRecorderState.IDLE) | |
517 || (!addMediaRecorder && mediaRecorderState != MediaRecorderState.ACTI VE)) { | |
518 reportUpdateMediaRecorderError( | |
519 "Incorrect state for MediaRecorder update.", mediaRecoderEventsHandl er); | |
520 return; | |
521 } | |
522 if (switchState != SwitchState.IDLE) { | |
523 reportUpdateMediaRecorderError( | |
524 "MediaRecorder update while camera is switching.", mediaRecoderEvent sHandler); | |
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 if (addMediaRecorder) { | |
magjed_webrtc
2017/04/22 08:41:52
I would like to move 'this.mediaRecorder = mediaRe
AlexG
2017/04/25 23:11:52
Done.
| |
535 this.mediaRecorder = mediaRecorder; | |
536 mediaRecorderState = MediaRecorderState.IDLE_TO_ACTIVE; | |
537 } else { | |
538 this.mediaRecorder = null; | |
539 mediaRecorderState = MediaRecorderState.ACTIVE_TO_IDLE; | |
540 } | |
541 | |
542 Logging.d(TAG, "updateMediaRecoder: Stopping session"); | |
magjed_webrtc
2017/04/22 08:41:52
The documentation for addMediaRecorderToCamera say
AlexG
2017/04/25 23:11:52
Done.
Yes, this case mat be supported as well, bu
| |
543 cameraStatistics.release(); | |
544 cameraStatistics = null; | |
545 final CameraSession oldSession = currentSession; | |
546 cameraThreadHandler.post(new Runnable() { | |
547 @Override | |
548 public void run() { | |
549 oldSession.stop(); | |
550 } | |
551 }); | |
552 currentSession = null; | |
553 | |
554 sessionOpening = true; | |
555 openAttemptsRemaining = 1; | |
556 createSessionInternal(0); | |
557 } | |
558 Logging.d(TAG, "updateMediaRecoderInternal done"); | |
559 } | |
560 | |
432 private void checkIsOnCameraThread() { | 561 private void checkIsOnCameraThread() { |
433 if (Thread.currentThread() != cameraThreadHandler.getLooper().getThread()) { | 562 if (Thread.currentThread() != cameraThreadHandler.getLooper().getThread()) { |
434 Logging.e(TAG, "Check is on camera thread failed."); | 563 Logging.e(TAG, "Check is on camera thread failed."); |
435 throw new RuntimeException("Not on camera thread."); | 564 throw new RuntimeException("Not on camera thread."); |
436 } | 565 } |
437 } | 566 } |
438 | 567 |
439 protected String getCameraName() { | 568 protected String getCameraName() { |
440 synchronized (stateLock) { | 569 synchronized (stateLock) { |
441 return cameraName; | 570 return cameraName; |
442 } | 571 } |
443 } | 572 } |
444 | 573 |
445 abstract protected void createCameraSession( | 574 abstract protected void createCameraSession( |
446 CameraSession.CreateSessionCallback createSessionCallback, CameraSession.E vents events, | 575 CameraSession.CreateSessionCallback createSessionCallback, CameraSession.E vents events, |
447 Context applicationContext, SurfaceTextureHelper surfaceTextureHelper, Str ing cameraName, | 576 Context applicationContext, SurfaceTextureHelper surfaceTextureHelper, |
448 int width, int height, int framerate); | 577 MediaRecorder mediaRecoder, String cameraName, int width, int height, int framerate); |
449 } | 578 } |
OLD | NEW |