| 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_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 Loading... |
| 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_EQ(serial_id, device_start_queue_.begin()->serial_id()); | 521 DCHECK(serial_id == device_start_queue_.begin()->serial_id()); |
| 522 DVLOG(3) << __func__; | 522 DVLOG(3) << "OnDeviceStarted"; |
| 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 } | |
| 557 } | 548 } |
| 558 | 549 |
| 559 device_start_queue_.pop_front(); | 550 device_start_queue_.pop_front(); |
| 560 HandleQueuedStartRequest(); | 551 HandleQueuedStartRequest(); |
| 561 } | 552 } |
| 562 | 553 |
| 563 std::unique_ptr<media::VideoCaptureDevice> | 554 std::unique_ptr<media::VideoCaptureDevice> |
| 564 VideoCaptureManager::DoStartDeviceCaptureOnDeviceThread( | 555 VideoCaptureManager::DoStartDeviceCaptureOnDeviceThread( |
| 565 const VideoCaptureDeviceDescriptor& descriptor, | 556 const VideoCaptureDeviceDescriptor& descriptor, |
| 566 const media::VideoCaptureParams& params, | 557 const media::VideoCaptureParams& params, |
| (...skipping 298 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 865 existing_device->video_capture_device(), | 856 existing_device->video_capture_device(), |
| 866 window_id_it->second)); | 857 window_id_it->second)); |
| 867 | 858 |
| 868 notification_window_ids_.erase(window_id_it); | 859 notification_window_ids_.erase(window_id_it); |
| 869 } | 860 } |
| 870 | 861 |
| 871 void VideoCaptureManager::GetPhotoCapabilities( | 862 void VideoCaptureManager::GetPhotoCapabilities( |
| 872 int session_id, | 863 int session_id, |
| 873 VideoCaptureDevice::GetPhotoCapabilitiesCallback callback) { | 864 VideoCaptureDevice::GetPhotoCapabilitiesCallback callback) { |
| 874 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 865 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 875 | 866 VideoCaptureDevice* device = GetVideoCaptureDeviceBySessionId(session_id); |
| 876 const DeviceEntry* entry = GetDeviceEntryBySessionId(session_id); | 867 if (!device) |
| 877 if (!entry) | |
| 878 return; | 868 return; |
| 879 VideoCaptureDevice* device = entry->video_capture_device(); | 869 // Unretained(device) is safe to use here because |device| would be null if it |
| 880 if (device) { | 870 // was scheduled for shutdown and destruction, and because this task is |
| 881 VideoCaptureManager::DoGetPhotoCapabilities(std::move(callback), device); | 871 // guaranteed to run before the task that destroys the |device|. |
| 882 return; | 872 device_task_runner_->PostTask( |
| 883 } | 873 FROM_HERE, base::Bind(&VideoCaptureDevice::GetPhotoCapabilities, |
| 884 // |entry| is known but |device| is nullptr, queue up a request for later. | 874 base::Unretained(device), base::Passed(&callback))); |
| 885 photo_request_queue_.emplace_back( | |
| 886 session_id, base::Bind(&VideoCaptureManager::DoGetPhotoCapabilities, this, | |
| 887 base::Passed(&callback))); | |
| 888 } | 875 } |
| 889 | 876 |
| 890 void VideoCaptureManager::SetPhotoOptions( | 877 void VideoCaptureManager::SetPhotoOptions( |
| 891 int session_id, | 878 int session_id, |
| 892 media::mojom::PhotoSettingsPtr settings, | 879 media::mojom::PhotoSettingsPtr settings, |
| 893 VideoCaptureDevice::SetPhotoOptionsCallback callback) { | 880 VideoCaptureDevice::SetPhotoOptionsCallback callback) { |
| 894 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 881 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 895 | 882 VideoCaptureDevice* device = GetVideoCaptureDeviceBySessionId(session_id); |
| 896 const DeviceEntry* entry = GetDeviceEntryBySessionId(session_id); | 883 if (!device) |
| 897 if (!entry) | |
| 898 return; | 884 return; |
| 899 VideoCaptureDevice* device = entry->video_capture_device(); | 885 device_task_runner_->PostTask( |
| 900 if (device) { | 886 FROM_HERE, |
| 901 VideoCaptureManager::DoSetPhotoOptions(std::move(callback), | 887 base::Bind(&VideoCaptureDevice::SetPhotoOptions, base::Unretained(device), |
| 902 std::move(settings), device); | 888 base::Passed(&settings), base::Passed(&callback))); |
| 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))); | |
| 909 } | 889 } |
| 910 | 890 |
| 911 void VideoCaptureManager::TakePhoto( | 891 void VideoCaptureManager::TakePhoto( |
| 912 int session_id, | 892 int session_id, |
| 913 VideoCaptureDevice::TakePhotoCallback callback) { | 893 VideoCaptureDevice::TakePhotoCallback callback) { |
| 914 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 894 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 915 | 895 VideoCaptureDevice* device = GetVideoCaptureDeviceBySessionId(session_id); |
| 916 const DeviceEntry* entry = GetDeviceEntryBySessionId(session_id); | 896 if (!device) |
| 917 if (!entry) | |
| 918 return; | 897 return; |
| 919 VideoCaptureDevice* device = entry->video_capture_device(); | 898 // Unretained(device) is safe to use here because |device| would be null if it |
| 920 if (device) { | 899 // was scheduled for shutdown and destruction, and because this task is |
| 921 VideoCaptureManager::DoTakePhoto(std::move(callback), device); | 900 // guaranteed to run before the task that destroys the |device|. |
| 922 return; | 901 device_task_runner_->PostTask( |
| 923 } | 902 FROM_HERE, base::Bind(&VideoCaptureDevice::TakePhoto, |
| 924 // |entry| is known but |device| is nullptr, queue up a request for later. | 903 base::Unretained(device), base::Passed(&callback))); |
| 925 photo_request_queue_.emplace_back( | |
| 926 session_id, base::Bind(&VideoCaptureManager::DoTakePhoto, this, | |
| 927 base::Passed(&callback))); | |
| 928 } | 904 } |
| 929 | 905 |
| 930 void VideoCaptureManager::DoStopDeviceOnDeviceThread( | 906 void VideoCaptureManager::DoStopDeviceOnDeviceThread( |
| 931 std::unique_ptr<VideoCaptureDevice> device) { | 907 std::unique_ptr<VideoCaptureDevice> device) { |
| 932 SCOPED_UMA_HISTOGRAM_TIMER("Media.VideoCaptureManager.StopDeviceTime"); | 908 SCOPED_UMA_HISTOGRAM_TIMER("Media.VideoCaptureManager.StopDeviceTime"); |
| 933 DCHECK(IsOnDeviceThread()); | 909 DCHECK(IsOnDeviceThread()); |
| 934 device->StopAndDeAllocate(); | 910 device->StopAndDeAllocate(); |
| 935 DVLOG(3) << "DoStopDeviceOnDeviceThread"; | 911 DVLOG(3) << "DoStopDeviceOnDeviceThread"; |
| 936 } | 912 } |
| 937 | 913 |
| (...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1042 // TODO(mcasas): use a helper function https://crbug.com/624854. | 1018 // TODO(mcasas): use a helper function https://crbug.com/624854. |
| 1043 DeviceEntries::iterator device_it = | 1019 DeviceEntries::iterator device_it = |
| 1044 std::find_if(devices_.begin(), devices_.end(), | 1020 std::find_if(devices_.begin(), devices_.end(), |
| 1045 [entry](const std::unique_ptr<DeviceEntry>& device_entry) { | 1021 [entry](const std::unique_ptr<DeviceEntry>& device_entry) { |
| 1046 return device_entry.get() == entry; | 1022 return device_entry.get() == entry; |
| 1047 }); | 1023 }); |
| 1048 devices_.erase(device_it); | 1024 devices_.erase(device_it); |
| 1049 } | 1025 } |
| 1050 } | 1026 } |
| 1051 | 1027 |
| 1052 VideoCaptureManager::DeviceEntry* | 1028 media::VideoCaptureDevice* |
| 1053 VideoCaptureManager::GetDeviceEntryBySessionId(int session_id) { | 1029 VideoCaptureManager::GetVideoCaptureDeviceBySessionId(int session_id) { |
| 1054 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 1030 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 1055 SessionMap::const_iterator session_it = sessions_.find(session_id); | 1031 SessionMap::const_iterator session_it = sessions_.find(session_id); |
| 1056 if (session_it == sessions_.end()) | 1032 if (session_it == sessions_.end()) |
| 1057 return nullptr; | 1033 return nullptr; |
| 1058 | 1034 |
| 1059 return GetDeviceEntryByTypeAndId(session_it->second.type, | 1035 DeviceEntry* const device_info = |
| 1060 session_it->second.id); | 1036 GetDeviceEntryByTypeAndId(session_it->second.type, session_it->second.id); |
| 1037 return device_info ? device_info->video_capture_device() : nullptr; |
| 1061 } | 1038 } |
| 1062 | 1039 |
| 1063 VideoCaptureManager::DeviceEntry* | 1040 VideoCaptureManager::DeviceEntry* |
| 1064 VideoCaptureManager::GetDeviceEntryByTypeAndId( | 1041 VideoCaptureManager::GetDeviceEntryByTypeAndId( |
| 1065 MediaStreamType type, | 1042 MediaStreamType type, |
| 1066 const std::string& device_id) const { | 1043 const std::string& device_id) const { |
| 1067 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 1044 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 1068 | 1045 |
| 1069 for (const std::unique_ptr<DeviceEntry>& device : devices_) { | 1046 for (const std::unique_ptr<DeviceEntry>& device : devices_) { |
| 1070 if (type == device->stream_type && device_id == device->id) | 1047 if (type == device->stream_type && device_id == device->id) |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1141 gfx::NativeViewId window_id) { | 1118 gfx::NativeViewId window_id) { |
| 1142 DCHECK(IsOnDeviceThread()); | 1119 DCHECK(IsOnDeviceThread()); |
| 1143 #if defined(ENABLE_SCREEN_CAPTURE) | 1120 #if defined(ENABLE_SCREEN_CAPTURE) |
| 1144 DesktopCaptureDevice* desktop_device = | 1121 DesktopCaptureDevice* desktop_device = |
| 1145 static_cast<DesktopCaptureDevice*>(device); | 1122 static_cast<DesktopCaptureDevice*>(device); |
| 1146 desktop_device->SetNotificationWindowId(window_id); | 1123 desktop_device->SetNotificationWindowId(window_id); |
| 1147 VLOG(2) << "Screen capture notification window passed on device thread."; | 1124 VLOG(2) << "Screen capture notification window passed on device thread."; |
| 1148 #endif | 1125 #endif |
| 1149 } | 1126 } |
| 1150 | 1127 |
| 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 | |
| 1186 #if defined(OS_MACOSX) | 1128 #if defined(OS_MACOSX) |
| 1187 void VideoCaptureManager::OnDeviceLayerInitialized( | 1129 void VideoCaptureManager::OnDeviceLayerInitialized( |
| 1188 const base::Closure& and_then) { | 1130 const base::Closure& and_then) { |
| 1189 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 1131 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 1190 capture_device_api_initialized_ = true; | 1132 capture_device_api_initialized_ = true; |
| 1191 and_then.Run(); | 1133 and_then.Run(); |
| 1192 } | 1134 } |
| 1193 | 1135 |
| 1194 bool VideoCaptureManager::NeedToInitializeCaptureDeviceApi( | 1136 bool VideoCaptureManager::NeedToInitializeCaptureDeviceApi( |
| 1195 MediaStreamType stream_type) { | 1137 MediaStreamType stream_type) { |
| (...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1260 if (!device_in_queue) { | 1202 if (!device_in_queue) { |
| 1261 // Session ID is only valid for Screen capture. So we can fake it to | 1203 // Session ID is only valid for Screen capture. So we can fake it to |
| 1262 // resume video capture devices here. | 1204 // resume video capture devices here. |
| 1263 QueueStartDevice(kFakeSessionId, entry.get(), entry->parameters); | 1205 QueueStartDevice(kFakeSessionId, entry.get(), entry->parameters); |
| 1264 } | 1206 } |
| 1265 } | 1207 } |
| 1266 } | 1208 } |
| 1267 #endif // defined(OS_ANDROID) | 1209 #endif // defined(OS_ANDROID) |
| 1268 | 1210 |
| 1269 } // namespace content | 1211 } // namespace content |
| OLD | NEW |