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/browser/renderer_host/media/video_capture_controller.h" | 5 #include "content/browser/renderer_host/media/video_capture_controller.h" |
6 | 6 |
7 #include <stddef.h> | 7 #include <stddef.h> |
8 #include <stdint.h> | 8 #include <stdint.h> |
9 | 9 |
10 #include <map> | 10 #include <map> |
11 #include <set> | 11 #include <set> |
12 | 12 |
13 #include "base/bind.h" | 13 #include "base/bind.h" |
14 #include "base/command_line.h" | 14 #include "base/command_line.h" |
15 #include "base/memory/ptr_util.h" | 15 #include "base/memory/ptr_util.h" |
16 #include "base/metrics/histogram_macros.h" | 16 #include "base/metrics/histogram_macros.h" |
17 #include "base/metrics/sparse_histogram.h" | 17 #include "base/metrics/sparse_histogram.h" |
18 #include "build/build_config.h" | 18 #include "build/build_config.h" |
19 #include "components/display_compositor/gl_helper.h" | 19 #include "components/display_compositor/gl_helper.h" |
20 #include "content/browser/renderer_host/media/media_stream_manager.h" | 20 #include "content/browser/renderer_host/media/media_stream_manager.h" |
21 #include "content/browser/renderer_host/media/video_capture_buffer_pool.h" | 21 #include "content/browser/renderer_host/media/video_capture_buffer_pool.h" |
22 #include "content/browser/renderer_host/media/video_capture_device_client.h" | 22 #include "content/browser/renderer_host/media/video_capture_device_client.h" |
| 23 #include "content/browser/renderer_host/media/video_capture_gpu_jpeg_decoder.h" |
23 #include "content/browser/renderer_host/media/video_capture_manager.h" | 24 #include "content/browser/renderer_host/media/video_capture_manager.h" |
24 #include "content/public/browser/browser_thread.h" | 25 #include "content/public/browser/browser_thread.h" |
25 #include "content/public/common/content_switches.h" | 26 #include "content/public/common/content_switches.h" |
26 #include "media/base/video_frame.h" | 27 #include "media/base/video_frame.h" |
27 | 28 |
28 #if !defined(OS_ANDROID) | 29 #if !defined(OS_ANDROID) |
29 #include "content/browser/compositor/image_transport_factory.h" | 30 #include "content/browser/compositor/image_transport_factory.h" |
30 #endif | 31 #endif |
31 | 32 |
32 using media::VideoCaptureFormat; | 33 using media::VideoCaptureFormat; |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
71 // UpdateReleaseSyncToken() creates a new sync_token using |gl_helper|, so | 72 // UpdateReleaseSyncToken() creates a new sync_token using |gl_helper|, so |
72 // wait the given |sync_token| using |gl_helper|. | 73 // wait the given |sync_token| using |gl_helper|. |
73 if (gl_helper) { | 74 if (gl_helper) { |
74 gl_helper->WaitSyncToken(sync_token); | 75 gl_helper->WaitSyncToken(sync_token); |
75 SyncTokenClientImpl client(gl_helper); | 76 SyncTokenClientImpl client(gl_helper); |
76 video_frame->UpdateReleaseSyncToken(&client); | 77 video_frame->UpdateReleaseSyncToken(&client); |
77 } | 78 } |
78 #endif | 79 #endif |
79 } | 80 } |
80 | 81 |
| 82 std::unique_ptr<VideoCaptureJpegDecoder> CreateGpuJpegDecoder( |
| 83 const VideoCaptureJpegDecoder::DecodeDoneCB& decode_done_cb) { |
| 84 return base::MakeUnique<VideoCaptureGpuJpegDecoder>(decode_done_cb); |
| 85 } |
| 86 |
| 87 // Decorator for VideoFrameReceiver that forwards all incoming calls |
| 88 // to the Browser IO thread. |
| 89 class VideoFrameReceiverOnIOThread : public VideoFrameReceiver { |
| 90 public: |
| 91 explicit VideoFrameReceiverOnIOThread( |
| 92 const base::WeakPtr<VideoFrameReceiver>& receiver) |
| 93 : receiver_(receiver) {} |
| 94 |
| 95 void OnIncomingCapturedVideoFrame( |
| 96 std::unique_ptr<media::VideoCaptureDevice::Client::Buffer> buffer, |
| 97 const scoped_refptr<media::VideoFrame>& frame) override { |
| 98 BrowserThread::PostTask( |
| 99 BrowserThread::IO, FROM_HERE, |
| 100 base::Bind(&VideoFrameReceiver::OnIncomingCapturedVideoFrame, receiver_, |
| 101 base::Passed(&buffer), frame)); |
| 102 } |
| 103 |
| 104 void OnError() override { |
| 105 BrowserThread::PostTask( |
| 106 BrowserThread::IO, FROM_HERE, |
| 107 base::Bind(&VideoFrameReceiver::OnError, receiver_)); |
| 108 } |
| 109 |
| 110 void OnLog(const std::string& message) override { |
| 111 BrowserThread::PostTask( |
| 112 BrowserThread::IO, FROM_HERE, |
| 113 base::Bind(&VideoFrameReceiver::OnLog, receiver_, message)); |
| 114 } |
| 115 |
| 116 void OnBufferDestroyed(int buffer_id_to_drop) override { |
| 117 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, |
| 118 base::Bind(&VideoFrameReceiver::OnBufferDestroyed, |
| 119 receiver_, buffer_id_to_drop)); |
| 120 } |
| 121 |
| 122 private: |
| 123 base::WeakPtr<VideoFrameReceiver> receiver_; |
| 124 }; |
| 125 |
81 } // anonymous namespace | 126 } // anonymous namespace |
82 | 127 |
83 struct VideoCaptureController::ControllerClient { | 128 struct VideoCaptureController::ControllerClient { |
84 ControllerClient(VideoCaptureControllerID id, | 129 ControllerClient(VideoCaptureControllerID id, |
85 VideoCaptureControllerEventHandler* handler, | 130 VideoCaptureControllerEventHandler* handler, |
86 base::ProcessHandle render_process, | 131 base::ProcessHandle render_process, |
87 media::VideoCaptureSessionId session_id, | 132 media::VideoCaptureSessionId session_id, |
88 const media::VideoCaptureParams& params) | 133 const media::VideoCaptureParams& params) |
89 : controller_id(id), | 134 : controller_id(id), |
90 event_handler(handler), | 135 event_handler(handler), |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
124 // implicitly), we could avoid tracking this state here in the Controller, and | 169 // implicitly), we could avoid tracking this state here in the Controller, and |
125 // simplify the code in both places. | 170 // simplify the code in both places. |
126 bool session_closed; | 171 bool session_closed; |
127 | 172 |
128 // Indicates whether the client is paused, if true, VideoCaptureController | 173 // Indicates whether the client is paused, if true, VideoCaptureController |
129 // stops updating its buffer. | 174 // stops updating its buffer. |
130 bool paused; | 175 bool paused; |
131 }; | 176 }; |
132 | 177 |
133 VideoCaptureController::VideoCaptureController(int max_buffers) | 178 VideoCaptureController::VideoCaptureController(int max_buffers) |
134 : buffer_pool_(new VideoCaptureBufferPool(max_buffers)), | 179 : buffer_pool_(new VideoCaptureBufferPoolImpl(max_buffers)), |
135 state_(VIDEO_CAPTURE_STATE_STARTED), | 180 state_(VIDEO_CAPTURE_STATE_STARTED), |
136 has_received_frames_(false), | 181 has_received_frames_(false), |
137 weak_ptr_factory_(this) { | 182 weak_ptr_factory_(this) { |
138 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 183 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
139 } | 184 } |
140 | 185 |
141 base::WeakPtr<VideoCaptureController> | 186 base::WeakPtr<VideoCaptureController> |
142 VideoCaptureController::GetWeakPtrForIOThread() { | 187 VideoCaptureController::GetWeakPtrForIOThread() { |
143 return weak_ptr_factory_.GetWeakPtr(); | 188 return weak_ptr_factory_.GetWeakPtr(); |
144 } | 189 } |
145 | 190 |
146 std::unique_ptr<media::VideoCaptureDevice::Client> | 191 std::unique_ptr<media::VideoCaptureDevice::Client> |
147 VideoCaptureController::NewDeviceClient() { | 192 VideoCaptureController::NewDeviceClient() { |
148 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 193 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
149 return base::MakeUnique<VideoCaptureDeviceClient>( | 194 return base::MakeUnique<VideoCaptureDeviceClient>( |
150 this->GetWeakPtrForIOThread(), buffer_pool_); | 195 base::MakeUnique<VideoFrameReceiverOnIOThread>( |
| 196 this->GetWeakPtrForIOThread()), |
| 197 buffer_pool_, |
| 198 base::Bind(&CreateGpuJpegDecoder, |
| 199 base::Bind(&VideoFrameReceiver::OnIncomingCapturedVideoFrame, |
| 200 this->GetWeakPtrForIOThread()))); |
151 } | 201 } |
152 | 202 |
153 void VideoCaptureController::AddClient( | 203 void VideoCaptureController::AddClient( |
154 VideoCaptureControllerID id, | 204 VideoCaptureControllerID id, |
155 VideoCaptureControllerEventHandler* event_handler, | 205 VideoCaptureControllerEventHandler* event_handler, |
156 base::ProcessHandle render_process, | 206 base::ProcessHandle render_process, |
157 media::VideoCaptureSessionId session_id, | 207 media::VideoCaptureSessionId session_id, |
158 const media::VideoCaptureParams& params) { | 208 const media::VideoCaptureParams& params) { |
159 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 209 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
160 DVLOG(1) << "VideoCaptureController::AddClient() -- id=" << id | 210 DVLOG(1) << "VideoCaptureController::AddClient() -- id=" << id |
(...skipping 185 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
346 | 396 |
347 const media::VideoCaptureFormat& | 397 const media::VideoCaptureFormat& |
348 VideoCaptureController::GetVideoCaptureFormat() const { | 398 VideoCaptureController::GetVideoCaptureFormat() const { |
349 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 399 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
350 return video_capture_format_; | 400 return video_capture_format_; |
351 } | 401 } |
352 | 402 |
353 VideoCaptureController::~VideoCaptureController() { | 403 VideoCaptureController::~VideoCaptureController() { |
354 } | 404 } |
355 | 405 |
356 void VideoCaptureController::DoIncomingCapturedVideoFrameOnIOThread( | 406 void VideoCaptureController::OnIncomingCapturedVideoFrame( |
357 std::unique_ptr<media::VideoCaptureDevice::Client::Buffer> buffer, | 407 std::unique_ptr<media::VideoCaptureDevice::Client::Buffer> buffer, |
358 const scoped_refptr<VideoFrame>& frame) { | 408 const scoped_refptr<VideoFrame>& frame) { |
359 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 409 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
360 const int buffer_id = buffer->id(); | 410 const int buffer_id = buffer->id(); |
361 DCHECK_NE(buffer_id, VideoCaptureBufferPool::kInvalidId); | 411 DCHECK_NE(buffer_id, VideoCaptureBufferPool::kInvalidId); |
362 | 412 |
363 int count = 0; | 413 int count = 0; |
364 if (state_ == VIDEO_CAPTURE_STATE_STARTED) { | 414 if (state_ == VIDEO_CAPTURE_STATE_STARTED) { |
365 if (!frame->metadata()->HasKey(VideoFrameMetadata::FRAME_RATE)) { | 415 if (!frame->metadata()->HasKey(VideoFrameMetadata::FRAME_RATE)) { |
366 frame->metadata()->SetDouble(VideoFrameMetadata::FRAME_RATE, | 416 frame->metadata()->SetDouble(VideoFrameMetadata::FRAME_RATE, |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
417 &frame_rate)) { | 467 &frame_rate)) { |
418 frame_rate = video_capture_format_.frame_rate; | 468 frame_rate = video_capture_format_.frame_rate; |
419 } | 469 } |
420 UMA_HISTOGRAM_COUNTS("Media.VideoCapture.FrameRate", frame_rate); | 470 UMA_HISTOGRAM_COUNTS("Media.VideoCapture.FrameRate", frame_rate); |
421 has_received_frames_ = true; | 471 has_received_frames_ = true; |
422 } | 472 } |
423 | 473 |
424 buffer_pool_->HoldForConsumers(buffer_id, count); | 474 buffer_pool_->HoldForConsumers(buffer_id, count); |
425 } | 475 } |
426 | 476 |
427 void VideoCaptureController::DoErrorOnIOThread() { | 477 void VideoCaptureController::OnError() { |
428 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 478 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
429 state_ = VIDEO_CAPTURE_STATE_ERROR; | 479 state_ = VIDEO_CAPTURE_STATE_ERROR; |
430 | 480 |
431 for (const auto& client : controller_clients_) { | 481 for (const auto& client : controller_clients_) { |
432 if (client->session_closed) | 482 if (client->session_closed) |
433 continue; | 483 continue; |
434 client->event_handler->OnError(client->controller_id); | 484 client->event_handler->OnError(client->controller_id); |
435 } | 485 } |
436 } | 486 } |
437 | 487 |
438 void VideoCaptureController::DoLogOnIOThread(const std::string& message) { | 488 void VideoCaptureController::OnLog(const std::string& message) { |
439 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 489 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
440 MediaStreamManager::SendMessageToNativeLog("Video capture: " + message); | 490 MediaStreamManager::SendMessageToNativeLog("Video capture: " + message); |
441 } | 491 } |
442 | 492 |
443 void VideoCaptureController::DoBufferDestroyedOnIOThread( | 493 void VideoCaptureController::OnBufferDestroyed(int buffer_id_to_drop) { |
444 int buffer_id_to_drop) { | |
445 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 494 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
446 | 495 |
447 for (const auto& client : controller_clients_) { | 496 for (const auto& client : controller_clients_) { |
448 if (client->session_closed) | 497 if (client->session_closed) |
449 continue; | 498 continue; |
450 | 499 |
451 if (client->known_buffers.erase(buffer_id_to_drop)) { | 500 if (client->known_buffers.erase(buffer_id_to_drop)) { |
452 client->event_handler->OnBufferDestroyed(client->controller_id, | 501 client->event_handler->OnBufferDestroyed(client->controller_id, |
453 buffer_id_to_drop); | 502 buffer_id_to_drop); |
454 } | 503 } |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
506 int session_id, | 555 int session_id, |
507 const ControllerClients& clients) { | 556 const ControllerClients& clients) { |
508 for (const auto& client : clients) { | 557 for (const auto& client : clients) { |
509 if (client->session_id == session_id) | 558 if (client->session_id == session_id) |
510 return client.get(); | 559 return client.get(); |
511 } | 560 } |
512 return nullptr; | 561 return nullptr; |
513 } | 562 } |
514 | 563 |
515 } // namespace content | 564 } // namespace content |
OLD | NEW |