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/single_thread_task_runner.h"
     22 #include "base/time/time.h"
     23 #include "media/base/media_export.h"
     24 #include "media/base/video_frame.h"
     25 #include "media/video/capture/video_capture_types.h"
     26 
     27 namespace media {
     28 
     29 class MEDIA_EXPORT VideoCaptureDevice {
     30  public:
     31   // Represents a capture device name and ID.
     32   // You should not create an instance of this class directly by e.g. setting
     33   // various properties directly.  Instead use
     34   // VideoCaptureDevice::GetDeviceNames to do this for you and if you need to
     35   // cache your own copy of a name, you can do so via the copy constructor.
     36   // The reason for this is that a device name might contain platform specific
     37   // settings that are relevant only to the platform specific implementation of
     38   // VideoCaptureDevice::Create.
     39   class MEDIA_EXPORT Name {
     40    public:
     41     Name();
     42     Name(const std::string& name, const std::string& 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       DIRECT_SHOW_WDM_CROSSBAR,
     50       API_TYPE_UNKNOWN
     51     };
     52 #endif
     53 #if defined(OS_MACOSX)
     54     // Mac targets Capture Api type: it can only be set on construction.
     55     enum CaptureApiType {
     56       AVFOUNDATION,
     57       QTKIT,
     58       DECKLINK,
     59       API_TYPE_UNKNOWN
     60     };
     61     // For AVFoundation Api, identify devices that are built-in or USB.
     62     enum TransportType {
     63       USB_OR_BUILT_IN,
     64       OTHER_TRANSPORT
     65     };
     66 #endif
     67 #if defined(OS_WIN) || defined(OS_MACOSX)
     68     Name(const std::string& name,
     69          const std::string& id,
     70          const CaptureApiType api_type);
     71 #endif
     72 #if defined(OS_MACOSX)
     73     Name(const std::string& name,
     74          const std::string& id,
     75          const CaptureApiType api_type,
     76          const TransportType transport_type);
     77 #endif
     78     ~Name();
     79 
     80     // Friendly name of a device
     81     const std::string& name() const { return device_name_; }
     82 
     83     // Unique name of a device. Even if there are multiple devices with the same
     84     // friendly name connected to the computer this will be unique.
     85     const std::string& id() const { return unique_id_; }
     86 
     87     // The unique hardware model identifier of the capture device. Returns
     88     // "[vid]:[pid]" when a USB device is detected, otherwise "".
     89     // The implementation of this method is platform-dependent.
     90     const std::string GetModel() const;
     91 
     92     // Friendly name of a device, plus the model identifier in parentheses.
     93     const std::string GetNameAndModel() const;
     94 
     95     // These operators are needed due to storing the name in an STL container.
     96     // In the shared build, all methods from the STL container will be exported
     97     // so even though they're not used, they're still depended upon.
     98     bool operator==(const Name& other) const {
     99       return other.id() == unique_id_;
    100     }
    101     bool operator<(const Name& other) const {
    102       return unique_id_ < other.id();
    103     }
    104 
    105 #if defined(OS_WIN) || defined(OS_MACOSX)
    106     CaptureApiType capture_api_type() const {
    107       return capture_api_class_.capture_api_type();
    108     }
    109 #endif
    110 #if defined(OS_WIN)
    111     // Certain devices need an ID different from the |unique_id_| for
    112     // capabilities retrieval.
    113     const std::string& capabilities_id() const {
    114       return capabilities_id_;
    115     }
    116     void set_capabilities_id(const std::string& id) {
    117       capabilities_id_ = id;
    118     }
    119 #endif
    120 #if defined(OS_MACOSX)
    121     TransportType transport_type() const {
    122       return transport_type_;
    123     }
    124     bool is_blacklisted() const {
    125       return is_blacklisted_;
    126     }
    127     void set_is_blacklisted(bool is_blacklisted) {
    128       is_blacklisted_ = is_blacklisted;
    129     }
    130 #endif  // if defined(OS_WIN)
    131 
    132    private:
    133     std::string device_name_;
    134     std::string unique_id_;
    135 #if defined(OS_WIN) || defined(OS_MACOSX)
    136     // This class wraps the CaptureApiType to give it a by default value if not
    137     // initialized.
    138     class CaptureApiClass {
    139      public:
    140       CaptureApiClass(): capture_api_type_(API_TYPE_UNKNOWN) {}
    141       CaptureApiClass(const CaptureApiType api_type)
    142           : capture_api_type_(api_type) {}
    143       CaptureApiType capture_api_type() const {
    144         DCHECK_NE(capture_api_type_, API_TYPE_UNKNOWN);
    145         return capture_api_type_;
    146       }
    147      private:
    148       CaptureApiType capture_api_type_;
    149     };
    150 
    151     CaptureApiClass capture_api_class_;
    152 #endif
    153 #if defined(OS_WIN)
    154     // ID used for capabilities retrieval. By default is equal to |unique_id|.
    155     std::string capabilities_id_;
    156 #endif
    157 #if defined(OS_MACOSX)
    158     TransportType transport_type_;
    159     // Flag used to mark blacklisted devices for QTKit Api.
    160     bool is_blacklisted_;
    161 #endif
    162     // Allow generated copy constructor and assignment.
    163   };
    164 
    165   // Manages a list of Name entries.
    166   typedef std::list<Name> Names;
    167 
    168   class MEDIA_EXPORT Client {
    169    public:
    170     // Memory buffer returned by Client::ReserveOutputBuffer().
    171     class Buffer : public base::RefCountedThreadSafe<Buffer> {
    172      public:
    173       int id() const { return id_; }
    174       void* data() const { return data_; }
    175       size_t size() const { return size_; }
    176 
    177      protected:
    178       friend class base::RefCountedThreadSafe<Buffer>;
    179 
    180       Buffer(int id, void* data, size_t size)
    181           : id_(id), data_(data), size_(size) {}
    182       virtual ~Buffer() {}
    183 
    184       const int id_;
    185       void* const data_;
    186       const size_t size_;
    187     };
    188 
    189     virtual ~Client() {}
    190 
    191     // Reserve an output buffer into which contents can be captured directly.
    192     // The returned Buffer will always be allocated with a memory size suitable
    193     // for holding a packed video frame with pixels of |format| format, of
    194     // |dimensions| frame dimensions. It is permissible for |dimensions| to be
    195     // zero; in which case the returned Buffer does not guarantee memory
    196     // backing, but functions as a reservation for external input for the
    197     // purposes of buffer throttling.
    198     //
    199     // The output buffer stays reserved for use until the Buffer object is
    200     // destroyed.
    201     virtual scoped_refptr<Buffer> ReserveOutputBuffer(
    202         media::VideoFrame::Format format,
    203         const gfx::Size& dimensions) = 0;
    204 
    205     // Captured a new video frame, data for which is pointed to by |data|.
    206     //
    207     // The format of the frame is described by |frame_format|, and is assumed to
    208     // be tightly packed. This method will try to reserve an output buffer and
    209     // copy from |data| into the output buffer. If no output buffer is
    210     // available, the frame will be silently dropped.
    211     virtual void OnIncomingCapturedData(const uint8* data,
    212                                         int length,
    213                                         const VideoCaptureFormat& frame_format,
    214                                         int rotation,  // Clockwise.
    215                                         base::TimeTicks timestamp) = 0;
    216 
    217     // Captured a new video frame, held in |frame|.
    218     //
    219     // As the frame is backed by a reservation returned by
    220     // ReserveOutputBuffer(), delivery is guaranteed and will require no
    221     // additional copies in the browser process.
    222     virtual void OnIncomingCapturedVideoFrame(
    223         const scoped_refptr<Buffer>& buffer,
    224         const VideoCaptureFormat& buffer_format,
    225         const scoped_refptr<media::VideoFrame>& frame,
    226         base::TimeTicks timestamp) = 0;
    227 
    228     // An error has occurred that cannot be handled and VideoCaptureDevice must
    229     // be StopAndDeAllocate()-ed. |reason| is a text description of the error.
    230     virtual void OnError(const std::string& reason) = 0;
    231 
    232     // VideoCaptureDevice requests the |message| to be logged.
    233     virtual void OnLog(const std::string& message) {}
    234   };
    235 
    236   virtual ~VideoCaptureDevice();
    237 
    238   // Prepares the camera for use. After this function has been called no other
    239   // applications can use the camera. StopAndDeAllocate() must be called before
    240   // the object is deleted.
    241   virtual void AllocateAndStart(const VideoCaptureParams& params,
    242                                 scoped_ptr<Client> client) = 0;
    243 
    244   // Deallocates the camera, possibly asynchronously.
    245   //
    246   // This call requires the device to do the following things, eventually: put
    247   // camera hardware into a state where other applications could use it, free
    248   // the memory associated with capture, and delete the |client| pointer passed
    249   // into AllocateAndStart.
    250   //
    251   // If deallocation is done asynchronously, then the device implementation must
    252   // ensure that a subsequent AllocateAndStart() operation targeting the same ID
    253   // would be sequenced through the same task runner, so that deallocation
    254   // happens first.
    255   virtual void StopAndDeAllocate() = 0;
    256 
    257   // Gets the power line frequency from the current system time zone if this is
    258   // defined, otherwise returns 0.
    259   int GetPowerLineFrequencyForLocation() const;
    260 
    261  protected:
    262   static const int kPowerLine50Hz = 50;
    263   static const int kPowerLine60Hz = 60;
    264 };
    265 
    266 }  // namespace media
    267 
    268 #endif  // MEDIA_VIDEO_CAPTURE_VIDEO_CAPTURE_DEVICE_H_
    269