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 "base/stl_util.h" | |
19 #include "build/build_config.h" | 18 #include "build/build_config.h" |
20 #include "components/display_compositor/gl_helper.h" | 19 #include "components/display_compositor/gl_helper.h" |
21 #include "content/browser/renderer_host/media/media_stream_manager.h" | 20 #include "content/browser/renderer_host/media/media_stream_manager.h" |
22 #include "content/browser/renderer_host/media/video_capture_buffer_pool.h" | 21 #include "content/browser/renderer_host/media/video_capture_buffer_pool.h" |
23 #include "content/browser/renderer_host/media/video_capture_device_client.h" | 22 #include "content/browser/renderer_host/media/video_capture_device_client.h" |
24 #include "content/browser/renderer_host/media/video_capture_manager.h" | 23 #include "content/browser/renderer_host/media/video_capture_manager.h" |
25 #include "content/public/browser/browser_thread.h" | 24 #include "content/public/browser/browser_thread.h" |
26 #include "content/public/common/content_switches.h" | 25 #include "content/public/common/content_switches.h" |
27 #include "media/base/video_frame.h" | 26 #include "media/base/video_frame.h" |
28 | 27 |
(...skipping 156 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
185 // Signal error in case device is already in error state. | 184 // Signal error in case device is already in error state. |
186 if (state_ == VIDEO_CAPTURE_STATE_ERROR) { | 185 if (state_ == VIDEO_CAPTURE_STATE_ERROR) { |
187 event_handler->OnError(id); | 186 event_handler->OnError(id); |
188 return; | 187 return; |
189 } | 188 } |
190 | 189 |
191 // Do nothing if this client has called AddClient before. | 190 // Do nothing if this client has called AddClient before. |
192 if (FindClient(id, event_handler, controller_clients_)) | 191 if (FindClient(id, event_handler, controller_clients_)) |
193 return; | 192 return; |
194 | 193 |
195 ControllerClient* client = new ControllerClient( | 194 std::unique_ptr<ControllerClient> client = base::MakeUnique<ControllerClient>( |
196 id, event_handler, render_process, session_id, params); | 195 id, event_handler, render_process, session_id, params); |
197 // If we already have gotten frame_info from the device, repeat it to the new | 196 // If we already have gotten frame_info from the device, repeat it to the new |
198 // client. | 197 // client. |
199 if (state_ == VIDEO_CAPTURE_STATE_STARTED) { | 198 if (state_ == VIDEO_CAPTURE_STATE_STARTED) { |
200 controller_clients_.push_back(client); | 199 controller_clients_.push_back(std::move(client)); |
201 return; | 200 return; |
202 } | 201 } |
203 } | 202 } |
204 | 203 |
205 int VideoCaptureController::RemoveClient( | 204 int VideoCaptureController::RemoveClient( |
206 VideoCaptureControllerID id, | 205 VideoCaptureControllerID id, |
207 VideoCaptureControllerEventHandler* event_handler) { | 206 VideoCaptureControllerEventHandler* event_handler) { |
208 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 207 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
209 DVLOG(1) << "VideoCaptureController::RemoveClient, id " << id; | 208 DVLOG(1) << "VideoCaptureController::RemoveClient, id " << id; |
210 | 209 |
211 ControllerClient* client = FindClient(id, event_handler, controller_clients_); | 210 ControllerClient* client = FindClient(id, event_handler, controller_clients_); |
212 if (!client) | 211 if (!client) |
213 return kInvalidMediaCaptureSessionId; | 212 return kInvalidMediaCaptureSessionId; |
214 | 213 |
215 // Take back all buffers held by the |client|. | 214 // Take back all buffers held by the |client|. |
216 for (const auto& buffer : client->active_buffers) | 215 for (const auto& buffer : client->active_buffers) |
217 buffer_pool_->RelinquishConsumerHold(buffer.first, 1); | 216 buffer_pool_->RelinquishConsumerHold(buffer.first, 1); |
218 client->active_buffers.clear(); | 217 client->active_buffers.clear(); |
219 | 218 |
220 int session_id = client->session_id; | 219 int session_id = client->session_id; |
221 controller_clients_.remove(client); | 220 controller_clients_.remove_if( |
222 delete client; | 221 [client](const std::unique_ptr<ControllerClient>& ptr) { |
| 222 return ptr.get() == client; |
| 223 }); |
223 | 224 |
224 return session_id; | 225 return session_id; |
225 } | 226 } |
226 | 227 |
227 void VideoCaptureController::PauseClient( | 228 void VideoCaptureController::PauseClient( |
228 VideoCaptureControllerID id, | 229 VideoCaptureControllerID id, |
229 VideoCaptureControllerEventHandler* event_handler) { | 230 VideoCaptureControllerEventHandler* event_handler) { |
230 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 231 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
231 DVLOG(1) << "VideoCaptureController::PauseClient, id " << id; | 232 DVLOG(1) << "VideoCaptureController::PauseClient, id " << id; |
232 | 233 |
(...skipping 25 matching lines...) Expand all Loading... |
258 return true; | 259 return true; |
259 } | 260 } |
260 | 261 |
261 int VideoCaptureController::GetClientCount() const { | 262 int VideoCaptureController::GetClientCount() const { |
262 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 263 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
263 return controller_clients_.size(); | 264 return controller_clients_.size(); |
264 } | 265 } |
265 | 266 |
266 bool VideoCaptureController::HasActiveClient() const { | 267 bool VideoCaptureController::HasActiveClient() const { |
267 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 268 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
268 for (ControllerClient* client : controller_clients_) { | 269 for (const auto& client : controller_clients_) { |
269 if (!client->paused) | 270 if (!client->paused) |
270 return true; | 271 return true; |
271 } | 272 } |
272 return false; | 273 return false; |
273 } | 274 } |
274 | 275 |
275 bool VideoCaptureController::HasPausedClient() const { | 276 bool VideoCaptureController::HasPausedClient() const { |
276 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 277 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
277 for (ControllerClient* client : controller_clients_) { | 278 for (const auto& client : controller_clients_) { |
278 if (client->paused) | 279 if (client->paused) |
279 return true; | 280 return true; |
280 } | 281 } |
281 return false; | 282 return false; |
282 } | 283 } |
283 | 284 |
284 void VideoCaptureController::StopSession(int session_id) { | 285 void VideoCaptureController::StopSession(int session_id) { |
285 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 286 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
286 DVLOG(1) << "VideoCaptureController::StopSession, id " << session_id; | 287 DVLOG(1) << "VideoCaptureController::StopSession, id " << session_id; |
287 | 288 |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
343 base::Bind(&ReturnVideoFrame, frame, sync_token)); | 344 base::Bind(&ReturnVideoFrame, frame, sync_token)); |
344 } | 345 } |
345 | 346 |
346 const media::VideoCaptureFormat& | 347 const media::VideoCaptureFormat& |
347 VideoCaptureController::GetVideoCaptureFormat() const { | 348 VideoCaptureController::GetVideoCaptureFormat() const { |
348 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 349 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
349 return video_capture_format_; | 350 return video_capture_format_; |
350 } | 351 } |
351 | 352 |
352 VideoCaptureController::~VideoCaptureController() { | 353 VideoCaptureController::~VideoCaptureController() { |
353 base::STLDeleteContainerPointers(controller_clients_.begin(), | |
354 controller_clients_.end()); | |
355 } | 354 } |
356 | 355 |
357 void VideoCaptureController::DoIncomingCapturedVideoFrameOnIOThread( | 356 void VideoCaptureController::DoIncomingCapturedVideoFrameOnIOThread( |
358 std::unique_ptr<media::VideoCaptureDevice::Client::Buffer> buffer, | 357 std::unique_ptr<media::VideoCaptureDevice::Client::Buffer> buffer, |
359 const scoped_refptr<VideoFrame>& frame) { | 358 const scoped_refptr<VideoFrame>& frame) { |
360 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 359 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
361 const int buffer_id = buffer->id(); | 360 const int buffer_id = buffer->id(); |
362 DCHECK_NE(buffer_id, VideoCaptureBufferPool::kInvalidId); | 361 DCHECK_NE(buffer_id, VideoCaptureBufferPool::kInvalidId); |
363 | 362 |
364 int count = 0; | 363 int count = 0; |
(...skipping 14 matching lines...) Expand all Loading... |
379 // Sanity-checks to confirm |frame| is actually being backed by |buffer|. | 378 // Sanity-checks to confirm |frame| is actually being backed by |buffer|. |
380 DCHECK(frame->storage_type() == media::VideoFrame::STORAGE_SHMEM || | 379 DCHECK(frame->storage_type() == media::VideoFrame::STORAGE_SHMEM || |
381 (frame->storage_type() == | 380 (frame->storage_type() == |
382 media::VideoFrame::STORAGE_GPU_MEMORY_BUFFERS)); | 381 media::VideoFrame::STORAGE_GPU_MEMORY_BUFFERS)); |
383 DCHECK(frame->data(media::VideoFrame::kYPlane) >= buffer->data(0) && | 382 DCHECK(frame->data(media::VideoFrame::kYPlane) >= buffer->data(0) && |
384 (frame->data(media::VideoFrame::kYPlane) < | 383 (frame->data(media::VideoFrame::kYPlane) < |
385 (reinterpret_cast<const uint8_t*>(buffer->data(0)) + | 384 (reinterpret_cast<const uint8_t*>(buffer->data(0)) + |
386 buffer->mapped_size()))) | 385 buffer->mapped_size()))) |
387 << "VideoFrame does not appear to be backed by Buffer"; | 386 << "VideoFrame does not appear to be backed by Buffer"; |
388 | 387 |
389 for (auto* client : controller_clients_) { | 388 for (const auto& client : controller_clients_) { |
390 if (client->session_closed || client->paused) | 389 if (client->session_closed || client->paused) |
391 continue; | 390 continue; |
392 | 391 |
393 // On the first use of a buffer on a client, share the memory handles. | 392 // On the first use of a buffer on a client, share the memory handles. |
394 const bool is_new_buffer = client->known_buffers.insert(buffer_id).second; | 393 const bool is_new_buffer = client->known_buffers.insert(buffer_id).second; |
395 if (is_new_buffer) | 394 if (is_new_buffer) |
396 DoNewBufferOnIOThread(client, buffer.get(), frame); | 395 DoNewBufferOnIOThread(client.get(), buffer.get(), frame); |
397 | 396 |
398 client->event_handler->OnBufferReady(client->controller_id, buffer_id, | 397 client->event_handler->OnBufferReady(client->controller_id, buffer_id, |
399 frame); | 398 frame); |
400 const bool inserted = | 399 const bool inserted = |
401 client->active_buffers.insert(std::make_pair(buffer_id, frame)) | 400 client->active_buffers.insert(std::make_pair(buffer_id, frame)) |
402 .second; | 401 .second; |
403 DCHECK(inserted) << "Unexpected duplicate buffer: " << buffer_id; | 402 DCHECK(inserted) << "Unexpected duplicate buffer: " << buffer_id; |
404 count++; | 403 count++; |
405 } | 404 } |
406 } | 405 } |
(...skipping 15 matching lines...) Expand all Loading... |
422 has_received_frames_ = true; | 421 has_received_frames_ = true; |
423 } | 422 } |
424 | 423 |
425 buffer_pool_->HoldForConsumers(buffer_id, count); | 424 buffer_pool_->HoldForConsumers(buffer_id, count); |
426 } | 425 } |
427 | 426 |
428 void VideoCaptureController::DoErrorOnIOThread() { | 427 void VideoCaptureController::DoErrorOnIOThread() { |
429 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 428 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
430 state_ = VIDEO_CAPTURE_STATE_ERROR; | 429 state_ = VIDEO_CAPTURE_STATE_ERROR; |
431 | 430 |
432 for (const auto* client : controller_clients_) { | 431 for (const auto& client : controller_clients_) { |
433 if (client->session_closed) | 432 if (client->session_closed) |
434 continue; | 433 continue; |
435 client->event_handler->OnError(client->controller_id); | 434 client->event_handler->OnError(client->controller_id); |
436 } | 435 } |
437 } | 436 } |
438 | 437 |
439 void VideoCaptureController::DoLogOnIOThread(const std::string& message) { | 438 void VideoCaptureController::DoLogOnIOThread(const std::string& message) { |
440 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 439 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
441 MediaStreamManager::SendMessageToNativeLog("Video capture: " + message); | 440 MediaStreamManager::SendMessageToNativeLog("Video capture: " + message); |
442 } | 441 } |
443 | 442 |
444 void VideoCaptureController::DoBufferDestroyedOnIOThread( | 443 void VideoCaptureController::DoBufferDestroyedOnIOThread( |
445 int buffer_id_to_drop) { | 444 int buffer_id_to_drop) { |
446 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 445 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
447 | 446 |
448 for (auto* client : controller_clients_) { | 447 for (const auto& client : controller_clients_) { |
449 if (client->session_closed) | 448 if (client->session_closed) |
450 continue; | 449 continue; |
451 | 450 |
452 if (client->known_buffers.erase(buffer_id_to_drop)) { | 451 if (client->known_buffers.erase(buffer_id_to_drop)) { |
453 client->event_handler->OnBufferDestroyed(client->controller_id, | 452 client->event_handler->OnBufferDestroyed(client->controller_id, |
454 buffer_id_to_drop); | 453 buffer_id_to_drop); |
455 } | 454 } |
456 } | 455 } |
457 } | 456 } |
458 | 457 |
(...skipping 30 matching lines...) Expand all Loading... |
489 default: | 488 default: |
490 NOTREACHED(); | 489 NOTREACHED(); |
491 break; | 490 break; |
492 } | 491 } |
493 } | 492 } |
494 | 493 |
495 VideoCaptureController::ControllerClient* VideoCaptureController::FindClient( | 494 VideoCaptureController::ControllerClient* VideoCaptureController::FindClient( |
496 VideoCaptureControllerID id, | 495 VideoCaptureControllerID id, |
497 VideoCaptureControllerEventHandler* handler, | 496 VideoCaptureControllerEventHandler* handler, |
498 const ControllerClients& clients) { | 497 const ControllerClients& clients) { |
499 for (auto* client : clients) { | 498 for (const auto& client : clients) { |
500 if (client->controller_id == id && client->event_handler == handler) | 499 if (client->controller_id == id && client->event_handler == handler) |
501 return client; | 500 return client.get(); |
502 } | 501 } |
503 return NULL; | 502 return nullptr; |
504 } | 503 } |
505 | 504 |
506 VideoCaptureController::ControllerClient* VideoCaptureController::FindClient( | 505 VideoCaptureController::ControllerClient* VideoCaptureController::FindClient( |
507 int session_id, | 506 int session_id, |
508 const ControllerClients& clients) { | 507 const ControllerClients& clients) { |
509 for (auto* client : clients) { | 508 for (const auto& client : clients) { |
510 if (client->session_id == session_id) | 509 if (client->session_id == session_id) |
511 return client; | 510 return client.get(); |
512 } | 511 } |
513 return NULL; | 512 return nullptr; |
514 } | 513 } |
515 | 514 |
516 } // namespace content | 515 } // namespace content |
OLD | NEW |