From bd639c3c7ca9fa8f1986ce4d342905ae25edd9eb Mon Sep 17 00:00:00 2001 From: "wjia@chromium.org" Date: Fri, 28 Sep 2012 22:04:10 +0000 Subject: move lock into qtkit code to remove racing condition. BUG=147104 Review URL: https://codereview.chromium.org/10911314 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@159347 0039d316-1c4b-4281-b951-d872f2087c98 --- media/video/capture/mac/video_capture_device_mac.h | 2 -- .../video/capture/mac/video_capture_device_mac.mm | 16 ++++++--------- .../capture/mac/video_capture_device_qtkit_mac.h | 6 ++++-- .../capture/mac/video_capture_device_qtkit_mac.mm | 23 +++++++++++++--------- 4 files changed, 24 insertions(+), 23 deletions(-) (limited to 'media/video') diff --git a/media/video/capture/mac/video_capture_device_mac.h b/media/video/capture/mac/video_capture_device_mac.h index ffb1790..95d78e0 100644 --- a/media/video/capture/mac/video_capture_device_mac.h +++ b/media/video/capture/mac/video_capture_device_mac.h @@ -10,7 +10,6 @@ #include #include "base/compiler_specific.h" -#include "base/synchronization/lock.h" #include "media/video/capture/video_capture_device.h" #include "media/video/capture/video_capture_types.h" @@ -56,7 +55,6 @@ class VideoCaptureDeviceMac : public VideoCaptureDevice { VideoCaptureDevice::Name device_name_; VideoCaptureDevice::EventHandler* observer_; InternalState state_; - base::Lock lock_; VideoCaptureDeviceQTKit* capture_device_; diff --git a/media/video/capture/mac/video_capture_device_mac.mm b/media/video/capture/mac/video_capture_device_mac.mm index 315d07e..5fc614f 100644 --- a/media/video/capture/mac/video_capture_device_mac.mm +++ b/media/video/capture/mac/video_capture_device_mac.mm @@ -49,7 +49,6 @@ VideoCaptureDeviceMac::~VideoCaptureDeviceMac() { void VideoCaptureDeviceMac::Allocate(int width, int height, int frame_rate, EventHandler* observer) { - base::AutoLock auto_lock(lock_); if (state_ != kIdle) { return; } @@ -57,6 +56,8 @@ void VideoCaptureDeviceMac::Allocate(int width, int height, int frame_rate, NSString* deviceId = [NSString stringWithUTF8String:device_name_.unique_id.c_str()]; + [capture_device_ setFrameReceiver:this]; + if (![capture_device_ setCaptureDevice:deviceId]) { SetErrorState("Could not open capture device."); return; @@ -86,19 +87,16 @@ void VideoCaptureDeviceMac::Start() { SetErrorState("Could not start capture device."); return; } - base::AutoLock auto_lock(lock_); state_ = kCapturing; } void VideoCaptureDeviceMac::Stop() { DCHECK_EQ(state_, kCapturing); [capture_device_ stopCapture]; - base::AutoLock auto_lock(lock_); state_ = kAllocated; } void VideoCaptureDeviceMac::DeAllocate() { - base::AutoLock auto_lock(lock_); if (state_ != kAllocated && state_ != kCapturing) { return; } @@ -106,6 +104,8 @@ void VideoCaptureDeviceMac::DeAllocate() { [capture_device_ stopCapture]; } [capture_device_ setCaptureDevice:nil]; + [capture_device_ setFrameReceiver:nil]; + state_ = kIdle; } @@ -138,16 +138,12 @@ void VideoCaptureDeviceMac::ReceiveFrame( const uint8* video_frame, int video_frame_length, const VideoCaptureCapability& frame_info) { - base::AutoLock auto_lock(lock_); - if (state_ == kCapturing) { - observer_->OnIncomingCapturedFrame(video_frame, video_frame_length, - base::Time::Now()); - } + observer_->OnIncomingCapturedFrame(video_frame, video_frame_length, + base::Time::Now()); } void VideoCaptureDeviceMac::SetErrorState(const std::string& reason) { DLOG(ERROR) << reason; - base::AutoLock auto_lock(lock_); state_ = kError; observer_->OnError(); } diff --git a/media/video/capture/mac/video_capture_device_qtkit_mac.h b/media/video/capture/mac/video_capture_device_qtkit_mac.h index 526c855..5739c2e 100644 --- a/media/video/capture/mac/video_capture_device_qtkit_mac.h +++ b/media/video/capture/mac/video_capture_device_qtkit_mac.h @@ -14,7 +14,6 @@ namespace media { class VideoCaptureDeviceMac; } -@class QTCaptureDecompressedVideoOutput; @class QTCaptureDeviceInput; @class QTCaptureSession; @@ -25,12 +24,12 @@ namespace media { int frameWidth_; int frameHeight_; + NSLock *lock_; media::VideoCaptureDeviceMac *frameReceiver_; // QTKit variables. QTCaptureSession *captureSession_; QTCaptureDeviceInput *captureDeviceInput_; - QTCaptureDecompressedVideoOutput *captureDecompressedOutput_; } // Returns a dictionary of capture devices with friendly name and unique id. @@ -39,6 +38,9 @@ namespace media { // Initializes the instance and registers the frame receiver. - (id)initWithFrameReceiver:(media::VideoCaptureDeviceMac *)frameReceiver; +// Set the frame receiver. +- (void)setFrameReceiver:(media::VideoCaptureDeviceMac *)frameReceiver; + // Sets which capture device to use. Returns YES on sucess, NO otherwise. - (BOOL)setCaptureDevice:(NSString *)deviceId; 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 a7e2c58..096ce44 100644 --- a/media/video/capture/mac/video_capture_device_qtkit_mac.mm +++ b/media/video/capture/mac/video_capture_device_qtkit_mac.mm @@ -35,6 +35,7 @@ self = [super init]; if (self) { frameReceiver_ = frameReceiver; + lock_ = [[NSLock alloc] init]; } return self; } @@ -42,10 +43,15 @@ - (void)dealloc { [captureSession_ release]; [captureDeviceInput_ release]; - [captureDecompressedOutput_ release]; [super dealloc]; } +- (void)setFrameReceiver:(media::VideoCaptureDeviceMac *)frameReceiver { + [lock_ lock]; + frameReceiver_ = frameReceiver; + [lock_ unlock]; +} + - (BOOL)setCaptureDevice:(NSString *)deviceId { if (deviceId) { // Set the capture device. @@ -73,10 +79,10 @@ captureDeviceInput_ = [[QTCaptureDeviceInput alloc] initWithDevice:device]; captureSession_ = [[QTCaptureSession alloc] init]; - captureDecompressedOutput_ = - [[QTCaptureDecompressedVideoOutput alloc] init]; - [captureDecompressedOutput_ setDelegate:self]; - if (![captureSession_ addOutput:captureDecompressedOutput_ error:&error]) { + QTCaptureDecompressedVideoOutput *captureDecompressedOutput = + [[[QTCaptureDecompressedVideoOutput alloc] init] autorelease]; + [captureDecompressedOutput setDelegate:self]; + if (![captureSession_ addOutput:captureDecompressedOutput error:&error]) { DLOG(ERROR) << "Could not connect video capture output." << [[error localizedDescription] UTF8String]; return NO; @@ -92,14 +98,10 @@ // The device is still running. [self stopCapture]; } - [captureDecompressedOutput_ setDelegate:nil]; - [captureSession_ removeOutput:captureDecompressedOutput_]; [captureSession_ release]; captureSession_ = nil; [captureDeviceInput_ release]; captureDeviceInput_ = nil; - [captureDecompressedOutput_ release]; - captureDecompressedOutput_ = nil; return YES; } } @@ -163,7 +165,9 @@ didOutputVideoFrame:(CVImageBufferRef)videoFrame withSampleBuffer:(QTSampleBuffer *)sampleBuffer fromConnection:(QTCaptureConnection *)connection { + [lock_ lock]; if(!frameReceiver_) { + [lock_ unlock]; return; } @@ -189,6 +193,7 @@ CVPixelBufferUnlockBaseAddress(videoFrame, kLockFlags); } + [lock_ unlock]; } @end -- cgit v1.1