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/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