Home | History | Annotate | Download | only in mac
      1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 // MacOSX implementation of generic VideoCaptureDevice, using either QTKit or
      6 // AVFoundation as native capture API. QTKit is available in all OSX versions,
      7 // although namely deprecated in 10.9, and AVFoundation is available in versions
      8 // 10.7 (Lion) and later.
      9 
     10 #ifndef MEDIA_VIDEO_CAPTURE_MAC_VIDEO_CAPTURE_DEVICE_MAC_H_
     11 #define MEDIA_VIDEO_CAPTURE_MAC_VIDEO_CAPTURE_DEVICE_MAC_H_
     12 
     13 #import <Foundation/Foundation.h>
     14 
     15 #include <string>
     16 
     17 #include "base/compiler_specific.h"
     18 #include "base/mac/scoped_nsobject.h"
     19 #include "base/memory/ref_counted.h"
     20 #include "base/memory/weak_ptr.h"
     21 #include "media/video/capture/video_capture_device.h"
     22 #include "media/video/capture/video_capture_types.h"
     23 
     24 @protocol PlatformVideoCapturingMac;
     25 
     26 namespace base {
     27 class SingleThreadTaskRunner;
     28 }
     29 
     30 // Small class to bundle device name and connection type into a dictionary.
     31 MEDIA_EXPORT
     32 @interface DeviceNameAndTransportType : NSObject {
     33  @private
     34   base::scoped_nsobject<NSString> deviceName_;
     35   // The transport type of the device (USB, PCI, etc), values are defined in
     36   // <IOKit/audio/IOAudioTypes.h> as kIOAudioDeviceTransportType*.
     37   int32_t transportType_;
     38 }
     39 
     40 - (id)initWithName:(NSString*)name transportType:(int32_t)transportType;
     41 
     42 - (NSString*)deviceName;
     43 - (int32_t)transportType;
     44 @end
     45 
     46 namespace media {
     47 
     48 enum {
     49   // Unknown transport type, addition to the kIOAudioDeviceTransportType*
     50   // family for QTKit devices where this attribute isn't published.
     51   kIOAudioDeviceTransportTypeUnknown = 'unkn'
     52 };
     53 
     54 // Called by VideoCaptureManager to open, close and start, stop Mac video
     55 // capture devices.
     56 class VideoCaptureDeviceMac : public VideoCaptureDevice {
     57  public:
     58   explicit VideoCaptureDeviceMac(const Name& device_name);
     59   virtual ~VideoCaptureDeviceMac();
     60 
     61   // VideoCaptureDevice implementation.
     62   virtual void AllocateAndStart(
     63       const VideoCaptureParams& params,
     64       scoped_ptr<VideoCaptureDevice::Client> client) OVERRIDE;
     65   virtual void StopAndDeAllocate() OVERRIDE;
     66 
     67   bool Init(VideoCaptureDevice::Name::CaptureApiType capture_api_type);
     68 
     69   // Called to deliver captured video frames.
     70   void ReceiveFrame(const uint8* video_frame,
     71                     int video_frame_length,
     72                     const VideoCaptureFormat& frame_format,
     73                     int aspect_numerator,
     74                     int aspect_denominator);
     75 
     76   // Forwarder to VideoCaptureDevice::Client::OnError().
     77   void ReceiveError(const std::string& reason);
     78 
     79   // Forwarder to VideoCaptureDevice::Client::OnLog().
     80   void LogMessage(const std::string& message);
     81 
     82  private:
     83   void SetErrorState(const std::string& reason);
     84   bool UpdateCaptureResolution();
     85 
     86   // Flag indicating the internal state.
     87   enum InternalState {
     88     kNotInitialized,
     89     kIdle,
     90     kCapturing,
     91     kError
     92   };
     93 
     94   Name device_name_;
     95   scoped_ptr<VideoCaptureDevice::Client> client_;
     96 
     97   VideoCaptureFormat capture_format_;
     98   // These variables control the two-step configure-start process for QTKit HD:
     99   // the device is first started with no configuration and the captured frames
    100   // are inspected to check if the camera really supports HD. AVFoundation does
    101   // not need this process so |final_resolution_selected_| is false then.
    102   bool final_resolution_selected_;
    103   bool tried_to_square_pixels_;
    104 
    105   // Only read and write state_ from inside this loop.
    106   const scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
    107   InternalState state_;
    108 
    109   id<PlatformVideoCapturingMac> capture_device_;
    110 
    111   // Used with Bind and PostTask to ensure that methods aren't called after the
    112   // VideoCaptureDeviceMac is destroyed.
    113   // NOTE: Weak pointers must be invalidated before all other member variables.
    114   base::WeakPtrFactory<VideoCaptureDeviceMac> weak_factory_;
    115 
    116   DISALLOW_COPY_AND_ASSIGN(VideoCaptureDeviceMac);
    117 };
    118 
    119 }  // namespace media
    120 
    121 #endif  // MEDIA_VIDEO_CAPTURE_MAC_VIDEO_CAPTURE_DEVICE_MAC_H_
    122