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,
77                                 bool* message_was_ok) OVERRIDE;
78
79  // VideoCaptureControllerEventHandler implementation.
80  virtual void OnError(const VideoCaptureControllerID& id) OVERRIDE;
81  virtual void OnBufferCreated(const VideoCaptureControllerID& id,
82                               base::SharedMemoryHandle handle,
83                               int length,
84                               int buffer_id) OVERRIDE;
85  virtual void OnBufferDestroyed(const VideoCaptureControllerID& id,
86                                 int buffer_id) OVERRIDE;
87  virtual void OnBufferReady(
88      const VideoCaptureControllerID& id,
89      int buffer_id,
90      base::Time timestamp,
91      const media::VideoCaptureFormat& format) OVERRIDE;
92  virtual void OnEnded(const VideoCaptureControllerID& id) OVERRIDE;
93
94 private:
95  friend class BrowserThread;
96  friend class base::DeleteHelper<VideoCaptureHost>;
97  friend class MockVideoCaptureHost;
98  friend class VideoCaptureHostTest;
99
100  virtual ~VideoCaptureHost();
101
102  // IPC message: Start capture on the VideoCaptureDevice referenced by
103  // |session_id|. |device_id| is an id created by VideoCaptureMessageFilter
104  // to identify a session between a VideoCaptureMessageFilter and a
105  // VideoCaptureHost.
106  void OnStartCapture(int device_id,
107                      media::VideoCaptureSessionId session_id,
108                      const media::VideoCaptureParams& params);
109  void OnControllerAdded(
110      int device_id,
111      const base::WeakPtr<VideoCaptureController>& controller);
112  void DoControllerAddedOnIOThread(
113      int device_id,
114      const base::WeakPtr<VideoCaptureController>& controller);
115
116  // IPC message: Stop capture on device referenced by |device_id|.
117  void OnStopCapture(int device_id);
118
119  // IPC message: Pause capture on device referenced by |device_id|.
120  void OnPauseCapture(int device_id);
121
122  // IPC message: Receive an empty buffer from renderer. Send it to device
123  // referenced by |device_id|.
124  void OnReceiveEmptyBuffer(int device_id, int buffer_id);
125
126  // Send a newly created buffer to the VideoCaptureMessageFilter.
127  void DoSendNewBufferOnIOThread(
128      const VideoCaptureControllerID& controller_id,
129      base::SharedMemoryHandle handle,
130      int length,
131      int buffer_id);
132
133  void DoSendFreeBufferOnIOThread(
134      const VideoCaptureControllerID& controller_id,
135      int buffer_id);
136
137  // Send a filled buffer to the VideoCaptureMessageFilter.
138  void DoSendFilledBufferOnIOThread(
139      const VideoCaptureControllerID& controller_id,
140      int buffer_id,
141      base::Time timestamp,
142      const media::VideoCaptureFormat& format);
143
144  // Handle error coming from VideoCaptureDevice.
145  void DoHandleErrorOnIOThread(const VideoCaptureControllerID& controller_id);
146
147  void DoEndedOnIOThread(const VideoCaptureControllerID& controller_id);
148
149  void DeleteVideoCaptureControllerOnIOThread(
150      const VideoCaptureControllerID& controller_id);
151
152  MediaStreamManager* media_stream_manager_;
153
154  typedef std::map<VideoCaptureControllerID,
155                   base::WeakPtr<VideoCaptureController> > EntryMap;
156
157  // A map of VideoCaptureControllerID to the VideoCaptureController to which it
158  // is connected. An entry in this map holds a null controller while it is in
159  // the process of starting.
160  EntryMap entries_;
161
162  DISALLOW_COPY_AND_ASSIGN(VideoCaptureHost);
163};
164
165}  // namespace content
166
167#endif  // CONTENT_BROWSER_RENDERER_HOST_MEDIA_VIDEO_CAPTURE_HOST_H_
168