1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
|
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// VideoCaptureImpl represents a capture device in renderer process. It provides
// interfaces for clients to Start/Stop capture. It also communicates to clients
// when buffer is ready, state of capture device is changed.
// VideoCaptureImpl is also a delegate of VideoCaptureMessageFilter which
// relays operation of capture device to browser process and receives response
// from browser process.
// The media::VideoCapture and VideoCaptureMessageFilter::Delegate are
// asynchronous interfaces, which means callers can call those interfaces
// from any threads without worrying about thread safety.
// The |capture_message_loop_proxy_| is the working thread of VideoCaptureImpl.
// All non-const members are accessed only on that working thread.
//
// Implementation note: tasks are posted bound to Unretained(this) to both the
// I/O and Capture threads and this is safe (even though the I/O thread is
// scoped to the renderer process and the capture_message_loop_proxy_ thread is
// scoped to the VideoCaptureImplManager) because VideoCaptureImplManager only
// triggers deletion of its VideoCaptureImpl's by calling DeInit which detours
// through the capture & I/O threads, so as long as nobody posts tasks after the
// DeInit() call is made, it is guaranteed none of these Unretained posted tasks
// will dangle after the delete goes through. The "as long as" is guaranteed by
// clients of VideoCaptureImplManager not using devices after they've
// RemoveDevice'd them.
#ifndef CONTENT_RENDERER_MEDIA_VIDEO_CAPTURE_IMPL_H_
#define CONTENT_RENDERER_MEDIA_VIDEO_CAPTURE_IMPL_H_
#include <list>
#include <map>
#include "content/common/content_export.h"
#include "content/common/media/video_capture.h"
#include "content/renderer/media/video_capture_message_filter.h"
#include "media/video/capture/video_capture.h"
#include "media/video/capture/video_capture_types.h"
#include "media/video/encoded_video_source.h"
namespace base {
class MessageLoopProxy;
}
namespace content {
class CONTENT_EXPORT VideoCaptureImpl
: public media::VideoCapture,
public VideoCaptureMessageFilter::Delegate,
public media::EncodedVideoSource {
public:
// media::VideoCapture interface.
virtual void StartCapture(
media::VideoCapture::EventHandler* handler,
const media::VideoCaptureCapability& capability) OVERRIDE;
virtual void StopCapture(media::VideoCapture::EventHandler* handler) OVERRIDE;
virtual void FeedBuffer(scoped_refptr<VideoFrameBuffer> buffer) OVERRIDE;
virtual bool CaptureStarted() OVERRIDE;
virtual int CaptureWidth() OVERRIDE;
virtual int CaptureHeight() OVERRIDE;
virtual int CaptureFrameRate() OVERRIDE;
// VideoCaptureMessageFilter::Delegate interface.
virtual void OnBufferCreated(base::SharedMemoryHandle handle,
int length, int buffer_id) OVERRIDE;
virtual void OnBufferReceived(int buffer_id, base::Time timestamp) OVERRIDE;
virtual void OnStateChanged(VideoCaptureState state) OVERRIDE;
virtual void OnDeviceInfoReceived(
const media::VideoCaptureParams& device_info) OVERRIDE;
virtual void OnDelegateAdded(int32 device_id) OVERRIDE;
virtual void OnEncodingCapabilitiesAvailable(
const media::VideoEncodingCapabilities& capabilities) OVERRIDE;
virtual void OnEncodedBitstreamOpened(
const media::VideoEncodingParameters& params,
const std::vector<base::SharedMemoryHandle>& buffers,
uint32 buffer_size) OVERRIDE;
virtual void OnEncodedBitstreamClosed() OVERRIDE;
virtual void OnEncodingConfigChanged(
const media::RuntimeVideoEncodingParameters& params) OVERRIDE;
virtual void OnEncodedBufferReady(
int buffer_id,
uint32 size,
const media::BufferEncodingMetadata& metadata) OVERRIDE;
// media::EncodedVideoSource interface.
virtual void RequestCapabilities(
const RequestCapabilitiesCallback& callback) OVERRIDE;
virtual void OpenBitstream(
media::EncodedVideoSource::Client* client,
const media::VideoEncodingParameters& params) OVERRIDE;
virtual void CloseBitstream() OVERRIDE;
virtual void ReturnBitstreamBuffer(
scoped_refptr<const media::EncodedBitstreamBuffer> buffer) OVERRIDE;
virtual void TrySetBitstreamConfig(
const media::RuntimeVideoEncodingParameters& params) OVERRIDE;
// Stop/resume delivering video frames to clients, based on flag |suspend|.
virtual void SuspendCapture(bool suspend);
private:
friend class VideoCaptureImplManager;
friend class VideoCaptureImplTest;
friend class MockVideoCaptureImpl;
struct DIBBuffer;
typedef std::map<media::VideoCapture::EventHandler*,
media::VideoCaptureCapability> ClientInfo;
VideoCaptureImpl(media::VideoCaptureSessionId id,
base::MessageLoopProxy* capture_message_loop_proxy,
VideoCaptureMessageFilter* filter);
virtual ~VideoCaptureImpl();
void DoStartCaptureOnCaptureThread(
media::VideoCapture::EventHandler* handler,
const media::VideoCaptureCapability& capability);
void DoStopCaptureOnCaptureThread(media::VideoCapture::EventHandler* handler);
void DoFeedBufferOnCaptureThread(scoped_refptr<VideoFrameBuffer> buffer);
void DoBufferCreatedOnCaptureThread(base::SharedMemoryHandle handle,
int length, int buffer_id);
void DoBufferReceivedOnCaptureThread(int buffer_id, base::Time timestamp);
void DoStateChangedOnCaptureThread(VideoCaptureState state);
void DoDeviceInfoReceivedOnCaptureThread(
const media::VideoCaptureParams& device_info);
void DoDelegateAddedOnCaptureThread(int32 device_id);
void DoSuspendCaptureOnCaptureThread(bool suspend);
void StartFetchCapabilities();
void DoRequestCapabilitiesOnCaptureThread(
const RequestCapabilitiesCallback& callback);
void DoOpenBitstreamOnCaptureThread(
media::EncodedVideoSource::Client* client,
const media::VideoEncodingParameters& params);
void DoCloseBitstreamOnCaptureThread();
void DoNotifyBitstreamOpenedOnCaptureThread(
const media::VideoEncodingParameters& params,
const std::vector<base::SharedMemoryHandle>& buffers,
uint32 buffer_size);
void DoNotifyBitstreamClosedOnCaptureThread();
void DoNotifyBitstreamConfigChangedOnCaptureThread(
const media::RuntimeVideoEncodingParameters& params);
void DoNotifyBitstreamBufferReadyOnCaptureThread(
int buffer_id, uint32 size,
const media::BufferEncodingMetadata& metadata);
void DoNotifyCapabilitiesAvailableOnCaptureThread(
const media::VideoEncodingCapabilities& capabilities);
void Init();
void DeInit(base::Closure task);
void DoDeInitOnCaptureThread(base::Closure task);
void StopDevice();
void RestartCapture();
void StartCaptureInternal();
void AddDelegateOnIOThread();
void RemoveDelegateOnIOThread(base::Closure task);
virtual void Send(IPC::Message* message);
// Helpers.
bool ClientHasDIB() const;
bool RemoveClient(media::VideoCapture::EventHandler* handler,
ClientInfo* clients);
const scoped_refptr<VideoCaptureMessageFilter> message_filter_;
const scoped_refptr<base::MessageLoopProxy> capture_message_loop_proxy_;
const scoped_refptr<base::MessageLoopProxy> io_message_loop_proxy_;
int device_id_;
// Pool of DIBs. The key is buffer_id.
typedef std::map<int, DIBBuffer*> CachedDIB;
CachedDIB cached_dibs_;
ClientInfo clients_;
ClientInfo clients_pending_on_filter_;
ClientInfo clients_pending_on_restart_;
media::VideoCaptureCapability::Format video_type_;
// The parameter is being used in current capture session. A capture session
// starts with StartCapture and ends with StopCapture.
media::VideoCaptureParams current_params_;
// The information about the device sent from browser process side.
media::VideoCaptureParams device_info_;
bool device_info_available_;
bool suspended_;
VideoCaptureState state_;
// Video encoding capabilities as reported by the device.
media::VideoEncodingCapabilities encoding_caps_;
// Callback for RequestCapabilities().
RequestCapabilitiesCallback encoding_caps_callback_;
// Pointer to the EVS client.
media::EncodedVideoSource::Client* encoded_video_source_client_;
// Bitstream buffers returned by the video capture device. Unowned.
std::vector<base::SharedMemory*> bitstream_buffers_;
// |bitstream_open_| is set to true when renderer receives BitstreamOpened
// message acknowledging an OpenBitstream request, and is set to false when
// the EVS client requests to close bitstream, or when renderer receives
// BitstreamClosed message from the browser procses.
bool bitstream_open_;
DISALLOW_COPY_AND_ASSIGN(VideoCaptureImpl);
};
} // namespace content
#endif // CONTENT_RENDERER_MEDIA_VIDEO_CAPTURE_IMPL_H_
|