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 : device_name_(name), unique_id_(id) {} 44 45 #if defined(OS_WIN) 46 // Windows targets Capture Api type: it can only be set on construction. 47 enum CaptureApiType { 48 MEDIA_FOUNDATION, 49 DIRECT_SHOW, 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 API_TYPE_UNKNOWN 59 }; 60 #endif 61 #if defined(OS_WIN) || defined(OS_MACOSX) 62 Name(const std::string& name, 63 const std::string& id, 64 const CaptureApiType api_type) 65 : device_name_(name), unique_id_(id), capture_api_class_(api_type) {} 66 #endif 67 ~Name() {} 68 69 // Friendly name of a device 70 const std::string& name() const { return device_name_; } 71 72 // Unique name of a device. Even if there are multiple devices with the same 73 // friendly name connected to the computer this will be unique. 74 const std::string& id() const { return unique_id_; } 75 76 // The unique hardware model identifier of the capture device. Returns 77 // "[vid]:[pid]" when a USB device is detected, otherwise "". 78 // The implementation of this method is platform-dependent. 79 const std::string GetModel() const; 80 81 // Friendly name of a device, plus the model identifier in parentheses. 82 const std::string GetNameAndModel() const; 83 84 // These operators are needed due to storing the name in an STL container. 85 // In the shared build, all methods from the STL container will be exported 86 // so even though they're not used, they're still depended upon. 87 bool operator==(const Name& other) const { 88 return other.id() == unique_id_; 89 } 90 bool operator<(const Name& other) const { 91 return unique_id_ < other.id(); 92 } 93 94 #if defined(OS_WIN) || defined(OS_MACOSX) 95 CaptureApiType capture_api_type() const { 96 return capture_api_class_.capture_api_type(); 97 } 98 #endif // if defined(OS_WIN) 99 100 private: 101 std::string device_name_; 102 std::string unique_id_; 103 #if defined(OS_WIN) || defined(OS_MACOSX) 104 // This class wraps the CaptureApiType to give it a by default value if not 105 // initialized. 106 class CaptureApiClass { 107 public: 108 CaptureApiClass(): capture_api_type_(API_TYPE_UNKNOWN) {} 109 CaptureApiClass(const CaptureApiType api_type) 110 : capture_api_type_(api_type) {} 111 CaptureApiType capture_api_type() const { 112 DCHECK_NE(capture_api_type_, API_TYPE_UNKNOWN); 113 return capture_api_type_; 114 } 115 private: 116 CaptureApiType capture_api_type_; 117 }; 118 119 CaptureApiClass capture_api_class_; 120 #endif 121 // Allow generated copy constructor and assignment. 122 }; 123 124 // Manages a list of Name entries. 125 typedef std::list<Name> Names; 126 127 class MEDIA_EXPORT Client { 128 public: 129 // Memory buffer returned by Client::ReserveOutputBuffer(). 130 class Buffer : public base::RefCountedThreadSafe<Buffer> { 131 public: 132 int id() const { return id_; } 133 void* data() const { return data_; } 134 size_t size() const { return size_; } 135 136 protected: 137 friend class base::RefCountedThreadSafe<Buffer>; 138 139 Buffer(int id, void* data, size_t size) 140 : id_(id), data_(data), size_(size) {} 141 virtual ~Buffer() {} 142 143 const int id_; 144 void* const data_; 145 const size_t size_; 146 }; 147 148 virtual ~Client() {} 149 150 // Reserve an output buffer into which contents can be captured directly. 151 // The returned Buffer will always be allocated with a memory size suitable 152 // for holding a packed video frame with pixels of |format| format, of 153 // |dimensions| frame dimensions. It is permissible for |dimensions| to be 154 // zero; in which case the returned Buffer does not guarantee memory 155 // backing, but functions as a reservation for external input for the 156 // purposes of buffer throttling. 157 // 158 // The output buffer stays reserved for use until the Buffer object is 159 // destroyed. 160 virtual scoped_refptr<Buffer> ReserveOutputBuffer( 161 media::VideoFrame::Format format, 162 const gfx::Size& dimensions) = 0; 163 164 // Captured a new video frame, data for which is pointed to by |data|. 165 // 166 // The format of the frame is described by |frame_format|, and is assumed to 167 // be tightly packed. This method will try to reserve an output buffer and 168 // copy from |data| into the output buffer. If no output buffer is 169 // available, the frame will be silently dropped. 170 virtual void OnIncomingCapturedData(const uint8* data, 171 int length, 172 const VideoCaptureFormat& frame_format, 173 int rotation, // Clockwise. 174 base::TimeTicks timestamp) = 0; 175 176 // Captured a new video frame, held in |frame|. 177 // 178 // As the frame is backed by a reservation returned by 179 // ReserveOutputBuffer(), delivery is guaranteed and will require no 180 // additional copies in the browser process. 181 virtual void OnIncomingCapturedVideoFrame( 182 const scoped_refptr<Buffer>& buffer, 183 const VideoCaptureFormat& buffer_format, 184 const scoped_refptr<media::VideoFrame>& frame, 185 base::TimeTicks timestamp) = 0; 186 187 // An error has occurred that cannot be handled and VideoCaptureDevice must 188 // be StopAndDeAllocate()-ed. |reason| is a text description of the error. 189 virtual void OnError(const std::string& reason) = 0; 190 191 // VideoCaptureDevice requests the |message| to be logged. 192 virtual void OnLog(const std::string& message) {} 193 }; 194 195 // Creates a VideoCaptureDevice object. 196 // Return NULL if the hardware is not available. 197 static VideoCaptureDevice* Create( 198 scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner, 199 const Name& device_name); 200 virtual ~VideoCaptureDevice(); 201 202 // Gets the names of all video capture devices connected to this computer. 203 static void GetDeviceNames(Names* device_names); 204 205 // Gets the supported formats of a particular device attached to the system. 206 // This method should be called before allocating or starting a device. In 207 // case format enumeration is not supported, or there was a problem, the 208 // formats array will be empty. 209 static void GetDeviceSupportedFormats(const Name& device, 210 VideoCaptureFormats* supported_formats); 211 212 // Prepares the camera for use. After this function has been called no other 213 // applications can use the camera. StopAndDeAllocate() must be called before 214 // the object is deleted. 215 virtual void AllocateAndStart(const VideoCaptureParams& params, 216 scoped_ptr<Client> client) = 0; 217 218 // Deallocates the camera, possibly asynchronously. 219 // 220 // This call requires the device to do the following things, eventually: put 221 // camera hardware into a state where other applications could use it, free 222 // the memory associated with capture, and delete the |client| pointer passed 223 // into AllocateAndStart. 224 // 225 // If deallocation is done asynchronously, then the device implementation must 226 // ensure that a subsequent AllocateAndStart() operation targeting the same ID 227 // would be sequenced through the same task runner, so that deallocation 228 // happens first. 229 virtual void StopAndDeAllocate() = 0; 230 231 // Gets the power line frequency from the current system time zone if this is 232 // defined, otherwise returns 0. 233 int GetPowerLineFrequencyForLocation() const; 234 235 protected: 236 static const int kPowerLine50Hz = 50; 237 static const int kPowerLine60Hz = 60; 238 }; 239 240 } // namespace media 241 242 #endif // MEDIA_VIDEO_CAPTURE_VIDEO_CAPTURE_DEVICE_H_ 243