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/common/child_process.h" | 9 #include "content/common/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. | |
Ami GONE FROM CHROMIUM
2013/06/12 01:44:06
s/is/are/
hshi1
2013/06/12 17:52:39
Done.
| |
111 if (!capabilities_.empty()) | |
112 callback_.Run(capabilities_); | |
Ami GONE FROM CHROMIUM
2013/06/12 01:44:06
Don't you want to clear the callback once it's run
hshi1
2013/06/12 17:52:39
Done. Thanks for the suggestion!
| |
113 } | |
114 | |
115 void VideoCaptureImpl::StartFetchCapabilities() { | |
116 capture_message_loop_proxy_->PostTask(FROM_HERE, | |
117 base::Bind(&VideoCaptureImpl::DoStartFetchCapabilitiesOnCaptureThread, | |
118 base::Unretained(this))); | |
Ami GONE FROM CHROMIUM
2013/06/12 01:44:06
Is it obvious why Unretained is safe here and belo
hshi1
2013/06/12 17:52:39
No it is not obvious. I'm using Unretained only be
| |
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 size_t 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_)); | |
Ami GONE FROM CHROMIUM
2013/06/12 01:44:06
Why proxy through this thread just to jump to the
hshi1
2013/06/12 17:52:39
I am puzzled as well but all the existing function
| |
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 size_t 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)) { | |
Ami GONE FROM CHROMIUM
2013/06/12 01:44:06
what if this fails?
better yet, why not map all SH
hshi1
2013/06/12 17:52:39
This wasn't possible with the IPC messages I defin
| |
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 |