video_capture_device.h revision d0247b1b59f9c528cb6df88b4f2b9afaf80d181e
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
23namespace media {
24
25class 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_;
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    virtual ~EventHandler() {}
124
125    // Reserve an output buffer into which a video frame can be captured
126    // directly. If all buffers are currently busy, returns NULL.
127    //
128    // The returned VideoFrames will always be allocated with a YV12 format. The
129    // size will match that specified by an earlier call to OnFrameInfo. It is
130    // the VideoCaptureDevice's responsibility to obey whatever stride and
131    // memory layout are indicated on the returned VideoFrame object.
132    //
133    // The output buffer stays reserved for use by the calling
134    // VideoCaptureDevice until either the last reference to the VideoFrame is
135    // released, or until the buffer is passed back to the EventHandler's
136    // OnIncomingCapturedFrame() method.
137    virtual scoped_refptr<media::VideoFrame> ReserveOutputBuffer() = 0;
138
139    // Captured a new video frame as a raw buffer. The size, color format, and
140    // layout are taken from the parameters specified by an earlier call to
141    // OnFrameInfo(). |data| must be packed, with no padding between rows and/or
142    // color planes.
143    //
144    // This method will try to reserve an output buffer and copy from |data|
145    // into the output buffer. If no output buffer is available, the frame will
146    // be silently dropped.
147    virtual void OnIncomingCapturedFrame(const uint8* data,
148                                         int length,
149                                         base::Time timestamp,
150                                         int rotation,  // Clockwise.
151                                         bool flip_vert,
152                                         bool flip_horiz) = 0;
153
154    // Captured a new video frame, held in a VideoFrame container.
155    //
156    // If |frame| was created via the ReserveOutputBuffer() mechanism, then the
157    // frame delivery is guaranteed (it will not be silently dropped), and
158    // delivery will require no additional copies in the browser process. For
159    // such frames, the VideoCaptureDevice's reservation on the output buffer
160    // ends immediately. The VideoCaptureDevice may not read or write the
161    // underlying memory afterwards, and it should release its references to
162    // |frame| as soon as possible, to allow buffer reuse.
163    //
164    // If |frame| was NOT created via ReserveOutputBuffer(), then this method
165    // will try to reserve an output buffer and copy from |frame| into the
166    // output buffer. If no output buffer is available, the frame will be
167    // silently dropped. |frame| must be allocated as RGB32, YV12 or I420, and
168    // the size must match that specified by an earlier call to OnFrameInfo().
169    virtual void OnIncomingCapturedVideoFrame(
170        const scoped_refptr<media::VideoFrame>& frame,
171        base::Time timestamp) = 0;
172
173    // An error has occurred that cannot be handled and VideoCaptureDevice must
174    // be StopAndDeAllocate()-ed.
175    virtual void OnError() = 0;
176
177    // Called when VideoCaptureDevice::AllocateAndStart() has been called to
178    // inform of the resulting frame size.
179    virtual void OnFrameInfo(const VideoCaptureCapability& info) = 0;
180
181    // Called when the native resolution of VideoCaptureDevice has been changed
182    // and it needs to inform its client of the new frame size.
183    virtual void OnFrameInfoChanged(const VideoCaptureCapability& info) {};
184  };
185  // Creates a VideoCaptureDevice object.
186  // Return NULL if the hardware is not available.
187  static VideoCaptureDevice* Create(const Name& device_name);
188  virtual ~VideoCaptureDevice();
189
190  // Gets the names of all video capture devices connected to this computer.
191  static void GetDeviceNames(Names* device_names);
192
193  // Prepare the camera for use. After this function has been called no other
194  // applications can use the camera. On completion EventHandler::OnFrameInfo()
195  // is called informing of the resulting resolution and frame rate.
196  // StopAndDeAllocate() must be called before the object is deleted.
197  virtual void AllocateAndStart(
198      const VideoCaptureCapability& capture_format,
199      scoped_ptr<EventHandler> client) = 0;
200
201  // Deallocates the camera, possibly asynchronously.
202  //
203  // This call requires the device to do the following things, eventually: put
204  // camera hardware into a state where other applications could use it, free
205  // the memory associated with capture, and delete the |client| pointer passed
206  // into AllocateAndStart.
207  //
208  // If deallocation is done asynchronously, then the device implementation must
209  // ensure that a subsequent AllocateAndStart() operation targeting the same ID
210  // would be sequenced through the same task runner, so that deallocation
211  // happens first.
212  virtual void StopAndDeAllocate() = 0;
213};
214
215// VideoCaptureDevice1 is a bridge to an older API against which
216// VideoCaptureDevices were implemented. Differences between VideoCaptureDevice
217// (new style) and VideoCaptureDevice1 (old style) are as follows:
218//
219// [1] The Stop+DeAllocate calls are merged in the new style.
220// [2] The Allocate+Start calls are merged in the new style.
221// [3] New style devices own their EventHandler* pointers, allowing handlers to
222//     remain valid even after the device is stopped. Whereas old style devices
223//     may not dereference their handlers after DeAllocate().
224// [4] device_name() is eliminated from the new-style interface.
225//
226// TODO(nick): Remove this bridge class. It exists to enable incremental
227// migration to an alternative VideoCaptureDevice API.
228class MEDIA_EXPORT VideoCaptureDevice1 : public VideoCaptureDevice {
229 public:
230  VideoCaptureDevice1();
231  virtual ~VideoCaptureDevice1();
232
233  // VideoCaptureDevice implementation.
234  virtual void AllocateAndStart(
235      const VideoCaptureCapability& capture_format,
236      scoped_ptr<EventHandler> client) OVERRIDE;
237  virtual void StopAndDeAllocate() OVERRIDE;
238
239  // Prepare the camera for use. After this function has been called no other
240  // applications can use the camera. On completion EventHandler::OnFrameInfo()
241  // is called informing of the resulting resolution and frame rate.
242  // DeAllocate() must be called before this function can be called again and
243  // before the object is deleted.
244  virtual void Allocate(const VideoCaptureCapability& capture_format,
245                        EventHandler* client) = 0;
246
247  // Start capturing video frames. Allocate must be called before this function.
248  virtual void Start() = 0;
249
250  // Stop capturing video frames.
251  virtual void Stop() = 0;
252
253  // Deallocates the camera. This means other applications can use it. After
254  // this function has been called the capture device is reset to the state it
255  // was when created. After DeAllocate() is called, the VideoCaptureDevice is
256  // not permitted to make any additional calls to its EventHandler.
257  virtual void DeAllocate() = 0;
258
259  // Get the name of the capture device.
260  virtual const Name& device_name() = 0;
261
262 private:
263  // The device client which proxies device events to the controller.
264  scoped_ptr<EventHandler> client_;
265};
266
267}  // namespace media
268
269#endif  // MEDIA_VIDEO_CAPTURE_VIDEO_CAPTURE_DEVICE_H_
270