| Index: media/video/capture/mac/video_capture_device_qtkit_mac.mm
|
| diff --git a/media/video/capture/mac/video_capture_device_qtkit_mac.mm b/media/video/capture/mac/video_capture_device_qtkit_mac.mm
|
| index 86d4e82d71ac2933e44a0954db702558e663120f..dec74158743f6ffd36105d9e75921d695184d2e1 100644
|
| --- a/media/video/capture/mac/video_capture_device_qtkit_mac.mm
|
| +++ b/media/video/capture/mac/video_capture_device_qtkit_mac.mm
|
| @@ -146,28 +146,8 @@
|
| stringWithUTF8String:"No video capture device set, on removal."]];
|
| return YES;
|
| }
|
| - if ([[captureSession_ inputs] count] > 0) {
|
| - // The device is still running.
|
| - [self stopCapture];
|
| - }
|
| - if ([[captureSession_ outputs] count] > 0) {
|
| - // Only one output is set for |captureSession_|.
|
| - DCHECK_EQ([[captureSession_ outputs] count], 1u);
|
| - id output = [[captureSession_ outputs] objectAtIndex:0];
|
| - [output setDelegate:nil];
|
| -
|
| - // TODO(shess): QTKit achieves thread safety by posting messages to the
|
| - // main thread. As part of -addOutput:, it posts a message to the main
|
| - // thread which in turn posts a notification which will run in a future
|
| - // spin after the original method returns. -removeOutput: can post a
|
| - // main-thread message in between while holding a lock which the
|
| - // notification handler will need. Posting either -addOutput: or
|
| - // -removeOutput: to the main thread should fix it, remove is likely
|
| - // safer. http://crbug.com/152757
|
| - [captureSession_ performSelectorOnMainThread:@selector(removeOutput:)
|
| - withObject:output
|
| - waitUntilDone:YES];
|
| - }
|
| + // Tear down input and output, stop the capture and deregister observers.
|
| + [self stopCapture];
|
| [captureSession_ release];
|
| captureSession_ = nil;
|
| [captureDeviceInput_ release];
|
| @@ -242,12 +222,30 @@
|
| }
|
|
|
| - (void)stopCapture {
|
| - if ([[captureSession_ inputs] count] == 1) {
|
| + // QTKit achieves thread safety and asynchronous execution by posting messages
|
| + // to the main thread, e.g. -addOutput:. Both -removeOutput: and -removeInput:
|
| + // post a message to the main thread while holding a lock that the
|
| + // notification handler might need. To avoid a deadlock, we perform those
|
| + // tasks in the main thread. See bugs http://crbug.com/152757 and
|
| + // http://crbug.com/399792.
|
| + [self performSelectorOnMainThread:@selector(stopCaptureOnUIThread:)
|
| + withObject:nil
|
| + waitUntilDone:YES];
|
| + [[NSNotificationCenter defaultCenter] removeObserver:self];
|
| +}
|
| +
|
| +- (void)stopCaptureOnUIThread:(id)dummy {
|
| + if ([[captureSession_ inputs] count] > 0) {
|
| [captureSession_ removeInput:captureDeviceInput_];
|
| + DCHECK_EQ([[captureSession_ inputs] count], 1u);
|
| [captureSession_ stopRunning];
|
| }
|
| -
|
| - [[NSNotificationCenter defaultCenter] removeObserver:self];
|
| + if ([[captureSession_ outputs] count] > 0) {
|
| + DCHECK_EQ([[captureSession_ outputs] count], 1u);
|
| + id output = [[captureSession_ outputs] objectAtIndex:0];
|
| + [output setDelegate:nil];
|
| + [captureSession_ removeOutput:output];
|
| + }
|
| }
|
|
|
| // |captureOutput| is called by the capture device to deliver a new frame.
|
|
|