Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(142)

Side by Side Diff: content/browser/renderer_host/media/video_capture_manager.cc

Issue 899943004: Fix race when setting Desktop window id. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Fix race when setting the notification window. Created 5 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « content/browser/renderer_host/media/video_capture_manager.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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_manager.h" 5 #include "content/browser/renderer_host/media/video_capture_manager.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <set> 8 #include <set>
9 9
10 #include "base/bind.h" 10 #include "base/bind.h"
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after
106 MediaStreamType stream_type, 106 MediaStreamType stream_type,
107 const std::string& id, 107 const std::string& id,
108 scoped_ptr<VideoCaptureController> controller) 108 scoped_ptr<VideoCaptureController> controller)
109 : serial_id(g_device_start_id++), 109 : serial_id(g_device_start_id++),
110 stream_type(stream_type), 110 stream_type(stream_type),
111 id(id), 111 id(id),
112 video_capture_controller_(controller.Pass()) {} 112 video_capture_controller_(controller.Pass()) {}
113 113
114 VideoCaptureManager::DeviceEntry::~DeviceEntry() { 114 VideoCaptureManager::DeviceEntry::~DeviceEntry() {
115 DCHECK(thread_checker_.CalledOnValidThread()); 115 DCHECK(thread_checker_.CalledOnValidThread());
116 // CHECK that the media::VideoCaptureDevice is not
miu 2015/02/06 21:51:47 s/media::VideoCaptureDevice/media::VideoCaptureDev
perkj_chrome 2015/02/09 08:27:41 I want to check that the entry does not own a medi
117 // deleted on the wrong thread.
118 CHECK(video_capture_device_ == NULL);
Sergey Ulanov 2015/02/06 22:20:03 s/NULL/nullptr/, or CHECK(!video_capture_device_)
perkj_chrome 2015/02/09 08:27:41 ok. I am pretty sure the race is the problem that
116 } 119 }
117 120
118 void VideoCaptureManager::DeviceEntry::SetVideoCaptureDevice( 121 void VideoCaptureManager::DeviceEntry::SetVideoCaptureDevice(
119 scoped_ptr<media::VideoCaptureDevice> device) { 122 scoped_ptr<media::VideoCaptureDevice> device) {
120 DCHECK(thread_checker_.CalledOnValidThread()); 123 DCHECK(thread_checker_.CalledOnValidThread());
121 video_capture_device_.swap(device); 124 video_capture_device_.swap(device);
122 } 125 }
123 126
124 scoped_ptr<media::VideoCaptureDevice> 127 scoped_ptr<media::VideoCaptureDevice>
125 VideoCaptureManager::DeviceEntry::ReleaseVideoCaptureDevice() { 128 VideoCaptureManager::DeviceEntry::ReleaseVideoCaptureDevice() {
(...skipping 226 matching lines...) Expand 10 before | Expand all | Expand 10 after
352 // PostTask failed. The device must be stopped anyway. 355 // PostTask failed. The device must be stopped anyway.
353 device_ptr->StopAndDeAllocate(); 356 device_ptr->StopAndDeAllocate();
354 } 357 }
355 } else { 358 } else {
356 DeviceEntries::iterator entry_it = std::find_if( 359 DeviceEntries::iterator entry_it = std::find_if(
357 devices_.begin(), devices_.end(), 360 devices_.begin(), devices_.end(),
358 [serial_id] (const DeviceEntry* e) { 361 [serial_id] (const DeviceEntry* e) {
359 return e->serial_id == serial_id; 362 return e->serial_id == serial_id;
360 }); 363 });
361 DCHECK(entry_it != devices_.end()); 364 DCHECK(entry_it != devices_.end());
362 DCHECK(!(*entry_it)->video_capture_device()); 365 DeviceEntry* entry = *entry_it;
363 (*entry_it)->SetVideoCaptureDevice(device.Pass()); 366 DCHECK(!entry->video_capture_device());
367 entry->SetVideoCaptureDevice(device.Pass());
368
369 if (entry->stream_type == MEDIA_DESKTOP_VIDEO_CAPTURE) {
370 const media::VideoCaptureSessionId session_id =
371 device_start_queue_.front().session_id();
372 MaybePostDesktopCaptureWindowId(session_id);
373 }
364 } 374 }
365 375
366 device_start_queue_.pop_front(); 376 device_start_queue_.pop_front();
367 HandleQueuedStartRequest(); 377 HandleQueuedStartRequest();
368 } 378 }
369 379
370 scoped_ptr<media::VideoCaptureDevice> 380 scoped_ptr<media::VideoCaptureDevice>
371 VideoCaptureManager::DoStartDeviceOnDeviceThread( 381 VideoCaptureManager::DoStartDeviceOnDeviceThread(
372 media::VideoCaptureSessionId session_id, 382 media::VideoCaptureSessionId session_id,
373 const std::string& id, 383 const std::string& id,
(...skipping 27 matching lines...) Expand all
401 DesktopMediaID desktop_id = DesktopMediaID::Parse(id); 411 DesktopMediaID desktop_id = DesktopMediaID::Parse(id);
402 #if defined(USE_AURA) 412 #if defined(USE_AURA)
403 if (desktop_id.type == DesktopMediaID::TYPE_AURA_WINDOW) { 413 if (desktop_id.type == DesktopMediaID::TYPE_AURA_WINDOW) {
404 video_capture_device.reset( 414 video_capture_device.reset(
405 DesktopCaptureDeviceAura::Create(desktop_id)); 415 DesktopCaptureDeviceAura::Create(desktop_id));
406 } else 416 } else
407 #endif 417 #endif
408 if (desktop_id.type != DesktopMediaID::TYPE_NONE && 418 if (desktop_id.type != DesktopMediaID::TYPE_NONE &&
409 desktop_id.type != DesktopMediaID::TYPE_AURA_WINDOW) { 419 desktop_id.type != DesktopMediaID::TYPE_AURA_WINDOW) {
410 video_capture_device = DesktopCaptureDevice::Create(desktop_id); 420 video_capture_device = DesktopCaptureDevice::Create(desktop_id);
411 if (notification_window_ids_.find(session_id) !=
412 notification_window_ids_.end()) {
413 static_cast<DesktopCaptureDevice*>(video_capture_device.get())
414 ->SetNotificationWindowId(notification_window_ids_[session_id]);
415 VLOG(2) << "Screen capture notification window passed for session "
416 << session_id;
417 }
418 } 421 }
419 #endif // defined(ENABLE_SCREEN_CAPTURE) 422 #endif // defined(ENABLE_SCREEN_CAPTURE)
420 break; 423 break;
421 } 424 }
422 default: { 425 default: {
423 NOTIMPLEMENTED(); 426 NOTIMPLEMENTED();
424 break; 427 break;
425 } 428 }
426 } 429 }
427 430
(...skipping 180 matching lines...) Expand 10 before | Expand all | Expand 10 after
608 } 611 }
609 return true; 612 return true;
610 } 613 }
611 614
612 void VideoCaptureManager::SetDesktopCaptureWindowId( 615 void VideoCaptureManager::SetDesktopCaptureWindowId(
613 media::VideoCaptureSessionId session_id, 616 media::VideoCaptureSessionId session_id,
614 gfx::NativeViewId window_id) { 617 gfx::NativeViewId window_id) {
615 DCHECK_CURRENTLY_ON(BrowserThread::IO); 618 DCHECK_CURRENTLY_ON(BrowserThread::IO);
616 VLOG(2) << "SetDesktopCaptureWindowId called for session " << session_id; 619 VLOG(2) << "SetDesktopCaptureWindowId called for session " << session_id;
617 620
621 notification_window_ids_[session_id] = window_id;
622 MaybePostDesktopCaptureWindowId(session_id);
623 }
624
625 void VideoCaptureManager::MaybePostDesktopCaptureWindowId(
626 media::VideoCaptureSessionId session_id) {
618 SessionMap::iterator session_it = sessions_.find(session_id); 627 SessionMap::iterator session_it = sessions_.find(session_id);
619 if (session_it == sessions_.end()) { 628 if (session_it == sessions_.end()) {
620 VLOG(2) << "Session not found, will save the notification window."; 629 return;
621 device_task_runner_->PostTask( 630 }
622 FROM_HERE, 631
623 base::Bind( 632 if (notification_window_ids_.find(session_id) ==
624 &VideoCaptureManager::SaveDesktopCaptureWindowIdOnDeviceThread, 633 notification_window_ids_.end()) {
625 this, 634 DVLOG(2) << "Notification window id not set for screen capture.";
626 session_id,
627 window_id));
628 return; 635 return;
629 } 636 }
630 637
631 DeviceEntry* const existing_device = 638 DeviceEntry* const existing_device =
632 GetDeviceEntryForMediaStreamDevice(session_it->second); 639 GetDeviceEntryForMediaStreamDevice(session_it->second);
633 if (!existing_device) { 640 if (!existing_device) {
634 VLOG(2) << "Failed to find an existing device."; 641 DVLOG(2) << "Failed to find an existing screen capture device.";
635 return; 642 return;
636 } 643 }
637 644
645 if (!existing_device->video_capture_device()) {
646 DVLOG(2) << "Screen capture device not yet started.";
647 return;
648 }
649
638 DCHECK_EQ(MEDIA_DESKTOP_VIDEO_CAPTURE, existing_device->stream_type); 650 DCHECK_EQ(MEDIA_DESKTOP_VIDEO_CAPTURE, existing_device->stream_type);
639 DesktopMediaID id = DesktopMediaID::Parse(existing_device->id); 651 DesktopMediaID id = DesktopMediaID::Parse(existing_device->id);
640 if (id.type == DesktopMediaID::TYPE_NONE || 652 if (id.type == DesktopMediaID::TYPE_NONE ||
641 id.type == DesktopMediaID::TYPE_AURA_WINDOW) { 653 id.type == DesktopMediaID::TYPE_AURA_WINDOW) {
642 VLOG(2) << "Video capture device type mismatch."; 654 VLOG(2) << "Video capture device type mismatch.";
643 return; 655 return;
644 } 656 }
645 657
646 // Post |existing_device->video_capture_device| to the VideoCaptureDevice to 658 // Post |existing_device->video_capture_device| to the VideoCaptureDevice to
647 // the device_task_runner_. This is safe since the device is destroyed on the 659 // the device_task_runner_. This is safe since the device is destroyed on the
648 // device_task_runner_. 660 // device_task_runner_.
649 device_task_runner_->PostTask( 661 device_task_runner_->PostTask(
650 FROM_HERE, 662 FROM_HERE,
651 base::Bind(&VideoCaptureManager::SetDesktopCaptureWindowIdOnDeviceThread, 663 base::Bind(&VideoCaptureManager::SetDesktopCaptureWindowIdOnDeviceThread,
652 this, 664 this,
653 existing_device->video_capture_device(), 665 existing_device->video_capture_device(),
654 window_id)); 666 notification_window_ids_[session_id]));
Sergey Ulanov 2015/02/06 22:20:03 I think you also want to remove the value from not
perkj_chrome 2015/02/09 08:27:41 ok, so this will fix an old bug as well? It looks
655 } 667 }
656 668
657 void VideoCaptureManager::DoStopDeviceOnDeviceThread( 669 void VideoCaptureManager::DoStopDeviceOnDeviceThread(
658 scoped_ptr<media::VideoCaptureDevice> device) { 670 scoped_ptr<media::VideoCaptureDevice> device) {
659 SCOPED_UMA_HISTOGRAM_TIMER("Media.VideoCaptureManager.StopDeviceTime"); 671 SCOPED_UMA_HISTOGRAM_TIMER("Media.VideoCaptureManager.StopDeviceTime");
660 DCHECK(IsOnDeviceThread()); 672 DCHECK(IsOnDeviceThread());
661 device->StopAndDeAllocate(); 673 device->StopAndDeAllocate();
662 DVLOG(3) << "DoStopDeviceOnDeviceThread"; 674 DVLOG(3) << "DoStopDeviceOnDeviceThread";
663 } 675 }
664 676
(...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after
842 gfx::NativeViewId window_id) { 854 gfx::NativeViewId window_id) {
843 DCHECK(IsOnDeviceThread()); 855 DCHECK(IsOnDeviceThread());
844 #if defined(ENABLE_SCREEN_CAPTURE) 856 #if defined(ENABLE_SCREEN_CAPTURE)
845 DesktopCaptureDevice* desktop_device = 857 DesktopCaptureDevice* desktop_device =
846 static_cast<DesktopCaptureDevice*>(device); 858 static_cast<DesktopCaptureDevice*>(device);
847 desktop_device->SetNotificationWindowId(window_id); 859 desktop_device->SetNotificationWindowId(window_id);
848 VLOG(2) << "Screen capture notification window passed on device thread."; 860 VLOG(2) << "Screen capture notification window passed on device thread.";
849 #endif 861 #endif
850 } 862 }
851 863
852 void VideoCaptureManager::SaveDesktopCaptureWindowIdOnDeviceThread(
853 media::VideoCaptureSessionId session_id,
854 gfx::NativeViewId window_id) {
855 DCHECK(IsOnDeviceThread());
856 DCHECK(notification_window_ids_.find(session_id) ==
857 notification_window_ids_.end());
858 notification_window_ids_[session_id] = window_id;
859 VLOG(2) << "Screen capture notification window saved for session "
860 << session_id << " on device thread.";
861 }
862
863 } // namespace content 864 } // namespace content
OLDNEW
« no previous file with comments | « content/browser/renderer_host/media/video_capture_manager.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698