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

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

Issue 1815983003: Remove deprecated QTKit Video Capture Support (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Rebased Created 4 years, 9 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/capture/video/mac/video_capture_device_qtkit_mac.mm
diff --git a/media/capture/video/mac/video_capture_device_qtkit_mac.mm b/media/capture/video/mac/video_capture_device_qtkit_mac.mm
deleted file mode 100644
index 847c61acdf2e4cb9ea11870a2fdf30b8a7656135..0000000000000000000000000000000000000000
--- a/media/capture/video/mac/video_capture_device_qtkit_mac.mm
+++ /dev/null
@@ -1,372 +0,0 @@
-// Copyright (c) 2012 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/capture/video/mac/video_capture_device_qtkit_mac.h"
-
-#import <QTKit/QTKit.h>
-#include <stddef.h>
-
-#include "base/debug/crash_logging.h"
-#include "base/location.h"
-#include "base/logging.h"
-#include "media/base/timestamp_constants.h"
-#include "media/base/video_capture_types.h"
-#include "media/capture/video/mac/video_capture_device_mac.h"
-#include "media/capture/video/video_capture_device.h"
-#include "ui/gfx/geometry/size.h"
-
-@implementation VideoCaptureDeviceQTKit
-
-#pragma mark Class methods
-
-+ (void)getDeviceNames:(NSMutableDictionary*)deviceNames {
- // Third-party drivers often throw exceptions. The following catches any
- // exceptions and continues in an orderly fashion with no devices detected.
- NSArray* captureDevices = nil;
- @try {
- captureDevices =
- [QTCaptureDevice inputDevicesWithMediaType:QTMediaTypeVideo];
- } @catch (id exception) {
- }
-
- for (QTCaptureDevice* device in captureDevices) {
- if ([[device attributeForKey:QTCaptureDeviceSuspendedAttribute] boolValue])
- continue;
- DeviceNameAndTransportType* nameAndTransportType = [[
- [DeviceNameAndTransportType alloc]
- initWithName:[device localizedDisplayName]
- transportType:media::kIOAudioDeviceTransportTypeUnknown] autorelease];
- [deviceNames setObject:nameAndTransportType forKey:[device uniqueID]];
- }
-}
-
-+ (NSDictionary*)deviceNames {
- NSMutableDictionary* deviceNames =
- [[[NSMutableDictionary alloc] init] autorelease];
-
- // TODO(shess): Post to the main thread to see if that helps
- // http://crbug.com/139164
- [self performSelectorOnMainThread:@selector(getDeviceNames:)
- withObject:deviceNames
- waitUntilDone:YES];
- return deviceNames;
-}
-
-#pragma mark Public methods
-
-- (id)initWithFrameReceiver:(media::VideoCaptureDeviceMac*)frameReceiver {
- self = [super init];
- if (self) {
- frameReceiver_ = frameReceiver;
- lock_ = [[NSLock alloc] init];
- }
- return self;
-}
-
-- (void)dealloc {
- [captureSession_ release];
- [captureDeviceInput_ release];
- [super dealloc];
-}
-
-- (void)setFrameReceiver:(media::VideoCaptureDeviceMac*)frameReceiver {
- [lock_ lock];
- frameReceiver_ = frameReceiver;
- [lock_ unlock];
-}
-
-- (BOOL)setCaptureDevice:(NSString*)deviceId {
- if (deviceId) {
- // Set the capture device.
- if (captureDeviceInput_) {
- DLOG(ERROR) << "Video capture device already set.";
- return NO;
- }
-
- // TODO(mcasas): Consider using [QTCaptureDevice deviceWithUniqueID] instead
- // of explicitly forcing reenumeration of devices.
- NSArray* captureDevices =
- [QTCaptureDevice inputDevicesWithMediaType:QTMediaTypeVideo];
- NSArray* captureDevicesNames = [captureDevices valueForKey:@"uniqueID"];
- NSUInteger index = [captureDevicesNames indexOfObject:deviceId];
- if (index == NSNotFound) {
- [self sendErrorString:[NSString stringWithUTF8String:
- "Video capture device not found."]];
- return NO;
- }
- QTCaptureDevice* device = [captureDevices objectAtIndex:index];
- if ([[device
- attributeForKey:QTCaptureDeviceSuspendedAttribute] boolValue]) {
- [self sendErrorString:
- [NSString stringWithUTF8String:
- "Cannot open suspended video capture device."]];
- return NO;
- }
- NSError* error;
- if (![device open:&error]) {
- [self sendErrorString:
- [NSString stringWithFormat:
- @"Could not open video capture device (%@): %@",
- [error localizedDescription],
- [error localizedFailureReason]]];
- return NO;
- }
- captureDeviceInput_ = [[QTCaptureDeviceInput alloc] initWithDevice:device];
- captureSession_ = [[QTCaptureSession alloc] init];
-
- QTCaptureDecompressedVideoOutput* captureDecompressedOutput =
- [[[QTCaptureDecompressedVideoOutput alloc] init] autorelease];
- [captureDecompressedOutput setDelegate:self];
- [captureDecompressedOutput setAutomaticallyDropsLateVideoFrames:YES];
- if (![captureSession_ addOutput:captureDecompressedOutput error:&error]) {
- [self
- sendErrorString:
- [NSString stringWithFormat:
- @"Could not connect video capture output (%@): %@",
- [error localizedDescription],
- [error localizedFailureReason]]];
- return NO;
- }
-
- // This key can be used to check if video capture code was related to a
- // particular crash.
- base::debug::SetCrashKeyValue("VideoCaptureDeviceQTKit", "OpenedDevice");
-
- // Set the video pixel format to 2VUY (a.k.a UYVY, packed 4:2:2).
- NSDictionary* captureDictionary = [NSDictionary
- dictionaryWithObject:
- [NSNumber numberWithUnsignedInt:kCVPixelFormatType_422YpCbCr8]
- forKey:(id)kCVPixelBufferPixelFormatTypeKey];
- [captureDecompressedOutput setPixelBufferAttributes:captureDictionary];
-
- return YES;
- } else {
- // Remove the previously set capture device.
- if (!captureDeviceInput_) {
- // Being here means stopping a device that never started OK in the first
- // place, log it.
- [self sendLogString:[NSString
- stringWithUTF8String:
- "No video capture device set, on removal."]];
- return YES;
- }
- // Tear down input and output, stop the capture and deregister observers.
- [self stopCapture];
- [captureSession_ release];
- captureSession_ = nil;
- [captureDeviceInput_ release];
- captureDeviceInput_ = nil;
- return YES;
- }
-}
-
-- (BOOL)setCaptureHeight:(int)height
- width:(int)width
- frameRate:(float)frameRate {
- if (!captureDeviceInput_) {
- [self sendErrorString:
- [NSString stringWithUTF8String:"No video capture device set."]];
- return NO;
- }
- if ([[captureSession_ outputs] count] != 1) {
- [self sendErrorString:[NSString
- stringWithUTF8String:
- "Video capture capabilities already set."]];
- return NO;
- }
- if (frameRate <= 0.0f) {
- [self sendErrorString:[NSString stringWithUTF8String:"Wrong frame rate."]];
- return NO;
- }
-
- frameRate_ = frameRate;
-
- QTCaptureDecompressedVideoOutput* output =
- [[captureSession_ outputs] objectAtIndex:0];
-
- // Set up desired output properties. The old capture dictionary is used to
- // retrieve the initial pixel format, which must be maintained.
- NSDictionary* videoSettingsDictionary = @{
- (id)kCVPixelBufferWidthKey : @(width), (id)
- kCVPixelBufferHeightKey : @(height), (id)
- kCVPixelBufferPixelFormatTypeKey : [[output pixelBufferAttributes]
- valueForKey:(id)kCVPixelBufferPixelFormatTypeKey]
- };
- [output setPixelBufferAttributes:videoSettingsDictionary];
-
- [output setMinimumVideoFrameInterval:(NSTimeInterval)1 / frameRate];
- return YES;
-}
-
-- (BOOL)startCapture {
- if ([[captureSession_ outputs] count] == 0) {
- // Capture properties not set.
- [self
- sendErrorString:[NSString stringWithUTF8String:
- "Video capture device not initialized."]];
- return NO;
- }
- if ([[captureSession_ inputs] count] == 0) {
- NSError* error;
- if (![captureSession_ addInput:captureDeviceInput_ error:&error]) {
- [self
- sendErrorString:
- [NSString stringWithFormat:
- @"Could not connect video capture device (%@): %@",
- [error localizedDescription],
- [error localizedFailureReason]]];
-
- return NO;
- }
- NSNotificationCenter* notificationCenter =
- [NSNotificationCenter defaultCenter];
- [notificationCenter addObserver:self
- selector:@selector(handleNotification:)
- name:QTCaptureSessionRuntimeErrorNotification
- object:captureSession_];
- [captureSession_ startRunning];
- }
- return YES;
-}
-
-- (void)stopCapture {
- // QTKit achieves thread safety and asynchronous execution by posting messages
- // to the main thread, e.g. -addOutput:. Both -removeOutput: and -removeInput:
- // post a message to the main thread while holding a lock that the
- // notification handler might need. To avoid a deadlock, we perform those
- // tasks in the main thread. See bugs http://crbug.com/152757 and
- // http://crbug.com/399792.
- [self performSelectorOnMainThread:@selector(stopCaptureOnUIThread:)
- withObject:nil
- waitUntilDone:YES];
- [[NSNotificationCenter defaultCenter] removeObserver:self];
-}
-
-- (void)stopCaptureOnUIThread:(id)dummy {
- if ([[captureSession_ inputs] count] > 0) {
- DCHECK_EQ([[captureSession_ inputs] count], 1u);
- [captureSession_ removeInput:captureDeviceInput_];
- [captureSession_ stopRunning];
- }
- if ([[captureSession_ outputs] count] > 0) {
- DCHECK_EQ([[captureSession_ outputs] count], 1u);
- id output = [[captureSession_ outputs] objectAtIndex:0];
- [output setDelegate:nil];
- [captureSession_ removeOutput:output];
- }
-}
-
-// |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_ lock];
- if (!frameReceiver_) {
- [lock_ unlock];
- return;
- }
-
- // Lock the frame and calculate frame size.
- const int kLockFlags = 0;
- if (CVPixelBufferLockBaseAddress(videoFrame, kLockFlags) ==
- kCVReturnSuccess) {
- void* baseAddress = CVPixelBufferGetBaseAddress(videoFrame);
- size_t bytesPerRow = CVPixelBufferGetBytesPerRow(videoFrame);
- size_t frameWidth = CVPixelBufferGetWidth(videoFrame);
- size_t frameHeight = CVPixelBufferGetHeight(videoFrame);
- size_t frameSize = bytesPerRow * frameHeight;
-
- // TODO(shess): bytesPerRow may not correspond to frameWidth_*2,
- // but VideoCaptureController::OnIncomingCapturedData() requires
- // it to do so. Plumbing things through is intrusive, for now
- // just deliver an adjusted buffer.
- // TODO(nick): This workaround could probably be eliminated by using
- // VideoCaptureController::OnIncomingCapturedVideoFrame, which supports
- // pitches.
- UInt8* addressToPass = static_cast<UInt8*>(baseAddress);
- // UYVY is 2 bytes per pixel.
- size_t expectedBytesPerRow = frameWidth * 2;
- if (bytesPerRow > expectedBytesPerRow) {
- // TODO(shess): frameHeight and frameHeight_ are not the same,
- // try to do what the surrounding code seems to assume.
- // Ironically, captureCapability and frameSize are ignored
- // anyhow.
- adjustedFrame_.resize(expectedBytesPerRow * frameHeight);
- // std::vector is contiguous according to standard.
- UInt8* adjustedAddress = &adjustedFrame_[0];
-
- for (size_t y = 0; y < frameHeight; ++y) {
- memcpy(adjustedAddress + y * expectedBytesPerRow,
- addressToPass + y * bytesPerRow, expectedBytesPerRow);
- }
-
- addressToPass = adjustedAddress;
- frameSize = frameHeight * expectedBytesPerRow;
- }
-
- media::VideoCaptureFormat captureFormat(
- gfx::Size(frameWidth, frameHeight), frameRate_,
- media::PIXEL_FORMAT_UYVY);
-
- // The aspect ratio dictionary is often missing, in which case we report
- // a pixel aspect ratio of 0:0.
- int aspectNumerator = 0, aspectDenominator = 0;
- CFDictionaryRef aspectRatioDict = (CFDictionaryRef)CVBufferGetAttachment(
- videoFrame, kCVImageBufferPixelAspectRatioKey, NULL);
- if (aspectRatioDict) {
- CFNumberRef aspectNumeratorRef = (CFNumberRef)CFDictionaryGetValue(
- aspectRatioDict, kCVImageBufferPixelAspectRatioHorizontalSpacingKey);
- CFNumberRef aspectDenominatorRef = (CFNumberRef)CFDictionaryGetValue(
- aspectRatioDict, kCVImageBufferPixelAspectRatioVerticalSpacingKey);
- DCHECK(aspectNumeratorRef && aspectDenominatorRef)
- << "Aspect Ratio dictionary missing its entries.";
- CFNumberGetValue(aspectNumeratorRef, kCFNumberIntType, &aspectNumerator);
- CFNumberGetValue(aspectDenominatorRef, kCFNumberIntType,
- &aspectDenominator);
- }
-
- // Deliver the captured video frame.
- const QTTime qt_timestamp = [sampleBuffer presentationTime];
- base::TimeDelta timestamp;
- if (!(qt_timestamp.flags & kQTTimeIsIndefinite) && qt_timestamp.timeScale) {
- timestamp = base::TimeDelta::FromMicroseconds(
- qt_timestamp.timeValue * base::TimeTicks::kMicrosecondsPerSecond /
- qt_timestamp.timeScale);
- } else {
- timestamp = media::kNoTimestamp();
- }
- frameReceiver_->ReceiveFrame(addressToPass, frameSize, captureFormat,
- aspectNumerator, aspectDenominator, timestamp);
-
- CVPixelBufferUnlockBaseAddress(videoFrame, kLockFlags);
- }
- [lock_ unlock];
-}
-
-- (void)handleNotification:(NSNotification*)errorNotification {
- NSError* error = (NSError*)
- [[errorNotification userInfo] objectForKey:QTCaptureSessionErrorKey];
- [self sendErrorString:
- [NSString stringWithFormat:@"%@: %@", [error localizedDescription],
- [error localizedFailureReason]]];
-}
-
-- (void)sendErrorString:(NSString*)error {
- DLOG(ERROR) << [error UTF8String];
- [lock_ lock];
- if (frameReceiver_)
- frameReceiver_->ReceiveError(FROM_HERE, [error UTF8String]);
- [lock_ unlock];
-}
-
-- (void)sendLogString:(NSString*)message {
- DVLOG(1) << [message UTF8String];
- [lock_ lock];
- if (frameReceiver_)
- frameReceiver_->LogMessage([message UTF8String]);
- [lock_ unlock];
-}
-
-@end
« no previous file with comments | « media/capture/video/mac/video_capture_device_qtkit_mac.h ('k') | media/capture/video/video_capture_device.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698