Chromium Code Reviews| 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..e24e8fd5abf1ff79625c83d3da6d7c4f07b4592b |
| --- /dev/null |
| +++ b/media/video/capture/mac/video_capture_device_mac_qtkit.mm |
| @@ -0,0 +1,171 @@ |
| +// 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> |
| + |
| +#include "base/logging.h" |
| +#include "media/video/capture/mac/video_capture_device_mac.h" |
| +#include "media/video/capture/video_capture_device.h" |
| + |
| +@implementation VideoCaptureDeviceMacQTKit |
| + |
| +- (void)dealloc { |
|
dmac
2011/10/14 23:31:35
please move dealloc down under init
mflodman_chromium_OOO
2011/10/16 21:58:38
Done.
|
| + [captureSession_ release]; |
| + [captureDeviceInput_ release]; |
| + [super dealloc]; |
| +} |
| + |
| +#pragma mark Class methods |
| + |
| ++ (NSArray *)deviceNames { |
| + return [QTCaptureDevice inputDevicesWithMediaType:QTMediaTypeVideo]; |
| +} |
| + |
| +#pragma mark Public methods |
| + |
| +- (id)initWithFrameReceiver:(media::VideoCaptureDeviceMac *)frameReceiver { |
| + frameReceiver_ = frameReceiver; |
| + return [super init]; |
| +} |
| + |
| +- (BOOL)setCaptureDevice:(NSString *)deviceId { |
| + if (deviceId) { |
| + // Set the capture device. |
| + if (captureDeviceInput_) { |
| + DLOG(ERROR) << "Video capture device already set."; |
| + return NO; |
| + } |
| + |
| + NSArray *captureDevices = |
| + [QTCaptureDevice inputDevicesWithMediaType:QTMediaTypeVideo]; |
| + NSArray *captureDevicesNames = |
| + [captureDevices valueForKey:@"uniqueID"]; |
| + NSUInteger index = [captureDevicesNames indexOfObject:deviceId]; |
| + if (index == NSNotFound) { |
| + DLOG(ERROR) << "Video capture device not found."; |
| + return NO; |
| + } |
| + QTCaptureDevice *device = [captureDevices objectAtIndex:index]; |
| + NSError *error; |
| + if (![device open:&error]) { |
| + DLOG(ERROR) << "Could not open video capture device."; |
| + return NO; |
| + } |
| + captureDeviceInput_ = [[QTCaptureDeviceInput alloc] initWithDevice:device]; |
| + captureSession_ = [[QTCaptureSession alloc] init]; |
| + |
| + QTCaptureDecompressedVideoOutput *captureDecompressedOutput = |
| + [[[QTCaptureDecompressedVideoOutput alloc] init] autorelease]; |
| + [captureDecompressedOutput setDelegate:self]; |
| + if (![captureSession_ addOutput:captureDecompressedOutput error:&error]) { |
| + DLOG(ERROR) << "Could not connect video capture output."; |
| + return NO; |
| + } |
| + return YES; |
| + } else { |
| + // Remove the previously set capture device. |
| + if (!captureDeviceInput_) { |
| + DLOG(ERROR) << "No video capture device set."; |
| + return YES; |
| + } |
| + if ([[captureSession_ inputs] count] > 0) { |
| + // The device is still running. |
| + [self stopCapture]; |
| + } |
| + [captureSession_ release]; |
| + captureSession_ = nil; |
| + [captureDeviceInput_ release]; |
| + captureDeviceInput_ = nil; |
| + return YES; |
| + } |
| +} |
| + |
| +- (BOOL)setCaptureHeight:(int)height width:(int)width frameRate:(int)frameRate { |
| + if (!captureDeviceInput_) { |
| + DLOG(ERROR) << "No video capture device set."; |
| + return NO; |
| + } |
| + if ([[captureSession_ outputs] count] != 1) { |
| + DLOG(ERROR) << "Video capture capabilities already set."; |
| + 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]; |
| + [[[captureSession_ outputs] objectAtIndex:0] |
| + setPixelBufferAttributes:captureDictionary]; |
| + return YES; |
| +} |
| + |
| +- (BOOL)startCapture { |
| + if ([[captureSession_ outputs] count] == 0) { |
| + // Capture properties not set. |
| + DLOG(ERROR) << "Video capture device not initialized."; |
| + return NO; |
| + } |
| + if ([[captureSession_ inputs] count] == 0) { |
| + NSError *error; |
| + if (![captureSession_ addInput:captureDeviceInput_ error:&error]) { |
| + DLOG(ERROR) << "Could not connect video capture device."; |
|
dmac
2011/10/14 23:31:35
worth logging the error as well? [[error localized
mflodman_chromium_OOO
2011/10/16 21:58:38
Done, here and two other places.
|
| + return NO; |
| + } |
| + [captureSession_ startRunning]; |
| + } |
| + return YES; |
| +} |
| + |
| +- (void)stopCapture { |
| + if ([[captureSession_ inputs] count] == 1) { |
| + [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 { |
| + |
|
dmac
2011/10/14 23:31:35
get rid of blank line
mflodman_chromium_OOO
2011/10/16 21:58:38
Done.
|
| + if(!frameReceiver_) { |
| + return; |
| + } |
| + |
| + // Lock the frame and calculate frame size. |
| + const int LOCK_FLAGS = 0; |
|
dmac
2011/10/14 23:31:35
we tend to use kLockFlags for constants
mflodman_chromium_OOO
2011/10/16 21:58:38
Done.
|
| + if (CVPixelBufferLockBaseAddress(videoFrame, LOCK_FLAGS) |
| + == kCVReturnSuccess) { |
| + void *baseAddress = CVPixelBufferGetBaseAddress(videoFrame); |
| + size_t bytesPerRow = CVPixelBufferGetBytesPerRow(videoFrame); |
| + int frameHeight = CVPixelBufferGetHeight(videoFrame); |
| + int frameSize = bytesPerRow * frameHeight; |
| + media::VideoCaptureDevice::Capability captureCapability; |
| + captureCapability.width = frameWidth_; |
| + captureCapability.height = frameHeight_; |
| + captureCapability.frame_rate = frameRate_; |
| + captureCapability.color = media::VideoCaptureDevice::kARGB; |
| + |
| + // Deliver the captured video frame. |
| + frameReceiver_->ReceiveFrame((UInt8 *)baseAddress, frameSize, |
|
dmac
2011/10/14 23:31:35
static_cast<UInt8*>
mflodman_chromium_OOO
2011/10/16 21:58:38
Done.
|
| + captureCapability); |
| + |
| + CVPixelBufferUnlockBaseAddress(videoFrame, LOCK_FLAGS); |
| + } |
| +} |
| + |
| +@end |