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 263 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
274 if (NeedToInitializeCaptureDeviceApi(stream_type)) { | 274 if (NeedToInitializeCaptureDeviceApi(stream_type)) { |
275 InitializeCaptureDeviceApiOnUIThread( | 275 InitializeCaptureDeviceApiOnUIThread( |
276 base::Bind(&VideoCaptureManager::EnumerateDevices, this, stream_type)); | 276 base::Bind(&VideoCaptureManager::EnumerateDevices, this, stream_type)); |
277 return; | 277 return; |
278 } | 278 } |
279 #endif | 279 #endif |
280 | 280 |
281 // Bind a callback to ConsolidateDevicesInfoOnDeviceThread() with an argument | 281 // Bind a callback to ConsolidateDevicesInfoOnDeviceThread() with an argument |
282 // for another callback to OnDevicesInfoEnumerated() to be run in the current | 282 // for another callback to OnDevicesInfoEnumerated() to be run in the current |
283 // loop, i.e. IO loop. Pass a timer for UMA histogram collection. | 283 // loop, i.e. IO loop. Pass a timer for UMA histogram collection. |
284 base::Callback<void(std::unique_ptr<VideoCaptureDevice::Names>)> | 284 base::Callback<void(std::unique_ptr<VideoCaptureDeviceDescriptors>)> |
285 devices_enumerated_callback = base::Bind( | 285 devices_enumerated_callback = base::Bind( |
286 &VideoCaptureManager::ConsolidateDevicesInfoOnDeviceThread, this, | 286 &VideoCaptureManager::ConsolidateDevicesInfoOnDeviceThread, this, |
287 media::BindToCurrentLoop( | 287 media::BindToCurrentLoop( |
288 base::Bind(&VideoCaptureManager::OnDevicesInfoEnumerated, this, | 288 base::Bind(&VideoCaptureManager::OnDevicesInfoEnumerated, this, |
289 stream_type, base::Owned(new base::ElapsedTimer()))), | 289 stream_type, base::Owned(new base::ElapsedTimer()))), |
290 stream_type, devices_info_cache_); | 290 stream_type, devices_info_cache_); |
291 // OK to use base::Unretained() since we own the VCDFactory and |this| is | 291 // OK to use base::Unretained() since we own the VCDFactory and |this| is |
292 // bound in |devices_enumerated_callback|. | 292 // bound in |devices_enumerated_callback|. |
293 device_task_runner_->PostTask(FROM_HERE, | 293 device_task_runner_->PostTask( |
294 base::Bind(&media::VideoCaptureDeviceFactory::EnumerateDeviceNames, | 294 FROM_HERE, |
| 295 base::Bind(&media::VideoCaptureDeviceFactory::EnumerateDeviceDescriptors, |
295 base::Unretained(video_capture_device_factory_.get()), | 296 base::Unretained(video_capture_device_factory_.get()), |
296 devices_enumerated_callback)); | 297 devices_enumerated_callback)); |
297 } | 298 } |
298 | 299 |
299 int VideoCaptureManager::Open(const StreamDeviceInfo& device_info) { | 300 int VideoCaptureManager::Open(const StreamDeviceInfo& device_info) { |
300 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 301 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
301 DCHECK(listener_); | 302 DCHECK(listener_); |
302 | 303 |
303 // Generate a new id for the session being opened. | 304 // Generate a new id for the session being opened. |
304 const media::VideoCaptureSessionId capture_session_id = | 305 const media::VideoCaptureSessionId capture_session_id = |
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
423 << entry->id << " start id = " << entry->serial_id; | 424 << entry->id << " start id = " << entry->serial_id; |
424 | 425 |
425 base::Callback<std::unique_ptr<VideoCaptureDevice>(void)> | 426 base::Callback<std::unique_ptr<VideoCaptureDevice>(void)> |
426 start_capture_function; | 427 start_capture_function; |
427 | 428 |
428 switch (entry->stream_type) { | 429 switch (entry->stream_type) { |
429 case MEDIA_DEVICE_VIDEO_CAPTURE: { | 430 case MEDIA_DEVICE_VIDEO_CAPTURE: { |
430 // We look up the device id from the renderer in our local enumeration | 431 // We look up the device id from the renderer in our local enumeration |
431 // since the renderer does not have all the information that might be | 432 // since the renderer does not have all the information that might be |
432 // held in the browser-side VideoCaptureDevice::Name structure. | 433 // held in the browser-side VideoCaptureDevice::Name structure. |
433 const media::VideoCaptureDeviceInfo* found = GetDeviceInfoById(entry->id); | 434 const VideoCaptureDeviceInfo* found = GetDeviceInfoById(entry->id); |
434 if (found) { | 435 if (found) { |
435 entry->video_capture_controller()->DoLogOnIOThread(base::StringPrintf( | 436 entry->video_capture_controller()->DoLogOnIOThread( |
436 "Starting device: id: %s, name: %s, api: %s", | 437 base::StringPrintf("Starting device: id: %s, name: %s, api: %s", |
437 found->name.id().c_str(), found->name.GetNameAndModel().c_str(), | 438 found->descriptor.device_id.c_str(), |
438 found->name.GetCaptureApiTypeString())); | 439 found->descriptor.GetNameAndModel().c_str(), |
| 440 found->descriptor.GetCaptureApiTypeString())); |
439 | 441 |
440 start_capture_function = base::Bind( | 442 start_capture_function = base::Bind( |
441 &VideoCaptureManager::DoStartDeviceCaptureOnDeviceThread, this, | 443 &VideoCaptureManager::DoStartDeviceCaptureOnDeviceThread, this, |
442 found->name, request->params(), | 444 found->descriptor, request->params(), |
443 base::Passed(entry->video_capture_controller()->NewDeviceClient())); | 445 base::Passed(entry->video_capture_controller()->NewDeviceClient())); |
444 } else { | 446 } else { |
445 // Errors from DoStartDeviceCaptureOnDeviceThread go via | 447 // Errors from DoStartDeviceCaptureOnDeviceThread go via |
446 // VideoCaptureDeviceClient::OnError, which needs some thread | 448 // VideoCaptureDeviceClient::OnError, which needs some thread |
447 // dancing to get errors processed on the IO thread. But since | 449 // dancing to get errors processed on the IO thread. But since |
448 // we're on that thread, we call VideoCaptureController | 450 // we're on that thread, we call VideoCaptureController |
449 // methods directly. | 451 // methods directly. |
450 const std::string log_message = base::StringPrintf( | 452 const std::string log_message = base::StringPrintf( |
451 "Error on %s:%d: device %s unknown. Maybe recently disconnected?", | 453 "Error on %s:%d: device %s unknown. Maybe recently disconnected?", |
452 __FILE__, __LINE__, entry->id.c_str()); | 454 __FILE__, __LINE__, entry->id.c_str()); |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
517 MaybePostDesktopCaptureWindowId(session_id); | 519 MaybePostDesktopCaptureWindowId(session_id); |
518 } | 520 } |
519 } | 521 } |
520 | 522 |
521 device_start_queue_.pop_front(); | 523 device_start_queue_.pop_front(); |
522 HandleQueuedStartRequest(); | 524 HandleQueuedStartRequest(); |
523 } | 525 } |
524 | 526 |
525 std::unique_ptr<media::VideoCaptureDevice> | 527 std::unique_ptr<media::VideoCaptureDevice> |
526 VideoCaptureManager::DoStartDeviceCaptureOnDeviceThread( | 528 VideoCaptureManager::DoStartDeviceCaptureOnDeviceThread( |
527 const VideoCaptureDevice::Name& name, | 529 const VideoCaptureDeviceDescriptor& descriptor, |
528 const media::VideoCaptureParams& params, | 530 const media::VideoCaptureParams& params, |
529 std::unique_ptr<VideoCaptureDevice::Client> device_client) { | 531 std::unique_ptr<VideoCaptureDevice::Client> device_client) { |
530 SCOPED_UMA_HISTOGRAM_TIMER("Media.VideoCaptureManager.StartDeviceTime"); | 532 SCOPED_UMA_HISTOGRAM_TIMER("Media.VideoCaptureManager.StartDeviceTime"); |
531 DCHECK(IsOnDeviceThread()); | 533 DCHECK(IsOnDeviceThread()); |
532 | 534 |
533 std::unique_ptr<VideoCaptureDevice> video_capture_device; | 535 std::unique_ptr<VideoCaptureDevice> video_capture_device; |
534 video_capture_device = video_capture_device_factory_->Create(name); | 536 video_capture_device = |
| 537 video_capture_device_factory_->CreateDevice(descriptor); |
535 | 538 |
536 if (!video_capture_device) { | 539 if (!video_capture_device) { |
537 device_client->OnError(FROM_HERE, "Could not create capture device"); | 540 device_client->OnError(FROM_HERE, "Could not create capture device"); |
538 return nullptr; | 541 return nullptr; |
539 } | 542 } |
540 | 543 |
541 video_capture_device->AllocateAndStart(params, std::move(device_client)); | 544 video_capture_device->AllocateAndStart(params, std::move(device_client)); |
542 return video_capture_device; | 545 return video_capture_device; |
543 } | 546 } |
544 | 547 |
(...skipping 197 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
742 media::VideoCaptureFormats* supported_formats) { | 745 media::VideoCaptureFormats* supported_formats) { |
743 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 746 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
744 DCHECK(supported_formats->empty()); | 747 DCHECK(supported_formats->empty()); |
745 | 748 |
746 SessionMap::iterator it = sessions_.find(capture_session_id); | 749 SessionMap::iterator it = sessions_.find(capture_session_id); |
747 if (it == sessions_.end()) | 750 if (it == sessions_.end()) |
748 return false; | 751 return false; |
749 DVLOG(1) << "GetDeviceSupportedFormats for device: " << it->second.name; | 752 DVLOG(1) << "GetDeviceSupportedFormats for device: " << it->second.name; |
750 | 753 |
751 // Return all available formats of the device, regardless its started state. | 754 // Return all available formats of the device, regardless its started state. |
752 media::VideoCaptureDeviceInfo* existing_device = | 755 VideoCaptureDeviceInfo* existing_device = GetDeviceInfoById(it->second.id); |
753 GetDeviceInfoById(it->second.id); | |
754 if (existing_device) | 756 if (existing_device) |
755 *supported_formats = existing_device->supported_formats; | 757 *supported_formats = existing_device->supported_formats; |
756 return true; | 758 return true; |
757 } | 759 } |
758 | 760 |
759 bool VideoCaptureManager::GetDeviceFormatsInUse( | 761 bool VideoCaptureManager::GetDeviceFormatsInUse( |
760 media::VideoCaptureSessionId capture_session_id, | 762 media::VideoCaptureSessionId capture_session_id, |
761 media::VideoCaptureFormats* formats_in_use) { | 763 media::VideoCaptureFormats* formats_in_use) { |
762 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 764 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
763 DCHECK(formats_in_use->empty()); | 765 DCHECK(formats_in_use->empty()); |
(...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
900 if (!listener_) { | 902 if (!listener_) { |
901 // Listener has been removed. | 903 // Listener has been removed. |
902 return; | 904 return; |
903 } | 905 } |
904 listener_->Closed(stream_type, capture_session_id); | 906 listener_->Closed(stream_type, capture_session_id); |
905 } | 907 } |
906 | 908 |
907 void VideoCaptureManager::OnDevicesInfoEnumerated( | 909 void VideoCaptureManager::OnDevicesInfoEnumerated( |
908 MediaStreamType stream_type, | 910 MediaStreamType stream_type, |
909 base::ElapsedTimer* timer, | 911 base::ElapsedTimer* timer, |
910 const media::VideoCaptureDeviceInfos& new_devices_info_cache) { | 912 const VideoCaptureDeviceInfos& new_devices_info_cache) { |
911 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 913 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
912 UMA_HISTOGRAM_TIMES( | 914 UMA_HISTOGRAM_TIMES( |
913 "Media.VideoCaptureManager.GetAvailableDevicesInfoOnDeviceThreadTime", | 915 "Media.VideoCaptureManager.GetAvailableDevicesInfoOnDeviceThreadTime", |
914 timer->Elapsed()); | 916 timer->Elapsed()); |
915 if (!listener_) { | 917 if (!listener_) { |
916 // Listener has been removed. | 918 // Listener has been removed. |
917 return; | 919 return; |
918 } | 920 } |
919 devices_info_cache_ = new_devices_info_cache; | 921 devices_info_cache_ = new_devices_info_cache; |
920 | 922 |
921 MediaInternals::GetInstance()->UpdateVideoCaptureDeviceCapabilities( | 923 MediaInternals::GetInstance()->UpdateVideoCaptureDeviceCapabilities( |
922 devices_info_cache_); | 924 devices_info_cache_); |
923 | 925 |
924 // Walk the |devices_info_cache_| and transform from VCD::Name to | 926 // Walk the |devices_info_cache_| and transform from VCD::Name to |
925 // StreamDeviceInfo for return purposes. | 927 // StreamDeviceInfo for return purposes. |
926 StreamDeviceInfoArray devices; | 928 StreamDeviceInfoArray devices; |
927 for (const auto& it : devices_info_cache_) { | 929 for (const auto& it : devices_info_cache_) { |
928 devices.push_back(StreamDeviceInfo( | 930 devices.emplace_back(stream_type, it.descriptor.GetNameAndModel(), |
929 stream_type, it.name.GetNameAndModel(), it.name.id())); | 931 it.descriptor.device_id); |
930 } | 932 } |
931 listener_->DevicesEnumerated(stream_type, devices); | 933 listener_->DevicesEnumerated(stream_type, devices); |
932 } | 934 } |
933 | 935 |
934 bool VideoCaptureManager::IsOnDeviceThread() const { | 936 bool VideoCaptureManager::IsOnDeviceThread() const { |
935 return device_task_runner_->BelongsToCurrentThread(); | 937 return device_task_runner_->BelongsToCurrentThread(); |
936 } | 938 } |
937 | 939 |
938 void VideoCaptureManager::ConsolidateDevicesInfoOnDeviceThread( | 940 void VideoCaptureManager::ConsolidateDevicesInfoOnDeviceThread( |
939 base::Callback<void(const media::VideoCaptureDeviceInfos&)> | 941 base::Callback<void(const VideoCaptureDeviceInfos&)> |
940 on_devices_enumerated_callback, | 942 on_devices_enumerated_callback, |
941 MediaStreamType stream_type, | 943 MediaStreamType stream_type, |
942 const media::VideoCaptureDeviceInfos& old_device_info_cache, | 944 const VideoCaptureDeviceInfos& old_device_info_cache, |
943 std::unique_ptr<VideoCaptureDevice::Names> names_snapshot) { | 945 std::unique_ptr<VideoCaptureDeviceDescriptors> descriptors_snapshot) { |
944 DCHECK(IsOnDeviceThread()); | 946 DCHECK(IsOnDeviceThread()); |
945 // Construct |new_devices_info_cache| with the cached devices that are still | 947 // Construct |new_devices_info_cache| with the cached devices that are still |
946 // present in the system, and remove their names from |names_snapshot|, so we | 948 // present in the system, and remove their names from |names_snapshot|, so we |
947 // keep there the truly new devices. | 949 // keep there the truly new devices. |
948 media::VideoCaptureDeviceInfos new_devices_info_cache; | 950 VideoCaptureDeviceInfos new_devices_info_cache; |
949 for (const auto& device_info : old_device_info_cache) { | 951 for (const auto& device_info : old_device_info_cache) { |
950 for (VideoCaptureDevice::Names::iterator it = names_snapshot->begin(); | 952 for (VideoCaptureDeviceDescriptors::iterator it = |
951 it != names_snapshot->end(); ++it) { | 953 descriptors_snapshot->begin(); |
952 if (device_info.name.id() == it->id()) { | 954 it != descriptors_snapshot->end(); ++it) { |
| 955 if (device_info.descriptor.device_id == it->device_id) { |
953 new_devices_info_cache.push_back(device_info); | 956 new_devices_info_cache.push_back(device_info); |
954 names_snapshot->erase(it); | 957 descriptors_snapshot->erase(it); |
955 break; | 958 break; |
956 } | 959 } |
957 } | 960 } |
958 } | 961 } |
959 | 962 |
960 // Get the supported capture formats for the new devices in |names_snapshot|. | 963 // Get the device info for the new devices in |names_snapshot|. |
961 for (const auto& it : *names_snapshot) { | 964 for (const auto& it : *descriptors_snapshot) { |
962 media::VideoCaptureDeviceInfo device_info(it, media::VideoCaptureFormats()); | 965 VideoCaptureDeviceInfo device_info(it); |
963 video_capture_device_factory_->GetDeviceSupportedFormats( | 966 video_capture_device_factory_->GetSupportedFormats( |
964 it, &(device_info.supported_formats)); | 967 it, &device_info.supported_formats); |
965 ConsolidateCaptureFormats(&device_info.supported_formats); | 968 ConsolidateCaptureFormats(&device_info.supported_formats); |
966 new_devices_info_cache.push_back(device_info); | 969 new_devices_info_cache.push_back(device_info); |
967 } | 970 } |
968 | 971 |
969 on_devices_enumerated_callback.Run(new_devices_info_cache); | 972 on_devices_enumerated_callback.Run(new_devices_info_cache); |
970 } | 973 } |
971 | 974 |
972 void VideoCaptureManager::DestroyDeviceEntryIfNoClients(DeviceEntry* entry) { | 975 void VideoCaptureManager::DestroyDeviceEntryIfNoClients(DeviceEntry* entry) { |
973 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 976 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
974 // Removal of the last client stops the device. | 977 // Removal of the last client stops the device. |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1034 int serial_id) const { | 1037 int serial_id) const { |
1035 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 1038 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
1036 | 1039 |
1037 for (const std::unique_ptr<DeviceEntry>& device : devices_) { | 1040 for (const std::unique_ptr<DeviceEntry>& device : devices_) { |
1038 if (device->serial_id == serial_id) | 1041 if (device->serial_id == serial_id) |
1039 return device.get(); | 1042 return device.get(); |
1040 } | 1043 } |
1041 return nullptr; | 1044 return nullptr; |
1042 } | 1045 } |
1043 | 1046 |
1044 media::VideoCaptureDeviceInfo* VideoCaptureManager::GetDeviceInfoById( | 1047 VideoCaptureDeviceInfo* VideoCaptureManager::GetDeviceInfoById( |
1045 const std::string& id) { | 1048 const std::string& id) { |
1046 for (auto& it : devices_info_cache_) { | 1049 for (auto& it : devices_info_cache_) { |
1047 if (it.name.id() == id) | 1050 if (it.descriptor.device_id == id) |
1048 return ⁢ | 1051 return ⁢ |
1049 } | 1052 } |
1050 return nullptr; | 1053 return nullptr; |
1051 } | 1054 } |
1052 | 1055 |
1053 VideoCaptureManager::DeviceEntry* VideoCaptureManager::GetOrCreateDeviceEntry( | 1056 VideoCaptureManager::DeviceEntry* VideoCaptureManager::GetOrCreateDeviceEntry( |
1054 media::VideoCaptureSessionId capture_session_id, | 1057 media::VideoCaptureSessionId capture_session_id, |
1055 const media::VideoCaptureParams& params) { | 1058 const media::VideoCaptureParams& params) { |
1056 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 1059 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
1057 | 1060 |
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1169 if (!device_in_queue) { | 1172 if (!device_in_queue) { |
1170 // Session ID is only valid for Screen capture. So we can fake it to | 1173 // Session ID is only valid for Screen capture. So we can fake it to |
1171 // resume video capture devices here. | 1174 // resume video capture devices here. |
1172 QueueStartDevice(kFakeSessionId, entry.get(), entry->parameters); | 1175 QueueStartDevice(kFakeSessionId, entry.get(), entry->parameters); |
1173 } | 1176 } |
1174 } | 1177 } |
1175 } | 1178 } |
1176 #endif // defined(OS_ANDROID) | 1179 #endif // defined(OS_ANDROID) |
1177 | 1180 |
1178 } // namespace content | 1181 } // namespace content |
OLD | NEW |