Home | History | Annotate | Download | only in media
      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 // VideoCaptureManager is used to open/close, start/stop, enumerate available
      6 // video capture devices, and manage VideoCaptureController's.
      7 // All functions are expected to be called from Browser::IO thread. Some helper
      8 // functions (*OnDeviceThread) will dispatch operations to the device thread.
      9 // VideoCaptureManager will open OS dependent instances of VideoCaptureDevice.
     10 // A device can only be opened once.
     11 
     12 #ifndef CONTENT_BROWSER_RENDERER_HOST_MEDIA_VIDEO_CAPTURE_MANAGER_H_
     13 #define CONTENT_BROWSER_RENDERER_HOST_MEDIA_VIDEO_CAPTURE_MANAGER_H_
     14 
     15 #include <map>
     16 #include <set>
     17 #include <string>
     18 
     19 #include "base/memory/ref_counted.h"
     20 #include "base/memory/weak_ptr.h"
     21 #include "base/message_loop/message_loop.h"
     22 #include "base/process/process_handle.h"
     23 #include "base/timer/elapsed_timer.h"
     24 #include "content/browser/renderer_host/media/media_stream_provider.h"
     25 #include "content/browser/renderer_host/media/video_capture_controller_event_handler.h"
     26 #include "content/common/content_export.h"
     27 #include "content/common/media/media_stream_options.h"
     28 #include "media/video/capture/video_capture_device.h"
     29 #include "media/video/capture/video_capture_device_factory.h"
     30 #include "media/video/capture/video_capture_types.h"
     31 
     32 namespace content {
     33 class VideoCaptureController;
     34 class VideoCaptureControllerEventHandler;
     35 
     36 // VideoCaptureManager opens/closes and start/stops video capture devices.
     37 class CONTENT_EXPORT VideoCaptureManager : public MediaStreamProvider {
     38  public:
     39   // Callback used to signal the completion of a controller lookup.
     40   typedef base::Callback<
     41       void(const base::WeakPtr<VideoCaptureController>&)> DoneCB;
     42 
     43   explicit VideoCaptureManager(
     44       scoped_ptr<media::VideoCaptureDeviceFactory> factory);
     45 
     46   // Implements MediaStreamProvider.
     47   virtual void Register(MediaStreamProviderListener* listener,
     48                         const scoped_refptr<base::SingleThreadTaskRunner>&
     49                             device_task_runner) OVERRIDE;
     50 
     51   virtual void Unregister() OVERRIDE;
     52 
     53   virtual void EnumerateDevices(MediaStreamType stream_type) OVERRIDE;
     54 
     55   virtual int Open(const StreamDeviceInfo& device) OVERRIDE;
     56 
     57   virtual void Close(int capture_session_id) OVERRIDE;
     58 
     59   // Called by VideoCaptureHost to locate a capture device for |capture_params|,
     60   // adding the Host as a client of the device's controller if successful. The
     61   // value of |session_id| controls which device is selected;
     62   // this value should be a session id previously returned by Open().
     63   //
     64   // If the device is not already started (i.e., no other client is currently
     65   // capturing from this device), this call will cause a VideoCaptureController
     66   // and VideoCaptureDevice to be created, possibly asynchronously.
     67   //
     68   // On success, the controller is returned via calling |done_cb|, indicating
     69   // that the client was successfully added. A NULL controller is passed to
     70   // the callback on failure.
     71   void StartCaptureForClient(media::VideoCaptureSessionId session_id,
     72                              const media::VideoCaptureParams& capture_params,
     73                              base::ProcessHandle client_render_process,
     74                              VideoCaptureControllerID client_id,
     75                              VideoCaptureControllerEventHandler* client_handler,
     76                              const DoneCB& done_cb);
     77 
     78   // Called by VideoCaptureHost to remove |client_handler|. If this is the last
     79   // client of the device, the |controller| and its VideoCaptureDevice may be
     80   // destroyed. The client must not access |controller| after calling this
     81   // function.
     82   void StopCaptureForClient(VideoCaptureController* controller,
     83                             VideoCaptureControllerID client_id,
     84                             VideoCaptureControllerEventHandler* client_handler,
     85                             bool aborted_due_to_error);
     86 
     87   // Retrieves all capture supported formats for a particular device. Returns
     88   // false if the |capture_session_id| is not found. The supported formats are
     89   // cached during device(s) enumeration, and depending on the underlying
     90   // implementation, could be an empty list.
     91   bool GetDeviceSupportedFormats(
     92       media::VideoCaptureSessionId capture_session_id,
     93       media::VideoCaptureFormats* supported_formats);
     94 
     95   // Retrieves the format(s) currently in use.  Returns false if the
     96   // |capture_session_id| is not found. Returns true and |formats_in_use|
     97   // otherwise. |formats_in_use| is empty if the device is not in use.
     98   bool GetDeviceFormatsInUse(media::VideoCaptureSessionId capture_session_id,
     99                              media::VideoCaptureFormats* formats_in_use);
    100 
    101   // Sets the platform-dependent window ID for the desktop capture notification
    102   // UI for the given session.
    103   void SetDesktopCaptureWindowId(media::VideoCaptureSessionId session_id,
    104                                  gfx::NativeViewId window_id);
    105 
    106   // Gets a weak reference to the device factory, used for tests.
    107   media::VideoCaptureDeviceFactory* video_capture_device_factory() const {
    108     return video_capture_device_factory_.get();
    109   }
    110 
    111  private:
    112   virtual ~VideoCaptureManager();
    113   struct DeviceEntry;
    114 
    115   // This data structure is a convenient wrap of a devices' name and associated
    116   // video capture supported formats.
    117   struct DeviceInfo {
    118     DeviceInfo();
    119     DeviceInfo(const media::VideoCaptureDevice::Name& name,
    120                const media::VideoCaptureFormats& supported_formats);
    121     ~DeviceInfo();
    122 
    123     media::VideoCaptureDevice::Name name;
    124     media::VideoCaptureFormats supported_formats;
    125   };
    126   typedef std::vector<DeviceInfo> DeviceInfos;
    127 
    128   // Checks to see if |entry| has no clients left on its controller. If so,
    129   // remove it from the list of devices, and delete it asynchronously. |entry|
    130   // may be freed by this function.
    131   void DestroyDeviceEntryIfNoClients(DeviceEntry* entry);
    132 
    133   // Helpers to report an event to our Listener.
    134   void OnOpened(MediaStreamType type,
    135                 media::VideoCaptureSessionId capture_session_id);
    136   void OnClosed(MediaStreamType type,
    137                 media::VideoCaptureSessionId capture_session_id);
    138   void OnDevicesInfoEnumerated(MediaStreamType stream_type,
    139                                base::ElapsedTimer* timer,
    140                                const DeviceInfos& new_devices_info_cache);
    141 
    142   // Finds a DeviceEntry by its device ID and type, if it is already opened.
    143   DeviceEntry* GetDeviceEntryForMediaStreamDevice(
    144       const MediaStreamDevice& device_info);
    145 
    146   // Finds a DeviceEntry entry for the indicated session, creating a fresh one
    147   // if necessary. Returns NULL if the session id is invalid.
    148   DeviceEntry* GetOrCreateDeviceEntry(
    149       media::VideoCaptureSessionId capture_session_id);
    150 
    151   // Finds the DeviceEntry that owns a particular controller pointer.
    152   DeviceEntry* GetDeviceEntryForController(
    153       const VideoCaptureController* controller) const;
    154 
    155   bool IsOnDeviceThread() const;
    156 
    157   // Consolidates the cached devices list with the list of currently connected
    158   // devices in the system |names_snapshot|. Retrieves the supported formats of
    159   // the new devices and sends the new cache to OnDevicesInfoEnumerated().
    160   void ConsolidateDevicesInfoOnDeviceThread(
    161       base::Callback<void(const DeviceInfos&)> on_devices_enumerated_callback,
    162       MediaStreamType stream_type,
    163       const DeviceInfos& old_device_info_cache,
    164       scoped_ptr<media::VideoCaptureDevice::Names> names_snapshot);
    165 
    166   // Creates and Starts a new VideoCaptureDevice, storing the result in
    167   // |entry->video_capture_device|. Ownership of |client| passes to
    168   // the device.
    169   void DoStartDeviceOnDeviceThread(
    170       media::VideoCaptureSessionId session_id,
    171       DeviceEntry* entry,
    172       const media::VideoCaptureParams& params,
    173       scoped_ptr<media::VideoCaptureDevice::Client> client);
    174 
    175   // Stops and destroys the VideoCaptureDevice held in
    176   // |entry->video_capture_device|.
    177   void DoStopDeviceOnDeviceThread(DeviceEntry* entry);
    178 
    179   DeviceInfo* FindDeviceInfoById(const std::string& id,
    180                                  DeviceInfos& device_vector);
    181 
    182   void SetDesktopCaptureWindowIdOnDeviceThread(DeviceEntry* entry,
    183                                                gfx::NativeViewId window_id);
    184 
    185   void SaveDesktopCaptureWindowIdOnDeviceThread(
    186       media::VideoCaptureSessionId session_id,
    187       gfx::NativeViewId window_id);
    188 
    189   // The message loop of media stream device thread, where VCD's live.
    190   scoped_refptr<base::SingleThreadTaskRunner> device_task_runner_;
    191 
    192   // Only accessed on Browser::IO thread.
    193   MediaStreamProviderListener* listener_;
    194   media::VideoCaptureSessionId new_capture_session_id_;
    195 
    196   typedef std::map<media::VideoCaptureSessionId, MediaStreamDevice> SessionMap;
    197   // An entry is kept in this map for every session that has been created via
    198   // the Open() entry point. The keys are session_id's. This map is used to
    199   // determine which device to use when StartCaptureForClient() occurs. Used
    200   // only on the IO thread.
    201   SessionMap sessions_;
    202 
    203   // An entry, kept in a map, that owns a VideoCaptureDevice and its associated
    204   // VideoCaptureController. VideoCaptureManager owns all VideoCaptureDevices
    205   // and VideoCaptureControllers and is responsible for deleting the instances
    206   // when they are not used any longer.
    207   //
    208   // The set of currently started VideoCaptureDevice and VideoCaptureController
    209   // objects is only accessed from IO thread, though the DeviceEntry instances
    210   // themselves may visit to the device thread for device creation and
    211   // destruction.
    212   struct DeviceEntry {
    213     DeviceEntry(MediaStreamType stream_type,
    214                 const std::string& id,
    215                 scoped_ptr<VideoCaptureController> controller);
    216     ~DeviceEntry();
    217 
    218     const MediaStreamType stream_type;
    219     const std::string id;
    220 
    221     // The controller. Only used from the IO thread.
    222     scoped_ptr<VideoCaptureController> video_capture_controller;
    223 
    224     // The capture device. Only used from the device thread.
    225     scoped_ptr<media::VideoCaptureDevice> video_capture_device;
    226   };
    227   typedef std::set<DeviceEntry*> DeviceEntries;
    228   DeviceEntries devices_;
    229 
    230   // Device creation factory injected on construction from MediaStreamManager or
    231   // from the test harness.
    232   scoped_ptr<media::VideoCaptureDeviceFactory> video_capture_device_factory_;
    233 
    234   // Local cache of the enumerated video capture devices' names and capture
    235   // supported formats. A snapshot of the current devices and their capabilities
    236   // is composed in VideoCaptureDeviceFactory::EnumerateDeviceNames() and
    237   // ConsolidateDevicesInfoOnDeviceThread(), and this snapshot is used to update
    238   // this list in OnDevicesInfoEnumerated(). GetDeviceSupportedFormats() will
    239   // use this list if the device is not started, otherwise it will retrieve the
    240   // active device capture format from the VideoCaptureController associated.
    241   DeviceInfos devices_info_cache_;
    242 
    243   // Accessed on the device thread only.
    244   std::map<media::VideoCaptureSessionId, gfx::NativeViewId>
    245       notification_window_ids_;
    246 
    247   DISALLOW_COPY_AND_ASSIGN(VideoCaptureManager);
    248 };
    249 
    250 }  // namespace content
    251 
    252 #endif  // CONTENT_BROWSER_RENDERER_HOST_MEDIA_VIDEO_CAPTURE_MANAGER_H_
    253