15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 51e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)// MacOSX implementation of generic VideoCaptureDevice, using either QTKit or 6cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// AVFoundation as native capture API. QTKit is available in all OSX versions, 7cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// although namely deprecated in 10.9, and AVFoundation is available in versions 8cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// 10.7 (Lion) and later. 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef MEDIA_VIDEO_CAPTURE_MAC_VIDEO_CAPTURE_DEVICE_MAC_H_ 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define MEDIA_VIDEO_CAPTURE_MAC_VIDEO_CAPTURE_DEVICE_MAC_H_ 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#import <Foundation/Foundation.h> 14116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string> 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/compiler_specific.h" 18116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "base/mac/scoped_nsobject.h" 193551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "base/memory/ref_counted.h" 203551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "base/memory/weak_ptr.h" 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "media/video/capture/video_capture_device.h" 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "media/video/capture/video_capture_types.h" 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 241e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)@protocol PlatformVideoCapturingMac; 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)namespace base { 275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)class SingleThreadTaskRunner; 285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 30116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// Small class to bundle device name and connection type into a dictionary. 31116680a4aac90f2aa7413d9095a592090648e557Ben MurdochMEDIA_EXPORT 32116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch@interface DeviceNameAndTransportType : NSObject { 33116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch @private 34116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch base::scoped_nsobject<NSString> deviceName_; 35116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // The transport type of the device (USB, PCI, etc), values are defined in 36116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // <IOKit/audio/IOAudioTypes.h> as kIOAudioDeviceTransportType*. 37116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch int32_t transportType_; 38116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch} 39116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 40116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch- (id)initWithName:(NSString*)name transportType:(int32_t)transportType; 41116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 42116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch- (NSString*)deviceName; 43116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch- (int32_t)transportType; 44116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch@end 45116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace media { 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 48116680a4aac90f2aa7413d9095a592090648e557Ben Murdochenum { 49116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // Unknown transport type, addition to the kIOAudioDeviceTransportType* 50116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // family for QTKit devices where this attribute isn't published. 51116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch kIOAudioDeviceTransportTypeUnknown = 'unkn' 52116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}; 53116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 54cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// Called by VideoCaptureManager to open, close and start, stop Mac video 55cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// capture devices. 564e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)class VideoCaptureDeviceMac : public VideoCaptureDevice { 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) explicit VideoCaptureDeviceMac(const Name& device_name); 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual ~VideoCaptureDeviceMac(); 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // VideoCaptureDevice implementation. 62cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) virtual void AllocateAndStart( 63cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) const VideoCaptureParams& params, 64cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) scoped_ptr<VideoCaptureDevice::Client> client) OVERRIDE; 654e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) virtual void StopAndDeAllocate() OVERRIDE; 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 67cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) bool Init(VideoCaptureDevice::Name::CaptureApiType capture_api_type); 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Called to deliver captured video frames. 7068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) void ReceiveFrame(const uint8* video_frame, 7168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) int video_frame_length, 72f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) const VideoCaptureFormat& frame_format, 7368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) int aspect_numerator, 7468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) int aspect_denominator); 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // Forwarder to VideoCaptureDevice::Client::OnError(). 773551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) void ReceiveError(const std::string& reason); 783551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 7903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // Forwarder to VideoCaptureDevice::Client::OnLog(). 8003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) void LogMessage(const std::string& message); 8103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void SetErrorState(const std::string& reason); 8468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) bool UpdateCaptureResolution(); 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Flag indicating the internal state. 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) enum InternalState { 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) kNotInitialized, 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) kIdle, 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) kCapturing, 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) kError 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 94eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch Name device_name_; 954e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) scoped_ptr<VideoCaptureDevice::Client> client_; 9668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 97f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) VideoCaptureFormat capture_format_; 9823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) // These variables control the two-step configure-start process for QTKit HD: 9923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) // the device is first started with no configuration and the captured frames 10023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) // are inspected to check if the camera really supports HD. AVFoundation does 10123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) // not need this process so |final_resolution_selected_| is false then. 10223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) bool final_resolution_selected_; 1030f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) bool tried_to_square_pixels_; 1043551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 1053551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // Only read and write state_ from inside this loop. 1065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const scoped_refptr<base::SingleThreadTaskRunner> task_runner_; 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) InternalState state_; 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1091e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) id<PlatformVideoCapturingMac> capture_device_; 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) // Used with Bind and PostTask to ensure that methods aren't called after the 11223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) // VideoCaptureDeviceMac is destroyed. 11323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) // NOTE: Weak pointers must be invalidated before all other member variables. 11423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) base::WeakPtrFactory<VideoCaptureDeviceMac> weak_factory_; 11523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(VideoCaptureDeviceMac); 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace media 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif // MEDIA_VIDEO_CAPTURE_MAC_VIDEO_CAPTURE_DEVICE_MAC_H_ 122