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

Unified Diff: media/video/capture/mac/video_capture_device_mac_qtkit.mm

Issue 8177008: Adding VideoCaptureDevice for Mac. (Closed) Base URL: http://git.chromium.org/chromium/src.git@master
Patch Set: Created 9 years, 2 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 side-by-side diff with in-line comments
Download patch
Index: media/video/capture/mac/video_capture_device_mac_qtkit.mm
diff --git a/media/video/capture/mac/video_capture_device_mac_qtkit.mm b/media/video/capture/mac/video_capture_device_mac_qtkit.mm
new file mode 100644
index 0000000000000000000000000000000000000000..7ddccc1dbfe5ea199f339d0ef13a3c78856fe99b
--- /dev/null
+++ b/media/video/capture/mac/video_capture_device_mac_qtkit.mm
@@ -0,0 +1,198 @@
+// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#import "media/video/capture/mac/video_capture_device_mac_qtkit.h"
+
+#import <QTKit/QTKit.h>
+
+@implementation VideoCaptureDeviceMacQTKit
+
+- (id)init {
+ if (self = [super init]) {
+ pool_ = [[NSAutoreleasePool alloc]init];
dmac 2011/10/06 23:36:22 space between ] and init
dmac 2011/10/06 23:36:22 do you really need an autoreleasepool? please expl
mflodman_chromium_OOO 2011/10/07 13:03:51 Done.
mflodman_chromium_OOO 2011/10/07 13:03:51 Removed. One of my object-c misunderstandings.
+ frameRate_ = 0;
+ frameWidth_ = 0;
dmac 2011/10/06 23:36:22 no need to set things to zero/nil. This happens au
mflodman_chromium_OOO 2011/10/07 13:03:51 Done.
+ frameHeight_ = 0;
+ captureSession_ = nil;
+ captureDecompressedOutput_ = nil;
+ captureDeviceInput_ = nil;
+ }
+ return self;
+}
+
+- (void)dealloc {
+ if(captureSession_) {
dmac 2011/10/06 23:36:22 no need to check if these are nil
mflodman_chromium_OOO 2011/10/07 13:03:51 Done.
+ [captureSession_ release];
+ captureSession_ = nil;
+ }
+ if (captureDecompressedOutput_) {
+ [captureDecompressedOutput_ release];
+ captureDecompressedOutput_ = nil;
+ }
+ if (captureDeviceInput_) {
+ [captureDeviceInput_ release];
+ captureDeviceInput_ = nil;
+ }
+ [pool_ drain];
+ [super dealloc];
+}
+
+#pragma mark Class methods
+
++ (void) deviceNames:(NSArray *) deviceList {
dmac 2011/10/06 23:36:22 no space between ) and device (in both cases)
mflodman_chromium_OOO 2011/10/07 13:03:51 Modified.
+ [deviceList initWithArray:[QTCaptureDevice
dmac 2011/10/06 23:36:22 This does not do what you think it does. My guess
mflodman_chromium_OOO 2011/10/07 13:03:51 Done.
+ inputDevicesWithMediaType:QTMediaTypeVideo]];
+}
+
+#pragma mark Public methods
+
+- (void)registerReceiver:(media::VideoCaptureDeviceMac *)frameReceiver {
dmac 2011/10/06 23:36:22 should this be "setFrameReceiver" since you can on
mflodman_chromium_OOO 2011/10/07 13:03:51 Good point, changed.
+ frameReceiver_ = frameReceiver;
+}
+
+- (BOOL)setCaptureDevice:(const char *)name {
dmac 2011/10/06 23:36:22 so on one side of the interface you take an NSStri
mflodman_chromium_OOO 2011/10/07 13:03:51 Done.
+ if (captureDeviceInput_) {
+ // A device is already set.
+ return NO;
+ }
+
+ // Find the requested device, open it and set as input.
+ NSArray* captureDevices;
+ captureDevices = [[[NSArray alloc] initWithArray:
dmac 2011/10/06 23:36:22 There's a couple of bugs here, but can I suggest a
mflodman_chromium_OOO 2011/10/07 13:03:51 Changed to the suggested code, almost... I changed
+ [QTCaptureDevice inputDevicesWithMediaType:QTMediaTypeVideo]]
+ autorelease];
+
+ if ([captureDevices count] == 0) {
+ return NO;
+ }
+
+ for(NSUInteger index = 0; index < captureDevices.count; ++index) {
+ NSError* error;
+ QTCaptureDevice* captureDevice =
+ (QTCaptureDevice*)[captureDevices objectAtIndex:index];
+
+ char captureDeviceName[1024];
+ [[captureDevice localizedDisplayName] getCString:captureDeviceName
+ maxLength:1024
+ encoding:NSUTF8StringEncoding];
+ if (!strcmp(captureDeviceName, name)) {
+ if (![captureDevice open:&error]) {
+ return NO;
+ }
+ captureDeviceInput_ = [QTCaptureDeviceInput alloc];
+ [captureDeviceInput_ initWithDevice:captureDevice];
+ captureSession_ = [[QTCaptureSession alloc] init];
+ captureDecompressedOutput_ =
+ [[QTCaptureDecompressedVideoOutput alloc] init];
+ [captureDecompressedOutput_ setDelegate:self];
+ return YES;
+ }
+ }
+ return NO;
+}
+
+- (void)removeCaptureDevice {
+ if ([[captureSession_ inputs] count] > 0) {
+ // The device is still running.
+ [self stopCapture];
+ }
+ if (captureDecompressedOutput_) {
dmac 2011/10/06 23:36:22 no need to check. Just call release on it. Same w
mflodman_chromium_OOO 2011/10/07 13:03:51 Done.
+ [captureDecompressedOutput_ release];
+ captureDecompressedOutput_ = nil;
+ }
+ if(captureSession_) {
+ [captureSession_ release];
+ captureSession_ = nil;
+ }
+ if (captureDeviceInput_) {
+ [captureDeviceInput_ release];
+ captureDeviceInput_ = nil;
+ }
+}
+
+- (BOOL)setCaptureHeight:(int)height
+ AndWidth:(int)width
+ AndFrameRate:(int)frameRate {
+ // Verify an input device has been set.
+ if (!captureDeviceInput_) {
+ return NO;
+ }
+
+ frameWidth_ = width;
+ frameHeight_ = height;
+ frameRate_ = frameRate;
+
+ // Set up desired output properties.
+ NSDictionary* captureDictionary =
+ [NSDictionary dictionaryWithObjectsAndKeys:
+ [NSNumber numberWithDouble:frameWidth_],
+ (id)kCVPixelBufferWidthKey,
+ [NSNumber numberWithDouble:frameHeight_],
+ (id)kCVPixelBufferHeightKey,
+ [NSNumber numberWithUnsignedInt:kCVPixelFormatType_32BGRA],
+ (id)kCVPixelBufferPixelFormatTypeKey,
+ nil];
+ [captureDecompressedOutput_ setPixelBufferAttributes:captureDictionary];
+
+ // Connect the output with the session.
+ NSError* error;
+ if (![captureSession_ addOutput:captureDecompressedOutput_ error:&error]) {
+ return NO;
dmac 2011/10/06 23:36:22 log the error?
mflodman_chromium_OOO 2011/10/07 13:03:51 Done.
+ }
+ return YES;
+}
+
+- (BOOL)startCapture {
+ if ([[captureSession_ outputs] count] == 0) {
+ // Capture properties not set.
+ return NO;
+ }
+ if ([[captureSession_ inputs] count] == 0) {
+ NSError* error;
+ if (![captureSession_ addInput:captureDeviceInput_ error:&error]) {
+ return NO;
dmac 2011/10/06 23:36:22 log the error?
mflodman_chromium_OOO 2011/10/07 13:03:51 Done.
+ }
+ [[NSRunLoop currentRunLoop] runUntilDate:[NSDate distantFuture]];
dmac 2011/10/06 23:36:22 what breaks out of this runloop?
mflodman_chromium_OOO 2011/10/07 13:03:51 The runloop was originally from sample, which I pr
+ [captureSession_ startRunning];
+ }
+ return YES;
+}
+
+- (void)stopCapture {
+ if ([[captureSession_ inputs] count] > 0) {
+ [captureSession_ removeInput:captureDeviceInput_];
+ [captureSession_ stopRunning];
+ }
+}
+
+// |captureOutput| is called by the capture device to deliver a new frame.
+- (void)captureOutput:(QTCaptureOutput *)captureOutput
+ didOutputVideoFrame:(CVImageBufferRef)videoFrame
+ withSampleBuffer:(QTSampleBuffer *)sampleBuffer
+ fromConnection:(QTCaptureConnection *)connection {
+
+ // Lock the frame and calculate frame size.
+ const int LOCK_FLAGS = 0;
+ CVPixelBufferLockBaseAddress(videoFrame, LOCK_FLAGS);
+ void* baseAddress = CVPixelBufferGetBaseAddress(videoFrame);
+ size_t bytesPerRow = CVPixelBufferGetBytesPerRow(videoFrame);
+ int frameHeight = CVPixelBufferGetHeight(videoFrame);
+
+ if(frameReceiver_) {
dmac 2011/10/06 23:36:22 do you want to check frameReceiver_ before doing a
mflodman_chromium_OOO 2011/10/07 13:03:51 Good point, changed.
+ int frameSize = bytesPerRow * frameHeight;
+ CVBufferRetain(videoFrame);
dmac 2011/10/06 23:36:22 why do feel you need to retain and release the vid
mflodman_chromium_OOO 2011/10/07 13:03:51 It was to make sure videoFrame was valid during th
+ media::VideoCaptureDevice::Capability captureCapability;
+ captureCapability.width = frameWidth_;
+ captureCapability.height = frameHeight_;
+ captureCapability.frame_rate = frameRate_;
+ captureCapability.color = media::VideoCaptureDevice::kARGB;
+
+ frameReceiver_->IncomingFrame(baseAddress, frameSize, captureCapability);
+
+ CVBufferRelease(videoFrame);
+ }
+ CVPixelBufferUnlockBaseAddress(videoFrame, LOCK_FLAGS);
+}
+
+@end

Powered by Google App Engine
This is Rietveld 408576698