Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(121)

Side by Side Diff: content/browser/renderer_host/media/video_capture_host.cc

Issue 10537057: refactor VideoCaptureHost and VideoCaptureController. (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: Created 8 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « content/browser/renderer_host/media/video_capture_host.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "content/browser/renderer_host/media/video_capture_host.h" 5 #include "content/browser/renderer_host/media/video_capture_host.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/memory/scoped_ptr.h" 8 #include "base/memory/scoped_ptr.h"
9 #include "base/stl_util.h" 9 #include "base/stl_util.h"
10 #include "content/browser/renderer_host/media/media_stream_manager.h" 10 #include "content/browser/renderer_host/media/media_stream_manager.h"
11 #include "content/browser/renderer_host/media/video_capture_manager.h" 11 #include "content/browser/renderer_host/media/video_capture_manager.h"
12 #include "content/common/media/video_capture_messages.h" 12 #include "content/common/media/video_capture_messages.h"
13 13
14 using content::BrowserMessageFilter; 14 using content::BrowserMessageFilter;
15 using content::BrowserThread; 15 using content::BrowserThread;
16 16
17 struct VideoCaptureHost::Entry { 17 struct VideoCaptureHost::Entry {
18 Entry() : state(video_capture::kStopped) {} 18 Entry(VideoCaptureController* controller)
19 19 : controller(controller) {}
20 Entry(VideoCaptureController* controller, video_capture::State state)
21 : controller(controller),
22 state(state) {
23 }
24 20
25 ~Entry() {} 21 ~Entry() {}
26 22
27 scoped_refptr<VideoCaptureController> controller; 23 scoped_refptr<VideoCaptureController> controller;
28
29 // Record state of each VideoCaptureControllerID.
30 // There are 5 states:
31 // kStarting: host has requested a controller, but has not got it yet.
32 // kStarted: host got a controller and has called StartCapture.
33 // kStopping: renderer process requests StopCapture before host gets
34 // a controller.
35 // kStopped: host has called StopCapture.
36 // kError: an error occurred and capture is stopped consequently.
37 video_capture::State state;
38 }; 24 };
39 25
40 VideoCaptureHost::VideoCaptureHost(content::ResourceContext* resource_context, 26 VideoCaptureHost::VideoCaptureHost(content::ResourceContext* resource_context,
41 media::AudioManager* audio_manager) 27 media::AudioManager* audio_manager)
42 : resource_context_(resource_context), 28 : resource_context_(resource_context),
43 audio_manager_(audio_manager) { 29 audio_manager_(audio_manager) {
44 } 30 }
45 31
46 VideoCaptureHost::~VideoCaptureHost() {} 32 VideoCaptureHost::~VideoCaptureHost() {}
47 33
48 void VideoCaptureHost::OnChannelClosing() { 34 void VideoCaptureHost::OnChannelClosing() {
49 BrowserMessageFilter::OnChannelClosing(); 35 BrowserMessageFilter::OnChannelClosing();
50 36
51 // Since the IPC channel is gone, close all requested VideCaptureDevices. 37 // Since the IPC channel is gone, close all requested VideCaptureDevices.
52 for (EntryMap::iterator it = entries_.begin(); it != entries_.end(); it++) { 38 for (EntryMap::iterator it = entries_.begin(); it != entries_.end(); it++) {
53 VideoCaptureController* controller = it->second->controller; 39 VideoCaptureController* controller = it->second->controller;
54 if (controller) { 40 if (controller) {
55 VideoCaptureControllerID controller_id(it->first); 41 VideoCaptureControllerID controller_id(it->first);
56 controller->StopCapture(controller_id, this, true); 42 controller->StopCapture(controller_id, this);
57 GetVideoCaptureManager()->RemoveController(controller, this); 43 GetVideoCaptureManager()->RemoveController(controller, this);
58 } 44 }
59 } 45 }
60 STLDeleteValues(&entries_); 46 STLDeleteValues(&entries_);
61 } 47 }
62 48
63 void VideoCaptureHost::OnDestruct() const { 49 void VideoCaptureHost::OnDestruct() const {
64 BrowserThread::DeleteOnIOThread::Destruct(this); 50 BrowserThread::DeleteOnIOThread::Destruct(this);
65 } 51 }
66 52
67 /////////////////////////////////////////////////////////////////////////////// 53 ///////////////////////////////////////////////////////////////////////////////
68 54
69 // Implements VideoCaptureControllerEventHandler. 55 // Implements VideoCaptureControllerEventHandler.
70 void VideoCaptureHost::OnError(const VideoCaptureControllerID& id) { 56 void VideoCaptureHost::OnError(const VideoCaptureControllerID& controller_id) {
71 BrowserThread::PostTask( 57 BrowserThread::PostTask(
72 BrowserThread::IO, FROM_HERE, 58 BrowserThread::IO, FROM_HERE,
73 base::Bind(&VideoCaptureHost::DoHandleErrorOnIOThread, 59 base::Bind(&VideoCaptureHost::DoHandleErrorOnIOThread,
74 this, id.device_id)); 60 this, controller_id));
75 } 61 }
76 62
77 void VideoCaptureHost::OnBufferCreated( 63 void VideoCaptureHost::OnBufferCreated(
78 const VideoCaptureControllerID& id, 64 const VideoCaptureControllerID& controller_id,
79 base::SharedMemoryHandle handle, 65 base::SharedMemoryHandle handle,
80 int length, 66 int length,
81 int buffer_id) { 67 int buffer_id) {
82 BrowserThread::PostTask( 68 BrowserThread::PostTask(
83 BrowserThread::IO, FROM_HERE, 69 BrowserThread::IO, FROM_HERE,
84 base::Bind(&VideoCaptureHost::DoSendNewBufferOnIOThread, 70 base::Bind(&VideoCaptureHost::DoSendNewBufferOnIOThread,
85 this, id.device_id, handle, length, buffer_id)); 71 this, controller_id, handle, length, buffer_id));
86 } 72 }
87 73
88 void VideoCaptureHost::OnBufferReady( 74 void VideoCaptureHost::OnBufferReady(
89 const VideoCaptureControllerID& id, 75 const VideoCaptureControllerID& controller_id,
90 int buffer_id, 76 int buffer_id,
91 base::Time timestamp) { 77 base::Time timestamp) {
92 BrowserThread::PostTask( 78 BrowserThread::PostTask(
93 BrowserThread::IO, FROM_HERE, 79 BrowserThread::IO, FROM_HERE,
94 base::Bind(&VideoCaptureHost::DoSendFilledBufferOnIOThread, 80 base::Bind(&VideoCaptureHost::DoSendFilledBufferOnIOThread,
95 this, id.device_id, buffer_id, timestamp)); 81 this, controller_id, buffer_id, timestamp));
96 } 82 }
97 83
98 void VideoCaptureHost::OnFrameInfo(const VideoCaptureControllerID& id, 84 void VideoCaptureHost::OnFrameInfo(
99 int width, 85 const VideoCaptureControllerID& controller_id,
100 int height, 86 int width,
101 int frame_per_second) { 87 int height,
88 int frame_per_second) {
102 BrowserThread::PostTask( 89 BrowserThread::PostTask(
103 BrowserThread::IO, FROM_HERE, 90 BrowserThread::IO, FROM_HERE,
104 base::Bind(&VideoCaptureHost::DoSendFrameInfoOnIOThread, 91 base::Bind(&VideoCaptureHost::DoSendFrameInfoOnIOThread,
105 this, id.device_id, width, height, frame_per_second)); 92 this, controller_id, width, height, frame_per_second));
106 } 93 }
107 94
108 void VideoCaptureHost::OnPaused(const VideoCaptureControllerID& id) { 95 void VideoCaptureHost::OnPaused(const VideoCaptureControllerID& controller_id) {
109 BrowserThread::PostTask( 96 BrowserThread::PostTask(
110 BrowserThread::IO, FROM_HERE, 97 BrowserThread::IO, FROM_HERE,
111 base::Bind(&VideoCaptureHost::DoPausedOnIOThread, this, id.device_id)); 98 base::Bind(&VideoCaptureHost::DoPausedOnIOThread, this, controller_id));
112 }
113
114 void VideoCaptureHost::OnReadyToDelete(const VideoCaptureControllerID& id) {
115 BrowserThread::PostTask(
116 BrowserThread::IO, FROM_HERE,
117 base::Bind(&VideoCaptureHost::DoDeleteVideoCaptureControllerOnIOThread,
118 this, id));
119 } 99 }
120 100
121 void VideoCaptureHost::DoSendNewBufferOnIOThread( 101 void VideoCaptureHost::DoSendNewBufferOnIOThread(
122 int device_id, base::SharedMemoryHandle handle, 102 const VideoCaptureControllerID& controller_id,
123 int length, int buffer_id) { 103 base::SharedMemoryHandle handle,
104 int length,
105 int buffer_id) {
124 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 106 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
125 107
126 Send(new VideoCaptureMsg_NewBuffer(device_id, handle, 108 if (entries_.find(controller_id) == entries_.end())
109 return;
110
111 Send(new VideoCaptureMsg_NewBuffer(controller_id.device_id, handle,
127 length, buffer_id)); 112 length, buffer_id));
128 } 113 }
129 114
130 void VideoCaptureHost::DoSendFilledBufferOnIOThread( 115 void VideoCaptureHost::DoSendFilledBufferOnIOThread(
131 int device_id, int buffer_id, base::Time timestamp) { 116 const VideoCaptureControllerID& controller_id,
117 int buffer_id, base::Time timestamp) {
132 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 118 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
133 119
134 Send(new VideoCaptureMsg_BufferReady(device_id, buffer_id, 120 if (entries_.find(controller_id) == entries_.end())
121 return;
122
123 Send(new VideoCaptureMsg_BufferReady(controller_id.device_id, buffer_id,
135 timestamp)); 124 timestamp));
136 } 125 }
137 126
138 void VideoCaptureHost::DoHandleErrorOnIOThread(int device_id) { 127 void VideoCaptureHost::DoHandleErrorOnIOThread(
128 const VideoCaptureControllerID& controller_id) {
139 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 129 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
140 130
141 VideoCaptureControllerID id(device_id); 131 if (entries_.find(controller_id) == entries_.end())
142 EntryMap::iterator it = entries_.find(id);
143 if (it == entries_.end() || it->second->state == video_capture::kError)
144 return; 132 return;
145 133
146 it->second->state = video_capture::kError; 134 Send(new VideoCaptureMsg_StateChanged(controller_id.device_id,
147 Send(new VideoCaptureMsg_StateChanged(device_id,
148 video_capture::kError)); 135 video_capture::kError));
149 136 DeleteVideoCaptureControllerOnIOThread(controller_id);
150 VideoCaptureController* controller = it->second->controller;
151 controller->StopCapture(id, this, false);
152 } 137 }
153 138
154 void VideoCaptureHost::DoPausedOnIOThread(int device_id) { 139 void VideoCaptureHost::DoPausedOnIOThread(
140 const VideoCaptureControllerID& controller_id) {
155 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 141 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
156 142
157 VideoCaptureControllerID id(device_id); 143 if (entries_.find(controller_id) == entries_.end())
158 EntryMap::iterator it = entries_.find(id);
159 if (it == entries_.end() || it->second->state == video_capture::kPaused)
160 return; 144 return;
161 145
162 it->second->state = video_capture::kPaused; 146 Send(new VideoCaptureMsg_StateChanged(controller_id.device_id,
163 Send(new VideoCaptureMsg_StateChanged(device_id,
164 video_capture::kPaused)); 147 video_capture::kPaused));
148 DeleteVideoCaptureControllerOnIOThread(controller_id);
165 } 149 }
166 150
167 void VideoCaptureHost::DoSendFrameInfoOnIOThread(int device_id, 151 void VideoCaptureHost::DoSendFrameInfoOnIOThread(
168 int width, 152 const VideoCaptureControllerID& controller_id,
169 int height, 153 int width, int height, int frame_per_second) {
170 int frame_per_second) {
171 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 154 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
172 155
156 if (entries_.find(controller_id) == entries_.end())
157 return;
158
173 media::VideoCaptureParams params; 159 media::VideoCaptureParams params;
174 params.width = width; 160 params.width = width;
175 params.height = height; 161 params.height = height;
176 params.frame_per_second = frame_per_second; 162 params.frame_per_second = frame_per_second;
177 Send(new VideoCaptureMsg_DeviceInfo(device_id, params)); 163 Send(new VideoCaptureMsg_DeviceInfo(controller_id.device_id, params));
178 Send(new VideoCaptureMsg_StateChanged(device_id, 164 Send(new VideoCaptureMsg_StateChanged(controller_id.device_id,
179 video_capture::kStarted)); 165 video_capture::kStarted));
180 } 166 }
181 167
182 /////////////////////////////////////////////////////////////////////////////// 168 ///////////////////////////////////////////////////////////////////////////////
183 // IPC Messages handler. 169 // IPC Messages handler.
184 bool VideoCaptureHost::OnMessageReceived(const IPC::Message& message, 170 bool VideoCaptureHost::OnMessageReceived(const IPC::Message& message,
185 bool* message_was_ok) { 171 bool* message_was_ok) {
186 bool handled = true; 172 bool handled = true;
187 IPC_BEGIN_MESSAGE_MAP_EX(VideoCaptureHost, message, *message_was_ok) 173 IPC_BEGIN_MESSAGE_MAP_EX(VideoCaptureHost, message, *message_was_ok)
188 IPC_MESSAGE_HANDLER(VideoCaptureHostMsg_Start, OnStartCapture) 174 IPC_MESSAGE_HANDLER(VideoCaptureHostMsg_Start, OnStartCapture)
(...skipping 11 matching lines...) Expand all
200 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 186 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
201 DVLOG(1) << "VideoCaptureHost::OnStartCapture, device_id " << device_id 187 DVLOG(1) << "VideoCaptureHost::OnStartCapture, device_id " << device_id
202 << ", (" << params.width 188 << ", (" << params.width
203 << ", " << params.height 189 << ", " << params.height
204 << ", " << params.frame_per_second 190 << ", " << params.frame_per_second
205 << ", " << params.session_id 191 << ", " << params.session_id
206 << ")"; 192 << ")";
207 VideoCaptureControllerID controller_id(device_id); 193 VideoCaptureControllerID controller_id(device_id);
208 DCHECK(entries_.find(controller_id) == entries_.end()); 194 DCHECK(entries_.find(controller_id) == entries_.end());
209 195
210 entries_[controller_id] = new Entry(NULL, video_capture::kStarting); 196 entries_[controller_id] = new Entry(NULL);
211 GetVideoCaptureManager()->AddController( 197 GetVideoCaptureManager()->AddController(
212 params, this, base::Bind(&VideoCaptureHost::OnControllerAdded, this, 198 params, this, base::Bind(&VideoCaptureHost::OnControllerAdded, this,
213 device_id, params)); 199 device_id, params));
214 } 200 }
215 201
216 void VideoCaptureHost::OnControllerAdded( 202 void VideoCaptureHost::OnControllerAdded(
217 int device_id, const media::VideoCaptureParams& params, 203 int device_id, const media::VideoCaptureParams& params,
218 VideoCaptureController* controller) { 204 VideoCaptureController* controller) {
219 BrowserThread::PostTask( 205 BrowserThread::PostTask(
220 BrowserThread::IO, FROM_HERE, 206 BrowserThread::IO, FROM_HERE,
221 base::Bind(&VideoCaptureHost::DoControllerAddedOnIOThread, 207 base::Bind(&VideoCaptureHost::DoControllerAddedOnIOThread,
222 this, device_id, params, make_scoped_refptr(controller))); 208 this, device_id, params, make_scoped_refptr(controller)));
223 } 209 }
224 210
225 void VideoCaptureHost::DoControllerAddedOnIOThread( 211 void VideoCaptureHost::DoControllerAddedOnIOThread(
226 int device_id, const media::VideoCaptureParams params, 212 int device_id, const media::VideoCaptureParams params,
227 VideoCaptureController* controller) { 213 VideoCaptureController* controller) {
228 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 214 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
229 VideoCaptureControllerID controller_id(device_id); 215 VideoCaptureControllerID controller_id(device_id);
230 EntryMap::iterator it = entries_.find(controller_id); 216 EntryMap::iterator it = entries_.find(controller_id);
231 DCHECK(it != entries_.end()); 217 if (it == entries_.end()) {
218 if (controller)
219 GetVideoCaptureManager()->RemoveController(controller, this);
220 return;
221 }
232 222
233 if (controller == NULL) { 223 if (controller == NULL) {
234 Send(new VideoCaptureMsg_StateChanged(device_id, 224 Send(new VideoCaptureMsg_StateChanged(device_id,
235 video_capture::kError)); 225 video_capture::kError));
226 delete it->second;
227 entries_.erase(controller_id);
236 return; 228 return;
237 } 229 }
238 230
239 Entry* entry = it->second; 231 it->second->controller = controller;
240 entry->controller = controller; 232 controller->StartCapture(controller_id, this, peer_handle(), params);
241 if (entry->state == video_capture::kStarting) {
242 entry->state = video_capture::kStarted;
243 controller->StartCapture(controller_id, this, peer_handle(), params);
244 } else if (entry->state == video_capture::kStopping) {
245 DoDeleteVideoCaptureControllerOnIOThread(controller_id);
246 } else {
247 NOTREACHED();
248 }
249 } 233 }
250 234
251 void VideoCaptureHost::OnStopCapture(int device_id) { 235 void VideoCaptureHost::OnStopCapture(int device_id) {
252 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 236 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
253 DVLOG(1) << "VideoCaptureHost::OnStopCapture, device_id " << device_id; 237 DVLOG(1) << "VideoCaptureHost::OnStopCapture, device_id " << device_id;
254 238
255 VideoCaptureControllerID controller_id(device_id); 239 VideoCaptureControllerID controller_id(device_id);
256 EntryMap::iterator it = entries_.find(controller_id);
257 240
258 if (it == entries_.end()) { 241 Send(new VideoCaptureMsg_StateChanged(device_id,
259 // It does not exist. So it must have been stopped already. 242 video_capture::kStopped));
260 Send(new VideoCaptureMsg_StateChanged(device_id, 243 DeleteVideoCaptureControllerOnIOThread(controller_id);
261 video_capture::kStopped));
262 return;
263 }
264
265 Entry* entry = it->second;
266 if (entry->state == video_capture::kStopping ||
267 entry->state == video_capture::kStopped ||
268 entry->state == video_capture::kError) {
269 return;
270 }
271
272 if (entry->controller) {
273 entry->state = video_capture::kStopped;
274 scoped_refptr<VideoCaptureController> controller = entry->controller;
275 controller->StopCapture(controller_id, this, false);
276 } else {
277 entry->state = video_capture::kStopping;
278 }
279 } 244 }
280 245
281 void VideoCaptureHost::OnPauseCapture(int device_id) { 246 void VideoCaptureHost::OnPauseCapture(int device_id) {
282 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 247 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
283 // Not used. 248 // Not used.
284 Send(new VideoCaptureMsg_StateChanged(device_id, 249 Send(new VideoCaptureMsg_StateChanged(device_id,
285 video_capture::kError)); 250 video_capture::kError));
286 } 251 }
287 252
288 void VideoCaptureHost::OnReceiveEmptyBuffer(int device_id, int buffer_id) { 253 void VideoCaptureHost::OnReceiveEmptyBuffer(int device_id, int buffer_id) {
289 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 254 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
290 255
291 VideoCaptureControllerID controller_id(device_id); 256 VideoCaptureControllerID controller_id(device_id);
292 EntryMap::iterator it = entries_.find(controller_id); 257 EntryMap::iterator it = entries_.find(controller_id);
293 if (it != entries_.end()) { 258 if (it != entries_.end()) {
294 scoped_refptr<VideoCaptureController> controller = it->second->controller; 259 scoped_refptr<VideoCaptureController> controller = it->second->controller;
295 controller->ReturnBuffer(controller_id, this, buffer_id); 260 if (controller)
261 controller->ReturnBuffer(controller_id, this, buffer_id);
296 } 262 }
297 } 263 }
298 264
299 void VideoCaptureHost::DoDeleteVideoCaptureControllerOnIOThread( 265 void VideoCaptureHost::DeleteVideoCaptureControllerOnIOThread(
300 const VideoCaptureControllerID& id) { 266 const VideoCaptureControllerID& controller_id) {
301 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 267 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
302 268
303 // Report that the device have successfully been stopped. 269 EntryMap::iterator it = entries_.find(controller_id);
304 Send(new VideoCaptureMsg_StateChanged(id.device_id, 270 if (it == entries_.end())
305 video_capture::kStopped)); 271 return;
306 EntryMap::iterator it = entries_.find(id); 272
307 if (it != entries_.end()) { 273 VideoCaptureController* controller = it->second->controller;
308 if (it->second->controller) { 274 if (controller) {
309 GetVideoCaptureManager()->RemoveController(it->second->controller, this); 275 controller->StopCapture(controller_id, this);
310 } 276 GetVideoCaptureManager()->RemoveController(controller, this);
311 delete it->second;
312 entries_.erase(id);
313 } 277 }
278 delete it->second;
279 entries_.erase(controller_id);
314 } 280 }
315 281
316 media_stream::VideoCaptureManager* VideoCaptureHost::GetVideoCaptureManager() { 282 media_stream::VideoCaptureManager* VideoCaptureHost::GetVideoCaptureManager() {
317 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 283 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
318 return media_stream::MediaStreamManager::GetForResourceContext( 284 return media_stream::MediaStreamManager::GetForResourceContext(
319 resource_context_, audio_manager_)->video_capture_manager(); 285 resource_context_, audio_manager_)->video_capture_manager();
320 } 286 }
OLDNEW
« no previous file with comments | « content/browser/renderer_host/media/video_capture_host.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698