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// VideoCaptureImpl represents a capture device in renderer process. It provides
6// interfaces for clients to Start/Stop capture. It also communicates to clients
7// when buffer is ready, state of capture device is changed.
8
9// VideoCaptureImpl is also a delegate of VideoCaptureMessageFilter which relays
10// operation of a capture device to the browser process and receives responses
11// from browser process.
12//
13// VideoCaptureImpl is an IO thread only object. See the comments in
14// video_capture_impl_manager.cc for the lifetime of this object.
15// All methods must be called on the IO thread.
16//
17// This is an internal class used by VideoCaptureImplManager only. Do not access
18// this directly.
19
20#ifndef CONTENT_RENDERER_MEDIA_VIDEO_CAPTURE_IMPL_H_
21#define CONTENT_RENDERER_MEDIA_VIDEO_CAPTURE_IMPL_H_
22
23#include <list>
24#include <map>
25
26#include "base/memory/weak_ptr.h"
27#include "base/threading/thread_checker.h"
28#include "content/common/content_export.h"
29#include "content/common/media/video_capture.h"
30#include "content/public/renderer/media_stream_video_sink.h"
31#include "content/renderer/media/video_capture_message_filter.h"
32#include "media/video/capture/video_capture_types.h"
33
34namespace base {
35class MessageLoopProxy;
36}  // namespace base
37
38namespace gpu {
39struct MailboxHolder;
40}  // namespace gpu
41
42namespace media {
43class VideoFrame;
44}  // namespace media
45
46namespace content {
47
48class CONTENT_EXPORT VideoCaptureImpl
49    : public VideoCaptureMessageFilter::Delegate {
50 public:
51  virtual ~VideoCaptureImpl();
52
53  VideoCaptureImpl(media::VideoCaptureSessionId session_id,
54                   VideoCaptureMessageFilter* filter);
55
56  // Start listening to IPC messages.
57  void Init();
58
59  // Stop listening to IPC messages.
60  void DeInit();
61
62  // Stop/resume delivering video frames to clients, based on flag |suspend|.
63  void SuspendCapture(bool suspend);
64
65  // Start capturing using the provided parameters.
66  // |client_id| must be unique to this object in the render process. It is
67  // used later to stop receiving video frames.
68  // |state_update_cb| will be called when state changes.
69  // |deliver_frame_cb| will be called when a frame is ready.
70  void StartCapture(
71      int client_id,
72      const media::VideoCaptureParams& params,
73      const VideoCaptureStateUpdateCB& state_update_cb,
74      const VideoCaptureDeliverFrameCB& deliver_frame_cb);
75
76  // Stop capturing. |client_id| is the identifier used to call StartCapture.
77  void StopCapture(int client_id);
78
79  // Get capturing formats supported by this device.
80  // |callback| will be invoked with the results.
81  void GetDeviceSupportedFormats(
82      const VideoCaptureDeviceFormatsCB& callback);
83
84  // Get capturing formats currently in use by this device.
85  // |callback| will be invoked with the results.
86  void GetDeviceFormatsInUse(
87      const VideoCaptureDeviceFormatsCB& callback);
88
89  media::VideoCaptureSessionId session_id() const { return session_id_; }
90
91 private:
92  friend class VideoCaptureImplTest;
93  friend class MockVideoCaptureImpl;
94
95  // Carries a shared memory for transferring video frames from browser to
96  // renderer.
97  class ClientBuffer;
98
99  // Contains information for a video capture client. Including parameters
100  // for capturing and callbacks to the client.
101  struct ClientInfo {
102    ClientInfo();
103    ~ClientInfo();
104    media::VideoCaptureParams params;
105    VideoCaptureStateUpdateCB state_update_cb;
106    VideoCaptureDeliverFrameCB deliver_frame_cb;
107  };
108  typedef std::map<int, ClientInfo> ClientInfoMap;
109
110  // VideoCaptureMessageFilter::Delegate interface.
111  virtual void OnBufferCreated(base::SharedMemoryHandle handle,
112                               int length,
113                               int buffer_id) OVERRIDE;
114  virtual void OnBufferDestroyed(int buffer_id) OVERRIDE;
115  virtual void OnBufferReceived(int buffer_id,
116                                const media::VideoCaptureFormat& format,
117                                const gfx::Rect& visible_rect,
118                                base::TimeTicks) OVERRIDE;
119  virtual void OnMailboxBufferReceived(int buffer_id,
120                                       const gpu::MailboxHolder& mailbox_holder,
121                                       const media::VideoCaptureFormat& format,
122                                       base::TimeTicks timestamp) OVERRIDE;
123  virtual void OnStateChanged(VideoCaptureState state) OVERRIDE;
124  virtual void OnDeviceSupportedFormatsEnumerated(
125      const media::VideoCaptureFormats& supported_formats) OVERRIDE;
126  virtual void OnDeviceFormatsInUseReceived(
127      const media::VideoCaptureFormats& formats_in_use) OVERRIDE;
128  virtual void OnDelegateAdded(int32 device_id) OVERRIDE;
129
130  // Sends an IPC message to browser process when all clients are done with the
131  // buffer.
132  void OnClientBufferFinished(int buffer_id,
133                              const scoped_refptr<ClientBuffer>& buffer,
134                              uint32 release_sync_point);
135
136  void StopDevice();
137  void RestartCapture();
138  void StartCaptureInternal();
139
140  virtual void Send(IPC::Message* message);
141
142  // Helpers.
143  bool RemoveClient(int client_id, ClientInfoMap* clients);
144
145  const scoped_refptr<VideoCaptureMessageFilter> message_filter_;
146  int device_id_;
147  const int session_id_;
148
149  // Vector of callbacks to be notified of device format enumerations, used only
150  // on IO Thread.
151  std::vector<VideoCaptureDeviceFormatsCB> device_formats_cb_queue_;
152  // Vector of callbacks to be notified of a device's in use capture format(s),
153  // used only on IO Thread.
154  std::vector<VideoCaptureDeviceFormatsCB> device_formats_in_use_cb_queue_;
155
156  // Buffers available for sending to the client.
157  typedef std::map<int32, scoped_refptr<ClientBuffer> > ClientBufferMap;
158  ClientBufferMap client_buffers_;
159
160  ClientInfoMap clients_;
161  ClientInfoMap clients_pending_on_filter_;
162  ClientInfoMap clients_pending_on_restart_;
163
164  // Member params_ represents the video format requested by the
165  // client to this class via StartCapture().
166  media::VideoCaptureParams params_;
167
168  // The device's video capture format sent from browser process side.
169  media::VideoCaptureFormat last_frame_format_;
170
171  // The device's first captured frame timestamp sent from browser process side.
172  base::TimeTicks first_frame_timestamp_;
173
174  bool suspended_;
175  VideoCaptureState state_;
176
177  // |weak_factory_| and |thread_checker_| are bound to the IO thread.
178  base::ThreadChecker thread_checker_;
179
180  // WeakPtrFactory pointing back to |this| object, for use with
181  // media::VideoFrames constructed in OnBufferReceived() from buffers cached
182  // in |client_buffers_|.
183  // NOTE: Weak pointers must be invalidated before all other member variables.
184  base::WeakPtrFactory<VideoCaptureImpl> weak_factory_;
185
186  DISALLOW_COPY_AND_ASSIGN(VideoCaptureImpl);
187};
188
189}  // namespace content
190
191#endif  // CONTENT_RENDERER_MEDIA_VIDEO_CAPTURE_IMPL_H_
192