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 7f4a853c63a9bde6d9b260a720a947d143f68cbc..ad22e3511cd1481a9a80ffce8a58cb3bbca22797 100644 |
--- a/media/video/capture/mac/video_capture_device_qtkit_mac.mm |
+++ b/media/video/capture/mac/video_capture_device_qtkit_mac.mm |
@@ -144,28 +144,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]; |
@@ -240,14 +220,28 @@ |
} |
- (void)stopCapture { |
- if ([[captureSession_ inputs] count] == 1) { |
- [captureSession_ removeInput:captureDeviceInput_]; |
- [captureSession_ stopRunning]; |
- } |
- |
+ // QTKit achieves thread safety and asynchronous execution by posting messages |
+ // to main thread, e.g. -addOutput:. Both -removeOutput: and -removeInput: |
+ // post a message to main thread while holding a lock that the notification |
+ // handler might need. To avoid q deadlock, we perform those tasks in the UI |
Scott Hess - ex-Googler
2014/08/18 18:23:40
is the 'q' meant to be an 'a'?
Also straighten up
mcasas
2014/08/19 15:24:59
Done. I use them interchangeably, but is true that
Scott Hess - ex-Googler
2014/08/19 18:27:50
Mostly I'm aiming for consistent use w/in a single
|
+ // thread. See bug http://crbug.com/152757 and http://crbug.com/399792. |
+ [self performSelectorOnMainThread:@selector(stopCaptureOnUIThread:) |
+ withObject:captureSession_ |
+ waitUntilDone:YES]; |
[[NSNotificationCenter defaultCenter] removeObserver:self]; |
} |
+- (void)stopCaptureOnUIThread:(QTCaptureSession*)captureSession { |
Scott Hess - ex-Googler
2014/08/18 18:23:40
You never use |captureSession|, instead preferring
mcasas
2014/08/19 15:24:59
Done.
|
+ 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]; |
Scott Hess - ex-Googler
2014/08/18 18:23:40
Previously, the code handled 0 values for either c
mcasas
2014/08/19 15:24:59
I changed a bit the code to reflect your sharp obs
|
+} |
+ |
// |captureOutput| is called by the capture device to deliver a new frame. |
- (void)captureOutput:(QTCaptureOutput*)captureOutput |
didOutputVideoFrame:(CVImageBufferRef)videoFrame |