1b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org/* 2b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. 3b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * 4b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * Use of this source code is governed by a BSD-style license 5b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * that can be found in the LICENSE file in the root of the source 6b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * tree. An additional intellectual property rights grant can be found 7b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * in the file PATENTS. All contributing project authors may 8b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * be found in the AUTHORS file in the root of the source tree. 9b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org */ 10b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 11b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#define DEFAULT_CAPTURE_DEVICE_INDEX 1 12b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#define DEFAULT_FRAME_RATE 30 131fc08d3ea04de5616b9070115f0b66f5827de7f3mflodman@webrtc.org#define DEFAULT_FRAME_WIDTH 352 14b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#define DEFAULT_FRAME_HEIGHT 288 15b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#define ROTATE_CAPTURED_FRAME 1 16b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#define LOW_QUALITY 1 17b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 181fc08d3ea04de5616b9070115f0b66f5827de7f3mflodman@webrtc.org#import "webrtc/modules/video_capture/mac/qtkit/video_capture_qtkit_objc.h" 191fc08d3ea04de5616b9070115f0b66f5827de7f3mflodman@webrtc.org 201fc08d3ea04de5616b9070115f0b66f5827de7f3mflodman@webrtc.org#include "webrtc/system_wrappers/interface/trace.h" 21b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 22b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgusing namespace webrtc; 23b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgusing namespace videocapturemodule; 24b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 25b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org@implementation VideoCaptureMacQTKitObjC 26b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 271fc08d3ea04de5616b9070115f0b66f5827de7f3mflodman@webrtc.org-(id)init { 281fc08d3ea04de5616b9070115f0b66f5827de7f3mflodman@webrtc.org self = [super init]; 291fc08d3ea04de5616b9070115f0b66f5827de7f3mflodman@webrtc.org if (self) { 301fc08d3ea04de5616b9070115f0b66f5827de7f3mflodman@webrtc.org [self initializeVariables]; 311fc08d3ea04de5616b9070115f0b66f5827de7f3mflodman@webrtc.org } 321fc08d3ea04de5616b9070115f0b66f5827de7f3mflodman@webrtc.org return self; 33b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 34b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 35b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org- (void)dealloc { 361fc08d3ea04de5616b9070115f0b66f5827de7f3mflodman@webrtc.org if (_captureSession) 371fc08d3ea04de5616b9070115f0b66f5827de7f3mflodman@webrtc.org [_captureSession stopRunning]; 380dae366146cb5c6871db85c48cfefe97c8262e5cmflodman@webrtc.org 391fc08d3ea04de5616b9070115f0b66f5827de7f3mflodman@webrtc.org if (_captureVideoDeviceInput) { 401fc08d3ea04de5616b9070115f0b66f5827de7f3mflodman@webrtc.org if ([[_captureVideoDeviceInput device] isOpen]) 411fc08d3ea04de5616b9070115f0b66f5827de7f3mflodman@webrtc.org [[_captureVideoDeviceInput device] close]; 420dae366146cb5c6871db85c48cfefe97c8262e5cmflodman@webrtc.org 431fc08d3ea04de5616b9070115f0b66f5827de7f3mflodman@webrtc.org [_captureVideoDeviceInput release]; 441fc08d3ea04de5616b9070115f0b66f5827de7f3mflodman@webrtc.org } 450dae366146cb5c6871db85c48cfefe97c8262e5cmflodman@webrtc.org 461fc08d3ea04de5616b9070115f0b66f5827de7f3mflodman@webrtc.org [_captureDecompressedVideoOutput release]; 471fc08d3ea04de5616b9070115f0b66f5827de7f3mflodman@webrtc.org [_captureSession release]; 481fc08d3ea04de5616b9070115f0b66f5827de7f3mflodman@webrtc.org [_captureDevices release]; 490dae366146cb5c6871db85c48cfefe97c8262e5cmflodman@webrtc.org 501fc08d3ea04de5616b9070115f0b66f5827de7f3mflodman@webrtc.org [super dealloc]; 51b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 52b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 531fc08d3ea04de5616b9070115f0b66f5827de7f3mflodman@webrtc.org#pragma mark Public methods 54b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 551fc08d3ea04de5616b9070115f0b66f5827de7f3mflodman@webrtc.org- (void)registerOwner:(VideoCaptureMacQTKit*)owner { 561fc08d3ea04de5616b9070115f0b66f5827de7f3mflodman@webrtc.org [lock_ lock]; 571fc08d3ea04de5616b9070115f0b66f5827de7f3mflodman@webrtc.org _owner = owner; 581fc08d3ea04de5616b9070115f0b66f5827de7f3mflodman@webrtc.org [lock_ unlock]; 59b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 60b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 611fc08d3ea04de5616b9070115f0b66f5827de7f3mflodman@webrtc.org- (BOOL)setCaptureDeviceById:(char*)uniqueId { 621fc08d3ea04de5616b9070115f0b66f5827de7f3mflodman@webrtc.org if (uniqueId == nil || !strcmp("", uniqueId)) { 63b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WEBRTC_TRACE(kTraceInfo, kTraceVideoCapture, 0, 641fc08d3ea04de5616b9070115f0b66f5827de7f3mflodman@webrtc.org "Incorrect capture id argument"); 651fc08d3ea04de5616b9070115f0b66f5827de7f3mflodman@webrtc.org return NO; 661fc08d3ea04de5616b9070115f0b66f5827de7f3mflodman@webrtc.org } 671fc08d3ea04de5616b9070115f0b66f5827de7f3mflodman@webrtc.org 681fc08d3ea04de5616b9070115f0b66f5827de7f3mflodman@webrtc.org if (!strcmp(uniqueId, _captureDeviceNameUniqueID)) 691fc08d3ea04de5616b9070115f0b66f5827de7f3mflodman@webrtc.org return YES; 701fc08d3ea04de5616b9070115f0b66f5827de7f3mflodman@webrtc.org 711fc08d3ea04de5616b9070115f0b66f5827de7f3mflodman@webrtc.org QTCaptureDevice* captureDevice; 721fc08d3ea04de5616b9070115f0b66f5827de7f3mflodman@webrtc.org for(int index = 0; index < _captureDeviceCount; index++) { 731fc08d3ea04de5616b9070115f0b66f5827de7f3mflodman@webrtc.org captureDevice = (QTCaptureDevice*)[_captureDevices objectAtIndex:index]; 741fc08d3ea04de5616b9070115f0b66f5827de7f3mflodman@webrtc.org char captureDeviceId[1024] = ""; 751fc08d3ea04de5616b9070115f0b66f5827de7f3mflodman@webrtc.org [[captureDevice uniqueID] getCString:captureDeviceId 761fc08d3ea04de5616b9070115f0b66f5827de7f3mflodman@webrtc.org maxLength:1024 771fc08d3ea04de5616b9070115f0b66f5827de7f3mflodman@webrtc.org encoding:NSUTF8StringEncoding]; 781fc08d3ea04de5616b9070115f0b66f5827de7f3mflodman@webrtc.org if (strcmp(uniqueId, captureDeviceId) == 0) { 791fc08d3ea04de5616b9070115f0b66f5827de7f3mflodman@webrtc.org WEBRTC_TRACE(kTraceInfo, kTraceVideoCapture, 0, 801fc08d3ea04de5616b9070115f0b66f5827de7f3mflodman@webrtc.org "%s:%d Found capture device id %s as index %d", 811fc08d3ea04de5616b9070115f0b66f5827de7f3mflodman@webrtc.org __FUNCTION__, __LINE__, captureDeviceId, index); 821fc08d3ea04de5616b9070115f0b66f5827de7f3mflodman@webrtc.org [[captureDevice localizedDisplayName] getCString:_captureDeviceNameUTF8 831fc08d3ea04de5616b9070115f0b66f5827de7f3mflodman@webrtc.org maxLength:1024 841fc08d3ea04de5616b9070115f0b66f5827de7f3mflodman@webrtc.org encoding:NSUTF8StringEncoding]; 851fc08d3ea04de5616b9070115f0b66f5827de7f3mflodman@webrtc.org [[captureDevice uniqueID] getCString:_captureDeviceNameUniqueID 861fc08d3ea04de5616b9070115f0b66f5827de7f3mflodman@webrtc.org maxLength:1024 871fc08d3ea04de5616b9070115f0b66f5827de7f3mflodman@webrtc.org encoding:NSUTF8StringEncoding]; 881fc08d3ea04de5616b9070115f0b66f5827de7f3mflodman@webrtc.org break; 89b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 901fc08d3ea04de5616b9070115f0b66f5827de7f3mflodman@webrtc.org captureDevice = nil; 911fc08d3ea04de5616b9070115f0b66f5827de7f3mflodman@webrtc.org } 921fc08d3ea04de5616b9070115f0b66f5827de7f3mflodman@webrtc.org 931fc08d3ea04de5616b9070115f0b66f5827de7f3mflodman@webrtc.org if (!captureDevice) 941fc08d3ea04de5616b9070115f0b66f5827de7f3mflodman@webrtc.org return NO; 951fc08d3ea04de5616b9070115f0b66f5827de7f3mflodman@webrtc.org 961fc08d3ea04de5616b9070115f0b66f5827de7f3mflodman@webrtc.org NSError* error; 971fc08d3ea04de5616b9070115f0b66f5827de7f3mflodman@webrtc.org if (![captureDevice open:&error]) { 981fc08d3ea04de5616b9070115f0b66f5827de7f3mflodman@webrtc.org WEBRTC_TRACE(kTraceError, kTraceVideoCapture, 0, 991fc08d3ea04de5616b9070115f0b66f5827de7f3mflodman@webrtc.org "Failed to open capture device: %s", _captureDeviceNameUTF8); 1001fc08d3ea04de5616b9070115f0b66f5827de7f3mflodman@webrtc.org return NO; 1011fc08d3ea04de5616b9070115f0b66f5827de7f3mflodman@webrtc.org } 1021fc08d3ea04de5616b9070115f0b66f5827de7f3mflodman@webrtc.org 1031fc08d3ea04de5616b9070115f0b66f5827de7f3mflodman@webrtc.org if (_captureVideoDeviceInput) { 1041fc08d3ea04de5616b9070115f0b66f5827de7f3mflodman@webrtc.org [_captureVideoDeviceInput release]; 1051fc08d3ea04de5616b9070115f0b66f5827de7f3mflodman@webrtc.org } 1061fc08d3ea04de5616b9070115f0b66f5827de7f3mflodman@webrtc.org _captureVideoDeviceInput = 1071fc08d3ea04de5616b9070115f0b66f5827de7f3mflodman@webrtc.org [[QTCaptureDeviceInput alloc] initWithDevice:captureDevice]; 1081fc08d3ea04de5616b9070115f0b66f5827de7f3mflodman@webrtc.org 1091fc08d3ea04de5616b9070115f0b66f5827de7f3mflodman@webrtc.org if (![_captureSession addInput:_captureVideoDeviceInput error:&error]) { 1101fc08d3ea04de5616b9070115f0b66f5827de7f3mflodman@webrtc.org WEBRTC_TRACE(kTraceError, kTraceVideoCapture, 0, 1111fc08d3ea04de5616b9070115f0b66f5827de7f3mflodman@webrtc.org "Failed to add input from %s to the capture session", 1121fc08d3ea04de5616b9070115f0b66f5827de7f3mflodman@webrtc.org _captureDeviceNameUTF8); 1131fc08d3ea04de5616b9070115f0b66f5827de7f3mflodman@webrtc.org return NO; 1141fc08d3ea04de5616b9070115f0b66f5827de7f3mflodman@webrtc.org } 1151fc08d3ea04de5616b9070115f0b66f5827de7f3mflodman@webrtc.org 1161fc08d3ea04de5616b9070115f0b66f5827de7f3mflodman@webrtc.org WEBRTC_TRACE(kTraceInfo, kTraceVideoCapture, 0, 1171fc08d3ea04de5616b9070115f0b66f5827de7f3mflodman@webrtc.org "%s:%d successfully added capture device: %s", __FUNCTION__, 1181fc08d3ea04de5616b9070115f0b66f5827de7f3mflodman@webrtc.org __LINE__, _captureDeviceNameUTF8); 1191fc08d3ea04de5616b9070115f0b66f5827de7f3mflodman@webrtc.org return YES; 120b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 121b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1221fc08d3ea04de5616b9070115f0b66f5827de7f3mflodman@webrtc.org- (void)setCaptureHeight:(int)height width:(int)width frameRate:(int)frameRate { 1231fc08d3ea04de5616b9070115f0b66f5827de7f3mflodman@webrtc.org _frameWidth = width; 1241fc08d3ea04de5616b9070115f0b66f5827de7f3mflodman@webrtc.org _frameHeight = height; 1251fc08d3ea04de5616b9070115f0b66f5827de7f3mflodman@webrtc.org _frameRate = frameRate; 1261fc08d3ea04de5616b9070115f0b66f5827de7f3mflodman@webrtc.org 1271fc08d3ea04de5616b9070115f0b66f5827de7f3mflodman@webrtc.org NSDictionary* captureDictionary = 1281fc08d3ea04de5616b9070115f0b66f5827de7f3mflodman@webrtc.org [NSDictionary dictionaryWithObjectsAndKeys: 1291fc08d3ea04de5616b9070115f0b66f5827de7f3mflodman@webrtc.org [NSNumber numberWithDouble:_frameWidth], 1301fc08d3ea04de5616b9070115f0b66f5827de7f3mflodman@webrtc.org (id)kCVPixelBufferWidthKey, 1311fc08d3ea04de5616b9070115f0b66f5827de7f3mflodman@webrtc.org [NSNumber numberWithDouble:_frameHeight], 1321fc08d3ea04de5616b9070115f0b66f5827de7f3mflodman@webrtc.org (id)kCVPixelBufferHeightKey, 1331fc08d3ea04de5616b9070115f0b66f5827de7f3mflodman@webrtc.org [NSNumber numberWithUnsignedInt:kCVPixelFormatType_32ARGB], 1341fc08d3ea04de5616b9070115f0b66f5827de7f3mflodman@webrtc.org (id)kCVPixelBufferPixelFormatTypeKey, 1351fc08d3ea04de5616b9070115f0b66f5827de7f3mflodman@webrtc.org nil]; 1361fc08d3ea04de5616b9070115f0b66f5827de7f3mflodman@webrtc.org [_captureDecompressedVideoOutput 1371fc08d3ea04de5616b9070115f0b66f5827de7f3mflodman@webrtc.org performSelectorOnMainThread:@selector(setPixelBufferAttributes:) 1381fc08d3ea04de5616b9070115f0b66f5827de7f3mflodman@webrtc.org withObject:captureDictionary 1391fc08d3ea04de5616b9070115f0b66f5827de7f3mflodman@webrtc.org waitUntilDone:YES]; 140b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 141b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1421fc08d3ea04de5616b9070115f0b66f5827de7f3mflodman@webrtc.org- (void)startCapture { 1431fc08d3ea04de5616b9070115f0b66f5827de7f3mflodman@webrtc.org if (_capturing) 1441fc08d3ea04de5616b9070115f0b66f5827de7f3mflodman@webrtc.org return; 145b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1461fc08d3ea04de5616b9070115f0b66f5827de7f3mflodman@webrtc.org [_captureSession startRunning]; 1471fc08d3ea04de5616b9070115f0b66f5827de7f3mflodman@webrtc.org _capturing = YES; 148b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 149b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1501fc08d3ea04de5616b9070115f0b66f5827de7f3mflodman@webrtc.org- (void)stopCapture { 1511fc08d3ea04de5616b9070115f0b66f5827de7f3mflodman@webrtc.org if (!_capturing) 1521fc08d3ea04de5616b9070115f0b66f5827de7f3mflodman@webrtc.org return; 153b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1541fc08d3ea04de5616b9070115f0b66f5827de7f3mflodman@webrtc.org [_captureSession stopRunning]; 1551fc08d3ea04de5616b9070115f0b66f5827de7f3mflodman@webrtc.org _capturing = NO; 156b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 157b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1581fc08d3ea04de5616b9070115f0b66f5827de7f3mflodman@webrtc.org#pragma mark Private methods 1591fc08d3ea04de5616b9070115f0b66f5827de7f3mflodman@webrtc.org 1601fc08d3ea04de5616b9070115f0b66f5827de7f3mflodman@webrtc.org- (BOOL)initializeVariables { 1611fc08d3ea04de5616b9070115f0b66f5827de7f3mflodman@webrtc.org if (NSClassFromString(@"QTCaptureSession") == nil) 1621fc08d3ea04de5616b9070115f0b66f5827de7f3mflodman@webrtc.org return NO; 1631fc08d3ea04de5616b9070115f0b66f5827de7f3mflodman@webrtc.org 1641fc08d3ea04de5616b9070115f0b66f5827de7f3mflodman@webrtc.org memset(_captureDeviceNameUTF8, 0, 1024); 1651fc08d3ea04de5616b9070115f0b66f5827de7f3mflodman@webrtc.org _framesDelivered = 0; 1661fc08d3ea04de5616b9070115f0b66f5827de7f3mflodman@webrtc.org _framesRendered = 0; 1671fc08d3ea04de5616b9070115f0b66f5827de7f3mflodman@webrtc.org _captureDeviceCount = 0; 1681fc08d3ea04de5616b9070115f0b66f5827de7f3mflodman@webrtc.org _capturing = NO; 1691fc08d3ea04de5616b9070115f0b66f5827de7f3mflodman@webrtc.org _captureInitialized = NO; 1701fc08d3ea04de5616b9070115f0b66f5827de7f3mflodman@webrtc.org _frameRate = DEFAULT_FRAME_RATE; 1711fc08d3ea04de5616b9070115f0b66f5827de7f3mflodman@webrtc.org _frameWidth = DEFAULT_FRAME_WIDTH; 1721fc08d3ea04de5616b9070115f0b66f5827de7f3mflodman@webrtc.org _frameHeight = DEFAULT_FRAME_HEIGHT; 1731fc08d3ea04de5616b9070115f0b66f5827de7f3mflodman@webrtc.org lock_ = [[NSLock alloc] init]; 1741fc08d3ea04de5616b9070115f0b66f5827de7f3mflodman@webrtc.org _captureSession = [[QTCaptureSession alloc] init]; 1751fc08d3ea04de5616b9070115f0b66f5827de7f3mflodman@webrtc.org _captureDecompressedVideoOutput = 1761fc08d3ea04de5616b9070115f0b66f5827de7f3mflodman@webrtc.org [[QTCaptureDecompressedVideoOutput alloc] init]; 1771fc08d3ea04de5616b9070115f0b66f5827de7f3mflodman@webrtc.org [_captureDecompressedVideoOutput setDelegate:self]; 1781fc08d3ea04de5616b9070115f0b66f5827de7f3mflodman@webrtc.org 1791fc08d3ea04de5616b9070115f0b66f5827de7f3mflodman@webrtc.org [self getCaptureDevices]; 1801fc08d3ea04de5616b9070115f0b66f5827de7f3mflodman@webrtc.org if (![self initializeVideoCapture]) 1811fc08d3ea04de5616b9070115f0b66f5827de7f3mflodman@webrtc.org return NO; 1821fc08d3ea04de5616b9070115f0b66f5827de7f3mflodman@webrtc.org 1831fc08d3ea04de5616b9070115f0b66f5827de7f3mflodman@webrtc.org return NO; 184b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 185b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1861fc08d3ea04de5616b9070115f0b66f5827de7f3mflodman@webrtc.org- (void)getCaptureDevices { 1871fc08d3ea04de5616b9070115f0b66f5827de7f3mflodman@webrtc.org if (_captureDevices) 1881fc08d3ea04de5616b9070115f0b66f5827de7f3mflodman@webrtc.org [_captureDevices release]; 189b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1901fc08d3ea04de5616b9070115f0b66f5827de7f3mflodman@webrtc.org _captureDevices = [[NSArray alloc] initWithArray: 1911fc08d3ea04de5616b9070115f0b66f5827de7f3mflodman@webrtc.org [QTCaptureDevice inputDevicesWithMediaType:QTMediaTypeVideo]]; 192b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1931fc08d3ea04de5616b9070115f0b66f5827de7f3mflodman@webrtc.org _captureDeviceCount = _captureDevices.count; 194b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 195b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1961fc08d3ea04de5616b9070115f0b66f5827de7f3mflodman@webrtc.org- (BOOL)initializeVideoCapture{ 1971fc08d3ea04de5616b9070115f0b66f5827de7f3mflodman@webrtc.org NSDictionary *captureDictionary = 1981fc08d3ea04de5616b9070115f0b66f5827de7f3mflodman@webrtc.org [NSDictionary dictionaryWithObjectsAndKeys: 1991fc08d3ea04de5616b9070115f0b66f5827de7f3mflodman@webrtc.org [NSNumber numberWithDouble:_frameWidth], 2001fc08d3ea04de5616b9070115f0b66f5827de7f3mflodman@webrtc.org (id)kCVPixelBufferWidthKey, 2011fc08d3ea04de5616b9070115f0b66f5827de7f3mflodman@webrtc.org [NSNumber numberWithDouble:_frameHeight], 2021fc08d3ea04de5616b9070115f0b66f5827de7f3mflodman@webrtc.org (id)kCVPixelBufferHeightKey, 2031fc08d3ea04de5616b9070115f0b66f5827de7f3mflodman@webrtc.org [NSNumber numberWithUnsignedInt:kCVPixelFormatType_32ARGB], 2041fc08d3ea04de5616b9070115f0b66f5827de7f3mflodman@webrtc.org (id)kCVPixelBufferPixelFormatTypeKey, 2051fc08d3ea04de5616b9070115f0b66f5827de7f3mflodman@webrtc.org nil]; 2061fc08d3ea04de5616b9070115f0b66f5827de7f3mflodman@webrtc.org 2071fc08d3ea04de5616b9070115f0b66f5827de7f3mflodman@webrtc.org [_captureDecompressedVideoOutput setPixelBufferAttributes:captureDictionary]; 2081fc08d3ea04de5616b9070115f0b66f5827de7f3mflodman@webrtc.org [_captureDecompressedVideoOutput setAutomaticallyDropsLateVideoFrames:YES]; 2091fc08d3ea04de5616b9070115f0b66f5827de7f3mflodman@webrtc.org [_captureDecompressedVideoOutput 2101fc08d3ea04de5616b9070115f0b66f5827de7f3mflodman@webrtc.org setMinimumVideoFrameInterval:(NSTimeInterval)1/(float)_frameRate]; 2111fc08d3ea04de5616b9070115f0b66f5827de7f3mflodman@webrtc.org 2121fc08d3ea04de5616b9070115f0b66f5827de7f3mflodman@webrtc.org NSError *error; 2131fc08d3ea04de5616b9070115f0b66f5827de7f3mflodman@webrtc.org if (![_captureSession addOutput:_captureDecompressedVideoOutput error:&error]) 2141fc08d3ea04de5616b9070115f0b66f5827de7f3mflodman@webrtc.org return NO; 2151fc08d3ea04de5616b9070115f0b66f5827de7f3mflodman@webrtc.org 2161fc08d3ea04de5616b9070115f0b66f5827de7f3mflodman@webrtc.org return YES; 2171fc08d3ea04de5616b9070115f0b66f5827de7f3mflodman@webrtc.org} 218b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 2191fc08d3ea04de5616b9070115f0b66f5827de7f3mflodman@webrtc.org- (void)captureOutput:(QTCaptureOutput *)captureOutput 2201fc08d3ea04de5616b9070115f0b66f5827de7f3mflodman@webrtc.org didDropVideoFrameWithSampleBuffer:(QTSampleBuffer *)sampleBuffer 2211fc08d3ea04de5616b9070115f0b66f5827de7f3mflodman@webrtc.org fromConnection:(QTCaptureConnection *)connection { 2221fc08d3ea04de5616b9070115f0b66f5827de7f3mflodman@webrtc.org // TODO(mflodman) Experiment more when this happens. 223b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 224b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 225b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org- (void)captureOutput:(QTCaptureOutput *)captureOutput 2261fc08d3ea04de5616b9070115f0b66f5827de7f3mflodman@webrtc.org didOutputVideoFrame:(CVImageBufferRef)videoFrame 227b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org withSampleBuffer:(QTSampleBuffer *)sampleBuffer 2281fc08d3ea04de5616b9070115f0b66f5827de7f3mflodman@webrtc.org fromConnection:(QTCaptureConnection *)connection { 229b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 2301fc08d3ea04de5616b9070115f0b66f5827de7f3mflodman@webrtc.org [lock_ lock]; 2311fc08d3ea04de5616b9070115f0b66f5827de7f3mflodman@webrtc.org if (!_owner) { 2321fc08d3ea04de5616b9070115f0b66f5827de7f3mflodman@webrtc.org [lock_ unlock]; 2331fc08d3ea04de5616b9070115f0b66f5827de7f3mflodman@webrtc.org return; 2341fc08d3ea04de5616b9070115f0b66f5827de7f3mflodman@webrtc.org } 235b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 2361fc08d3ea04de5616b9070115f0b66f5827de7f3mflodman@webrtc.org const int kFlags = 0; 2371fc08d3ea04de5616b9070115f0b66f5827de7f3mflodman@webrtc.org if (CVPixelBufferLockBaseAddress(videoFrame, kFlags) == kCVReturnSuccess) { 2381fc08d3ea04de5616b9070115f0b66f5827de7f3mflodman@webrtc.org void *baseAddress = CVPixelBufferGetBaseAddress(videoFrame); 239b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org size_t bytesPerRow = CVPixelBufferGetBytesPerRow(videoFrame); 240b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int frameHeight = CVPixelBufferGetHeight(videoFrame); 2411fc08d3ea04de5616b9070115f0b66f5827de7f3mflodman@webrtc.org int frameSize = bytesPerRow * frameHeight; 2421fc08d3ea04de5616b9070115f0b66f5827de7f3mflodman@webrtc.org 2431fc08d3ea04de5616b9070115f0b66f5827de7f3mflodman@webrtc.org VideoCaptureCapability tempCaptureCapability; 2441fc08d3ea04de5616b9070115f0b66f5827de7f3mflodman@webrtc.org tempCaptureCapability.width = _frameWidth; 2451fc08d3ea04de5616b9070115f0b66f5827de7f3mflodman@webrtc.org tempCaptureCapability.height = _frameHeight; 2461fc08d3ea04de5616b9070115f0b66f5827de7f3mflodman@webrtc.org tempCaptureCapability.maxFPS = _frameRate; 2471fc08d3ea04de5616b9070115f0b66f5827de7f3mflodman@webrtc.org // TODO(wu) : Update actual type and not hard-coded value. 2481fc08d3ea04de5616b9070115f0b66f5827de7f3mflodman@webrtc.org tempCaptureCapability.rawType = kVideoBGRA; 2491fc08d3ea04de5616b9070115f0b66f5827de7f3mflodman@webrtc.org 2501fc08d3ea04de5616b9070115f0b66f5827de7f3mflodman@webrtc.org _owner->IncomingFrame((unsigned char*)baseAddress, frameSize, 2511fc08d3ea04de5616b9070115f0b66f5827de7f3mflodman@webrtc.org tempCaptureCapability, 0); 2521fc08d3ea04de5616b9070115f0b66f5827de7f3mflodman@webrtc.org CVPixelBufferUnlockBaseAddress(videoFrame, kFlags); 2531fc08d3ea04de5616b9070115f0b66f5827de7f3mflodman@webrtc.org } 2541fc08d3ea04de5616b9070115f0b66f5827de7f3mflodman@webrtc.org [lock_ unlock]; 2551fc08d3ea04de5616b9070115f0b66f5827de7f3mflodman@webrtc.org _framesDelivered++; 2561fc08d3ea04de5616b9070115f0b66f5827de7f3mflodman@webrtc.org _framesRendered++; 257b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 258b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 259b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org@end 260