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/encoded_video_source_messages.h" |
10 #include "content/common/media/video_capture_messages.h" | 11 #include "content/common/media/video_capture_messages.h" |
11 #include "media/base/limits.h" | 12 #include "media/base/limits.h" |
12 | 13 |
13 namespace content { | 14 namespace content { |
14 | 15 |
15 struct VideoCaptureImpl::DIBBuffer { | 16 struct VideoCaptureImpl::DIBBuffer { |
16 public: | 17 public: |
17 DIBBuffer( | 18 DIBBuffer( |
18 base::SharedMemory* d, | 19 base::SharedMemory* d, |
19 media::VideoCapture::VideoFrameBuffer* ptr) | 20 media::VideoCapture::VideoFrameBuffer* ptr) |
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
94 base::Bind(&VideoCaptureImpl::DoStartCaptureOnCaptureThread, | 95 base::Bind(&VideoCaptureImpl::DoStartCaptureOnCaptureThread, |
95 base::Unretained(this), handler, capability)); | 96 base::Unretained(this), handler, capability)); |
96 } | 97 } |
97 | 98 |
98 void VideoCaptureImpl::StopCapture(media::VideoCapture::EventHandler* handler) { | 99 void VideoCaptureImpl::StopCapture(media::VideoCapture::EventHandler* handler) { |
99 capture_message_loop_proxy_->PostTask(FROM_HERE, | 100 capture_message_loop_proxy_->PostTask(FROM_HERE, |
100 base::Bind(&VideoCaptureImpl::DoStopCaptureOnCaptureThread, | 101 base::Bind(&VideoCaptureImpl::DoStopCaptureOnCaptureThread, |
101 base::Unretained(this), handler)); | 102 base::Unretained(this), handler)); |
102 } | 103 } |
103 | 104 |
| 105 void VideoCaptureImpl::RequestCapabilities( |
| 106 const media::EncodedVideoSource::RequestCapabilitiesCallback& callback) { |
| 107 DCHECK(callback_.is_null()); |
| 108 callback_ = callback; |
| 109 |
| 110 // Invoke callback immediately if capabilities is already available. |
| 111 if (!capabilities_.empty()) |
| 112 callback_.Run(capabilities_); |
| 113 } |
| 114 |
| 115 void VideoCaptureImpl::StartFetchCapabilities() { |
| 116 capture_message_loop_proxy_->PostTask(FROM_HERE, |
| 117 base::Bind(&VideoCaptureImpl::DoStartFetchCapabilitiesOnCaptureThread, |
| 118 base::Unretained(this))); |
| 119 } |
| 120 |
| 121 void VideoCaptureImpl::OpenBitstream( |
| 122 media::EncodedVideoSource::Client* client, |
| 123 const media::VideoEncodingParameters& params) { |
| 124 DCHECK(!client_); |
| 125 client_ = client; |
| 126 capture_message_loop_proxy_->PostTask(FROM_HERE, |
| 127 base::Bind(&VideoCaptureImpl::DoOpenBitstreamOnCaptureThread, |
| 128 base::Unretained(this), params)); |
| 129 } |
| 130 |
| 131 void VideoCaptureImpl::CloseBitstream() { |
| 132 capture_message_loop_proxy_->PostTask(FROM_HERE, |
| 133 base::Bind(&VideoCaptureImpl::DoCloseBitstreamOnCaptureThread, |
| 134 base::Unretained(this))); |
| 135 client_ = NULL; |
| 136 } |
| 137 |
| 138 void VideoCaptureImpl::ReturnBitstreamBuffer( |
| 139 scoped_refptr<const media::EncodedBitstreamBuffer> buffer) { |
| 140 capture_message_loop_proxy_->PostTask(FROM_HERE, |
| 141 base::Bind(&VideoCaptureImpl::DoReturnBitstreamBufferOnCaptureThread, |
| 142 base::Unretained(this), buffer->buffer_id())); |
| 143 } |
| 144 |
| 145 void VideoCaptureImpl::TrySetBitstreamConfig( |
| 146 const media::RuntimeVideoEncodingParameters& params) { |
| 147 capture_message_loop_proxy_->PostTask(FROM_HERE, |
| 148 base::Bind(&VideoCaptureImpl::DoTrySetBitstreamConfigOnCaptureThread, |
| 149 base::Unretained(this), params)); |
| 150 } |
| 151 |
| 152 void VideoCaptureImpl::OnCapabilitiesAvailable( |
| 153 const media::VideoEncodingCapabilities& capabilities) { |
| 154 capabilities_ = capabilities; |
| 155 if (!callback_.is_null()) |
| 156 callback_.Run(capabilities_); |
| 157 } |
| 158 |
| 159 void VideoCaptureImpl::OnBitstreamOpened( |
| 160 const media::VideoEncodingParameters& params, |
| 161 const std::map<int, base::SharedMemoryHandle>& buffers) { |
| 162 capture_message_loop_proxy_->PostTask(FROM_HERE, |
| 163 base::Bind(&VideoCaptureImpl::DoNotifyBitstreamOpenedOnCaptureThread, |
| 164 base::Unretained(this), params, buffers)); |
| 165 } |
| 166 |
| 167 void VideoCaptureImpl::OnBitstreamClosed() { |
| 168 capture_message_loop_proxy_->PostTask(FROM_HERE, |
| 169 base::Bind(&VideoCaptureImpl::DoNotifyBitstreamClosedOnCaptureThread, |
| 170 base::Unretained(this))); |
| 171 } |
| 172 |
| 173 void VideoCaptureImpl::OnBitstreamConfigChanged( |
| 174 const media::RuntimeVideoEncodingParameters& params) { |
| 175 capture_message_loop_proxy_->PostTask(FROM_HERE, |
| 176 base::Bind( |
| 177 &VideoCaptureImpl::DoNotifyBitstreamConfigChangedOnCaptureThread, |
| 178 base::Unretained(this), params)); |
| 179 } |
| 180 |
| 181 void VideoCaptureImpl::OnBitstreamReady( |
| 182 int buffer_id, |
| 183 int size, |
| 184 const media::BufferEncodingMetadata& metadata) { |
| 185 capture_message_loop_proxy_->PostTask(FROM_HERE, |
| 186 base::Bind(&VideoCaptureImpl::DoNotifyBitstreamBufferReadyOnCaptureThread, |
| 187 base::Unretained(this), buffer_id, size, metadata)); |
| 188 } |
| 189 |
104 void VideoCaptureImpl::FeedBuffer(scoped_refptr<VideoFrameBuffer> buffer) { | 190 void VideoCaptureImpl::FeedBuffer(scoped_refptr<VideoFrameBuffer> buffer) { |
105 capture_message_loop_proxy_->PostTask(FROM_HERE, | 191 capture_message_loop_proxy_->PostTask(FROM_HERE, |
106 base::Bind(&VideoCaptureImpl::DoFeedBufferOnCaptureThread, | 192 base::Bind(&VideoCaptureImpl::DoFeedBufferOnCaptureThread, |
107 base::Unretained(this), buffer)); | 193 base::Unretained(this), buffer)); |
108 } | 194 } |
109 | 195 |
110 void VideoCaptureImpl::OnBufferCreated( | 196 void VideoCaptureImpl::OnBufferCreated( |
111 base::SharedMemoryHandle handle, | 197 base::SharedMemoryHandle handle, |
112 int length, int buffer_id) { | 198 int length, int buffer_id) { |
113 capture_message_loop_proxy_->PostTask(FROM_HERE, | 199 capture_message_loop_proxy_->PostTask(FROM_HERE, |
(...skipping 185 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
299 it->first->OnBufferReady(this, buffer); | 385 it->first->OnBufferReady(this, buffer); |
300 } | 386 } |
301 cached_dibs_[buffer_id]->references = clients_.size(); | 387 cached_dibs_[buffer_id]->references = clients_.size(); |
302 } | 388 } |
303 | 389 |
304 void VideoCaptureImpl::DoStateChangedOnCaptureThread(VideoCaptureState state) { | 390 void VideoCaptureImpl::DoStateChangedOnCaptureThread(VideoCaptureState state) { |
305 DCHECK(capture_message_loop_proxy_->BelongsToCurrentThread()); | 391 DCHECK(capture_message_loop_proxy_->BelongsToCurrentThread()); |
306 | 392 |
307 switch (state) { | 393 switch (state) { |
308 case VIDEO_CAPTURE_STATE_STARTED: | 394 case VIDEO_CAPTURE_STATE_STARTED: |
| 395 StartFetchCapabilities(); |
309 break; | 396 break; |
310 case VIDEO_CAPTURE_STATE_STOPPED: | 397 case VIDEO_CAPTURE_STATE_STOPPED: |
311 state_ = VIDEO_CAPTURE_STATE_STOPPED; | 398 state_ = VIDEO_CAPTURE_STATE_STOPPED; |
312 DVLOG(1) << "OnStateChanged: stopped!, device_id = " << device_id_; | 399 DVLOG(1) << "OnStateChanged: stopped!, device_id = " << device_id_; |
313 STLDeleteValues(&cached_dibs_); | 400 STLDeleteValues(&cached_dibs_); |
314 if (!clients_.empty() || !clients_pending_on_restart_.empty()) | 401 if (!clients_.empty() || !clients_pending_on_restart_.empty()) |
315 RestartCapture(); | 402 RestartCapture(); |
316 break; | 403 break; |
317 case VIDEO_CAPTURE_STATE_PAUSED: | 404 case VIDEO_CAPTURE_STATE_PAUSED: |
318 for (ClientInfo::iterator it = clients_.begin(); | 405 for (ClientInfo::iterator it = clients_.begin(); |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
373 } | 460 } |
374 } | 461 } |
375 | 462 |
376 void VideoCaptureImpl::DoSuspendCaptureOnCaptureThread(bool suspend) { | 463 void VideoCaptureImpl::DoSuspendCaptureOnCaptureThread(bool suspend) { |
377 DVLOG(1) << "DoSuspendCapture: suspend " << (suspend ? "yes" : "no"); | 464 DVLOG(1) << "DoSuspendCapture: suspend " << (suspend ? "yes" : "no"); |
378 DCHECK(capture_message_loop_proxy_->BelongsToCurrentThread()); | 465 DCHECK(capture_message_loop_proxy_->BelongsToCurrentThread()); |
379 | 466 |
380 suspended_ = suspend; | 467 suspended_ = suspend; |
381 } | 468 } |
382 | 469 |
| 470 void VideoCaptureImpl::DoStartFetchCapabilitiesOnCaptureThread() { |
| 471 DCHECK(capture_message_loop_proxy_->BelongsToCurrentThread()); |
| 472 Send(new EncodedVideoSourceHostMsg_GetCapabilities(device_id_)); |
| 473 } |
| 474 |
| 475 void VideoCaptureImpl::DoOpenBitstreamOnCaptureThread( |
| 476 const media::VideoEncodingParameters& params) { |
| 477 DCHECK(capture_message_loop_proxy_->BelongsToCurrentThread()); |
| 478 Send(new EncodedVideoSourceHostMsg_OpenBitstream(device_id_, params)); |
| 479 } |
| 480 |
| 481 void VideoCaptureImpl::DoCloseBitstreamOnCaptureThread() { |
| 482 DCHECK(capture_message_loop_proxy_->BelongsToCurrentThread()); |
| 483 Send(new EncodedVideoSourceHostMsg_CloseBitstream(device_id_)); |
| 484 } |
| 485 |
| 486 void VideoCaptureImpl::DoReturnBitstreamBufferOnCaptureThread(int buffer_id) { |
| 487 DCHECK(capture_message_loop_proxy_->BelongsToCurrentThread()); |
| 488 Send(new EncodedVideoSourceHostMsg_BitstreamBufferConsumed(device_id_, |
| 489 buffer_id)); |
| 490 } |
| 491 |
| 492 void VideoCaptureImpl::DoTrySetBitstreamConfigOnCaptureThread( |
| 493 const media::RuntimeVideoEncodingParameters& params) { |
| 494 DCHECK(capture_message_loop_proxy_->BelongsToCurrentThread()); |
| 495 Send(new EncodedVideoSourceHostMsg_TryConfigureBitstream(device_id_, params)); |
| 496 } |
| 497 |
| 498 void VideoCaptureImpl::DoNotifyBitstreamOpenedOnCaptureThread( |
| 499 const media::VideoEncodingParameters& params, |
| 500 const std::map<int, base::SharedMemoryHandle>& buffers) { |
| 501 std::map<int, base::SharedMemoryHandle>::const_iterator it; |
| 502 for (it = buffers.begin(); it != buffers.end(); ++it) { |
| 503 int buffer_id = it->first; |
| 504 buffers_[buffer_id] = new base::SharedMemory(it->second, true); |
| 505 } |
| 506 client_->OnStreaming(params); |
| 507 } |
| 508 |
| 509 void VideoCaptureImpl::DoNotifyBitstreamClosedOnCaptureThread() { |
| 510 std::map<int, base::SharedMemory*>::iterator it; |
| 511 for (it = buffers_.begin(); it != buffers_.end(); ++it) { |
| 512 if (it->second) { |
| 513 it->second->Close(); |
| 514 delete it->second; |
| 515 } |
| 516 } |
| 517 buffers_.clear(); |
| 518 client_->OnClosed(); |
| 519 } |
| 520 |
| 521 void VideoCaptureImpl::DoNotifyBitstreamConfigChangedOnCaptureThread( |
| 522 const media::RuntimeVideoEncodingParameters& params) { |
| 523 client_->OnConfigChanged(params); |
| 524 } |
| 525 |
| 526 void VideoCaptureImpl::DoNotifyBitstreamBufferReadyOnCaptureThread( |
| 527 int buffer_id, |
| 528 int size, |
| 529 const media::BufferEncodingMetadata& metadata) { |
| 530 if (buffers_.find(buffer_id) != buffers_.end()) { |
| 531 base::SharedMemory* shm = buffers_[buffer_id]; |
| 532 if (shm->Map(size)) { |
| 533 scoped_refptr<media::EncodedBitstreamBuffer> buffer = |
| 534 new media::EncodedBitstreamBuffer( |
| 535 buffer_id, (uint8*)shm->memory(), size, metadata); |
| 536 client_->OnBufferReady(buffer); |
| 537 shm->Unmap(); |
| 538 } |
| 539 } |
| 540 } |
| 541 |
383 void VideoCaptureImpl::StopDevice() { | 542 void VideoCaptureImpl::StopDevice() { |
384 DCHECK(capture_message_loop_proxy_->BelongsToCurrentThread()); | 543 DCHECK(capture_message_loop_proxy_->BelongsToCurrentThread()); |
385 | 544 |
386 device_info_available_ = false; | 545 device_info_available_ = false; |
387 if (state_ == VIDEO_CAPTURE_STATE_STARTED) { | 546 if (state_ == VIDEO_CAPTURE_STATE_STARTED) { |
388 state_ = VIDEO_CAPTURE_STATE_STOPPING; | 547 state_ = VIDEO_CAPTURE_STATE_STOPPING; |
389 Send(new VideoCaptureHostMsg_Stop(device_id_)); | 548 Send(new VideoCaptureHostMsg_Stop(device_id_)); |
390 current_params_.width = current_params_.height = 0; | 549 current_params_.width = current_params_.height = 0; |
391 } | 550 } |
392 } | 551 } |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
461 if (it != clients->end()) { | 620 if (it != clients->end()) { |
462 handler->OnStopped(this); | 621 handler->OnStopped(this); |
463 handler->OnRemoved(this); | 622 handler->OnRemoved(this); |
464 clients->erase(it); | 623 clients->erase(it); |
465 found = true; | 624 found = true; |
466 } | 625 } |
467 return found; | 626 return found; |
468 } | 627 } |
469 | 628 |
470 } // namespace content | 629 } // namespace content |
OLD | NEW |