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

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

Issue 2212343003: Reland: ImageCapture: Queue up requests while device not ready (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Disable Android tests with bug and explanation Created 4 years, 4 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
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 #include <utility> 9 #include <utility>
10 10
(...skipping 500 matching lines...) Expand 10 before | Expand all | Expand 10 after
511 base::PostTaskAndReplyWithResult( 511 base::PostTaskAndReplyWithResult(
512 device_task_runner_.get(), FROM_HERE, start_capture_function, 512 device_task_runner_.get(), FROM_HERE, start_capture_function,
513 base::Bind(&VideoCaptureManager::OnDeviceStarted, this, 513 base::Bind(&VideoCaptureManager::OnDeviceStarted, this,
514 request->serial_id())); 514 request->serial_id()));
515 } 515 }
516 516
517 void VideoCaptureManager::OnDeviceStarted( 517 void VideoCaptureManager::OnDeviceStarted(
518 int serial_id, 518 int serial_id,
519 std::unique_ptr<VideoCaptureDevice> device) { 519 std::unique_ptr<VideoCaptureDevice> device) {
520 DCHECK_CURRENTLY_ON(BrowserThread::IO); 520 DCHECK_CURRENTLY_ON(BrowserThread::IO);
521 DCHECK(serial_id == device_start_queue_.begin()->serial_id()); 521 DCHECK_EQ(serial_id, device_start_queue_.begin()->serial_id());
522 DVLOG(3) << "OnDeviceStarted"; 522 DVLOG(3) << __func__;
523 if (device_start_queue_.front().abort_start()) { 523 if (device_start_queue_.front().abort_start()) {
524 // |device| can be null if creation failed in 524 // |device| can be null if creation failed in
525 // DoStartDeviceCaptureOnDeviceThread. 525 // DoStartDeviceCaptureOnDeviceThread.
526 // The device is no longer wanted. Stop the device again. 526 // The device is no longer wanted. Stop the device again.
527 DVLOG(3) << "OnDeviceStarted but start request have been aborted."; 527 DVLOG(3) << "OnDeviceStarted but start request have been aborted.";
528 media::VideoCaptureDevice* device_ptr = device.get(); 528 media::VideoCaptureDevice* device_ptr = device.get();
529 base::Closure closure = 529 base::Closure closure =
530 base::Bind(&VideoCaptureManager::DoStopDeviceOnDeviceThread, this, 530 base::Bind(&VideoCaptureManager::DoStopDeviceOnDeviceThread, this,
531 base::Passed(&device)); 531 base::Passed(&device));
532 if (device_ptr && !device_task_runner_->PostTask(FROM_HERE, closure)) { 532 if (device_ptr && !device_task_runner_->PostTask(FROM_HERE, closure)) {
533 // PostTask failed. The device must be stopped anyway. 533 // PostTask failed. The device must be stopped anyway.
534 device_ptr->StopAndDeAllocate(); 534 device_ptr->StopAndDeAllocate();
535 } 535 }
536 } else { 536 } else {
537 DeviceEntry* const entry = GetDeviceEntryBySerialId(serial_id); 537 DeviceEntry* const entry = GetDeviceEntryBySerialId(serial_id);
538 DCHECK(entry); 538 DCHECK(entry);
539 DCHECK(!entry->video_capture_device()); 539 DCHECK(!entry->video_capture_device());
540 entry->SetVideoCaptureDevice(std::move(device)); 540 entry->SetVideoCaptureDevice(std::move(device));
541 541
542 if (entry->stream_type == MEDIA_DESKTOP_VIDEO_CAPTURE) { 542 if (entry->stream_type == MEDIA_DESKTOP_VIDEO_CAPTURE) {
543 const media::VideoCaptureSessionId session_id = 543 const media::VideoCaptureSessionId session_id =
544 device_start_queue_.front().session_id(); 544 device_start_queue_.front().session_id();
545 DCHECK(session_id != kFakeSessionId); 545 DCHECK(session_id != kFakeSessionId);
546 MaybePostDesktopCaptureWindowId(session_id); 546 MaybePostDesktopCaptureWindowId(session_id);
547 } 547 }
548
549 auto request = photo_request_queue_.begin();
550 while(request != photo_request_queue_.end()) {
551 if (GetDeviceEntryBySessionId(request->first)->video_capture_device()) {
552 request->second.Run(entry->video_capture_device());
553 photo_request_queue_.erase(request);
554 }
555 ++request;
556 }
548 } 557 }
549 558
550 device_start_queue_.pop_front(); 559 device_start_queue_.pop_front();
551 HandleQueuedStartRequest(); 560 HandleQueuedStartRequest();
552 } 561 }
553 562
554 std::unique_ptr<media::VideoCaptureDevice> 563 std::unique_ptr<media::VideoCaptureDevice>
555 VideoCaptureManager::DoStartDeviceCaptureOnDeviceThread( 564 VideoCaptureManager::DoStartDeviceCaptureOnDeviceThread(
556 const VideoCaptureDeviceDescriptor& descriptor, 565 const VideoCaptureDeviceDescriptor& descriptor,
557 const media::VideoCaptureParams& params, 566 const media::VideoCaptureParams& params,
(...skipping 298 matching lines...) Expand 10 before | Expand all | Expand 10 after
856 existing_device->video_capture_device(), 865 existing_device->video_capture_device(),
857 window_id_it->second)); 866 window_id_it->second));
858 867
859 notification_window_ids_.erase(window_id_it); 868 notification_window_ids_.erase(window_id_it);
860 } 869 }
861 870
862 void VideoCaptureManager::GetPhotoCapabilities( 871 void VideoCaptureManager::GetPhotoCapabilities(
863 int session_id, 872 int session_id,
864 VideoCaptureDevice::GetPhotoCapabilitiesCallback callback) { 873 VideoCaptureDevice::GetPhotoCapabilitiesCallback callback) {
865 DCHECK_CURRENTLY_ON(BrowserThread::IO); 874 DCHECK_CURRENTLY_ON(BrowserThread::IO);
866 VideoCaptureDevice* device = GetVideoCaptureDeviceBySessionId(session_id); 875
867 if (!device) 876 const DeviceEntry* entry = GetDeviceEntryBySessionId(session_id);
877 if (!entry)
868 return; 878 return;
869 // Unretained(device) is safe to use here because |device| would be null if it 879 VideoCaptureDevice* device = entry->video_capture_device();
870 // was scheduled for shutdown and destruction, and because this task is 880 if (device) {
871 // guaranteed to run before the task that destroys the |device|. 881 VideoCaptureManager::DoGetPhotoCapabilities(std::move(callback), device);
872 device_task_runner_->PostTask( 882 return;
873 FROM_HERE, base::Bind(&VideoCaptureDevice::GetPhotoCapabilities, 883 }
874 base::Unretained(device), base::Passed(&callback))); 884 // |entry| is known but |device| is nullptr, queue up a request for later.
885 photo_request_queue_.emplace_back(
886 session_id, base::Bind(&VideoCaptureManager::DoGetPhotoCapabilities, this,
887 base::Passed(&callback)));
875 } 888 }
876 889
877 void VideoCaptureManager::SetPhotoOptions( 890 void VideoCaptureManager::SetPhotoOptions(
878 int session_id, 891 int session_id,
879 media::mojom::PhotoSettingsPtr settings, 892 media::mojom::PhotoSettingsPtr settings,
880 VideoCaptureDevice::SetPhotoOptionsCallback callback) { 893 VideoCaptureDevice::SetPhotoOptionsCallback callback) {
881 DCHECK_CURRENTLY_ON(BrowserThread::IO); 894 DCHECK_CURRENTLY_ON(BrowserThread::IO);
882 VideoCaptureDevice* device = GetVideoCaptureDeviceBySessionId(session_id); 895
883 if (!device) 896 const DeviceEntry* entry = GetDeviceEntryBySessionId(session_id);
897 if (!entry)
884 return; 898 return;
885 device_task_runner_->PostTask( 899 VideoCaptureDevice* device = entry->video_capture_device();
886 FROM_HERE, 900 if (device) {
887 base::Bind(&VideoCaptureDevice::SetPhotoOptions, base::Unretained(device), 901 VideoCaptureManager::DoSetPhotoOptions(std::move(callback),
888 base::Passed(&settings), base::Passed(&callback))); 902 std::move(settings), device);
903 return;
904 }
905 // |entry| is known but |device| is nullptr, queue up a request for later.
906 photo_request_queue_.emplace_back(
907 session_id, base::Bind(&VideoCaptureManager::DoSetPhotoOptions, this,
908 base::Passed(&callback), base::Passed(&settings)));
889 } 909 }
890 910
891 void VideoCaptureManager::TakePhoto( 911 void VideoCaptureManager::TakePhoto(
892 int session_id, 912 int session_id,
893 VideoCaptureDevice::TakePhotoCallback callback) { 913 VideoCaptureDevice::TakePhotoCallback callback) {
894 DCHECK_CURRENTLY_ON(BrowserThread::IO); 914 DCHECK_CURRENTLY_ON(BrowserThread::IO);
895 VideoCaptureDevice* device = GetVideoCaptureDeviceBySessionId(session_id); 915
896 if (!device) 916 const DeviceEntry* entry = GetDeviceEntryBySessionId(session_id);
917 if (!entry)
897 return; 918 return;
898 // Unretained(device) is safe to use here because |device| would be null if it 919 VideoCaptureDevice* device = entry->video_capture_device();
899 // was scheduled for shutdown and destruction, and because this task is 920 if (device) {
900 // guaranteed to run before the task that destroys the |device|. 921 VideoCaptureManager::DoTakePhoto(std::move(callback), device);
901 device_task_runner_->PostTask( 922 return;
902 FROM_HERE, base::Bind(&VideoCaptureDevice::TakePhoto, 923 }
903 base::Unretained(device), base::Passed(&callback))); 924 // |entry| is known but |device| is nullptr, queue up a request for later.
925 photo_request_queue_.emplace_back(
926 session_id, base::Bind(&VideoCaptureManager::DoTakePhoto, this,
927 base::Passed(&callback)));
904 } 928 }
905 929
906 void VideoCaptureManager::DoStopDeviceOnDeviceThread( 930 void VideoCaptureManager::DoStopDeviceOnDeviceThread(
907 std::unique_ptr<VideoCaptureDevice> device) { 931 std::unique_ptr<VideoCaptureDevice> device) {
908 SCOPED_UMA_HISTOGRAM_TIMER("Media.VideoCaptureManager.StopDeviceTime"); 932 SCOPED_UMA_HISTOGRAM_TIMER("Media.VideoCaptureManager.StopDeviceTime");
909 DCHECK(IsOnDeviceThread()); 933 DCHECK(IsOnDeviceThread());
910 device->StopAndDeAllocate(); 934 device->StopAndDeAllocate();
911 DVLOG(3) << "DoStopDeviceOnDeviceThread"; 935 DVLOG(3) << "DoStopDeviceOnDeviceThread";
912 } 936 }
913 937
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after
1018 // TODO(mcasas): use a helper function https://crbug.com/624854. 1042 // TODO(mcasas): use a helper function https://crbug.com/624854.
1019 DeviceEntries::iterator device_it = 1043 DeviceEntries::iterator device_it =
1020 std::find_if(devices_.begin(), devices_.end(), 1044 std::find_if(devices_.begin(), devices_.end(),
1021 [entry](const std::unique_ptr<DeviceEntry>& device_entry) { 1045 [entry](const std::unique_ptr<DeviceEntry>& device_entry) {
1022 return device_entry.get() == entry; 1046 return device_entry.get() == entry;
1023 }); 1047 });
1024 devices_.erase(device_it); 1048 devices_.erase(device_it);
1025 } 1049 }
1026 } 1050 }
1027 1051
1028 media::VideoCaptureDevice* 1052 VideoCaptureManager::DeviceEntry*
1029 VideoCaptureManager::GetVideoCaptureDeviceBySessionId(int session_id) { 1053 VideoCaptureManager::GetDeviceEntryBySessionId(int session_id) {
1030 DCHECK_CURRENTLY_ON(BrowserThread::IO); 1054 DCHECK_CURRENTLY_ON(BrowserThread::IO);
1031 SessionMap::const_iterator session_it = sessions_.find(session_id); 1055 SessionMap::const_iterator session_it = sessions_.find(session_id);
1032 if (session_it == sessions_.end()) 1056 if (session_it == sessions_.end())
1033 return nullptr; 1057 return nullptr;
1034 1058
1035 DeviceEntry* const device_info = 1059 return GetDeviceEntryByTypeAndId(session_it->second.type,
1036 GetDeviceEntryByTypeAndId(session_it->second.type, session_it->second.id); 1060 session_it->second.id);
1037 return device_info ? device_info->video_capture_device() : nullptr;
1038 } 1061 }
1039 1062
1040 VideoCaptureManager::DeviceEntry* 1063 VideoCaptureManager::DeviceEntry*
1041 VideoCaptureManager::GetDeviceEntryByTypeAndId( 1064 VideoCaptureManager::GetDeviceEntryByTypeAndId(
1042 MediaStreamType type, 1065 MediaStreamType type,
1043 const std::string& device_id) const { 1066 const std::string& device_id) const {
1044 DCHECK_CURRENTLY_ON(BrowserThread::IO); 1067 DCHECK_CURRENTLY_ON(BrowserThread::IO);
1045 1068
1046 for (const std::unique_ptr<DeviceEntry>& device : devices_) { 1069 for (const std::unique_ptr<DeviceEntry>& device : devices_) {
1047 if (type == device->stream_type && device_id == device->id) 1070 if (type == device->stream_type && device_id == device->id)
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
1118 gfx::NativeViewId window_id) { 1141 gfx::NativeViewId window_id) {
1119 DCHECK(IsOnDeviceThread()); 1142 DCHECK(IsOnDeviceThread());
1120 #if defined(ENABLE_SCREEN_CAPTURE) 1143 #if defined(ENABLE_SCREEN_CAPTURE)
1121 DesktopCaptureDevice* desktop_device = 1144 DesktopCaptureDevice* desktop_device =
1122 static_cast<DesktopCaptureDevice*>(device); 1145 static_cast<DesktopCaptureDevice*>(device);
1123 desktop_device->SetNotificationWindowId(window_id); 1146 desktop_device->SetNotificationWindowId(window_id);
1124 VLOG(2) << "Screen capture notification window passed on device thread."; 1147 VLOG(2) << "Screen capture notification window passed on device thread.";
1125 #endif 1148 #endif
1126 } 1149 }
1127 1150
1151 void VideoCaptureManager::DoGetPhotoCapabilities(
1152 VideoCaptureDevice::GetPhotoCapabilitiesCallback callback,
1153 VideoCaptureDevice* device) {
1154 // Unretained() is safe to use here because |device| would be null if it
1155 // was scheduled for shutdown and destruction, and because this task is
1156 // guaranteed to run before the task that destroys the |device|.
1157 device_task_runner_->PostTask(
1158 FROM_HERE, base::Bind(&VideoCaptureDevice::GetPhotoCapabilities,
1159 base::Unretained(device), base::Passed(&callback)));
1160 }
1161
1162 void VideoCaptureManager::DoSetPhotoOptions(
1163 VideoCaptureDevice::SetPhotoOptionsCallback callback,
1164 media::mojom::PhotoSettingsPtr settings,
1165 VideoCaptureDevice* device) {
1166 // Unretained() is safe to use here because |device| would be null if it
1167 // was scheduled for shutdown and destruction, and because this task is
1168 // guaranteed to run before the task that destroys the |device|.
1169 device_task_runner_->PostTask(
1170 FROM_HERE,
1171 base::Bind(&VideoCaptureDevice::SetPhotoOptions, base::Unretained(device),
1172 base::Passed(&settings), base::Passed(&callback)));
1173 }
1174
1175 void VideoCaptureManager::DoTakePhoto(
1176 VideoCaptureDevice::TakePhotoCallback callback,
1177 VideoCaptureDevice* device) {
1178 // Unretained() is safe to use here because |device| would be null if it
1179 // was scheduled for shutdown and destruction, and because this task is
1180 // guaranteed to run before the task that destroys the |device|.
1181 device_task_runner_->PostTask(
1182 FROM_HERE, base::Bind(&VideoCaptureDevice::TakePhoto,
1183 base::Unretained(device), base::Passed(&callback)));
1184 }
1185
1128 #if defined(OS_MACOSX) 1186 #if defined(OS_MACOSX)
1129 void VideoCaptureManager::OnDeviceLayerInitialized( 1187 void VideoCaptureManager::OnDeviceLayerInitialized(
1130 const base::Closure& and_then) { 1188 const base::Closure& and_then) {
1131 DCHECK_CURRENTLY_ON(BrowserThread::IO); 1189 DCHECK_CURRENTLY_ON(BrowserThread::IO);
1132 capture_device_api_initialized_ = true; 1190 capture_device_api_initialized_ = true;
1133 and_then.Run(); 1191 and_then.Run();
1134 } 1192 }
1135 1193
1136 bool VideoCaptureManager::NeedToInitializeCaptureDeviceApi( 1194 bool VideoCaptureManager::NeedToInitializeCaptureDeviceApi(
1137 MediaStreamType stream_type) { 1195 MediaStreamType stream_type) {
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
1202 if (!device_in_queue) { 1260 if (!device_in_queue) {
1203 // Session ID is only valid for Screen capture. So we can fake it to 1261 // Session ID is only valid for Screen capture. So we can fake it to
1204 // resume video capture devices here. 1262 // resume video capture devices here.
1205 QueueStartDevice(kFakeSessionId, entry.get(), entry->parameters); 1263 QueueStartDevice(kFakeSessionId, entry.get(), entry->parameters);
1206 } 1264 }
1207 } 1265 }
1208 } 1266 }
1209 #endif // defined(OS_ANDROID) 1267 #endif // defined(OS_ANDROID)
1210 1268
1211 } // namespace content 1269 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698