Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(253)

Side by Side Diff: media/video/capture/mac/video_capture_device_qtkit_mac.mm

Issue 464363003: Mac QTKit Video Capture: Run QTCaptureSession teardown in UI thread, clean up -stopCapture use. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: shess@ comments, rebased. Created 6 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « media/video/capture/mac/video_capture_device_mac.mm ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #import "media/video/capture/mac/video_capture_device_qtkit_mac.h" 5 #import "media/video/capture/mac/video_capture_device_qtkit_mac.h"
6 6
7 #import <QTKit/QTKit.h> 7 #import <QTKit/QTKit.h>
8 8
9 #include "base/debug/crash_logging.h" 9 #include "base/debug/crash_logging.h"
10 #include "base/logging.h" 10 #include "base/logging.h"
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after
139 return YES; 139 return YES;
140 } else { 140 } else {
141 // Remove the previously set capture device. 141 // Remove the previously set capture device.
142 if (!captureDeviceInput_) { 142 if (!captureDeviceInput_) {
143 // Being here means stopping a device that never started OK in the first 143 // Being here means stopping a device that never started OK in the first
144 // place, log it. 144 // place, log it.
145 [self sendLogString:[NSString 145 [self sendLogString:[NSString
146 stringWithUTF8String:"No video capture device set, on removal."]]; 146 stringWithUTF8String:"No video capture device set, on removal."]];
147 return YES; 147 return YES;
148 } 148 }
149 if ([[captureSession_ inputs] count] > 0) { 149 // Tear down input and output, stop the capture and deregister observers.
150 // The device is still running. 150 [self stopCapture];
151 [self stopCapture];
152 }
153 if ([[captureSession_ outputs] count] > 0) {
154 // Only one output is set for |captureSession_|.
155 DCHECK_EQ([[captureSession_ outputs] count], 1u);
156 id output = [[captureSession_ outputs] objectAtIndex:0];
157 [output setDelegate:nil];
158
159 // TODO(shess): QTKit achieves thread safety by posting messages to the
160 // main thread. As part of -addOutput:, it posts a message to the main
161 // thread which in turn posts a notification which will run in a future
162 // spin after the original method returns. -removeOutput: can post a
163 // main-thread message in between while holding a lock which the
164 // notification handler will need. Posting either -addOutput: or
165 // -removeOutput: to the main thread should fix it, remove is likely
166 // safer. http://crbug.com/152757
167 [captureSession_ performSelectorOnMainThread:@selector(removeOutput:)
168 withObject:output
169 waitUntilDone:YES];
170 }
171 [captureSession_ release]; 151 [captureSession_ release];
172 captureSession_ = nil; 152 captureSession_ = nil;
173 [captureDeviceInput_ release]; 153 [captureDeviceInput_ release];
174 captureDeviceInput_ = nil; 154 captureDeviceInput_ = nil;
175 return YES; 155 return YES;
176 } 156 }
177 } 157 }
178 158
179 - (BOOL)setCaptureHeight:(int)height 159 - (BOOL)setCaptureHeight:(int)height
180 width:(int)width 160 width:(int)width
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
235 [notificationCenter addObserver:self 215 [notificationCenter addObserver:self
236 selector:@selector(handleNotification:) 216 selector:@selector(handleNotification:)
237 name:QTCaptureSessionRuntimeErrorNotification 217 name:QTCaptureSessionRuntimeErrorNotification
238 object:captureSession_]; 218 object:captureSession_];
239 [captureSession_ startRunning]; 219 [captureSession_ startRunning];
240 } 220 }
241 return YES; 221 return YES;
242 } 222 }
243 223
244 - (void)stopCapture { 224 - (void)stopCapture {
245 if ([[captureSession_ inputs] count] == 1) { 225 // QTKit achieves thread safety and asynchronous execution by posting messages
246 [captureSession_ removeInput:captureDeviceInput_]; 226 // to the main thread, e.g. -addOutput:. Both -removeOutput: and -removeInput:
247 [captureSession_ stopRunning]; 227 // post a message to the main thread while holding a lock that the
248 } 228 // notification handler might need. To avoid a deadlock, we perform those
229 // tasks in the main thread. See bugs http://crbug.com/152757 and
230 // http://crbug.com/399792.
231 [self performSelectorOnMainThread:@selector(stopCaptureOnUIThread:)
232 withObject:nil
233 waitUntilDone:YES];
234 [[NSNotificationCenter defaultCenter] removeObserver:self];
235 }
249 236
250 [[NSNotificationCenter defaultCenter] removeObserver:self]; 237 - (void)stopCaptureOnUIThread:(id)dummy {
238 if ([[captureSession_ outputs] count] == 0u ||
239 [[captureSession_ inputs] count] == 0u)
240 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
241 DCHECK_EQ([[captureSession_ inputs] count], 1u);
242 [captureSession_ removeInput:captureDeviceInput_];
243 [captureSession_ stopRunning];
244
245 DCHECK_EQ([[captureSession_ outputs] count], 1u);
246 id output = [[captureSession_ outputs] objectAtIndex:0];
247 [output setDelegate:nil];
248 [captureSession_ removeOutput:output];
251 } 249 }
252 250
253 // |captureOutput| is called by the capture device to deliver a new frame. 251 // |captureOutput| is called by the capture device to deliver a new frame.
254 - (void)captureOutput:(QTCaptureOutput*)captureOutput 252 - (void)captureOutput:(QTCaptureOutput*)captureOutput
255 didOutputVideoFrame:(CVImageBufferRef)videoFrame 253 didOutputVideoFrame:(CVImageBufferRef)videoFrame
256 withSampleBuffer:(QTSampleBuffer*)sampleBuffer 254 withSampleBuffer:(QTSampleBuffer*)sampleBuffer
257 fromConnection:(QTCaptureConnection*)connection { 255 fromConnection:(QTCaptureConnection*)connection {
258 [lock_ lock]; 256 [lock_ lock];
259 if(!frameReceiver_) { 257 if(!frameReceiver_) {
260 [lock_ unlock]; 258 [lock_ unlock];
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after
349 347
350 - (void)sendLogString:(NSString*)message { 348 - (void)sendLogString:(NSString*)message {
351 DVLOG(1) << [message UTF8String]; 349 DVLOG(1) << [message UTF8String];
352 [lock_ lock]; 350 [lock_ lock];
353 if (frameReceiver_) 351 if (frameReceiver_)
354 frameReceiver_->LogMessage([message UTF8String]); 352 frameReceiver_->LogMessage([message UTF8String]);
355 [lock_ unlock]; 353 [lock_ unlock];
356 } 354 }
357 355
358 @end 356 @end
OLDNEW
« no previous file with comments | « media/video/capture/mac/video_capture_device_mac.mm ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698