OLD | NEW |
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" |
11 #include "media/base/bind_to_loop.h" | 11 #include "media/base/bind_to_loop.h" |
12 #include "media/base/limits.h" | 12 #include "media/base/limits.h" |
13 #include "media/base/video_frame.h" | |
14 | 13 |
15 namespace content { | 14 namespace content { |
16 | 15 |
17 class VideoCaptureImpl::ClientBuffer | 16 class VideoCaptureImpl::ClientBuffer |
18 : public base::RefCountedThreadSafe<ClientBuffer> { | 17 : public base::RefCountedThreadSafe<ClientBuffer> { |
19 public: | 18 public: |
20 ClientBuffer(scoped_ptr<base::SharedMemory> buffer, | 19 ClientBuffer(scoped_ptr<base::SharedMemory> buffer, |
21 size_t buffer_size) | 20 size_t buffer_size) |
22 : buffer(buffer.Pass()), | 21 : buffer(buffer.Pass()), |
23 buffer_size(buffer_size) {} | 22 buffer_size(buffer_size) {} |
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
153 clients_.find(handler) != clients_.end() ) { | 152 clients_.find(handler) != clients_.end() ) { |
154 // This client has started. | 153 // This client has started. |
155 } else if (!device_id_) { | 154 } else if (!device_id_) { |
156 clients_pending_on_filter_[handler] = params; | 155 clients_pending_on_filter_[handler] = params; |
157 } else { | 156 } else { |
158 handler->OnStarted(this); | 157 handler->OnStarted(this); |
159 if (state_ == VIDEO_CAPTURE_STATE_STARTED) { | 158 if (state_ == VIDEO_CAPTURE_STATE_STARTED) { |
160 clients_[handler] = params; | 159 clients_[handler] = params; |
161 } else if (state_ == VIDEO_CAPTURE_STATE_STOPPING) { | 160 } else if (state_ == VIDEO_CAPTURE_STATE_STOPPING) { |
162 clients_pending_on_restart_[handler] = params; | 161 clients_pending_on_restart_[handler] = params; |
163 DVLOG(1) << "StartCapture: Got new resolution " | 162 DVLOG(1) << "StartCapture: Got new resolution (" |
164 << params.requested_format.frame_size.ToString() | 163 << params.requested_format.width << ", " |
165 << " during stopping."; | 164 << params.requested_format.height << ") " |
| 165 << ", during stopping."; |
166 } else { | 166 } else { |
167 // TODO(sheu): Allowing resolution change will require that all | 167 DCHECK_EQ(params.session_id, 0); |
168 // outstanding clients of a capture session support resolution change. | |
169 DCHECK(!params.allow_resolution_change); | |
170 clients_[handler] = params; | 168 clients_[handler] = params; |
171 DCHECK_EQ(1ul, clients_.size()); | 169 DCHECK_EQ(1ul, clients_.size()); |
172 params_ = params; | 170 params_ = params; |
| 171 params_.session_id = session_id_; |
173 if (params_.requested_format.frame_rate > | 172 if (params_.requested_format.frame_rate > |
174 media::limits::kMaxFramesPerSecond) { | 173 media::limits::kMaxFramesPerSecond) { |
175 params_.requested_format.frame_rate = | 174 params_.requested_format.frame_rate = |
176 media::limits::kMaxFramesPerSecond; | 175 media::limits::kMaxFramesPerSecond; |
177 } | 176 } |
178 DVLOG(1) << "StartCapture: starting with first resolution " | 177 DVLOG(1) << "StartCapture: starting with first resolution (" |
179 << params_.requested_format.frame_size.ToString(); | 178 << params_.requested_format.width << "," |
| 179 << params_.requested_format.height << ")"; |
180 | 180 |
181 StartCaptureInternal(); | 181 StartCaptureInternal(); |
182 } | 182 } |
183 } | 183 } |
184 } | 184 } |
185 | 185 |
186 void VideoCaptureImpl::DoStopCaptureOnCaptureThread( | 186 void VideoCaptureImpl::DoStopCaptureOnCaptureThread( |
187 media::VideoCapture::EventHandler* handler) { | 187 media::VideoCapture::EventHandler* handler) { |
188 DCHECK(capture_message_loop_proxy_->BelongsToCurrentThread()); | 188 DCHECK(capture_message_loop_proxy_->BelongsToCurrentThread()); |
189 | 189 |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
245 base::Time timestamp, | 245 base::Time timestamp, |
246 const media::VideoCaptureFormat& format) { | 246 const media::VideoCaptureFormat& format) { |
247 DCHECK(capture_message_loop_proxy_->BelongsToCurrentThread()); | 247 DCHECK(capture_message_loop_proxy_->BelongsToCurrentThread()); |
248 | 248 |
249 if (state_ != VIDEO_CAPTURE_STATE_STARTED || suspended_) { | 249 if (state_ != VIDEO_CAPTURE_STATE_STARTED || suspended_) { |
250 Send(new VideoCaptureHostMsg_BufferReady(device_id_, buffer_id)); | 250 Send(new VideoCaptureHostMsg_BufferReady(device_id_, buffer_id)); |
251 return; | 251 return; |
252 } | 252 } |
253 | 253 |
254 last_frame_format_ = format; | 254 last_frame_format_ = format; |
| 255 gfx::Size size(format.width, format.height); |
255 | 256 |
256 ClientBufferMap::iterator iter = client_buffers_.find(buffer_id); | 257 ClientBufferMap::iterator iter = client_buffers_.find(buffer_id); |
257 DCHECK(iter != client_buffers_.end()); | 258 DCHECK(iter != client_buffers_.end()); |
258 scoped_refptr<ClientBuffer> buffer = iter->second; | 259 scoped_refptr<ClientBuffer> buffer = iter->second; |
259 scoped_refptr<media::VideoFrame> frame = | 260 scoped_refptr<media::VideoFrame> frame = |
260 media::VideoFrame::WrapExternalPackedMemory( | 261 media::VideoFrame::WrapExternalPackedMemory( |
261 media::VideoFrame::I420, | 262 media::VideoFrame::I420, |
262 last_frame_format_.frame_size, | 263 size, |
263 gfx::Rect(last_frame_format_.frame_size), | 264 gfx::Rect(size), |
264 last_frame_format_.frame_size, | 265 size, |
265 reinterpret_cast<uint8*>(buffer->buffer->memory()), | 266 reinterpret_cast<uint8*>(buffer->buffer->memory()), |
266 buffer->buffer_size, | 267 buffer->buffer_size, |
267 buffer->buffer->handle(), | 268 buffer->buffer->handle(), |
268 // TODO(sheu): convert VideoCaptureMessageFilter::Delegate to use | 269 // TODO(sheu): convert VideoCaptureMessageFilter::Delegate to use |
269 // base::TimeTicks instead of base::Time. http://crbug.com/249215 | 270 // base::TimeTicks instead of base::Time. http://crbug.com/249215 |
270 timestamp - base::Time::UnixEpoch(), | 271 timestamp - base::Time::UnixEpoch(), |
271 media::BindToLoop( | 272 media::BindToLoop( |
272 capture_message_loop_proxy_, | 273 capture_message_loop_proxy_, |
273 base::Bind( | 274 base::Bind( |
274 &VideoCaptureImpl::DoClientBufferFinishedOnCaptureThread, | 275 &VideoCaptureImpl::DoClientBufferFinishedOnCaptureThread, |
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
352 | 353 |
353 suspended_ = suspend; | 354 suspended_ = suspend; |
354 } | 355 } |
355 | 356 |
356 void VideoCaptureImpl::StopDevice() { | 357 void VideoCaptureImpl::StopDevice() { |
357 DCHECK(capture_message_loop_proxy_->BelongsToCurrentThread()); | 358 DCHECK(capture_message_loop_proxy_->BelongsToCurrentThread()); |
358 | 359 |
359 if (state_ == VIDEO_CAPTURE_STATE_STARTED) { | 360 if (state_ == VIDEO_CAPTURE_STATE_STARTED) { |
360 state_ = VIDEO_CAPTURE_STATE_STOPPING; | 361 state_ = VIDEO_CAPTURE_STATE_STOPPING; |
361 Send(new VideoCaptureHostMsg_Stop(device_id_)); | 362 Send(new VideoCaptureHostMsg_Stop(device_id_)); |
362 params_.requested_format.frame_size.SetSize(0, 0); | 363 params_.requested_format.width = params_.requested_format.height = 0; |
363 } | 364 } |
364 } | 365 } |
365 | 366 |
366 void VideoCaptureImpl::RestartCapture() { | 367 void VideoCaptureImpl::RestartCapture() { |
367 DCHECK(capture_message_loop_proxy_->BelongsToCurrentThread()); | 368 DCHECK(capture_message_loop_proxy_->BelongsToCurrentThread()); |
368 DCHECK_EQ(state_, VIDEO_CAPTURE_STATE_STOPPED); | 369 DCHECK_EQ(state_, VIDEO_CAPTURE_STATE_STOPPED); |
369 | 370 |
370 int width = 0; | 371 int width = 0; |
371 int height = 0; | 372 int height = 0; |
372 for (ClientInfo::iterator it = clients_.begin(); | 373 for (ClientInfo::iterator it = clients_.begin(); |
373 it != clients_.end(); ++it) { | 374 it != clients_.end(); ++it) { |
374 width = std::max(width, it->second.requested_format.frame_size.width()); | 375 width = std::max(width, it->second.requested_format.width); |
375 height = std::max(height, it->second.requested_format.frame_size.height()); | 376 height = std::max(height, it->second.requested_format.height); |
376 } | 377 } |
377 for (ClientInfo::iterator it = clients_pending_on_restart_.begin(); | 378 for (ClientInfo::iterator it = clients_pending_on_restart_.begin(); |
378 it != clients_pending_on_restart_.end(); ) { | 379 it != clients_pending_on_restart_.end(); ) { |
379 width = std::max(width, it->second.requested_format.frame_size.width()); | 380 width = std::max(width, it->second.requested_format.width); |
380 height = std::max(height, it->second.requested_format.frame_size.height()); | 381 height = std::max(height, it->second.requested_format.height); |
381 clients_[it->first] = it->second; | 382 clients_[it->first] = it->second; |
382 clients_pending_on_restart_.erase(it++); | 383 clients_pending_on_restart_.erase(it++); |
383 } | 384 } |
384 params_.requested_format.frame_size.SetSize(width, height); | 385 params_.requested_format.width = width; |
385 DVLOG(1) << "RestartCapture, " | 386 params_.requested_format.height = height; |
386 << params_.requested_format.frame_size.ToString(); | 387 DVLOG(1) << "RestartCapture, " << params_.requested_format.width << ", " |
| 388 << params_.requested_format.height; |
387 StartCaptureInternal(); | 389 StartCaptureInternal(); |
388 } | 390 } |
389 | 391 |
390 void VideoCaptureImpl::StartCaptureInternal() { | 392 void VideoCaptureImpl::StartCaptureInternal() { |
391 DCHECK(capture_message_loop_proxy_->BelongsToCurrentThread()); | 393 DCHECK(capture_message_loop_proxy_->BelongsToCurrentThread()); |
392 DCHECK(device_id_); | 394 DCHECK(device_id_); |
393 | 395 |
394 Send(new VideoCaptureHostMsg_Start(device_id_, session_id_, params_)); | 396 Send(new VideoCaptureHostMsg_Start(device_id_, params_)); |
395 state_ = VIDEO_CAPTURE_STATE_STARTED; | 397 state_ = VIDEO_CAPTURE_STATE_STARTED; |
396 } | 398 } |
397 | 399 |
398 void VideoCaptureImpl::AddDelegateOnIOThread() { | 400 void VideoCaptureImpl::AddDelegateOnIOThread() { |
399 DCHECK(io_message_loop_proxy_->BelongsToCurrentThread()); | 401 DCHECK(io_message_loop_proxy_->BelongsToCurrentThread()); |
400 message_filter_->AddDelegate(this); | 402 message_filter_->AddDelegate(this); |
401 } | 403 } |
402 | 404 |
403 void VideoCaptureImpl::RemoveDelegateOnIOThread(base::Closure task) { | 405 void VideoCaptureImpl::RemoveDelegateOnIOThread(base::Closure task) { |
404 DCHECK(io_message_loop_proxy_->BelongsToCurrentThread()); | 406 DCHECK(io_message_loop_proxy_->BelongsToCurrentThread()); |
(...skipping 17 matching lines...) Expand all Loading... |
422 if (it != clients->end()) { | 424 if (it != clients->end()) { |
423 handler->OnStopped(this); | 425 handler->OnStopped(this); |
424 handler->OnRemoved(this); | 426 handler->OnRemoved(this); |
425 clients->erase(it); | 427 clients->erase(it); |
426 found = true; | 428 found = true; |
427 } | 429 } |
428 return found; | 430 return found; |
429 } | 431 } |
430 | 432 |
431 } // namespace content | 433 } // namespace content |
OLD | NEW |