Removed Mac capture crash and memory leak.

BUG=1697,1761
R=xians@webrtc.org

Review URL: https://webrtc-codereview.appspot.com/1465005

git-svn-id: http://webrtc.googlecode.com/svn/trunk@4023 4adac7df-926f-26a2-2b94-8c16560cd09d
This commit is contained in:
mflodman@webrtc.org 2013-05-14 10:47:19 +00:00
parent a6ff84503e
commit bb984f516e
7 changed files with 225 additions and 530 deletions

View File

@ -12,15 +12,12 @@
#define WEBRTC_MODULES_VIDEO_CAPTURE_MAIN_SOURCE_MAC_QTKIT_VIDEO_CAPTURE_QTKIT_H_
#import <QTKit/QTKit.h>
#include <stdio.h>
#include "../../video_capture_impl.h"
#include "video_capture_qtkit_utility.h"
#include "../../device_info_impl.h"
#include "webrtc/modules/video_capture/video_capture_impl.h"
#include "webrtc/modules/video_capture/mac/qtkit/video_capture_qtkit_utility.h"
#include "webrtc/modules/video_capture/device_info_impl.h"
// Forward declaraion
@class VideoCaptureMacQTKitObjC;
@class VideoCaptureMacQTKitInfoObjC;

View File

@ -45,6 +45,7 @@ VideoCaptureMacQTKit::~VideoCaptureMacQTKit()
"~VideoCaptureMacQTKit() called");
if(_captureDevice)
{
[_captureDevice registerOwner:nil];
[_captureDevice stopCapture];
[_captureDevice release];
}
@ -79,12 +80,7 @@ int32_t VideoCaptureMacQTKit::Init(
return -1;
}
if(-1 == [[_captureDevice registerOwner:this]intValue])
{
WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideoCapture, id,
"Failed to register owner for _captureDevice");
return -1;
}
[_captureDevice registerOwner:this];
if(0 == strcmp((char*)iDeviceUniqueIdUTF8, ""))
{
@ -148,8 +144,7 @@ int32_t VideoCaptureMacQTKit::Init(
// at this point we know that the user has passed in a valid camera. Let's
// set it as the current.
if(-1 == [[_captureDevice
setCaptureDeviceById:(char*)deviceUniqueIdUTF8]intValue])
if(![_captureDevice setCaptureDeviceById:(char*)deviceUniqueIdUTF8])
{
strcpy((char*)_deviceUniqueId, (char*)deviceUniqueIdUTF8);
WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideoCapture, _id,
@ -174,19 +169,11 @@ int32_t VideoCaptureMacQTKit::StartCapture(
_captureFrameRate = capability.maxFPS;
_captureDelay = 120;
if(-1 == [[_captureDevice setCaptureHeight:_captureHeight
AndWidth:_captureWidth AndFrameRate:_captureFrameRate]intValue])
{
WEBRTC_TRACE(webrtc::kTraceInfo, webrtc::kTraceVideoCapture, _id,
"Could not set width=%d height=%d frameRate=%d",
_captureWidth, _captureHeight, _captureFrameRate);
return -1;
}
[_captureDevice setCaptureHeight:_captureHeight
width:_captureWidth
frameRate:_captureFrameRate];
if(-1 == [[_captureDevice startCapture]intValue])
{
return -1;
}
[_captureDevice startCapture];
_isCapturing = true;
return 0;
}
@ -194,7 +181,6 @@ int32_t VideoCaptureMacQTKit::StartCapture(
int32_t VideoCaptureMacQTKit::StopCapture()
{
[_captureDevice stopCapture];
_isCapturing = false;
return 0;
}

View File

@ -23,58 +23,38 @@
#import <CoreFoundation/CoreFoundation.h>
#import <CoreVideo/CoreVideo.h>
#import "video_capture_recursive_lock.h"
#include "video_capture_qtkit.h"
@interface VideoCaptureMacQTKitObjC : NSObject{
// class properties
bool _capturing;
int _frameRate;
int _frameWidth;
int _frameHeight;
int _framesDelivered;
int _framesRendered;
bool _OSSupported;
bool _captureInitialized;
// WebRTC Custom classes
webrtc::videocapturemodule::VideoCaptureMacQTKit* _owner;
VideoCaptureRecursiveLock* _rLock;
// QTKit variables
QTCaptureSession* _captureSession;
QTCaptureDeviceInput* _captureVideoDeviceInput;
QTCaptureDecompressedVideoOutput* _captureDecompressedVideoOutput;
NSArray* _captureDevices;
int _captureDeviceCount;
char _captureDeviceNameUTF8[1024];
char _captureDeviceNameUniqueID[1024];
@interface VideoCaptureMacQTKitObjC : NSObject {
bool _capturing;
int _frameRate;
int _frameWidth;
int _frameHeight;
int _framesDelivered;
int _framesRendered;
bool _captureInitialized;
webrtc::videocapturemodule::VideoCaptureMacQTKit* _owner;
NSLock* lock_;
QTCaptureSession* _captureSession;
QTCaptureDeviceInput* _captureVideoDeviceInput;
QTCaptureDecompressedVideoOutput* _captureDecompressedVideoOutput;
NSArray* _captureDevices;
int _captureDeviceCount;
char _captureDeviceNameUTF8[1024];
char _captureDeviceNameUniqueID[1024];
}
/**************************************************************************
*
* The following functions are considered to be private.
*
***************************************************************************/
- (NSNumber*)getCaptureDevices;
- (NSNumber*)initializeVideoCapture;
- (NSNumber*)initializeVariables;
- (void)checkOSSupported;
- (void)getCaptureDevices;
- (BOOL)initializeVideoCapture;
- (BOOL)initializeVariables;
/**************************************************************************
*
* The following functions are considered public and to be called by the VideoCaptureMacQTKit class.
*
***************************************************************************/
- (NSNumber*)registerOwner:(webrtc::videocapturemodule::VideoCaptureMacQTKit*)owner;
- (NSNumber*)setCaptureDeviceById:(char*)uniqueId;
- (NSNumber*)setCaptureHeight:(int)height AndWidth:(int)width AndFrameRate:(int)frameRate;
- (NSNumber*)startCapture;
- (NSNumber*)stopCapture;
- (void)registerOwner:(webrtc::videocapturemodule::VideoCaptureMacQTKit*)owner;
- (BOOL)setCaptureDeviceById:(char*)uniqueId;
- (void)setCaptureHeight:(int)height width:(int)width frameRate:(int)frameRate;
- (void)startCapture;
- (void)stopCapture;
@end

View File

@ -10,451 +10,250 @@
#define DEFAULT_CAPTURE_DEVICE_INDEX 1
#define DEFAULT_FRAME_RATE 30
#define DEFAULT_FRAME_WIDTH 352
#define DEFAULT_FRAME_WIDTH 352
#define DEFAULT_FRAME_HEIGHT 288
#define ROTATE_CAPTURED_FRAME 1
#define LOW_QUALITY 1
#import "video_capture_qtkit_objc.h"
#include "video_capture_qtkit_utility.h"
#include "trace.h"
#import "webrtc/modules/video_capture/mac/qtkit/video_capture_qtkit_objc.h"
#include "webrtc/system_wrappers/interface/trace.h"
using namespace webrtc;
using namespace videocapturemodule;
@implementation VideoCaptureMacQTKitObjC
#pragma mark **** over-written OS methods
/// ***** Objective-C. Similar to C++ constructor, although must be invoked
/// manually.
/// ***** Potentially returns an instance of self
-(id)init{
self = [super init];
if(nil != self)
{
[self checkOSSupported];
[self initializeVariables];
}
else
{
return nil;
}
return self;
-(id)init {
self = [super init];
if (self) {
[self initializeVariables];
}
return self;
}
/// ***** Objective-C. Similar to C++ destructor
/// ***** Returns nothing
- (void)dealloc {
if(_captureSession)
[_captureSession stopRunning];
if (_captureSession)
[_captureSession stopRunning];
if (_captureVideoDeviceInput)
{
if([[_captureVideoDeviceInput device] isOpen])
[[_captureVideoDeviceInput device] close];
if (_captureVideoDeviceInput) {
if ([[_captureVideoDeviceInput device] isOpen])
[[_captureVideoDeviceInput device] close];
[_captureVideoDeviceInput release];
}
[_captureVideoDeviceInput release];
}
[_captureDecompressedVideoOutput release];
[_captureSession release];
[_captureDevices release];
[_rLock release];
[_captureDecompressedVideoOutput release];
[_captureSession release];
[_captureDevices release];
[super dealloc];
[super dealloc];
}
#pragma mark **** public methods
#pragma mark Public methods
/// ***** Registers the class's owner, which is where the delivered frames are
/// sent
/// ***** Returns 0 on success, -1 otherwise.
- (NSNumber*)registerOwner:(VideoCaptureMacQTKit*)owner{
if(!owner){
return [NSNumber numberWithInt:-1];
}
_owner = owner;
return [NSNumber numberWithInt:0];
- (void)registerOwner:(VideoCaptureMacQTKit*)owner {
[lock_ lock];
_owner = owner;
[lock_ unlock];
}
/// ***** Sets the QTCaptureSession's input device from a char*
/// ***** Sets several member variables. Can signal the error system if one has
/// occurred
/// ***** Returns 0 on success, -1 otherwise.
- (NSNumber*)setCaptureDeviceById:(char*)uniqueId{
if(NO == _OSSupported)
{
WEBRTC_TRACE(kTraceInfo, kTraceVideoCapture, 0,
"%s:%d OS version does not support necessary APIs",
__FUNCTION__, __LINE__);
return [NSNumber numberWithInt:0];
}
if(!uniqueId || (0 == strcmp("", uniqueId)))
{
WEBRTC_TRACE(kTraceInfo, kTraceVideoCapture, 0,
"%s:%d \"\" was passed in for capture device name",
__FUNCTION__, __LINE__);
memset(_captureDeviceNameUTF8, 0, 1024);
return [NSNumber numberWithInt:0];
}
if(0 == strcmp(uniqueId, _captureDeviceNameUniqueID))
{
// camera already set
WEBRTC_TRACE(kTraceInfo, kTraceVideoCapture, 0,
"%s:%d Capture device is already set to %s", __FUNCTION__,
__LINE__, _captureDeviceNameUTF8);
return [NSNumber numberWithInt:0];
}
bool success = NO;
QTCaptureDevice* tempCaptureDevice;
for(int index = 0; index < _captureDeviceCount; index++)
{
tempCaptureDevice = (QTCaptureDevice*)[_captureDevices
objectAtIndex:index];
char tempCaptureDeviceId[1024] = "";
[[tempCaptureDevice uniqueID]
getCString:tempCaptureDeviceId maxLength:1024
encoding:NSUTF8StringEncoding];
if(0 == strcmp(uniqueId, tempCaptureDeviceId))
{
WEBRTC_TRACE(kTraceInfo, kTraceVideoCapture, 0,
"%s:%d Found capture device id %s as index %d",
__FUNCTION__, __LINE__, tempCaptureDeviceId, index);
success = YES;
[[tempCaptureDevice localizedDisplayName]
getCString:_captureDeviceNameUTF8
maxLength:1024
encoding:NSUTF8StringEncoding];
[[tempCaptureDevice uniqueID]
getCString:_captureDeviceNameUniqueID
maxLength:1024
encoding:NSUTF8StringEncoding];
break;
}
}
if(NO == success)
{
// camera not found
// nothing has been changed yet, so capture device will stay in it's
// state
WEBRTC_TRACE(kTraceInfo, kTraceVideoCapture, 0,
"%s:%d Capture device id %s was not found in list of "
"available devices.", __FUNCTION__, __LINE__, uniqueId);
return [NSNumber numberWithInt:0];
}
NSError* error;
success = [tempCaptureDevice open:&error];
if(!success)
{
WEBRTC_TRACE(kTraceError, kTraceVideoCapture, 0,
"%s:%d Failed to open capture device: %s",
__FUNCTION__, __LINE__, _captureDeviceNameUTF8);
return [NSNumber numberWithInt:-1];
}
if(_captureVideoDeviceInput)
{
[_captureVideoDeviceInput release];
}
_captureVideoDeviceInput = [[QTCaptureDeviceInput alloc]
initWithDevice:tempCaptureDevice];
success = [_captureSession addInput:_captureVideoDeviceInput error:&error];
if(!success)
{
WEBRTC_TRACE(kTraceError, kTraceVideoCapture, 0,
"%s:%d Failed to add input from %s to the capture session",
__FUNCTION__, __LINE__, _captureDeviceNameUTF8);
return [NSNumber numberWithInt:-1];
}
- (BOOL)setCaptureDeviceById:(char*)uniqueId {
if (uniqueId == nil || !strcmp("", uniqueId)) {
WEBRTC_TRACE(kTraceInfo, kTraceVideoCapture, 0,
"%s:%d successfully added capture device: %s", __FUNCTION__,
__LINE__, _captureDeviceNameUTF8);
return [NSNumber numberWithInt:0];
"Incorrect capture id argument");
return NO;
}
if (!strcmp(uniqueId, _captureDeviceNameUniqueID))
return YES;
QTCaptureDevice* captureDevice;
for(int index = 0; index < _captureDeviceCount; index++) {
captureDevice = (QTCaptureDevice*)[_captureDevices objectAtIndex:index];
char captureDeviceId[1024] = "";
[[captureDevice uniqueID] getCString:captureDeviceId
maxLength:1024
encoding:NSUTF8StringEncoding];
if (strcmp(uniqueId, captureDeviceId) == 0) {
WEBRTC_TRACE(kTraceInfo, kTraceVideoCapture, 0,
"%s:%d Found capture device id %s as index %d",
__FUNCTION__, __LINE__, captureDeviceId, index);
[[captureDevice localizedDisplayName] getCString:_captureDeviceNameUTF8
maxLength:1024
encoding:NSUTF8StringEncoding];
[[captureDevice uniqueID] getCString:_captureDeviceNameUniqueID
maxLength:1024
encoding:NSUTF8StringEncoding];
break;
}
captureDevice = nil;
}
if (!captureDevice)
return NO;
NSError* error;
if (![captureDevice open:&error]) {
WEBRTC_TRACE(kTraceError, kTraceVideoCapture, 0,
"Failed to open capture device: %s", _captureDeviceNameUTF8);
return NO;
}
if (_captureVideoDeviceInput) {
[_captureVideoDeviceInput release];
}
_captureVideoDeviceInput =
[[QTCaptureDeviceInput alloc] initWithDevice:captureDevice];
if (![_captureSession addInput:_captureVideoDeviceInput error:&error]) {
WEBRTC_TRACE(kTraceError, kTraceVideoCapture, 0,
"Failed to add input from %s to the capture session",
_captureDeviceNameUTF8);
return NO;
}
WEBRTC_TRACE(kTraceInfo, kTraceVideoCapture, 0,
"%s:%d successfully added capture device: %s", __FUNCTION__,
__LINE__, _captureDeviceNameUTF8);
return YES;
}
- (void)setCaptureHeight:(int)height width:(int)width frameRate:(int)frameRate {
_frameWidth = width;
_frameHeight = height;
_frameRate = frameRate;
/// ***** Updates the capture devices size and frequency
/// ***** Sets member variables _frame* and _captureDecompressedVideoOutput
/// ***** Returns 0 on success, -1 otherwise.
- (NSNumber*)setCaptureHeight:(int)height AndWidth:(int)width
AndFrameRate:(int)frameRate{
if(NO == _OSSupported)
{
return [NSNumber numberWithInt:0];
}
_frameWidth = width;
_frameHeight = height;
_frameRate = frameRate;
// TODO(mflodman) Check fps settings.
// [_captureDecompressedVideoOutput
// setMinimumVideoFrameInterval:(NSTimeInterval)1/(float)_frameRate];
NSDictionary* captureDictionary = [NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithDouble:_frameWidth], (id)kCVPixelBufferWidthKey,
[NSNumber numberWithDouble:_frameHeight], (id)kCVPixelBufferHeightKey,
[NSNumber numberWithUnsignedInt:kCVPixelFormatType_32ARGB],
(id)kCVPixelBufferPixelFormatTypeKey, nil];
[_captureDecompressedVideoOutput performSelectorOnMainThread:@selector(setPixelBufferAttributes:) withObject:captureDictionary waitUntilDone:NO];
// [_captureDecompressedVideoOutput setPixelBufferAttributes:captureDictionary];
// these methods return type void so there isn't much we can do about
// checking success
return [NSNumber numberWithInt:0];
NSDictionary* captureDictionary =
[NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithDouble:_frameWidth],
(id)kCVPixelBufferWidthKey,
[NSNumber numberWithDouble:_frameHeight],
(id)kCVPixelBufferHeightKey,
[NSNumber numberWithUnsignedInt:kCVPixelFormatType_32ARGB],
(id)kCVPixelBufferPixelFormatTypeKey,
nil];
[_captureDecompressedVideoOutput
performSelectorOnMainThread:@selector(setPixelBufferAttributes:)
withObject:captureDictionary
waitUntilDone:YES];
}
/// ***** Starts the QTCaptureSession, assuming correct state. Also ensures that
/// an NSRunLoop is running
/// ***** Without and NSRunLoop to process events, the OS doesn't check for a
/// new frame.
/// ***** Sets member variables _capturing
/// ***** Returns 0 on success, -1 otherwise.
- (NSNumber*)startCapture{
if(NO == _OSSupported)
{
return [NSNumber numberWithInt:0];
}
- (void)startCapture {
if (_capturing)
return;
if(YES == _capturing)
{
return [NSNumber numberWithInt:0];
}
// NSLog(@"--------------- before ---------------");
[[NSRunLoop mainRunLoop] runUntilDate:[NSDate distantFuture]];
// NSLog(@"--------------- after ---------------");
if(NO == _captureInitialized)
{
// this should never be called..... it is initialized on class init
[self initializeVideoCapture];
}
[_captureSession startRunning];
_capturing = YES;
return [NSNumber numberWithInt:0];
[_captureSession startRunning];
_capturing = YES;
}
/// ***** Stops the QTCaptureSession, assuming correct state
/// ***** Sets member variables _capturing
/// ***** Returns 0 on success, -1 otherwise.
- (NSNumber*)stopCapture{
- (void)stopCapture {
if (!_capturing)
return;
if(NO == _OSSupported)
{
return [NSNumber numberWithInt:0];
}
if(nil == _captureSession)
{
return [NSNumber numberWithInt:0];
}
if(NO == _capturing)
{
return [NSNumber numberWithInt:0];
}
if(YES == _capturing)
{
[_captureSession stopRunning];
}
_capturing = NO;
return [NSNumber numberWithInt:0];
[_captureSession stopRunning];
_capturing = NO;
}
// ********** "private" functions below here **********
#pragma mark **** "private" methods
#pragma mark Private methods
/// ***** Class member variables are initialized here
/// ***** Returns 0 on success, -1 otherwise.
- (NSNumber*)initializeVariables{
- (BOOL)initializeVariables {
if (NSClassFromString(@"QTCaptureSession") == nil)
return NO;
if(NO == _OSSupported)
{
return [NSNumber numberWithInt:0];
}
memset(_captureDeviceNameUTF8, 0, 1024);
_framesDelivered = 0;
_framesRendered = 0;
_captureDeviceCount = 0;
_capturing = NO;
_captureInitialized = NO;
_frameRate = DEFAULT_FRAME_RATE;
_frameWidth = DEFAULT_FRAME_WIDTH;
_frameHeight = DEFAULT_FRAME_HEIGHT;
lock_ = [[NSLock alloc] init];
_captureSession = [[QTCaptureSession alloc] init];
_captureDecompressedVideoOutput =
[[QTCaptureDecompressedVideoOutput alloc] init];
[_captureDecompressedVideoOutput setDelegate:self];
memset(_captureDeviceNameUTF8, 0, 1024);
_framesDelivered = 0;
_framesRendered = 0;
_captureDeviceCount = 0;
_capturing = NO;
_captureInitialized = NO;
_frameRate = DEFAULT_FRAME_RATE;
_frameWidth = DEFAULT_FRAME_WIDTH;
_frameHeight = DEFAULT_FRAME_HEIGHT;
_rLock = [[VideoCaptureRecursiveLock alloc] init];
_captureSession = [[QTCaptureSession alloc] init];
_captureDecompressedVideoOutput = [[QTCaptureDecompressedVideoOutput alloc]
init];
[_captureDecompressedVideoOutput setDelegate:self];
[self getCaptureDevices];
[self initializeVideoCapture];
return [NSNumber numberWithInt:0];
[self getCaptureDevices];
if (![self initializeVideoCapture])
return NO;
return NO;
}
// Checks to see if the QTCaptureSession framework is available in the OS
// If it is not, isOSSupprted = NO.
// Throughout the rest of the class isOSSupprted is checked and functions
// are/aren't called depending
// The user can use weak linking to the QTKit framework and run on older
// versions of the OS. I.E. Backwards compaitibility
// Returns nothing. Sets member variable
- (void)checkOSSupported{
- (void)getCaptureDevices {
if (_captureDevices)
[_captureDevices release];
Class osSupportedTest = NSClassFromString(@"QTCaptureSession");
_OSSupported = NO;
if(nil == osSupportedTest)
{
}
_OSSupported = YES;
_captureDevices = [[NSArray alloc] initWithArray:
[QTCaptureDevice inputDevicesWithMediaType:QTMediaTypeVideo]];
_captureDeviceCount = _captureDevices.count;
}
/// ***** Retrieves the number of capture devices currently available
/// ***** Stores them in an NSArray instance
/// ***** Returns 0 on success, -1 otherwise.
- (NSNumber*)getCaptureDevices{
- (BOOL)initializeVideoCapture{
NSDictionary *captureDictionary =
[NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithDouble:_frameWidth],
(id)kCVPixelBufferWidthKey,
[NSNumber numberWithDouble:_frameHeight],
(id)kCVPixelBufferHeightKey,
[NSNumber numberWithUnsignedInt:kCVPixelFormatType_32ARGB],
(id)kCVPixelBufferPixelFormatTypeKey,
nil];
if(NO == _OSSupported)
{
return [NSNumber numberWithInt:0];
}
[_captureDecompressedVideoOutput setPixelBufferAttributes:captureDictionary];
[_captureDecompressedVideoOutput setAutomaticallyDropsLateVideoFrames:YES];
[_captureDecompressedVideoOutput
setMinimumVideoFrameInterval:(NSTimeInterval)1/(float)_frameRate];
if(_captureDevices)
{
[_captureDevices release];
}
_captureDevices = [[NSArray alloc] initWithArray:
[QTCaptureDevice inputDevicesWithMediaType:QTMediaTypeVideo]];
NSError *error;
if (![_captureSession addOutput:_captureDecompressedVideoOutput error:&error])
return NO;
_captureDeviceCount = _captureDevices.count;
if(_captureDeviceCount < 1)
{
return [NSNumber numberWithInt:0];
}
return [NSNumber numberWithInt:0];
return YES;
}
// Initializes a QTCaptureSession (member variable) to deliver frames via
// callback
// QTCapture* member variables affected
// The image format and frequency are setup here
// Returns 0 on success, -1 otherwise.
- (NSNumber*)initializeVideoCapture{
if(YES == _captureInitialized)
{
return [NSNumber numberWithInt:-1];
}
bool success = NO;
NSError* error;
[_captureDecompressedVideoOutput setPixelBufferAttributes:
[NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithDouble:_frameWidth], (id)kCVPixelBufferWidthKey,
[NSNumber numberWithDouble:_frameHeight], (id)kCVPixelBufferHeightKey,
[NSNumber numberWithUnsignedInt:kCVPixelFormatType_32ARGB],
(id)kCVPixelBufferPixelFormatTypeKey, nil]];
// TODO(mflodman) Check fps settings.
//[_captureDecompressedVideoOutput setMinimumVideoFrameInterval:
// (NSTimeInterval)1/(float)_frameRate];
//[_captureDecompressedVideoOutput setAutomaticallyDropsLateVideoFrames:YES];
success = [_captureSession addOutput:_captureDecompressedVideoOutput
error:&error];
if(!success)
{
return [NSNumber numberWithInt:-1];
}
_captureInitialized = YES;
return [NSNumber numberWithInt:0];
}
// This is the callback that is called when the OS has a frame to deliver to us.
// Starts being called when [_captureSession startRunning] is called. Stopped
// similarly.
// Parameter videoFrame contains the image. The format, size, and frequency
// were setup earlier.
// Returns 0 on success, -1 otherwise.
- (void)captureOutput:(QTCaptureOutput *)captureOutput
didOutputVideoFrame:(CVImageBufferRef)videoFrame
didDropVideoFrameWithSampleBuffer:(QTSampleBuffer *)sampleBuffer
fromConnection:(QTCaptureConnection *)connection {
// TODO(mflodman) Experiment more when this happens.
}
- (void)captureOutput:(QTCaptureOutput *)captureOutput
didOutputVideoFrame:(CVImageBufferRef)videoFrame
withSampleBuffer:(QTSampleBuffer *)sampleBuffer
fromConnection:(QTCaptureConnection *)connection{
fromConnection:(QTCaptureConnection *)connection {
if(YES == [_rLock tryLock])
{
[_rLock lock];
}
else
{
return;
}
[lock_ lock];
if (!_owner) {
[lock_ unlock];
return;
}
if(NO == _OSSupported)
{
return;
}
const int LOCK_FLAGS = 0; // documentation says to pass 0
// get size of the frame
CVPixelBufferLockBaseAddress(videoFrame, LOCK_FLAGS);
void* baseAddress = CVPixelBufferGetBaseAddress(videoFrame);
const int kFlags = 0;
if (CVPixelBufferLockBaseAddress(videoFrame, kFlags) == kCVReturnSuccess) {
void *baseAddress = CVPixelBufferGetBaseAddress(videoFrame);
size_t bytesPerRow = CVPixelBufferGetBytesPerRow(videoFrame);
int frameHeight = CVPixelBufferGetHeight(videoFrame);
CVPixelBufferUnlockBaseAddress(videoFrame, LOCK_FLAGS);
int frameSize = bytesPerRow * frameHeight;
if(_owner)
{
VideoCaptureCapability tempCaptureCapability;
tempCaptureCapability.width = _frameWidth;
tempCaptureCapability.height = _frameHeight;
tempCaptureCapability.maxFPS = _frameRate;
// TODO(wu) : Update actual type and not hard-coded value.
tempCaptureCapability.rawType = kVideoBGRA;
int frameSize = bytesPerRow * frameHeight; // 32 bit ARGB format
CVBufferRetain(videoFrame);
VideoCaptureCapability tempCaptureCapability;
tempCaptureCapability.width = _frameWidth;
tempCaptureCapability.height = _frameHeight;
tempCaptureCapability.maxFPS = _frameRate;
// TODO(wu) : Update actual type and not hard-coded value.
tempCaptureCapability.rawType = kVideoBGRA;
_owner->IncomingFrame((unsigned char*)baseAddress,
frameSize,
tempCaptureCapability,
0);
CVBufferRelease(videoFrame);
}
_framesDelivered++;
_framesRendered++;
if(YES == [_rLock locked])
{
[_rLock unlock];
}
_owner->IncomingFrame((unsigned char*)baseAddress, frameSize,
tempCaptureCapability, 0);
CVPixelBufferUnlockBaseAddress(videoFrame, kFlags);
}
[lock_ unlock];
_framesDelivered++;
_framesRendered++;
}
@end

View File

@ -1,32 +0,0 @@
/*
* Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
//
// video_capture_recursive_lock.h
//
//
#ifndef WEBRTC_MODULES_VIDEO_CAPTURE_MAIN_SOURCE_MAC_QTKIT_VIDEO_CAPTURE_RECURSIVE_LOCK_H_
#define WEBRTC_MODULES_VIDEO_CAPTURE_MAIN_SOURCE_MAC_QTKIT_VIDEO_CAPTURE_RECURSIVE_LOCK_H_
#import <Foundation/Foundation.h>
@interface VideoCaptureRecursiveLock : NSRecursiveLock <NSLocking> {
BOOL _locked;
}
@property BOOL locked;
- (void)lock;
- (void)unlock;
@end
#endif // WEBRTC_MODULES_VIDEO_CAPTURE_MAIN_SOURCE_MAC_QTKIT_VIDEO_CAPTURE_RECURSIVE_LOCK_H_

View File

@ -1,33 +0,0 @@
//
// video_capture_recursive_lock.mm
//
//
#import "video_capture_recursive_lock.h"
@implementation VideoCaptureRecursiveLock
@synthesize locked = _locked;
- (id)init{
self = [super init];
if(nil == self){
return nil;
}
[self setLocked:NO];
return self;
}
- (void)lock{
[self setLocked:YES];
[super lock];
}
- (void)unlock{
[self setLocked:NO];
[super unlock];
}
@end

View File

@ -63,8 +63,6 @@
'mac/qtkit/video_capture_qtkit_objc.h',
'mac/qtkit/video_capture_qtkit_objc.mm',
'mac/qtkit/video_capture_qtkit_utility.h',
'mac/qtkit/video_capture_recursive_lock.h',
'mac/qtkit/video_capture_recursive_lock.mm',
'mac/video_capture_mac.mm',
],
'include_dirs': [