| 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(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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 |
| OLD | NEW |