video_capture(iOS): move stopCapture to background thread
Also suspend frame delivery on stopCapture() to avoid pause+onVideoError during hangup. BUG=3162 R=noahric@google.com Review URL: https://webrtc-codereview.appspot.com/11389004 git-svn-id: http://webrtc.googlecode.com/svn/trunk@5863 4adac7df-926f-26a2-2b94-8c16560cd09d
This commit is contained in:
parent
2a03498825
commit
984e4fbaaa
@ -32,8 +32,8 @@ using namespace webrtc::videocapturemodule;
|
|||||||
AVCaptureSession* _captureSession;
|
AVCaptureSession* _captureSession;
|
||||||
int _captureId;
|
int _captureId;
|
||||||
AVCaptureConnection* _connection;
|
AVCaptureConnection* _connection;
|
||||||
BOOL _captureStarting; // Guarded by _captureStartingCondition.
|
BOOL _captureChanging; // Guarded by _captureChangingCondition.
|
||||||
NSCondition* _captureStartingCondition;
|
NSCondition* _captureChangingCondition;
|
||||||
}
|
}
|
||||||
|
|
||||||
@synthesize frameRotation = _framRotation;
|
@synthesize frameRotation = _framRotation;
|
||||||
@ -43,18 +43,16 @@ using namespace webrtc::videocapturemodule;
|
|||||||
_owner = owner;
|
_owner = owner;
|
||||||
_captureId = captureId;
|
_captureId = captureId;
|
||||||
_captureSession = [[AVCaptureSession alloc] init];
|
_captureSession = [[AVCaptureSession alloc] init];
|
||||||
_captureStarting = NO;
|
_captureChanging = NO;
|
||||||
_captureStartingCondition = [[NSCondition alloc] init];
|
_captureChangingCondition = [[NSCondition alloc] init];
|
||||||
|
|
||||||
if (!_captureSession || !_captureStartingCondition) {
|
if (!_captureSession || !_captureChangingCondition) {
|
||||||
return nil;
|
return nil;
|
||||||
}
|
}
|
||||||
|
|
||||||
// create and configure a new output (using callbacks)
|
// create and configure a new output (using callbacks)
|
||||||
AVCaptureVideoDataOutput* captureOutput =
|
AVCaptureVideoDataOutput* captureOutput =
|
||||||
[[AVCaptureVideoDataOutput alloc] init];
|
[[AVCaptureVideoDataOutput alloc] init];
|
||||||
[captureOutput setSampleBufferDelegate:self
|
|
||||||
queue:dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)];
|
|
||||||
NSString* key = (NSString*)kCVPixelBufferPixelFormatTypeKey;
|
NSString* key = (NSString*)kCVPixelBufferPixelFormatTypeKey;
|
||||||
|
|
||||||
NSNumber* val = [NSNumber
|
NSNumber* val = [NSNumber
|
||||||
@ -90,6 +88,17 @@ using namespace webrtc::videocapturemodule;
|
|||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (void)directOutputToSelf {
|
||||||
|
[[self currentOutput]
|
||||||
|
setSampleBufferDelegate:self
|
||||||
|
queue:dispatch_get_global_queue(
|
||||||
|
DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)directOutputToNil {
|
||||||
|
[[self currentOutput] setSampleBufferDelegate:nil queue:NULL];
|
||||||
|
}
|
||||||
|
|
||||||
- (void)statusBarOrientationDidChange:(NSNotification*)notification {
|
- (void)statusBarOrientationDidChange:(NSNotification*)notification {
|
||||||
[self setRelativeVideoOrientation];
|
[self setRelativeVideoOrientation];
|
||||||
}
|
}
|
||||||
@ -99,6 +108,7 @@ using namespace webrtc::videocapturemodule;
|
|||||||
}
|
}
|
||||||
|
|
||||||
- (BOOL)setCaptureDeviceByUniqueId:(NSString*)uniqueId {
|
- (BOOL)setCaptureDeviceByUniqueId:(NSString*)uniqueId {
|
||||||
|
[self waitForCaptureChangeToFinish];
|
||||||
// check to see if the camera is already set
|
// check to see if the camera is already set
|
||||||
if (_captureSession) {
|
if (_captureSession) {
|
||||||
NSArray* currentInputs = [NSArray arrayWithArray:[_captureSession inputs]];
|
NSArray* currentInputs = [NSArray arrayWithArray:[_captureSession inputs]];
|
||||||
@ -114,6 +124,7 @@ using namespace webrtc::videocapturemodule;
|
|||||||
}
|
}
|
||||||
|
|
||||||
- (BOOL)startCaptureWithCapability:(const VideoCaptureCapability&)capability {
|
- (BOOL)startCaptureWithCapability:(const VideoCaptureCapability&)capability {
|
||||||
|
[self waitForCaptureChangeToFinish];
|
||||||
if (!_captureSession) {
|
if (!_captureSession) {
|
||||||
return NO;
|
return NO;
|
||||||
}
|
}
|
||||||
@ -148,20 +159,23 @@ using namespace webrtc::videocapturemodule;
|
|||||||
|
|
||||||
_capability = capability;
|
_capability = capability;
|
||||||
|
|
||||||
NSArray* currentOutputs = [_captureSession outputs];
|
AVCaptureVideoDataOutput* currentOutput = [self currentOutput];
|
||||||
if ([currentOutputs count] == 0) {
|
if (!currentOutput)
|
||||||
return NO;
|
return NO;
|
||||||
}
|
|
||||||
|
|
||||||
AVCaptureVideoDataOutput* currentOutput =
|
[self directOutputToSelf];
|
||||||
(AVCaptureVideoDataOutput*)[currentOutputs objectAtIndex:0];
|
|
||||||
|
|
||||||
|
_captureChanging = YES;
|
||||||
dispatch_async(
|
dispatch_async(
|
||||||
dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0),
|
dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0),
|
||||||
^(void) { [self startCaptureInBackgroundWithOutput:currentOutput]; });
|
^(void) { [self startCaptureInBackgroundWithOutput:currentOutput]; });
|
||||||
return YES;
|
return YES;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (AVCaptureVideoDataOutput*)currentOutput {
|
||||||
|
return [[_captureSession outputs] firstObject];
|
||||||
|
}
|
||||||
|
|
||||||
- (void)startCaptureInBackgroundWithOutput:
|
- (void)startCaptureInBackgroundWithOutput:
|
||||||
(AVCaptureVideoDataOutput*)currentOutput {
|
(AVCaptureVideoDataOutput*)currentOutput {
|
||||||
NSString* captureQuality =
|
NSString* captureQuality =
|
||||||
@ -195,11 +209,7 @@ using namespace webrtc::videocapturemodule;
|
|||||||
[_captureSession commitConfiguration];
|
[_captureSession commitConfiguration];
|
||||||
|
|
||||||
[_captureSession startRunning];
|
[_captureSession startRunning];
|
||||||
|
[self signalCaptureChangeEnd];
|
||||||
[_captureStartingCondition lock];
|
|
||||||
_captureStarting = NO;
|
|
||||||
[_captureStartingCondition signal];
|
|
||||||
[_captureStartingCondition unlock];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)setRelativeVideoOrientation {
|
- (void)setRelativeVideoOrientation {
|
||||||
@ -235,17 +245,26 @@ using namespace webrtc::videocapturemodule;
|
|||||||
}
|
}
|
||||||
|
|
||||||
- (BOOL)stopCapture {
|
- (BOOL)stopCapture {
|
||||||
[self waitForCaptureStartToFinish];
|
[self waitForCaptureChangeToFinish];
|
||||||
|
[self directOutputToNil];
|
||||||
|
|
||||||
if (!_captureSession) {
|
if (!_captureSession) {
|
||||||
return NO;
|
return NO;
|
||||||
}
|
}
|
||||||
|
|
||||||
[_captureSession stopRunning];
|
_captureChanging = YES;
|
||||||
|
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0),
|
||||||
|
^(void) { [self stopCaptureInBackground]; });
|
||||||
return YES;
|
return YES;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (void)stopCaptureInBackground {
|
||||||
|
[_captureSession stopRunning];
|
||||||
|
[self signalCaptureChangeEnd];
|
||||||
|
}
|
||||||
|
|
||||||
- (BOOL)changeCaptureInputByUniqueId:(NSString*)uniqueId {
|
- (BOOL)changeCaptureInputByUniqueId:(NSString*)uniqueId {
|
||||||
|
[self waitForCaptureChangeToFinish];
|
||||||
NSArray* currentInputs = [_captureSession inputs];
|
NSArray* currentInputs = [_captureSession inputs];
|
||||||
// remove current input
|
// remove current input
|
||||||
if ([currentInputs count] > 0) {
|
if ([currentInputs count] > 0) {
|
||||||
@ -341,11 +360,18 @@ using namespace webrtc::videocapturemodule;
|
|||||||
CVPixelBufferUnlockBaseAddress(videoFrame, kFlags);
|
CVPixelBufferUnlockBaseAddress(videoFrame, kFlags);
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)waitForCaptureStartToFinish {
|
- (void)signalCaptureChangeEnd {
|
||||||
[_captureStartingCondition lock];
|
[_captureChangingCondition lock];
|
||||||
while (_captureStarting) {
|
_captureChanging = NO;
|
||||||
[_captureStartingCondition wait];
|
[_captureChangingCondition signal];
|
||||||
|
[_captureChangingCondition unlock];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)waitForCaptureChangeToFinish {
|
||||||
|
[_captureChangingCondition lock];
|
||||||
|
while (_captureChanging) {
|
||||||
|
[_captureChangingCondition wait];
|
||||||
}
|
}
|
||||||
[_captureStartingCondition unlock];
|
[_captureChangingCondition unlock];
|
||||||
}
|
}
|
||||||
@end
|
@end
|
||||||
|
@ -34,7 +34,7 @@ VideoCaptureIos::VideoCaptureIos(const int32_t capture_id)
|
|||||||
}
|
}
|
||||||
|
|
||||||
VideoCaptureIos::~VideoCaptureIos() {
|
VideoCaptureIos::~VideoCaptureIos() {
|
||||||
if (capture_device_) {
|
if (is_capturing_) {
|
||||||
[capture_device_ stopCapture];
|
[capture_device_ stopCapture];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user