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// VideoCaptureHost serves video capture related messages from
6// VideoCaptureMessageFilter which lives inside the render process.
7//
8// This class is owned by RenderProcessHostImpl, and instantiated on UI
9// thread, but all other operations and method calls happen on IO thread.
10//
11// Here's an example of a typical IPC dialog for video capture:
12//
13//   Renderer                             VideoCaptureHost
14//      |                                        |
15//      |  VideoCaptureHostMsg_Start >           |
16//      | < VideoCaptureMsg_StateChanged         |
17//      |        (VIDEO_CAPTURE_STATE_STARTED)   |
18//      | < VideoCaptureMsg_NewBuffer(1)         |
19//      | < VideoCaptureMsg_NewBuffer(2)         |
20//      | < VideoCaptureMsg_NewBuffer(3)         |
21//      |                                        |
22//      | < VideoCaptureMsg_BufferReady(1)       |
23//      | < VideoCaptureMsg_BufferReady(2)       |
24//      | VideoCaptureHostMsg_BufferReady(1) >   |
25//      | < VideoCaptureMsg_BufferReady(3)       |
26//      | VideoCaptureHostMsg_BufferReady(2) >   |
27//      | < VideoCaptureMsg_BufferReady(1)       |
28//      | VideoCaptureHostMsg_BufferReady(3) >   |
29//      | < VideoCaptureMsg_BufferReady(2)       |
30//      | VideoCaptureHostMsg_BufferReady(1) >   |
31//      |             ...                        |
32//      | < VideoCaptureMsg_BufferReady(3)       |
33//      |                                        |
34//      |             ... (resolution change)    |
35//      | < VideoCaptureMsg_FreeBuffer(1)        |  Buffers are re-allocated
36//      | < VideoCaptureMsg_NewBuffer(4)         |  at a larger size, as
37//      | < VideoCaptureMsg_BufferReady(4)       |  needed.
38//      | VideoCaptureHostMsg_BufferReady(2) >   |
39//      | < VideoCaptureMsg_FreeBuffer(2)        |
40//      | < VideoCaptureMsg_NewBuffer(5)         |
41//      | < VideoCaptureMsg_BufferReady(5)       |
42//      |             ...                        |
43//      |                                        |
44//      | < VideoCaptureMsg_BufferReady          |
45//      | VideoCaptureHostMsg_Stop >             |
46//      | VideoCaptureHostMsg_BufferReady >      |
47//      | < VideoCaptureMsg_StateChanged         |
48//      |         (VIDEO_CAPTURE_STATE_STOPPED)  |
49//      v                                        v
50
51#ifndef CONTENT_BROWSER_RENDERER_HOST_MEDIA_VIDEO_CAPTURE_HOST_H_
52#define CONTENT_BROWSER_RENDERER_HOST_MEDIA_VIDEO_CAPTURE_HOST_H_
53
54#include <map>
55
56#include "base/memory/ref_counted.h"
57#include "base/memory/weak_ptr.h"
58#include "base/sequenced_task_runner_helpers.h"
59#include "content/browser/renderer_host/media/video_capture_controller.h"
60#include "content/common/content_export.h"
61#include "content/public/browser/browser_message_filter.h"
62#include "ipc/ipc_message.h"
63
64namespace content {
65class MediaStreamManager;
66
67class CONTENT_EXPORT VideoCaptureHost
68    : public BrowserMessageFilter,
69      public VideoCaptureControllerEventHandler {
70 public:
71  explicit VideoCaptureHost(MediaStreamManager* media_stream_manager);
72
73  // BrowserMessageFilter implementation.
74  virtual void OnChannelClosing() OVERRIDE;
75  virtual void OnDestruct() const OVERRIDE;
76  virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE;
77
78  // VideoCaptureControllerEventHandler implementation.
79  virtual void OnError(const VideoCaptureControllerID& id) OVERRIDE;
80  virtual void OnBufferCreated(const VideoCaptureControllerID& id,
81                               base::SharedMemoryHandle handle,
82                               int length,
83                               int buffer_id) OVERRIDE;
84  virtual void OnBufferDestroyed(const VideoCaptureControllerID& id,
85                                 int buffer_id) OVERRIDE;
86  virtual void OnBufferReady(const VideoCaptureControllerID& id,
87                             int buffer_id,
88                             const media::VideoCaptureFormat& format,
89                             const gfx::Rect& visible_rect,
90                             base::TimeTicks timestamp) OVERRIDE;
91  virtual void OnMailboxBufferReady(const VideoCaptureControllerID& id,
92                                    int buffer_id,
93                                    const gpu::MailboxHolder& mailbox_holder,
94                                    const media::VideoCaptureFormat& format,
95                                    base::TimeTicks timestamp) OVERRIDE;
96  virtual void OnEnded(const VideoCaptureControllerID& id) OVERRIDE;
97
98 private:
99  friend class BrowserThread;
100  friend class base::DeleteHelper<VideoCaptureHost>;
101  friend class MockVideoCaptureHost;
102  friend class VideoCaptureHostTest;
103
104  virtual ~VideoCaptureHost();
105
106  // IPC message: Start capture on the VideoCaptureDevice referenced by
107  // |session_id|. |device_id| is an id created by VideoCaptureMessageFilter
108  // to identify a session between a VideoCaptureMessageFilter and a
109  // VideoCaptureHost.
110  void OnStartCapture(int device_id,
111                      media::VideoCaptureSessionId session_id,
112                      const media::VideoCaptureParams& params);
113  void OnControllerAdded(
114      int device_id,
115      const base::WeakPtr<VideoCaptureController>& controller);
116  void DoControllerAddedOnIOThread(
117      int device_id,
118      const base::WeakPtr<VideoCaptureController>& controller);
119
120  // IPC message: Stop capture on device referenced by |device_id|.
121  void OnStopCapture(int device_id);
122
123  // IPC message: Pause capture on device referenced by |device_id|.
124  void OnPauseCapture(int device_id);
125
126  void OnResumeCapture(int device_id,
127                       media::VideoCaptureSessionId session_id,
128                       const media::VideoCaptureParams& params);
129
130  // IPC message: Receive an empty buffer from renderer. Send it to device
131  // referenced by |device_id|.
132  void OnReceiveEmptyBuffer(int device_id, int buffer_id, uint32 sync_point);
133
134  // IPC message: Get supported formats referenced by |capture_session_id|.
135  // |device_id| is needed for message back-routing purposes.
136  void OnGetDeviceSupportedFormats(
137      int device_id,
138      media::VideoCaptureSessionId capture_session_id);
139
140  // IPC message: Get a device's currently in use format(s), referenced by
141  // |capture_session_id|. |device_id| is needed for message back-routing
142  // purposes.
143  void OnGetDeviceFormatsInUse(
144      int device_id,
145      media::VideoCaptureSessionId capture_session_id);
146
147  // Sends a newly created buffer to the VideoCaptureMessageFilter.
148  void DoSendNewBufferOnIOThread(
149      const VideoCaptureControllerID& controller_id,
150      base::SharedMemoryHandle handle,
151      int length,
152      int buffer_id);
153
154  void DoSendFreeBufferOnIOThread(
155      const VideoCaptureControllerID& controller_id,
156      int buffer_id);
157
158  // Sends a filled buffer to the VideoCaptureMessageFilter.
159  void DoSendFilledBufferOnIOThread(
160      const VideoCaptureControllerID& controller_id,
161      int buffer_id,
162      const media::VideoCaptureFormat& format,
163      const gfx::Rect& visible_rect,
164      base::TimeTicks timestamp);
165
166  // Sends a filled texture mailbox buffer to the VideoCaptureMessageFilter.
167  void DoSendFilledMailboxBufferOnIOThread(
168      const VideoCaptureControllerID& controller_id,
169      int buffer_id,
170      const gpu::MailboxHolder& mailbox_holder,
171      const media::VideoCaptureFormat& format,
172      base::TimeTicks timestamp);
173
174  // Handles error coming from VideoCaptureDevice.
175  void DoHandleErrorOnIOThread(const VideoCaptureControllerID& controller_id);
176
177  void DoEndedOnIOThread(const VideoCaptureControllerID& controller_id);
178
179  // Deletes the controller and notifies the VideoCaptureManager. |on_error| is
180  // true if this is triggered by VideoCaptureControllerEventHandler::OnError.
181  void DeleteVideoCaptureControllerOnIOThread(
182      const VideoCaptureControllerID& controller_id, bool on_error);
183
184  MediaStreamManager* media_stream_manager_;
185
186  typedef std::map<VideoCaptureControllerID,
187                   base::WeakPtr<VideoCaptureController> > EntryMap;
188
189  // A map of VideoCaptureControllerID to the VideoCaptureController to which it
190  // is connected. An entry in this map holds a null controller while it is in
191  // the process of starting.
192  EntryMap entries_;
193
194  DISALLOW_COPY_AND_ASSIGN(VideoCaptureHost);
195};
196
197}  // namespace content
198
199#endif  // CONTENT_BROWSER_RENDERER_HOST_MEDIA_VIDEO_CAPTURE_HOST_H_
200