Home | History | Annotate | Download | only in capture
      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