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/time/time.h" 20 #include "media/base/media_export.h" 21 #include "media/video/capture/video_capture_types.h" 22 23 namespace media { 24 25 class MEDIA_EXPORT VideoCaptureDevice { 26 public: 27 // Represents a capture device name and ID. 28 // You should not create an instance of this class directly by e.g. setting 29 // various properties directly. Instead use 30 // VideoCaptureDevice::GetDeviceNames to do this for you and if you need to 31 // cache your own copy of a name, you can do so via the copy constructor. 32 // The reason for this is that a device name might contain platform specific 33 // settings that are relevant only to the platform specific implementation of 34 // VideoCaptureDevice::Create. 35 class MEDIA_EXPORT Name { 36 public: 37 Name() {} 38 Name(const std::string& name, const std::string& id) 39 : device_name_(name), unique_id_(id) {} 40 41 #if defined(OS_WIN) 42 // Windows targets Capture Api type: it can only be set on construction. 43 enum CaptureApiType { 44 MEDIA_FOUNDATION, 45 DIRECT_SHOW, 46 API_TYPE_UNKNOWN 47 }; 48 49 Name(const std::string& name, 50 const std::string& id, 51 const CaptureApiType api_type) 52 : device_name_(name), unique_id_(id), capture_api_class_(api_type) {} 53 #endif // if defined(OS_WIN) 54 ~Name() {} 55 56 // Friendly name of a device 57 const std::string& name() const { return device_name_; } 58 59 // Unique name of a device. Even if there are multiple devices with the same 60 // friendly name connected to the computer this will be unique. 61 const std::string& id() const { return unique_id_; } 62 63 // The unique hardware model identifier of the capture device. Returns 64 // "[vid]:[pid]" when a USB device is detected, otherwise "". 65 // The implementation of this method is platform-dependent. 66 const std::string GetModel() const; 67 68 // Friendly name of a device, plus the model identifier in parentheses. 69 const std::string GetNameAndModel() const; 70 71 // These operators are needed due to storing the name in an STL container. 72 // In the shared build, all methods from the STL container will be exported 73 // so even though they're not used, they're still depended upon. 74 bool operator==(const Name& other) const { 75 return other.id() == unique_id_ && other.name() == device_name_; 76 } 77 bool operator<(const Name& other) const { 78 return unique_id_ < other.id(); 79 } 80 81 #if defined(OS_WIN) 82 CaptureApiType capture_api_type() const { 83 return capture_api_class_.capture_api_type(); 84 } 85 #endif // if defined(OS_WIN) 86 87 private: 88 std::string device_name_; 89 std::string unique_id_; 90 #if defined(OS_WIN) 91 // This class wraps the CaptureApiType, so it has a by default value if not 92 // inititalized, and I (mcasas) do a DCHECK on reading its value. 93 class CaptureApiClass{ 94 public: 95 CaptureApiClass(): capture_api_type_(API_TYPE_UNKNOWN) {} 96 CaptureApiClass(const CaptureApiType api_type) 97 : capture_api_type_(api_type) {} 98 CaptureApiType capture_api_type() const { 99 DCHECK_NE(capture_api_type_, API_TYPE_UNKNOWN); 100 return capture_api_type_; 101 } 102 private: 103 CaptureApiType capture_api_type_; 104 }; 105 106 CaptureApiClass capture_api_class_; 107 #endif // if defined(OS_WIN) 108 // Allow generated copy constructor and assignment. 109 }; 110 111 // Manages a list of Name entries. 112 class MEDIA_EXPORT Names 113 : public NON_EXPORTED_BASE(std::list<Name>) { 114 public: 115 // Returns NULL if no entry was found by that ID. 116 Name* FindById(const std::string& id); 117 118 // Allow generated copy constructor and assignment. 119 }; 120 121 class MEDIA_EXPORT EventHandler { 122 public: 123 124 // Reserve an output buffer into which a video frame can be captured 125 // directly. If all buffers are currently busy, returns NULL. 126 // 127 // The returned VideoFrames will always be allocated with a YV12 format. The 128 // size will match that specified by an earlier call to OnFrameInfo. It is 129 // the VideoCaptureDevice's responsibility to obey whatever stride and 130 // memory layout are indicated on the returned VideoFrame object. 131 // 132 // The output buffer stays reserved for use by the calling 133 // VideoCaptureDevice until either the last reference to the VideoFrame is 134 // released, or until the buffer is passed back to the EventHandler's 135 // OnIncomingCapturedFrame() method. 136 // 137 // Threading note: After VideoCaptureDevice::DeAllocate() occurs, the 138 // VideoCaptureDevice is not permitted to make any additional calls through 139 // its EventHandler. However, any VideoFrames returned from the EventHandler 140 // DO remain valid after DeAllocate(). The VideoCaptureDevice must still 141 // eventually release them, but it may do so later -- e.g., after a queued 142 // capture operation completes. 143 virtual scoped_refptr<media::VideoFrame> ReserveOutputBuffer() = 0; 144 145 // Captured a new video frame as a raw buffer. The size, color format, and 146 // layout are taken from the parameters specified by an earlier call to 147 // OnFrameInfo(). |data| must be packed, with no padding between rows and/or 148 // color planes. 149 // 150 // This method will try to reserve an output buffer and copy from |data| 151 // into the output buffer. If no output buffer is available, the frame will 152 // be silently dropped. 153 virtual void OnIncomingCapturedFrame(const uint8* data, 154 int length, 155 base::Time timestamp, 156 int rotation, // Clockwise. 157 bool flip_vert, 158 bool flip_horiz) = 0; 159 160 // Captured a new video frame, held in a VideoFrame container. 161 // 162 // If |frame| was created via the ReserveOutputBuffer() mechanism, then the 163 // frame delivery is guaranteed (it will not be silently dropped), and 164 // delivery will require no additional copies in the browser process. For 165 // such frames, the VideoCaptureDevice's reservation on the output buffer 166 // ends immediately. The VideoCaptureDevice may not read or write the 167 // underlying memory afterwards, and it should release its references to 168 // |frame| as soon as possible, to allow buffer reuse. 169 // 170 // If |frame| was NOT created via ReserveOutputBuffer(), then this method 171 // will try to reserve an output buffer and copy from |frame| into the 172 // output buffer. If no output buffer is available, the frame will be 173 // silently dropped. |frame| must be allocated as RGB32, YV12 or I420, and 174 // the size must match that specified by an earlier call to OnFrameInfo(). 175 virtual void OnIncomingCapturedVideoFrame( 176 const scoped_refptr<media::VideoFrame>& frame, 177 base::Time timestamp) = 0; 178 179 // An error has occurred that cannot be handled and VideoCaptureDevice must 180 // be DeAllocate()-ed. 181 virtual void OnError() = 0; 182 183 // Called when VideoCaptureDevice::Allocate() has been called to inform of 184 // the resulting frame size. 185 virtual void OnFrameInfo(const VideoCaptureCapability& info) = 0; 186 187 // Called when the native resolution of VideoCaptureDevice has been changed 188 // and it needs to inform its client of the new frame size. 189 virtual void OnFrameInfoChanged(const VideoCaptureCapability& info) {}; 190 191 protected: 192 virtual ~EventHandler() {} 193 }; 194 // Creates a VideoCaptureDevice object. 195 // Return NULL if the hardware is not available. 196 static VideoCaptureDevice* Create(const Name& device_name); 197 virtual ~VideoCaptureDevice() {} 198 199 // Gets the names of all video capture devices connected to this computer. 200 static void GetDeviceNames(Names* device_names); 201 202 // Prepare the camera for use. After this function has been called no other 203 // applications can use the camera. On completion EventHandler::OnFrameInfo() 204 // is called informing of the resulting resolution and frame rate. 205 // DeAllocate() must be called before this function can be called again and 206 // before the object is deleted. 207 virtual void Allocate(const VideoCaptureCapability& capture_format, 208 EventHandler* observer) = 0; 209 210 // Start capturing video frames. Allocate must be called before this function. 211 virtual void Start() = 0; 212 213 // Stop capturing video frames. 214 virtual void Stop() = 0; 215 216 // Deallocates the camera. This means other applications can use it. After 217 // this function has been called the capture device is reset to the state it 218 // was when created. After DeAllocate() is called, the VideoCaptureDevice is 219 // not permitted to make any additional calls to its EventHandler. 220 virtual void DeAllocate() = 0; 221 222 // Get the name of the capture device. 223 virtual const Name& device_name() = 0; 224 }; 225 226 } // namespace media 227 228 #endif // MEDIA_VIDEO_CAPTURE_VIDEO_CAPTURE_DEVICE_H_ 229