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/time/time.h" 22 #include "media/base/media_export.h" 23 #include "media/base/video_frame.h" 24 #include "media/video/capture/video_capture_types.h" 25 26 namespace media { 27 28 class MEDIA_EXPORT VideoCaptureDevice { 29 public: 30 // Represents a capture device name and ID. 31 // You should not create an instance of this class directly by e.g. setting 32 // various properties directly. Instead use 33 // VideoCaptureDevice::GetDeviceNames to do this for you and if you need to 34 // cache your own copy of a name, you can do so via the copy constructor. 35 // The reason for this is that a device name might contain platform specific 36 // settings that are relevant only to the platform specific implementation of 37 // VideoCaptureDevice::Create. 38 class MEDIA_EXPORT Name { 39 public: 40 Name() {} 41 Name(const std::string& name, const std::string& id) 42 : device_name_(name), unique_id_(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 API_TYPE_UNKNOWN 50 }; 51 52 Name(const std::string& name, 53 const std::string& id, 54 const CaptureApiType api_type) 55 : device_name_(name), unique_id_(id), capture_api_class_(api_type) {} 56 #endif // if defined(OS_WIN) 57 ~Name() {} 58 59 // Friendly name of a device 60 const std::string& name() const { return device_name_; } 61 62 // Unique name of a device. Even if there are multiple devices with the same 63 // friendly name connected to the computer this will be unique. 64 const std::string& id() const { return unique_id_; } 65 66 // The unique hardware model identifier of the capture device. Returns 67 // "[vid]:[pid]" when a USB device is detected, otherwise "". 68 // The implementation of this method is platform-dependent. 69 const std::string GetModel() const; 70 71 // Friendly name of a device, plus the model identifier in parentheses. 72 const std::string GetNameAndModel() const; 73 74 // These operators are needed due to storing the name in an STL container. 75 // In the shared build, all methods from the STL container will be exported 76 // so even though they're not used, they're still depended upon. 77 bool operator==(const Name& other) const { 78 return other.id() == unique_id_; 79 } 80 bool operator<(const Name& other) const { 81 return unique_id_ < other.id(); 82 } 83 84 #if defined(OS_WIN) 85 CaptureApiType capture_api_type() const { 86 return capture_api_class_.capture_api_type(); 87 } 88 #endif // if defined(OS_WIN) 89 90 private: 91 std::string device_name_; 92 std::string unique_id_; 93 #if defined(OS_WIN) 94 // This class wraps the CaptureApiType, so it has a by default value if not 95 // inititalized, and I (mcasas) do a DCHECK on reading its value. 96 class CaptureApiClass { 97 public: 98 CaptureApiClass(): capture_api_type_(API_TYPE_UNKNOWN) {} 99 CaptureApiClass(const CaptureApiType api_type) 100 : capture_api_type_(api_type) {} 101 CaptureApiType capture_api_type() const { 102 DCHECK_NE(capture_api_type_, API_TYPE_UNKNOWN); 103 return capture_api_type_; 104 } 105 private: 106 CaptureApiType capture_api_type_; 107 }; 108 109 CaptureApiClass capture_api_class_; 110 #endif // if defined(OS_WIN) 111 // Allow generated copy constructor and assignment. 112 }; 113 114 // Manages a list of Name entries. 115 typedef std::list<Name> Names; 116 117 class MEDIA_EXPORT Client { 118 public: 119 // Memory buffer returned by Client::ReserveOutputBuffer(). 120 class Buffer : public base::RefCountedThreadSafe<Buffer> { 121 public: 122 int id() const { return id_; } 123 void* data() const { return data_; } 124 size_t size() const { return size_; } 125 126 protected: 127 friend class base::RefCountedThreadSafe<Buffer>; 128 129 Buffer(int id, void* data, size_t size) 130 : id_(id), data_(data), size_(size) {} 131 virtual ~Buffer() {} 132 133 const int id_; 134 void* const data_; 135 const size_t size_; 136 }; 137 138 virtual ~Client() {} 139 140 // Reserve an output buffer into which contents can be captured directly. 141 // The returned Buffer will always be allocated with a memory size suitable 142 // for holding a packed video frame of |format| format, of |dimensions| 143 // dimensions. It is permissible for |dimensions| to be zero; in which 144 // case the returned Buffer does not guarantee memory backing, but functions 145 // as a reservation for external input for the purposes of buffer 146 // throttling. 147 // 148 // The output buffer stays reserved for use until the Buffer object is 149 // destroyed. 150 virtual scoped_refptr<Buffer> ReserveOutputBuffer( 151 media::VideoFrame::Format format, 152 const gfx::Size& dimensions) = 0; 153 154 // Captured a new video frame as a raw buffer. The size, color format, and 155 // layout are taken from the parameters specified by an earlier call to 156 // OnFrameInfo(). |data| must be packed, with no padding between rows and/or 157 // color planes. 158 // 159 // This method will try to reserve an output buffer and copy from |data| 160 // into the output buffer. If no output buffer is available, the frame will 161 // be silently dropped. 162 virtual void OnIncomingCapturedFrame( 163 const uint8* data, 164 int length, 165 base::Time timestamp, 166 int rotation, // Clockwise. 167 const VideoCaptureFormat& frame_format) = 0; 168 169 // Captured a new video frame, held in |buffer|. 170 // 171 // As the frame is backed by a reservation returned by 172 // ReserveOutputBuffer(), delivery is guaranteed and will require no 173 // additional copies in the browser process. |dimensions| indicates the 174 // frame width and height of the buffer contents; this is assumed to be of 175 // |format| format and tightly packed. 176 virtual void OnIncomingCapturedBuffer(const scoped_refptr<Buffer>& buffer, 177 media::VideoFrame::Format format, 178 const gfx::Size& dimensions, 179 base::Time timestamp, 180 int frame_rate) = 0; 181 182 // An error has occurred that cannot be handled and VideoCaptureDevice must 183 // be StopAndDeAllocate()-ed. 184 virtual void OnError() = 0; 185 }; 186 187 // Creates a VideoCaptureDevice object. 188 // Return NULL if the hardware is not available. 189 static VideoCaptureDevice* Create(const Name& device_name); 190 virtual ~VideoCaptureDevice(); 191 192 // Gets the names of all video capture devices connected to this computer. 193 static void GetDeviceNames(Names* device_names); 194 195 // Gets the supported formats of a particular device attached to the system. 196 // This method should be called before allocating or starting a device. In 197 // case format enumeration is not supported, or there was a problem, the 198 // formats array will be empty. 199 static void GetDeviceSupportedFormats(const Name& device, 200 VideoCaptureFormats* supported_formats); 201 202 // Prepares the camera for use. After this function has been called no other 203 // applications can use the camera. StopAndDeAllocate() must be called before 204 // the object is deleted. 205 virtual void AllocateAndStart(const VideoCaptureParams& params, 206 scoped_ptr<Client> client) = 0; 207 208 // Deallocates the camera, possibly asynchronously. 209 // 210 // This call requires the device to do the following things, eventually: put 211 // camera hardware into a state where other applications could use it, free 212 // the memory associated with capture, and delete the |client| pointer passed 213 // into AllocateAndStart. 214 // 215 // If deallocation is done asynchronously, then the device implementation must 216 // ensure that a subsequent AllocateAndStart() operation targeting the same ID 217 // would be sequenced through the same task runner, so that deallocation 218 // happens first. 219 virtual void StopAndDeAllocate() = 0; 220 }; 221 222 } // namespace media 223 224 #endif // MEDIA_VIDEO_CAPTURE_VIDEO_CAPTURE_DEVICE_H_ 225