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

Side by Side Diff: content/renderer/media/video_capture_impl.cc

Issue 242013002: Refactor video capturing code in the render process (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: merged Created 6 years, 8 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
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/renderer/media/video_capture_impl.h" 5 #include "content/renderer/media/video_capture_impl.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/stl_util.h" 8 #include "base/stl_util.h"
9 #include "content/child/child_process.h" 9 #include "content/child/child_process.h"
10 #include "content/common/media/video_capture_messages.h" 10 #include "content/common/media/video_capture_messages.h"
(...skipping 14 matching lines...) Expand all
25 const size_t buffer_size; 25 const size_t buffer_size;
26 26
27 private: 27 private:
28 friend class base::RefCountedThreadSafe<ClientBuffer>; 28 friend class base::RefCountedThreadSafe<ClientBuffer>;
29 29
30 virtual ~ClientBuffer() {} 30 virtual ~ClientBuffer() {}
31 31
32 DISALLOW_COPY_AND_ASSIGN(ClientBuffer); 32 DISALLOW_COPY_AND_ASSIGN(ClientBuffer);
33 }; 33 };
34 34
35 bool VideoCaptureImpl::CaptureStarted() { 35 VideoCaptureImpl::ClientInfo::ClientInfo() {}
36 return state_ == VIDEO_CAPTURE_STATE_STARTED; 36 VideoCaptureImpl::ClientInfo::~ClientInfo() {}
37 }
38 37
39 int VideoCaptureImpl::CaptureFrameRate() { 38 int VideoCaptureImpl::CaptureFrameRate() {
40 return last_frame_format_.frame_rate; 39 return last_frame_format_.frame_rate;
41 } 40 }
42 41
43 VideoCaptureImpl::VideoCaptureImpl( 42 VideoCaptureImpl::VideoCaptureImpl(
44 const media::VideoCaptureSessionId session_id, 43 const media::VideoCaptureSessionId session_id,
45 VideoCaptureMessageFilter* filter) 44 VideoCaptureMessageFilter* filter)
46 : VideoCapture(), 45 : message_filter_(filter),
47 message_filter_(filter),
48 io_message_loop_proxy_(ChildProcess::current()->io_message_loop_proxy()),
49 device_id_(0), 46 device_id_(0),
50 session_id_(session_id), 47 session_id_(session_id),
51 suspended_(false), 48 suspended_(false),
52 state_(VIDEO_CAPTURE_STATE_STOPPED), 49 state_(VIDEO_CAPTURE_STATE_STOPPED),
53 weak_factory_(this) { 50 weak_factory_(this) {
54 DCHECK(filter); 51 DCHECK(filter);
52 thread_checker_.DetachFromThread();
55 } 53 }
56 54
57 VideoCaptureImpl::~VideoCaptureImpl() {} 55 VideoCaptureImpl::~VideoCaptureImpl() {
56 DCHECK(thread_checker_.CalledOnValidThread());
57 }
58 58
59 void VideoCaptureImpl::Init() { 59 void VideoCaptureImpl::Init() {
60 io_message_loop_proxy_->PostTask(FROM_HERE, 60 DCHECK(thread_checker_.CalledOnValidThread());
61 base::Bind(&VideoCaptureImpl::InitOnIOThread, 61 message_filter_->AddDelegate(this);
62 base::Unretained(this)));
63 } 62 }
64 63
65 void VideoCaptureImpl::DeInit(base::Closure done_cb) { 64 void VideoCaptureImpl::DeInit() {
66 io_message_loop_proxy_->PostTask(FROM_HERE, 65 DCHECK(thread_checker_.CalledOnValidThread());
67 base::Bind(&VideoCaptureImpl::DeInitOnIOThread, 66 if (state_ == VIDEO_CAPTURE_STATE_STARTED)
68 base::Unretained(this), 67 Send(new VideoCaptureHostMsg_Stop(device_id_));
69 done_cb)); 68 message_filter_->RemoveDelegate(this);
70 } 69 }
71 70
72 void VideoCaptureImpl::SuspendCapture(bool suspend) { 71 void VideoCaptureImpl::SuspendCapture(bool suspend) {
73 io_message_loop_proxy_->PostTask(FROM_HERE, 72 DCHECK(thread_checker_.CalledOnValidThread());
74 base::Bind(&VideoCaptureImpl::SuspendCaptureOnIOThread, 73 suspended_ = suspend;
75 base::Unretained(this),
76 suspend));
77 } 74 }
78 75
79 void VideoCaptureImpl::StartCapture( 76 void VideoCaptureImpl::StartCapture(
80 media::VideoCapture::EventHandler* handler, 77 int client_id,
81 const media::VideoCaptureParams& params) { 78 const media::VideoCaptureParams& params,
82 io_message_loop_proxy_->PostTask(FROM_HERE, 79 const VideoCaptureStateUpdateCB& state_update_cb,
83 base::Bind(&VideoCaptureImpl::StartCaptureOnIOThread, 80 const VideoCaptureDeliverFrameCB& deliver_frame_cb) {
84 base::Unretained(this), handler, params)); 81 DCHECK(thread_checker_.CalledOnValidThread());
85 } 82 ClientInfo client_info;
83 client_info.params = params;
84 client_info.state_update_cb = state_update_cb;
85 client_info.deliver_frame_cb = deliver_frame_cb;
86 86
87 void VideoCaptureImpl::StopCapture(
88 media::VideoCapture::EventHandler* handler) {
89 io_message_loop_proxy_->PostTask(FROM_HERE,
90 base::Bind(&VideoCaptureImpl::StopCaptureOnIOThread,
91 base::Unretained(this), handler));
92 }
93
94 void VideoCaptureImpl::GetDeviceSupportedFormats(
95 const DeviceFormatsCallback& callback) {
96 DCHECK(!callback.is_null());
97 io_message_loop_proxy_->PostTask(FROM_HERE,
98 base::Bind(&VideoCaptureImpl::GetDeviceSupportedFormatsOnIOThread,
99 base::Unretained(this), media::BindToCurrentLoop(callback)));
100 }
101
102 void VideoCaptureImpl::GetDeviceFormatsInUse(
103 const DeviceFormatsInUseCallback& callback) {
104 DCHECK(!callback.is_null());
105 io_message_loop_proxy_->PostTask(FROM_HERE,
106 base::Bind(&VideoCaptureImpl::GetDeviceFormatsInUseOnIOThread,
107 base::Unretained(this), media::BindToCurrentLoop(callback)));
108 }
109
110 void VideoCaptureImpl::InitOnIOThread() {
111 DCHECK(io_message_loop_proxy_->BelongsToCurrentThread());
112 message_filter_->AddDelegate(this);
113 }
114
115 void VideoCaptureImpl::DeInitOnIOThread(base::Closure done_cb) {
116 DCHECK(io_message_loop_proxy_->BelongsToCurrentThread());
117 if (state_ == VIDEO_CAPTURE_STATE_STARTED)
118 Send(new VideoCaptureHostMsg_Stop(device_id_));
119 message_filter_->RemoveDelegate(this);
120 done_cb.Run();
121 }
122
123 void VideoCaptureImpl::SuspendCaptureOnIOThread(bool suspend) {
124 DCHECK(io_message_loop_proxy_->BelongsToCurrentThread());
125 suspended_ = suspend;
126 }
127
128 void VideoCaptureImpl::StartCaptureOnIOThread(
129 media::VideoCapture::EventHandler* handler,
130 const media::VideoCaptureParams& params) {
131 DCHECK(io_message_loop_proxy_->BelongsToCurrentThread());
132 if (state_ == VIDEO_CAPTURE_STATE_ERROR) { 87 if (state_ == VIDEO_CAPTURE_STATE_ERROR) {
133 handler->OnError(this, 1); 88 state_update_cb.Run(VIDEO_CAPTURE_STATE_ERROR);
134 handler->OnRemoved(this); 89 } else if ((clients_pending_on_filter_.find(client_id) !=
Ami GONE FROM CHROMIUM 2014/04/21 23:42:53 map_.find(foo) != map_.end() is shorter to write a
Alpha Left Google 2014/04/23 18:48:33 Done.
135 } else if ((clients_pending_on_filter_.find(handler) !=
136 clients_pending_on_filter_.end()) || 90 clients_pending_on_filter_.end()) ||
137 (clients_pending_on_restart_.find(handler) != 91 (clients_pending_on_restart_.find(client_id) !=
138 clients_pending_on_restart_.end()) || 92 clients_pending_on_restart_.end()) ||
139 clients_.find(handler) != clients_.end() ) { 93 clients_.find(client_id) != clients_.end() ) {
140 // This client has started. 94 // This client has started.
Ami GONE FROM CHROMIUM 2014/04/21 23:42:53 what about the callbacks? This seems like it shou
Alpha Left Google 2014/04/23 18:48:33 Done.
141 } else if (!device_id_) { 95 } else if (!device_id_) {
142 clients_pending_on_filter_[handler] = params; 96 clients_pending_on_filter_[client_id] = client_info;
143 } else { 97 } else {
144 handler->OnStarted(this); 98 // Note: |state_| might not be started at this point. But we tell
99 // client that we have started.
100 state_update_cb.Run(VIDEO_CAPTURE_STATE_STARTED);
145 if (state_ == VIDEO_CAPTURE_STATE_STARTED) { 101 if (state_ == VIDEO_CAPTURE_STATE_STARTED) {
146 clients_[handler] = params; 102 clients_[client_id] = client_info;
147 // TODO(sheu): Allowing resolution change will require that all 103 // TODO(sheu): Allowing resolution change will require that all
148 // outstanding clients of a capture session support resolution change. 104 // outstanding clients of a capture session support resolution change.
149 DCHECK_EQ(params_.allow_resolution_change, 105 DCHECK_EQ(params_.allow_resolution_change,
150 params.allow_resolution_change); 106 params.allow_resolution_change);
151 } else if (state_ == VIDEO_CAPTURE_STATE_STOPPING) { 107 } else if (state_ == VIDEO_CAPTURE_STATE_STOPPING) {
152 clients_pending_on_restart_[handler] = params; 108 clients_pending_on_restart_[client_id] = client_info;
153 DVLOG(1) << "StartCapture: Got new resolution " 109 DVLOG(1) << "StartCapture: Got new resolution "
154 << params.requested_format.frame_size.ToString() 110 << params.requested_format.frame_size.ToString()
155 << " during stopping."; 111 << " during stopping.";
156 } else { 112 } else {
157 clients_[handler] = params; 113 clients_[client_id] = client_info;
158 DCHECK_EQ(1ul, clients_.size()); 114 DCHECK_EQ(1ul, clients_.size());
Ami GONE FROM CHROMIUM 2014/04/21 23:42:53 'l' should not be necessary here.
Ami GONE FROM CHROMIUM 2014/04/21 23:42:53 what prevents two clients from registering almost-
Alpha Left Google 2014/04/23 18:48:33 Done.
Alpha Left Google 2014/04/23 18:48:33 I *think* the intention in this code is to verify
159 params_ = params; 115 params_ = params;
160 if (params_.requested_format.frame_rate > 116 if (params_.requested_format.frame_rate >
161 media::limits::kMaxFramesPerSecond) { 117 media::limits::kMaxFramesPerSecond) {
162 params_.requested_format.frame_rate = 118 params_.requested_format.frame_rate =
163 media::limits::kMaxFramesPerSecond; 119 media::limits::kMaxFramesPerSecond;
164 } 120 }
165 DVLOG(1) << "StartCapture: starting with first resolution " 121 DVLOG(1) << "StartCapture: starting with first resolution "
166 << params_.requested_format.frame_size.ToString(); 122 << params_.requested_format.frame_size.ToString();
167 first_frame_timestamp_ = base::TimeTicks(); 123 first_frame_timestamp_ = base::TimeTicks();
168 StartCaptureInternal(); 124 StartCaptureInternal();
169 } 125 }
170 } 126 }
171 } 127 }
172 128
173 void VideoCaptureImpl::StopCaptureOnIOThread( 129 void VideoCaptureImpl::StopCapture(int client_id) {
174 media::VideoCapture::EventHandler* handler) { 130 DCHECK(thread_checker_.CalledOnValidThread());
175 DCHECK(io_message_loop_proxy_->BelongsToCurrentThread());
176 131
177 // A handler can be in only one client list. 132 // A client ID can be in only one client list.
178 // If this handler is in any client list, we can just remove it from 133 // If this ID is in any client list, we can just remove it from
179 // that client list and don't have to run the other following RemoveClient(). 134 // that client list and don't have to run the other following RemoveClient().
180 RemoveClient(handler, &clients_pending_on_filter_) || 135 RemoveClient(client_id, &clients_pending_on_filter_) ||
181 RemoveClient(handler, &clients_pending_on_restart_) || 136 RemoveClient(client_id, &clients_pending_on_restart_) ||
182 RemoveClient(handler, &clients_); 137 RemoveClient(client_id, &clients_);
Ami GONE FROM CHROMIUM 2014/04/21 23:42:53 ick to using boolean short-cutting like this (in a
Alpha Left Google 2014/04/23 18:48:33 RemoveClient actually calls the client and give it
183 138
184 if (clients_.empty()) { 139 if (clients_.empty()) {
185 DVLOG(1) << "StopCapture: No more client, stopping ..."; 140 DVLOG(1) << "StopCapture: No more client, stopping ...";
186 StopDevice(); 141 StopDevice();
187 client_buffers_.clear(); 142 client_buffers_.clear();
188 weak_factory_.InvalidateWeakPtrs(); 143 weak_factory_.InvalidateWeakPtrs();
189 } 144 }
190 } 145 }
191 146
192 void VideoCaptureImpl::GetDeviceSupportedFormatsOnIOThread( 147 void VideoCaptureImpl::GetDeviceSupportedFormats(
193 const DeviceFormatsCallback& callback) { 148 const VideoCaptureDeviceFormatsCB& callback) {
194 DCHECK(io_message_loop_proxy_->BelongsToCurrentThread()); 149 DCHECK(thread_checker_.CalledOnValidThread());
195 device_formats_callback_queue_.push_back(callback); 150 device_formats_cb_queue_.push_back(callback);
196 if (device_formats_callback_queue_.size() == 1) 151 if (device_formats_cb_queue_.size() == 1)
197 Send(new VideoCaptureHostMsg_GetDeviceSupportedFormats(device_id_, 152 Send(new VideoCaptureHostMsg_GetDeviceSupportedFormats(device_id_,
198 session_id_)); 153 session_id_));
199 } 154 }
200 155
201 void VideoCaptureImpl::GetDeviceFormatsInUseOnIOThread( 156 void VideoCaptureImpl::GetDeviceFormatsInUse(
202 const DeviceFormatsInUseCallback& callback) { 157 const VideoCaptureDeviceFormatsCB& callback) {
203 DCHECK(io_message_loop_proxy_->BelongsToCurrentThread()); 158 DCHECK(thread_checker_.CalledOnValidThread());
204 device_formats_in_use_callback_queue_.push_back(callback); 159 device_formats_in_use_cb_queue_.push_back(callback);
205 if (device_formats_in_use_callback_queue_.size() == 1) 160 if (device_formats_in_use_cb_queue_.size() == 1)
206 Send( 161 Send(
207 new VideoCaptureHostMsg_GetDeviceFormatsInUse(device_id_, session_id_)); 162 new VideoCaptureHostMsg_GetDeviceFormatsInUse(device_id_, session_id_));
208 } 163 }
209 164
210 void VideoCaptureImpl::OnBufferCreated( 165 void VideoCaptureImpl::OnBufferCreated(
211 base::SharedMemoryHandle handle, 166 base::SharedMemoryHandle handle,
212 int length, int buffer_id) { 167 int length, int buffer_id) {
213 DCHECK(io_message_loop_proxy_->BelongsToCurrentThread()); 168 DCHECK(thread_checker_.CalledOnValidThread());
214 169
215 // In case client calls StopCapture before the arrival of created buffer, 170 // In case client calls StopCapture before the arrival of created buffer,
216 // just close this buffer and return. 171 // just close this buffer and return.
217 if (state_ != VIDEO_CAPTURE_STATE_STARTED) { 172 if (state_ != VIDEO_CAPTURE_STATE_STARTED) {
218 base::SharedMemory::CloseHandle(handle); 173 base::SharedMemory::CloseHandle(handle);
219 return; 174 return;
220 } 175 }
221 176
222 scoped_ptr<base::SharedMemory> shm(new base::SharedMemory(handle, false)); 177 scoped_ptr<base::SharedMemory> shm(new base::SharedMemory(handle, false));
223 if (!shm->Map(length)) { 178 if (!shm->Map(length)) {
224 DLOG(ERROR) << "OnBufferCreated: Map failed."; 179 DLOG(ERROR) << "OnBufferCreated: Map failed.";
225 return; 180 return;
226 } 181 }
227 182
228 bool inserted = 183 bool inserted =
229 client_buffers_.insert(std::make_pair( 184 client_buffers_.insert(std::make_pair(
230 buffer_id, 185 buffer_id,
231 new ClientBuffer(shm.Pass(), 186 new ClientBuffer(shm.Pass(),
232 length))).second; 187 length))).second;
233 DCHECK(inserted); 188 DCHECK(inserted);
234 } 189 }
235 190
236 void VideoCaptureImpl::OnBufferDestroyed(int buffer_id) { 191 void VideoCaptureImpl::OnBufferDestroyed(int buffer_id) {
237 DCHECK(io_message_loop_proxy_->BelongsToCurrentThread()); 192 DCHECK(thread_checker_.CalledOnValidThread());
238 193
239 ClientBufferMap::iterator iter = client_buffers_.find(buffer_id); 194 ClientBufferMap::iterator iter = client_buffers_.find(buffer_id);
240 if (iter == client_buffers_.end()) 195 if (iter == client_buffers_.end())
241 return; 196 return;
242 197
243 DCHECK(!iter->second || iter->second->HasOneRef()) 198 DCHECK(!iter->second || iter->second->HasOneRef())
244 << "Instructed to delete buffer we are still using."; 199 << "Instructed to delete buffer we are still using.";
245 client_buffers_.erase(iter); 200 client_buffers_.erase(iter);
246 } 201 }
247 202
248 void VideoCaptureImpl::OnBufferReceived(int buffer_id, 203 void VideoCaptureImpl::OnBufferReceived(int buffer_id,
249 const media::VideoCaptureFormat& format, 204 const media::VideoCaptureFormat& format,
250 base::TimeTicks timestamp) { 205 base::TimeTicks timestamp) {
251 DCHECK(io_message_loop_proxy_->BelongsToCurrentThread()); 206 DCHECK(thread_checker_.CalledOnValidThread());
252 207
253 // The capture pipeline supports only I420 for now. 208 // The capture pipeline supports only I420 for now.
254 DCHECK_EQ(format.pixel_format, media::PIXEL_FORMAT_I420); 209 DCHECK_EQ(format.pixel_format, media::PIXEL_FORMAT_I420);
255 210
256 if (state_ != VIDEO_CAPTURE_STATE_STARTED || suspended_) { 211 if (state_ != VIDEO_CAPTURE_STATE_STARTED || suspended_) {
257 Send(new VideoCaptureHostMsg_BufferReady(device_id_, buffer_id, 0)); 212 Send(new VideoCaptureHostMsg_BufferReady(device_id_, buffer_id, 0));
258 return; 213 return;
259 } 214 }
260 215
261 last_frame_format_ = format; 216 last_frame_format_ = format;
(...skipping 20 matching lines...) Expand all
282 buffer->buffer_size, 237 buffer->buffer_size,
283 buffer->buffer->handle(), 238 buffer->buffer->handle(),
284 timestamp - first_frame_timestamp_, 239 timestamp - first_frame_timestamp_,
285 media::BindToCurrentLoop(base::Bind( 240 media::BindToCurrentLoop(base::Bind(
286 &VideoCaptureImpl::OnClientBufferFinished, 241 &VideoCaptureImpl::OnClientBufferFinished,
287 weak_factory_.GetWeakPtr(), 242 weak_factory_.GetWeakPtr(),
288 buffer_id, 243 buffer_id,
289 buffer, 244 buffer,
290 base::Passed(scoped_ptr<gpu::MailboxHolder>().Pass())))); 245 base::Passed(scoped_ptr<gpu::MailboxHolder>().Pass()))));
291 246
292 for (ClientInfo::iterator it = clients_.begin(); it != clients_.end(); ++it) 247 for (ClientInfoMap::iterator it = clients_.begin(); it != clients_.end();
293 it->first->OnFrameReady(this, frame); 248 ++it) {
249 it->second.deliver_frame_cb.Run(frame, format, timestamp);
250 }
294 } 251 }
295 252
296 static void NullReadPixelsCB(const SkBitmap& bitmap) { NOTIMPLEMENTED(); } 253 static void NullReadPixelsCB(const SkBitmap& bitmap) { NOTIMPLEMENTED(); }
297 254
298 void VideoCaptureImpl::OnMailboxBufferReceived( 255 void VideoCaptureImpl::OnMailboxBufferReceived(
299 int buffer_id, 256 int buffer_id,
300 const gpu::MailboxHolder& mailbox_holder, 257 const gpu::MailboxHolder& mailbox_holder,
301 const media::VideoCaptureFormat& format, 258 const media::VideoCaptureFormat& format,
302 base::TimeTicks timestamp) { 259 base::TimeTicks timestamp) {
303 DCHECK(io_message_loop_proxy_->BelongsToCurrentThread()); 260 DCHECK(thread_checker_.CalledOnValidThread());
304 261
305 if (state_ != VIDEO_CAPTURE_STATE_STARTED || suspended_) { 262 if (state_ != VIDEO_CAPTURE_STATE_STARTED || suspended_) {
306 Send(new VideoCaptureHostMsg_BufferReady( 263 Send(new VideoCaptureHostMsg_BufferReady(
307 device_id_, buffer_id, mailbox_holder.sync_point)); 264 device_id_, buffer_id, mailbox_holder.sync_point));
308 return; 265 return;
309 } 266 }
310 267
311 last_frame_format_ = format; 268 last_frame_format_ = format;
312 if (first_frame_timestamp_.is_null()) 269 if (first_frame_timestamp_.is_null())
313 first_frame_timestamp_ = timestamp; 270 first_frame_timestamp_ = timestamp;
314 271
315 scoped_refptr<media::VideoFrame> frame = media::VideoFrame::WrapNativeTexture( 272 scoped_refptr<media::VideoFrame> frame = media::VideoFrame::WrapNativeTexture(
316 make_scoped_ptr(new gpu::MailboxHolder(mailbox_holder)), 273 make_scoped_ptr(new gpu::MailboxHolder(mailbox_holder)),
317 media::BindToCurrentLoop( 274 media::BindToCurrentLoop(
318 base::Bind(&VideoCaptureImpl::OnClientBufferFinished, 275 base::Bind(&VideoCaptureImpl::OnClientBufferFinished,
319 weak_factory_.GetWeakPtr(), 276 weak_factory_.GetWeakPtr(),
320 buffer_id, 277 buffer_id,
321 scoped_refptr<ClientBuffer>())), 278 scoped_refptr<ClientBuffer>())),
322 last_frame_format_.frame_size, 279 last_frame_format_.frame_size,
323 gfx::Rect(last_frame_format_.frame_size), 280 gfx::Rect(last_frame_format_.frame_size),
324 last_frame_format_.frame_size, 281 last_frame_format_.frame_size,
325 timestamp - first_frame_timestamp_, 282 timestamp - first_frame_timestamp_,
326 base::Bind(&NullReadPixelsCB)); 283 base::Bind(&NullReadPixelsCB));
327 284
328 for (ClientInfo::iterator it = clients_.begin(); it != clients_.end(); ++it) 285 for (ClientInfoMap::iterator it = clients_.begin(); it != clients_.end();
329 it->first->OnFrameReady(this, frame); 286 ++it) {
287 it->second.deliver_frame_cb.Run(frame, format, timestamp);
288 }
330 } 289 }
331 290
332 void VideoCaptureImpl::OnClientBufferFinished( 291 void VideoCaptureImpl::OnClientBufferFinished(
333 int buffer_id, 292 int buffer_id,
334 const scoped_refptr<ClientBuffer>& /* ignored_buffer */, 293 const scoped_refptr<ClientBuffer>& /* ignored_buffer */,
335 scoped_ptr<gpu::MailboxHolder> mailbox_holder) { 294 scoped_ptr<gpu::MailboxHolder> mailbox_holder) {
336 DCHECK(io_message_loop_proxy_->BelongsToCurrentThread()); 295 DCHECK(thread_checker_.CalledOnValidThread());
337 const uint32 sync_point = (mailbox_holder ? mailbox_holder->sync_point : 0); 296 const uint32 sync_point = (mailbox_holder ? mailbox_holder->sync_point : 0);
338 Send(new VideoCaptureHostMsg_BufferReady(device_id_, buffer_id, sync_point)); 297 Send(new VideoCaptureHostMsg_BufferReady(device_id_, buffer_id, sync_point));
339 } 298 }
340 299
341 void VideoCaptureImpl::OnStateChanged(VideoCaptureState state) { 300 void VideoCaptureImpl::OnStateChanged(VideoCaptureState state) {
342 DCHECK(io_message_loop_proxy_->BelongsToCurrentThread()); 301 DCHECK(thread_checker_.CalledOnValidThread());
343 302
344 switch (state) { 303 switch (state) {
345 case VIDEO_CAPTURE_STATE_STARTED: 304 case VIDEO_CAPTURE_STATE_STARTED:
Ami GONE FROM CHROMIUM 2014/04/21 23:42:53 seems strange that this is a no-op.
Alpha Left Google 2014/04/23 18:48:33 Added a comment.
346 break; 305 break;
347 case VIDEO_CAPTURE_STATE_STOPPED: 306 case VIDEO_CAPTURE_STATE_STOPPED:
348 state_ = VIDEO_CAPTURE_STATE_STOPPED; 307 state_ = VIDEO_CAPTURE_STATE_STOPPED;
349 DVLOG(1) << "OnStateChanged: stopped!, device_id = " << device_id_; 308 DVLOG(1) << "OnStateChanged: stopped!, device_id = " << device_id_;
350 client_buffers_.clear(); 309 client_buffers_.clear();
351 weak_factory_.InvalidateWeakPtrs(); 310 weak_factory_.InvalidateWeakPtrs();
352 if (!clients_.empty() || !clients_pending_on_restart_.empty()) 311 if (!clients_.empty() || !clients_pending_on_restart_.empty())
353 RestartCapture(); 312 RestartCapture();
354 break; 313 break;
355 case VIDEO_CAPTURE_STATE_PAUSED: 314 case VIDEO_CAPTURE_STATE_PAUSED:
356 for (ClientInfo::iterator it = clients_.begin(); 315 for (ClientInfoMap::iterator it = clients_.begin();
357 it != clients_.end(); ++it) { 316 it != clients_.end(); ++it) {
358 it->first->OnPaused(this); 317 it->second.state_update_cb.Run(VIDEO_CAPTURE_STATE_PAUSED);
359 } 318 }
360 break; 319 break;
361 case VIDEO_CAPTURE_STATE_ERROR: 320 case VIDEO_CAPTURE_STATE_ERROR:
362 DVLOG(1) << "OnStateChanged: error!, device_id = " << device_id_; 321 DVLOG(1) << "OnStateChanged: error!, device_id = " << device_id_;
363 for (ClientInfo::iterator it = clients_.begin(); 322 for (ClientInfoMap::iterator it = clients_.begin();
364 it != clients_.end(); ++it) { 323 it != clients_.end(); ++it) {
365 // TODO(wjia): browser process would send error code. 324 it->second.state_update_cb.Run(VIDEO_CAPTURE_STATE_ERROR);
366 it->first->OnError(this, 1);
367 it->first->OnRemoved(this);
368 } 325 }
369 clients_.clear(); 326 clients_.clear();
370 state_ = VIDEO_CAPTURE_STATE_ERROR; 327 state_ = VIDEO_CAPTURE_STATE_ERROR;
371 break; 328 break;
372 case VIDEO_CAPTURE_STATE_ENDED: 329 case VIDEO_CAPTURE_STATE_ENDED:
373 DVLOG(1) << "OnStateChanged: ended!, device_id = " << device_id_; 330 DVLOG(1) << "OnStateChanged: ended!, device_id = " << device_id_;
374 for (ClientInfo::iterator it = clients_.begin(); 331 for (ClientInfoMap::iterator it = clients_.begin();
375 it != clients_.end(); ++it) { 332 it != clients_.end(); ++it) {
376 it->first->OnRemoved(this); 333 // We'll only notify the client that the stream has stopped.
334 it->second.state_update_cb.Run(VIDEO_CAPTURE_STATE_STOPPED);
377 } 335 }
378 clients_.clear(); 336 clients_.clear();
379 state_ = VIDEO_CAPTURE_STATE_ENDED; 337 state_ = VIDEO_CAPTURE_STATE_ENDED;
380 break; 338 break;
381 default: 339 default:
382 break; 340 break;
383 } 341 }
384 } 342 }
385 343
386 void VideoCaptureImpl::OnDeviceSupportedFormatsEnumerated( 344 void VideoCaptureImpl::OnDeviceSupportedFormatsEnumerated(
387 const media::VideoCaptureFormats& supported_formats) { 345 const media::VideoCaptureFormats& supported_formats) {
388 DCHECK(io_message_loop_proxy_->BelongsToCurrentThread()); 346 DCHECK(thread_checker_.CalledOnValidThread());
389 for (size_t i = 0; i < device_formats_callback_queue_.size(); ++i) 347 for (size_t i = 0; i < device_formats_cb_queue_.size(); ++i)
390 device_formats_callback_queue_[i].Run(supported_formats); 348 device_formats_cb_queue_[i].Run(supported_formats);
391 device_formats_callback_queue_.clear(); 349 device_formats_cb_queue_.clear();
392 } 350 }
393 351
394 void VideoCaptureImpl::OnDeviceFormatsInUseReceived( 352 void VideoCaptureImpl::OnDeviceFormatsInUseReceived(
395 const media::VideoCaptureFormats& formats_in_use) { 353 const media::VideoCaptureFormats& formats_in_use) {
396 DCHECK(io_message_loop_proxy_->BelongsToCurrentThread()); 354 DCHECK(thread_checker_.CalledOnValidThread());
397 for (size_t i = 0; i < device_formats_in_use_callback_queue_.size(); ++i) 355 for (size_t i = 0; i < device_formats_in_use_cb_queue_.size(); ++i)
398 device_formats_in_use_callback_queue_[i].Run(formats_in_use); 356 device_formats_in_use_cb_queue_[i].Run(formats_in_use);
399 device_formats_in_use_callback_queue_.clear(); 357 device_formats_in_use_cb_queue_.clear();
400 } 358 }
401 359
402 void VideoCaptureImpl::OnDelegateAdded(int32 device_id) { 360 void VideoCaptureImpl::OnDelegateAdded(int32 device_id) {
361 DCHECK(thread_checker_.CalledOnValidThread());
403 DVLOG(1) << "OnDelegateAdded: device_id " << device_id; 362 DVLOG(1) << "OnDelegateAdded: device_id " << device_id;
404 DCHECK(io_message_loop_proxy_->BelongsToCurrentThread());
405 363
406 device_id_ = device_id; 364 device_id_ = device_id;
407 for (ClientInfo::iterator it = clients_pending_on_filter_.begin(); 365 for (ClientInfoMap::iterator it = clients_pending_on_filter_.begin();
408 it != clients_pending_on_filter_.end(); ) { 366 it != clients_pending_on_filter_.end(); ) {
409 media::VideoCapture::EventHandler* handler = it->first; 367 int client_id = it->first;
410 const media::VideoCaptureParams params = it->second; 368 VideoCaptureStateUpdateCB state_update_cb =
369 it->second.state_update_cb;
370 VideoCaptureDeliverFrameCB deliver_frame_cb =
371 it->second.deliver_frame_cb;
372 const media::VideoCaptureParams params = it->second.params;
411 clients_pending_on_filter_.erase(it++); 373 clients_pending_on_filter_.erase(it++);
412 StartCapture(handler, params); 374 StartCapture(client_id, params, state_update_cb,
375 deliver_frame_cb);
413 } 376 }
414 } 377 }
415 378
416 void VideoCaptureImpl::StopDevice() { 379 void VideoCaptureImpl::StopDevice() {
417 DCHECK(io_message_loop_proxy_->BelongsToCurrentThread()); 380 DCHECK(thread_checker_.CalledOnValidThread());
418 381
419 if (state_ == VIDEO_CAPTURE_STATE_STARTED) { 382 if (state_ == VIDEO_CAPTURE_STATE_STARTED) {
420 state_ = VIDEO_CAPTURE_STATE_STOPPING; 383 state_ = VIDEO_CAPTURE_STATE_STOPPING;
421 Send(new VideoCaptureHostMsg_Stop(device_id_)); 384 Send(new VideoCaptureHostMsg_Stop(device_id_));
422 params_.requested_format.frame_size.SetSize(0, 0); 385 params_.requested_format.frame_size.SetSize(0, 0);
423 } 386 }
424 } 387 }
425 388
426 void VideoCaptureImpl::RestartCapture() { 389 void VideoCaptureImpl::RestartCapture() {
427 DCHECK(io_message_loop_proxy_->BelongsToCurrentThread()); 390 DCHECK(thread_checker_.CalledOnValidThread());
428 DCHECK_EQ(state_, VIDEO_CAPTURE_STATE_STOPPED); 391 DCHECK_EQ(state_, VIDEO_CAPTURE_STATE_STOPPED);
429 392
430 int width = 0; 393 int width = 0;
431 int height = 0; 394 int height = 0;
432 for (ClientInfo::iterator it = clients_.begin(); 395 for (ClientInfoMap::iterator it = clients_.begin();
433 it != clients_.end(); ++it) { 396 it != clients_.end(); ++it) {
434 width = std::max(width, it->second.requested_format.frame_size.width()); 397 width = std::max(width,
435 height = std::max(height, it->second.requested_format.frame_size.height()); 398 it->second.params.requested_format.frame_size.width());
399 height = std::max(height,
400 it->second.params.requested_format.frame_size.height());
436 } 401 }
437 for (ClientInfo::iterator it = clients_pending_on_restart_.begin(); 402 for (ClientInfoMap::iterator it = clients_pending_on_restart_.begin();
438 it != clients_pending_on_restart_.end(); ) { 403 it != clients_pending_on_restart_.end(); ) {
439 width = std::max(width, it->second.requested_format.frame_size.width()); 404 width = std::max(width,
440 height = std::max(height, it->second.requested_format.frame_size.height()); 405 it->second.params.requested_format.frame_size.width());
406 height = std::max(height,
407 it->second.params.requested_format.frame_size.height());
441 clients_[it->first] = it->second; 408 clients_[it->first] = it->second;
442 clients_pending_on_restart_.erase(it++); 409 clients_pending_on_restart_.erase(it++);
443 } 410 }
Ami GONE FROM CHROMIUM 2014/04/21 23:42:53 if you did clients_.insert(clients_pending_on_res
Alpha Left Google 2014/04/23 18:48:33 Done.
444 params_.requested_format.frame_size.SetSize(width, height); 411 params_.requested_format.frame_size.SetSize(width, height);
445 DVLOG(1) << "RestartCapture, " 412 DVLOG(1) << "RestartCapture, "
446 << params_.requested_format.frame_size.ToString(); 413 << params_.requested_format.frame_size.ToString();
447 StartCaptureInternal(); 414 StartCaptureInternal();
448 } 415 }
449 416
450 void VideoCaptureImpl::StartCaptureInternal() { 417 void VideoCaptureImpl::StartCaptureInternal() {
451 DCHECK(io_message_loop_proxy_->BelongsToCurrentThread()); 418 DCHECK(thread_checker_.CalledOnValidThread());
452 DCHECK(device_id_); 419 DCHECK(device_id_);
453 420
454 Send(new VideoCaptureHostMsg_Start(device_id_, session_id_, params_)); 421 Send(new VideoCaptureHostMsg_Start(device_id_, session_id_, params_));
455 state_ = VIDEO_CAPTURE_STATE_STARTED; 422 state_ = VIDEO_CAPTURE_STATE_STARTED;
456 } 423 }
457 424
458 void VideoCaptureImpl::Send(IPC::Message* message) { 425 void VideoCaptureImpl::Send(IPC::Message* message) {
459 io_message_loop_proxy_->PostTask(FROM_HERE, 426 DCHECK(thread_checker_.CalledOnValidThread());
460 base::Bind(base::IgnoreResult(&VideoCaptureMessageFilter::Send), 427 message_filter_->Send(message);
461 message_filter_.get(), message));
462 } 428 }
463 429
464 bool VideoCaptureImpl::RemoveClient( 430 bool VideoCaptureImpl::RemoveClient(int client_id, ClientInfoMap* clients) {
465 media::VideoCapture::EventHandler* handler, 431 DCHECK(thread_checker_.CalledOnValidThread());
466 ClientInfo* clients) {
467 DCHECK(io_message_loop_proxy_->BelongsToCurrentThread());
468 bool found = false; 432 bool found = false;
469 433
470 ClientInfo::iterator it = clients->find(handler); 434 ClientInfoMap::iterator it = clients->find(client_id);
471 if (it != clients->end()) { 435 if (it != clients->end()) {
472 handler->OnStopped(this); 436 it->second.state_update_cb.Run(VIDEO_CAPTURE_STATE_STOPPED);
473 handler->OnRemoved(this);
474 clients->erase(it); 437 clients->erase(it);
475 found = true; 438 found = true;
476 } 439 }
477 return found; 440 return found;
Ami GONE FROM CHROMIUM 2014/04/21 23:42:53 l.432-440 can be replaced with return clients->era
Alpha Left Google 2014/04/23 18:48:33 I still need it to send the client the stopped sig
478 } 441 }
479 442
480 } // namespace content 443 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698