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
26namespace base {
27class SingleThreadTaskRunner;
28}
29
30// Small class to bundle device name and connection type into a dictionary.
31MEDIA_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
46namespace media {
47
48enum {
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.
56class 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