diff options
Diffstat (limited to 'media')
-rw-r--r-- | media/media.gyp | 2 | ||||
-rw-r--r-- | media/video/capture/mac/avfoundation_glue.h | 65 | ||||
-rw-r--r-- | media/video/capture/mac/avfoundation_glue.mm | 89 |
3 files changed, 156 insertions, 0 deletions
diff --git a/media/media.gyp b/media/media.gyp index dfcc858..17882b3 100644 --- a/media/media.gyp +++ b/media/media.gyp @@ -393,6 +393,8 @@ 'video/capture/fake_video_capture_device.h', 'video/capture/linux/video_capture_device_linux.cc', 'video/capture/linux/video_capture_device_linux.h', + 'video/capture/mac/avfoundation_glue.h', + 'video/capture/mac/avfoundation_glue.mm', 'video/capture/mac/video_capture_device_mac.h', 'video/capture/mac/video_capture_device_mac.mm', 'video/capture/mac/video_capture_device_qtkit_mac.h', diff --git a/media/video/capture/mac/avfoundation_glue.h b/media/video/capture/mac/avfoundation_glue.h new file mode 100644 index 0000000..e835c64 --- /dev/null +++ b/media/video/capture/mac/avfoundation_glue.h @@ -0,0 +1,65 @@ +// Copyright 2013 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. + +// AVFoundation API is only introduced in Mac OS X > 10.6, and there is only one +// build of Chromium, so the (potential) linking with AVFoundation has to happen +// in runtime. For this to be clean, a AVFoundationGlue class is defined to try +// and load these AVFoundation system libraries. If it succeeds, subsequent +// clients can use AVFoundation via the rest of the classes declared in this +// file. + +#ifndef MEDIA_VIDEO_CAPTURE_MAC_AVFOUNDATION_GLUE_H_ +#define MEDIA_VIDEO_CAPTURE_MAC_AVFOUNDATION_GLUE_H_ + +#import <Foundation/Foundation.h> + +#include "base/basictypes.h" +#include "media/base/media_export.h" + +class MEDIA_EXPORT AVFoundationGlue { + public: + // This method returns true if the OS version supports AVFoundation and the + // AVFoundation bundle could be loaded correctly, or false otherwise. + static bool IsAVFoundationSupported(); + + static NSBundle const* AVFoundationBundle(); + + static void* AVFoundationLibraryHandle(); + + // Originally coming from AVCaptureDevice.h but in global namespace. + static NSString* AVCaptureDeviceWasConnectedNotification(); + static NSString* AVCaptureDeviceWasDisconnectedNotification(); + + // Originally coming from AVMediaFormat.h but in global namespace. + static NSString* AVMediaTypeVideo(); + static NSString* AVMediaTypeAudio(); + static NSString* AVMediaTypeMuxed(); + + private: + static NSString* ReadNSStringPtr(const char* symbol); + + DISALLOW_IMPLICIT_CONSTRUCTORS(AVFoundationGlue); +}; + +// Originally AVCaptureDevice and coming from AVCaptureDevice.h +@interface CrAVCaptureDevice : NSObject + +- (BOOL)hasMediaType:(NSString*)mediaType; + +- (NSString*)uniqueID; + +@end + +@interface AVCaptureDeviceGlue : NSObject + ++ (NSArray*)devices; + ++ (BOOL)hasMediaType:(NSString*)mediaType + forCaptureDevice:(CrAVCaptureDevice*)device; + ++ (NSString*)uniqueID:(CrAVCaptureDevice*)device; + +@end + +#endif // MEDIA_VIDEO_CAPTURE_MAC_AVFOUNDATION_GLUE_H_ diff --git a/media/video/capture/mac/avfoundation_glue.mm b/media/video/capture/mac/avfoundation_glue.mm new file mode 100644 index 0000000..65e3dc3 --- /dev/null +++ b/media/video/capture/mac/avfoundation_glue.mm @@ -0,0 +1,89 @@ +// Copyright 2013 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/avfoundation_glue.h" + +#include <dlfcn.h> + +#include "base/mac/mac_util.h" + +bool AVFoundationGlue::IsAVFoundationSupported() { + return (base::mac::IsOSLionOrLater() && [AVFoundationBundle() load]); +} + +NSBundle const* AVFoundationGlue::AVFoundationBundle() { + static NSBundle* bundle = [NSBundle + bundleWithPath:@"/System/Library/Frameworks/AVFoundation.framework"]; + return bundle; +} + +void* AVFoundationGlue::AVFoundationLibraryHandle() { + const char* library_path = + [[AVFoundationBundle() executablePath] fileSystemRepresentation]; + if (library_path == NULL) { + DCHECK(false); + return NULL; + } + static void* library_handle = dlopen(library_path, RTLD_LAZY | RTLD_LOCAL); + DCHECK(library_handle) << dlerror(); + return library_handle; +} + +NSString* AVFoundationGlue::AVCaptureDeviceWasConnectedNotification() { + return ReadNSStringPtr("AVCaptureDeviceWasConnectedNotification"); +} + +NSString* AVFoundationGlue::AVCaptureDeviceWasDisconnectedNotification() { + return ReadNSStringPtr("AVCaptureDeviceWasDisconnectedNotification"); +} + +NSString* AVFoundationGlue::AVMediaTypeVideo() { + return ReadNSStringPtr("AVMediaTypeVideo"); +} + +NSString* AVFoundationGlue::AVMediaTypeAudio() { + return ReadNSStringPtr("AVMediaTypeAudio"); +} + +NSString* AVFoundationGlue::AVMediaTypeMuxed() { + return ReadNSStringPtr("AVMediaTypeMuxed"); +} + +NSString* AVFoundationGlue::ReadNSStringPtr(const char* symbol) { + NSString** string_pointer = reinterpret_cast<NSString**>( + dlsym(AVFoundationLibraryHandle(), symbol)); + DCHECK(string_pointer) << dlerror(); + return *string_pointer; +} + +@implementation AVCaptureDeviceGlue + ++ (NSArray*)devices { + Class avcClass = + [AVFoundationGlue::AVFoundationBundle() classNamed:@"AVCaptureDevice"]; + SEL selectorDevices = NSSelectorFromString(@"devices"); + if ([avcClass respondsToSelector:selectorDevices]) { + return [avcClass performSelector:selectorDevices]; + } + return nil; +} + ++ (BOOL)hasMediaType:(NSString*)mediaType + forCaptureDevice:(CrAVCaptureDevice*)device { + SEL selectorHasMediaType = NSSelectorFromString(@"hasMediaType:"); + if ([device respondsToSelector:selectorHasMediaType]) { + return [device hasMediaType:mediaType]; + } + return NO; +} + ++ (NSString*)uniqueID:(CrAVCaptureDevice*)device { + SEL selectorUniqueID = NSSelectorFromString(@"uniqueID"); + if ([device respondsToSelector:selectorUniqueID]) { + return [device uniqueID]; + } + return nil; +} + +@end // @implementation AVCaptureDevice |