Chromium Code Reviews| 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..26e942d19fd6d136156f5fe69bae430056e5e60e 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,14 +222,32 @@ |
| } |
| - (void)stopCapture { |
| - if ([[captureSession_ inputs] count] == 1) { |
| - [captureSession_ removeInput:captureDeviceInput_]; |
| - [captureSession_ stopRunning]; |
| - } |
| - |
| + // 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_ outputs] count] == 0u || |
| + [[captureSession_ inputs] count] == 0u) |
| + return; |
|
Scott Hess - ex-Googler
2014/08/19 18:27:50
If this is correct, it should be in -stopCapture i
mcasas
2014/08/20 09:08:25
I think that's reasonable. So I made it look more
|
| + DCHECK_EQ([[captureSession_ inputs] count], 1u); |
| + [captureSession_ removeInput:captureDeviceInput_]; |
| + [captureSession_ stopRunning]; |
| + |
| + 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. |
| - (void)captureOutput:(QTCaptureOutput*)captureOutput |
| didOutputVideoFrame:(CVImageBufferRef)videoFrame |