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 // VideoCaptureDevice is the abstract base class for realizing video capture 6 // device support in Chromium. It provides the interface for OS dependent 7 // implementations. 8 // The class is created and functions are invoked on a thread owned by 9 // VideoCaptureManager. Capturing is done on other threads, depending on the OS 10 // specific implementation. 11 12 #ifndef MEDIA_VIDEO_CAPTURE_VIDEO_CAPTURE_DEVICE_H_ 13 #define MEDIA_VIDEO_CAPTURE_VIDEO_CAPTURE_DEVICE_H_ 14 15 #include <list> 16 #include <string> 17 18 #include "base/logging.h" 19 #include "base/memory/ref_counted.h" 20 #include "base/memory/scoped_ptr.h" 21 #include "base/single_thread_task_runner.h" 22 #include "base/time/time.h" 23 #include "media/base/media_export.h" 24 #include "media/base/video_frame.h" 25 #include "media/video/capture/video_capture_types.h" 26 27 namespace media { 28 29 class MEDIA_EXPORT VideoCaptureDevice { 30 public: 31 // Represents a capture device name and ID. 32 // You should not create an instance of this class directly by e.g. setting 33 // various properties directly. Instead use 34 // VideoCaptureDevice::GetDeviceNames to do this for you and if you need to 35 // cache your own copy of a name, you can do so via the copy constructor. 36 // The reason for this is that a device name might contain platform specific 37 // settings that are relevant only to the platform specific implementation of 38 // VideoCaptureDevice::Create. 39 class MEDIA_EXPORT Name { 40 public: 41 Name(); 42 Name(const std::string& name, const std::string& id); 43 44 #if defined(OS_WIN) 45 // Windows targets Capture Api type: it can only be set on construction. 46 enum CaptureApiType { 47 MEDIA_FOUNDATION, 48 DIRECT_SHOW, 49 DIRECT_SHOW_WDM_CROSSBAR, 50 API_TYPE_UNKNOWN 51 }; 52 #endif 53 #if defined(OS_MACOSX) 54 // Mac targets Capture Api type: it can only be set on construction. 55 enum CaptureApiType { 56 AVFOUNDATION, 57 QTKIT, 58 DECKLINK, 59 API_TYPE_UNKNOWN 60 }; 61 // For AVFoundation Api, identify devices that are built-in or USB. 62 enum TransportType { 63 USB_OR_BUILT_IN, 64 OTHER_TRANSPORT 65 }; 66 #endif 67 #if defined(OS_WIN) || defined(OS_MACOSX) 68 Name(const std::string& name, 69 const std::string& id, 70 const CaptureApiType api_type); 71 #endif 72 #if defined(OS_MACOSX) 73 Name(const std::string& name, 74 const std::string& id, 75 const CaptureApiType api_type, 76 const TransportType transport_type); 77 #endif 78 ~Name(); 79 80 // Friendly name of a device 81 const std::string& name() const { return device_name_; } 82 83 // Unique name of a device. Even if there are multiple devices with the same 84 // friendly name connected to the computer this will be unique. 85 const std::string& id() const { return unique_id_; } 86 87 // The unique hardware model identifier of the capture device. Returns 88 // "[vid]:[pid]" when a USB device is detected, otherwise "". 89 // The implementation of this method is platform-dependent. 90 const std::string GetModel() const; 91 92 // Friendly name of a device, plus the model identifier in parentheses. 93 const std::string GetNameAndModel() const; 94 95 // These operators are needed due to storing the name in an STL container. 96 // In the shared build, all methods from the STL container will be exported 97 // so even though they're not used, they're still depended upon. 98 bool operator==(const Name& other) const { 99 return other.id() == unique_id_; 100 } 101 bool operator<(const Name& other) const { 102 return unique_id_ < other.id(); 103 } 104 105 #if defined(OS_WIN) || defined(OS_MACOSX) 106 CaptureApiType capture_api_type() const { 107 return capture_api_class_.capture_api_type(); 108 } 109 #endif 110 #if defined(OS_WIN) 111 // Certain devices need an ID different from the |unique_id_| for 112 // capabilities retrieval. 113 const std::string& capabilities_id() const { 114 return capabilities_id_; 115 } 116 void set_capabilities_id(const std::string& id) { 117 capabilities_id_ = id; 118 } 119 #endif 120 #if defined(OS_MACOSX) 121 TransportType transport_type() const { 122 return transport_type_; 123 } 124 bool is_blacklisted() const { 125 return is_blacklisted_; 126 } 127 void set_is_blacklisted(bool is_blacklisted) { 128 is_blacklisted_ = is_blacklisted; 129 } 130 #endif // if defined(OS_WIN) 131 132 private: 133 std::string device_name_; 134 std::string unique_id_; 135 #if defined(OS_WIN) || defined(OS_MACOSX) 136 // This class wraps the CaptureApiType to give it a by default value if not 137 // initialized. 138 class CaptureApiClass { 139 public: 140 CaptureApiClass(): capture_api_type_(API_TYPE_UNKNOWN) {} 141 CaptureApiClass(const CaptureApiType api_type) 142 : capture_api_type_(api_type) {} 143 CaptureApiType capture_api_type() const { 144 DCHECK_NE(capture_api_type_, API_TYPE_UNKNOWN); 145 return capture_api_type_; 146 } 147 private: 148 CaptureApiType capture_api_type_; 149 }; 150 151 CaptureApiClass capture_api_class_; 152 #endif 153 #if defined(OS_WIN) 154 // ID used for capabilities retrieval. By default is equal to |unique_id|. 155 std::string capabilities_id_; 156 #endif 157 #if defined(OS_MACOSX) 158 TransportType transport_type_; 159 // Flag used to mark blacklisted devices for QTKit Api. 160 bool is_blacklisted_; 161 #endif 162 // Allow generated copy constructor and assignment. 163 }; 164 165 // Manages a list of Name entries. 166 typedef std::list<Name> Names; 167 168 class MEDIA_EXPORT Client { 169 public: 170 // Memory buffer returned by Client::ReserveOutputBuffer(). 171 class Buffer : public base::RefCountedThreadSafe<Buffer> { 172 public: 173 int id() const { return id_; } 174 void* data() const { return data_; } 175 size_t size() const { return size_; } 176 177 protected: 178 friend class base::RefCountedThreadSafe<Buffer>; 179 180 Buffer(int id, void* data, size_t size) 181 : id_(id), data_(data), size_(size) {} 182 virtual ~Buffer() {} 183 184 const int id_; 185 void* const data_; 186 const size_t size_; 187 }; 188 189 virtual ~Client() {} 190 191 // Reserve an output buffer into which contents can be captured directly. 192 // The returned Buffer will always be allocated with a memory size suitable 193 // for holding a packed video frame with pixels of |format| format, of 194 // |dimensions| frame dimensions. It is permissible for |dimensions| to be 195 // zero; in which case the returned Buffer does not guarantee memory 196 // backing, but functions as a reservation for external input for the 197 // purposes of buffer throttling. 198 // 199 // The output buffer stays reserved for use until the Buffer object is 200 // destroyed. 201 virtual scoped_refptr<Buffer> ReserveOutputBuffer( 202 media::VideoFrame::Format format, 203 const gfx::Size& dimensions) = 0; 204 205 // Captured a new video frame, data for which is pointed to by |data|. 206 // 207 // The format of the frame is described by |frame_format|, and is assumed to 208 // be tightly packed. This method will try to reserve an output buffer and 209 // copy from |data| into the output buffer. If no output buffer is 210 // available, the frame will be silently dropped. 211 virtual void OnIncomingCapturedData(const uint8* data, 212 int length, 213 const VideoCaptureFormat& frame_format, 214 int rotation, // Clockwise. 215 base::TimeTicks timestamp) = 0; 216 217 // Captured a new video frame, held in |frame|. 218 // 219 // As the frame is backed by a reservation returned by 220 // ReserveOutputBuffer(), delivery is guaranteed and will require no 221 // additional copies in the browser process. 222 virtual void OnIncomingCapturedVideoFrame( 223 const scoped_refptr<Buffer>& buffer, 224 const VideoCaptureFormat& buffer_format, 225 const scoped_refptr<media::VideoFrame>& frame, 226 base::TimeTicks timestamp) = 0; 227 228 // An error has occurred that cannot be handled and VideoCaptureDevice must 229 // be StopAndDeAllocate()-ed. |reason| is a text description of the error. 230 virtual void OnError(const std::string& reason) = 0; 231 232 // VideoCaptureDevice requests the |message| to be logged. 233 virtual void OnLog(const std::string& message) {} 234 }; 235 236 virtual ~VideoCaptureDevice(); 237 238 // Prepares the camera for use. After this function has been called no other 239 // applications can use the camera. StopAndDeAllocate() must be called before 240 // the object is deleted. 241 virtual void AllocateAndStart(const VideoCaptureParams& params, 242 scoped_ptr<Client> client) = 0; 243 244 // Deallocates the camera, possibly asynchronously. 245 // 246 // This call requires the device to do the following things, eventually: put 247 // camera hardware into a state where other applications could use it, free 248 // the memory associated with capture, and delete the |client| pointer passed 249 // into AllocateAndStart. 250 // 251 // If deallocation is done asynchronously, then the device implementation must 252 // ensure that a subsequent AllocateAndStart() operation targeting the same ID 253 // would be sequenced through the same task runner, so that deallocation 254 // happens first. 255 virtual void StopAndDeAllocate() = 0; 256 257 // Gets the power line frequency from the current system time zone if this is 258 // defined, otherwise returns 0. 259 int GetPowerLineFrequencyForLocation() const; 260 261 protected: 262 static const int kPowerLine50Hz = 50; 263 static const int kPowerLine60Hz = 60; 264 }; 265 266 } // namespace media 267 268 #endif // MEDIA_VIDEO_CAPTURE_VIDEO_CAPTURE_DEVICE_H_ 269