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 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
51 #endif | 51 #endif |
52 | 52 |
53 #if defined(OS_ANDROID) | 53 #if defined(OS_ANDROID) |
54 #include "content/browser/media/capture/screen_capture_device_android.h" | 54 #include "content/browser/media/capture/screen_capture_device_android.h" |
55 #endif | 55 #endif |
56 | 56 |
57 #endif // defined(ENABLE_SCREEN_CAPTURE) | 57 #endif // defined(ENABLE_SCREEN_CAPTURE) |
58 | 58 |
59 namespace { | 59 namespace { |
60 | 60 |
| 61 // Compares two VideoCaptureFormat by checking smallest frame_size area, then |
| 62 // by _largest_ frame_rate. Used to order a VideoCaptureFormats vector so that |
| 63 // the first entry for a given resolution has the largest frame rate, as needed |
| 64 // by the ConsolidateCaptureFormats() method. |
| 65 bool IsCaptureFormatSmaller(const media::VideoCaptureFormat& format1, |
| 66 const media::VideoCaptureFormat& format2) { |
| 67 DCHECK(format1.frame_size.GetCheckedArea().IsValid()); |
| 68 DCHECK(format2.frame_size.GetCheckedArea().IsValid()); |
| 69 if (format1.frame_size.GetCheckedArea().ValueOrDefault(0) == |
| 70 format2.frame_size.GetCheckedArea().ValueOrDefault(0)) { |
| 71 return format1.frame_rate > format2.frame_rate; |
| 72 } |
| 73 return format1.frame_size.GetCheckedArea().ValueOrDefault(0) < |
| 74 format2.frame_size.GetCheckedArea().ValueOrDefault(0); |
| 75 } |
| 76 |
| 77 bool IsCaptureFormatSizeEqual(const media::VideoCaptureFormat& format1, |
| 78 const media::VideoCaptureFormat& format2) { |
| 79 DCHECK(format1.frame_size.GetCheckedArea().IsValid()); |
| 80 DCHECK(format2.frame_size.GetCheckedArea().IsValid()); |
| 81 return format1.frame_size.GetCheckedArea().ValueOrDefault(0) == |
| 82 format2.frame_size.GetCheckedArea().ValueOrDefault(0); |
| 83 } |
| 84 |
| 85 // This function receives a list of capture formats, removes duplicated |
| 86 // resolutions while keeping the highest frame rate for each, and forcing I420 |
| 87 // pixel format. |
| 88 void ConsolidateCaptureFormats(media::VideoCaptureFormats* formats) { |
| 89 if (formats->empty()) |
| 90 return; |
| 91 std::sort(formats->begin(), formats->end(), IsCaptureFormatSmaller); |
| 92 // Due to the ordering imposed, the largest frame_rate is kept while removing |
| 93 // duplicated resolutions. |
| 94 media::VideoCaptureFormats::iterator last = |
| 95 std::unique(formats->begin(), formats->end(), IsCaptureFormatSizeEqual); |
| 96 formats->erase(last, formats->end()); |
| 97 // Mark all formats as I420, since this is what the renderer side will get |
| 98 // anyhow: the actual pixel format is decided at the device level. |
| 99 // Don't do this for Y16 format as it is handled separatelly. |
| 100 for (auto& format : *formats) { |
| 101 if (format.pixel_format != media::PIXEL_FORMAT_Y16) |
| 102 format.pixel_format = media::PIXEL_FORMAT_I420; |
| 103 } |
| 104 } |
| 105 |
61 // Used for logging capture events. | 106 // Used for logging capture events. |
62 // Elements in this enum should not be deleted or rearranged; the only | 107 // Elements in this enum should not be deleted or rearranged; the only |
63 // permitted operation is to add new elements before NUM_VIDEO_CAPTURE_EVENT. | 108 // permitted operation is to add new elements before NUM_VIDEO_CAPTURE_EVENT. |
64 enum VideoCaptureEvent { | 109 enum VideoCaptureEvent { |
65 VIDEO_CAPTURE_START_CAPTURE = 0, | 110 VIDEO_CAPTURE_START_CAPTURE = 0, |
66 VIDEO_CAPTURE_STOP_CAPTURE_OK = 1, | 111 VIDEO_CAPTURE_STOP_CAPTURE_OK = 1, |
67 VIDEO_CAPTURE_STOP_CAPTURE_DUE_TO_ERROR = 2, | 112 VIDEO_CAPTURE_STOP_CAPTURE_DUE_TO_ERROR = 2, |
68 VIDEO_CAPTURE_STOP_CAPTURE_OK_NO_FRAMES_PRODUCED_BY_DEVICE = 3, | 113 VIDEO_CAPTURE_STOP_CAPTURE_OK_NO_FRAMES_PRODUCED_BY_DEVICE = 3, |
69 VIDEO_CAPTURE_STOP_CAPTURE_OK_NO_FRAMES_PRODUCED_BY_DESKTOP_OR_TAB = 4, | 114 VIDEO_CAPTURE_STOP_CAPTURE_OK_NO_FRAMES_PRODUCED_BY_DESKTOP_OR_TAB = 4, |
70 NUM_VIDEO_CAPTURE_EVENT | 115 NUM_VIDEO_CAPTURE_EVENT |
71 }; | 116 }; |
72 | 117 |
73 void LogVideoCaptureEvent(VideoCaptureEvent event) { | 118 void LogVideoCaptureEvent(VideoCaptureEvent event) { |
74 UMA_HISTOGRAM_ENUMERATION("Media.VideoCaptureManager.Event", event, | 119 UMA_HISTOGRAM_ENUMERATION("Media.VideoCaptureManager.Event", event, |
75 NUM_VIDEO_CAPTURE_EVENT); | 120 NUM_VIDEO_CAPTURE_EVENT); |
76 } | 121 } |
77 | 122 |
78 const media::VideoCaptureSessionId kFakeSessionId = -1; | 123 const media::VideoCaptureSessionId kFakeSessionId = -1; |
79 | 124 |
80 } // namespace | 125 } // namespace |
81 | 126 |
82 namespace content { | 127 namespace content { |
83 | 128 |
| 129 // Bundles a media::VideoCaptureDeviceDescriptor with corresponding supported |
| 130 // video formats. |
| 131 struct VideoCaptureManager::DeviceInfo { |
| 132 DeviceInfo(); |
| 133 DeviceInfo(media::VideoCaptureDeviceDescriptor descriptor); |
| 134 DeviceInfo(const DeviceInfo& other); |
| 135 ~DeviceInfo(); |
| 136 DeviceInfo& operator=(const DeviceInfo& other); |
| 137 |
| 138 media::VideoCaptureDeviceDescriptor descriptor; |
| 139 media::VideoCaptureFormats supported_formats; |
| 140 }; |
| 141 |
84 // Class used for queuing request for starting a device. | 142 // Class used for queuing request for starting a device. |
85 class VideoCaptureManager::CaptureDeviceStartRequest { | 143 class VideoCaptureManager::CaptureDeviceStartRequest { |
86 public: | 144 public: |
87 CaptureDeviceStartRequest(VideoCaptureController* controller, | 145 CaptureDeviceStartRequest(VideoCaptureController* controller, |
88 media::VideoCaptureSessionId session_id, | 146 media::VideoCaptureSessionId session_id, |
89 const media::VideoCaptureParams& params); | 147 const media::VideoCaptureParams& params); |
90 VideoCaptureController* controller() const { return controller_; } | 148 VideoCaptureController* controller() const { return controller_; } |
91 media::VideoCaptureSessionId session_id() const { return session_id_; } | 149 media::VideoCaptureSessionId session_id() const { return session_id_; } |
92 media::VideoCaptureParams params() const { return params_; } | 150 media::VideoCaptureParams params() const { return params_; } |
93 | 151 |
94 private: | 152 private: |
95 VideoCaptureController* const controller_; | 153 VideoCaptureController* const controller_; |
96 const media::VideoCaptureSessionId session_id_; | 154 const media::VideoCaptureSessionId session_id_; |
97 const media::VideoCaptureParams params_; | 155 const media::VideoCaptureParams params_; |
98 }; | 156 }; |
99 | 157 |
| 158 VideoCaptureManager::DeviceInfo::DeviceInfo() = default; |
| 159 |
| 160 VideoCaptureManager::DeviceInfo::DeviceInfo( |
| 161 media::VideoCaptureDeviceDescriptor descriptor) |
| 162 : descriptor(descriptor) {} |
| 163 |
| 164 VideoCaptureManager::DeviceInfo::DeviceInfo( |
| 165 const VideoCaptureManager::DeviceInfo& other) = default; |
| 166 |
| 167 VideoCaptureManager::DeviceInfo::~DeviceInfo() = default; |
| 168 |
| 169 VideoCaptureManager::DeviceInfo& VideoCaptureManager::DeviceInfo::operator=( |
| 170 const VideoCaptureManager::DeviceInfo& other) = default; |
| 171 |
100 VideoCaptureManager::CaptureDeviceStartRequest::CaptureDeviceStartRequest( | 172 VideoCaptureManager::CaptureDeviceStartRequest::CaptureDeviceStartRequest( |
101 VideoCaptureController* controller, | 173 VideoCaptureController* controller, |
102 media::VideoCaptureSessionId session_id, | 174 media::VideoCaptureSessionId session_id, |
103 const media::VideoCaptureParams& params) | 175 const media::VideoCaptureParams& params) |
104 : controller_(controller), session_id_(session_id), params_(params) {} | 176 : controller_(controller), session_id_(session_id), params_(params) {} |
105 | 177 |
106 VideoCaptureManager::VideoCaptureManager( | 178 VideoCaptureManager::VideoCaptureManager( |
107 std::unique_ptr<media::VideoCaptureSystem> video_capture_system, | 179 std::unique_ptr<media::VideoCaptureDeviceFactory> factory, |
108 scoped_refptr<base::SingleThreadTaskRunner> device_task_runner) | 180 scoped_refptr<base::SingleThreadTaskRunner> device_task_runner) |
109 : device_task_runner_(std::move(device_task_runner)), | 181 : device_task_runner_(std::move(device_task_runner)), |
110 new_capture_session_id_(1), | 182 new_capture_session_id_(1), |
111 video_capture_system_(std::move(video_capture_system)) {} | 183 video_capture_device_factory_(std::move(factory)) {} |
112 | 184 |
113 VideoCaptureManager::~VideoCaptureManager() { | 185 VideoCaptureManager::~VideoCaptureManager() { |
114 DCHECK(controllers_.empty()); | 186 DCHECK(controllers_.empty()); |
115 DCHECK(device_start_request_queue_.empty()); | 187 DCHECK(device_start_request_queue_.empty()); |
116 } | 188 } |
117 | 189 |
118 void VideoCaptureManager::AddVideoCaptureObserver( | 190 void VideoCaptureManager::AddVideoCaptureObserver( |
119 media::VideoCaptureObserver* observer) { | 191 media::VideoCaptureObserver* observer) { |
120 DCHECK(observer); | 192 DCHECK(observer); |
121 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 193 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
(...skipping 23 matching lines...) Expand all Loading... |
145 MediaStreamProviderListener* listener) { | 217 MediaStreamProviderListener* listener) { |
146 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 218 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
147 listeners_.RemoveObserver(listener); | 219 listeners_.RemoveObserver(listener); |
148 } | 220 } |
149 | 221 |
150 void VideoCaptureManager::EnumerateDevices( | 222 void VideoCaptureManager::EnumerateDevices( |
151 const EnumerationCallback& client_callback) { | 223 const EnumerationCallback& client_callback) { |
152 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 224 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
153 DVLOG(1) << "VideoCaptureManager::EnumerateDevices"; | 225 DVLOG(1) << "VideoCaptureManager::EnumerateDevices"; |
154 | 226 |
155 // OK to use base::Unretained(video_capture_system_) since we own the | 227 // Bind a callback to ConsolidateDevicesInfoOnDeviceThread() with an argument |
156 // |video_capture_system_| and |this| is bound in | 228 // for another callback to OnDevicesInfoEnumerated() to be run in the current |
157 // |devices_enumerated_callback|. | 229 // loop, i.e. IO loop. Pass a timer for UMA histogram collection. |
| 230 base::Callback<void(std::unique_ptr<VideoCaptureDeviceDescriptors>)> |
| 231 devices_enumerated_callback = base::Bind( |
| 232 &VideoCaptureManager::ConsolidateDevicesInfoOnDeviceThread, this, |
| 233 media::BindToCurrentLoop(base::Bind( |
| 234 &VideoCaptureManager::OnDevicesInfoEnumerated, this, |
| 235 base::Owned(new base::ElapsedTimer()), client_callback)), |
| 236 devices_info_cache_); |
| 237 // OK to use base::Unretained() since we own the VCDFactory and |this| is |
| 238 // bound in |devices_enumerated_callback|. |
158 device_task_runner_->PostTask( | 239 device_task_runner_->PostTask( |
159 FROM_HERE, | 240 FROM_HERE, |
160 base::Bind(&media::VideoCaptureSystem::GetDeviceInfosAsync, | 241 base::Bind(&media::VideoCaptureDeviceFactory::EnumerateDeviceDescriptors, |
161 base::Unretained(video_capture_system_.get()), | 242 base::Unretained(video_capture_device_factory_.get()), |
162 // Pass a timer for UMA histogram collection. | 243 devices_enumerated_callback)); |
163 media::BindToCurrentLoop(base::Bind( | 244 } |
164 &VideoCaptureManager::OnDeviceInfosReceived, this, | 245 |
165 base::Owned(new base::ElapsedTimer()), client_callback)))); | 246 const media::VideoCaptureDeviceDescriptor* |
| 247 VideoCaptureManager::LookupDeviceDescriptor(const std::string& id) { |
| 248 const DeviceInfo* info = GetDeviceInfoById(id); |
| 249 return info ? (&info->descriptor) : nullptr; |
166 } | 250 } |
167 | 251 |
168 int VideoCaptureManager::Open(const MediaStreamDevice& device) { | 252 int VideoCaptureManager::Open(const MediaStreamDevice& device) { |
169 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 253 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
170 | 254 |
171 // Generate a new id for the session being opened. | 255 // Generate a new id for the session being opened. |
172 const media::VideoCaptureSessionId capture_session_id = | 256 const media::VideoCaptureSessionId capture_session_id = |
173 new_capture_session_id_++; | 257 new_capture_session_id_++; |
174 | 258 |
175 DCHECK(sessions_.find(capture_session_id) == sessions_.end()); | 259 DCHECK(sessions_.find(capture_session_id) == sessions_.end()); |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
246 std::find_if(++request_iter, device_start_request_queue_.end(), | 330 std::find_if(++request_iter, device_start_request_queue_.end(), |
247 [controller](const CaptureDeviceStartRequest& request) { | 331 [controller](const CaptureDeviceStartRequest& request) { |
248 return request.controller() == controller; | 332 return request.controller() == controller; |
249 }); | 333 }); |
250 if (request_iter != device_start_request_queue_.end()) { | 334 if (request_iter != device_start_request_queue_.end()) { |
251 device_start_request_queue_.erase(request_iter); | 335 device_start_request_queue_.erase(request_iter); |
252 return; | 336 return; |
253 } | 337 } |
254 } | 338 } |
255 | 339 |
256 const media::VideoCaptureDeviceInfo* device_info = | 340 const DeviceInfo* device_info = GetDeviceInfoById(controller->device_id()); |
257 GetDeviceInfoById(controller->device_id()); | |
258 if (device_info != nullptr) { | 341 if (device_info != nullptr) { |
259 for (auto& observer : capture_observers_) | 342 for (auto& observer : capture_observers_) |
260 observer.OnVideoCaptureStopped(device_info->descriptor.facing); | 343 observer.OnVideoCaptureStopped(device_info->descriptor.facing); |
261 } | 344 } |
262 | 345 |
263 DVLOG(3) << "DoStopDevice. Send stop request for device = " | 346 DVLOG(3) << "DoStopDevice. Send stop request for device = " |
264 << controller->device_id() | 347 << controller->device_id() |
265 << " serial_id = " << controller->serial_id() << "."; | 348 << " serial_id = " << controller->serial_id() << "."; |
266 controller->OnLog(base::StringPrintf("Stopping device: id: %s", | 349 controller->OnLog(base::StringPrintf("Stopping device: id: %s", |
267 controller->device_id().c_str())); | 350 controller->device_id().c_str())); |
(...skipping 10 matching lines...) Expand all Loading... |
278 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 361 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
279 DeviceStartQueue::iterator request = device_start_request_queue_.begin(); | 362 DeviceStartQueue::iterator request = device_start_request_queue_.begin(); |
280 if (request == device_start_request_queue_.end()) | 363 if (request == device_start_request_queue_.end()) |
281 return; | 364 return; |
282 | 365 |
283 VideoCaptureController* const controller = request->controller(); | 366 VideoCaptureController* const controller = request->controller(); |
284 | 367 |
285 DVLOG(3) << "HandleQueuedStartRequest, Post start to device thread, device = " | 368 DVLOG(3) << "HandleQueuedStartRequest, Post start to device thread, device = " |
286 << controller->device_id() | 369 << controller->device_id() |
287 << " start id = " << controller->serial_id(); | 370 << " start id = " << controller->serial_id(); |
288 // The unit test VideoCaptureManagerTest.OpenNotExisting requires us to fail | |
289 // synchronously if the stream_type is MEDIA_DEVICE_VIDEO_CAPTURE and no | |
290 // DeviceInfo matching the requested id is present (which is the case when | |
291 // requesting a device with a bogus id). Note, that since other types of | |
292 // failure during startup of the device are allowed to be reported | |
293 // asynchronously, this requirement is questionable. | |
294 // TODO(chfremer): Check if any production code actually depends on this | |
295 // requirement. If not, relax the requirement in the test and remove the below | |
296 // if block. See crbug.com/708251 | |
297 if (controller->stream_type() == MEDIA_DEVICE_VIDEO_CAPTURE) { | |
298 const media::VideoCaptureDeviceInfo* device_info = | |
299 GetDeviceInfoById(controller->device_id()); | |
300 if (!device_info) { | |
301 OnDeviceStartFailed(controller); | |
302 return; | |
303 } | |
304 for (auto& observer : capture_observers_) | |
305 observer.OnVideoCaptureStarted(device_info->descriptor.facing); | |
306 } | |
307 | 371 |
308 // The method CreateAndStartDeviceAsync() is going to run asynchronously. | 372 // The method CreateAndStartDeviceAsync() is going to run asynchronously. |
309 // Since we may be removing the controller while it is executing, we need to | 373 // Since we may be removing the controller while it is executing, we need to |
310 // pass it shared ownership to itself so that it stays alive while executing. | 374 // pass it shared ownership to itself so that it stays alive while executing. |
311 // And since the execution may make callbacks into |this|, we also need | 375 // And since the execution may make callbacks into |this|, we also need |
312 // to pass it shared ownership to |this|. | 376 // to pass it shared ownership to |this|. |
313 // TODO(chfremer): Check if request->params() can actually be different from | 377 // TODO(chfremer): Check if request->params() can actually be different from |
314 // controller->parameters, and simplify if this is not the case. | 378 // controller->parameters, and simplify if this is not the case. |
315 controller->CreateAndStartDeviceAsync( | 379 controller->CreateAndStartDeviceAsync( |
316 request->params(), | 380 request->params(), |
317 static_cast<BuildableVideoCaptureDevice::Callbacks*>(this), | 381 static_cast<BuildableVideoCaptureDevice::Callbacks*>(this), |
318 base::Bind([](scoped_refptr<VideoCaptureManager>, | 382 base::Bind([](scoped_refptr<VideoCaptureManager>, |
319 scoped_refptr<VideoCaptureController>) {}, | 383 scoped_refptr<VideoCaptureController>) {}, |
320 scoped_refptr<VideoCaptureManager>(this), | 384 scoped_refptr<VideoCaptureManager>(this), |
321 GetControllerSharedRef(controller))); | 385 GetControllerSharedRef(controller))); |
322 } | 386 } |
323 | 387 |
324 void VideoCaptureManager::OnDeviceStarted(VideoCaptureController* controller) { | 388 void VideoCaptureManager::WillStartDevice(media::VideoFacingMode facing_mode) { |
| 389 for (auto& observer : capture_observers_) |
| 390 observer.OnVideoCaptureStarted(facing_mode); |
| 391 } |
| 392 |
| 393 void VideoCaptureManager::DidStartDevice(VideoCaptureController* controller) { |
325 DVLOG(3) << __func__; | 394 DVLOG(3) << __func__; |
326 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 395 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
327 DCHECK(!device_start_request_queue_.empty()); | 396 DCHECK(!device_start_request_queue_.empty()); |
328 DCHECK_EQ(controller, device_start_request_queue_.begin()->controller()); | 397 DCHECK_EQ(controller, device_start_request_queue_.begin()->controller()); |
329 DCHECK(controller); | 398 DCHECK(controller); |
330 | |
331 if (controller->stream_type() == MEDIA_DESKTOP_VIDEO_CAPTURE) { | 399 if (controller->stream_type() == MEDIA_DESKTOP_VIDEO_CAPTURE) { |
332 const media::VideoCaptureSessionId session_id = | 400 const media::VideoCaptureSessionId session_id = |
333 device_start_request_queue_.front().session_id(); | 401 device_start_request_queue_.front().session_id(); |
334 DCHECK(session_id != kFakeSessionId); | 402 DCHECK(session_id != kFakeSessionId); |
335 MaybePostDesktopCaptureWindowId(session_id); | 403 MaybePostDesktopCaptureWindowId(session_id); |
336 } | 404 } |
337 | 405 |
338 auto it = photo_request_queue_.begin(); | 406 auto it = photo_request_queue_.begin(); |
339 while (it != photo_request_queue_.end()) { | 407 while (it != photo_request_queue_.end()) { |
340 auto request = it++; | 408 auto request = it++; |
(...skipping 170 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
511 return GetDeviceSupportedFormats(it->second.id, supported_formats); | 579 return GetDeviceSupportedFormats(it->second.id, supported_formats); |
512 } | 580 } |
513 | 581 |
514 bool VideoCaptureManager::GetDeviceSupportedFormats( | 582 bool VideoCaptureManager::GetDeviceSupportedFormats( |
515 const std::string& device_id, | 583 const std::string& device_id, |
516 media::VideoCaptureFormats* supported_formats) { | 584 media::VideoCaptureFormats* supported_formats) { |
517 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 585 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
518 DCHECK(supported_formats->empty()); | 586 DCHECK(supported_formats->empty()); |
519 | 587 |
520 // Return all available formats of the device, regardless its started state. | 588 // Return all available formats of the device, regardless its started state. |
521 media::VideoCaptureDeviceInfo* existing_device = GetDeviceInfoById(device_id); | 589 DeviceInfo* existing_device = GetDeviceInfoById(device_id); |
522 if (existing_device) | 590 if (existing_device) |
523 *supported_formats = existing_device->supported_formats; | 591 *supported_formats = existing_device->supported_formats; |
524 return true; | 592 return true; |
525 } | 593 } |
526 | 594 |
527 bool VideoCaptureManager::GetDeviceFormatsInUse( | 595 bool VideoCaptureManager::GetDeviceFormatsInUse( |
528 media::VideoCaptureSessionId capture_session_id, | 596 media::VideoCaptureSessionId capture_session_id, |
529 media::VideoCaptureFormats* formats_in_use) { | 597 media::VideoCaptureFormats* formats_in_use) { |
530 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 598 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
531 DCHECK(formats_in_use->empty()); | 599 DCHECK(formats_in_use->empty()); |
(...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
669 } | 737 } |
670 | 738 |
671 void VideoCaptureManager::OnClosed( | 739 void VideoCaptureManager::OnClosed( |
672 MediaStreamType stream_type, | 740 MediaStreamType stream_type, |
673 media::VideoCaptureSessionId capture_session_id) { | 741 media::VideoCaptureSessionId capture_session_id) { |
674 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 742 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
675 for (auto& listener : listeners_) | 743 for (auto& listener : listeners_) |
676 listener.Closed(stream_type, capture_session_id); | 744 listener.Closed(stream_type, capture_session_id); |
677 } | 745 } |
678 | 746 |
679 void VideoCaptureManager::OnDeviceInfosReceived( | 747 void VideoCaptureManager::OnDevicesInfoEnumerated( |
680 base::ElapsedTimer* timer, | 748 base::ElapsedTimer* timer, |
681 const EnumerationCallback& client_callback, | 749 const EnumerationCallback& client_callback, |
682 const std::vector<media::VideoCaptureDeviceInfo>& device_infos) { | 750 const VideoCaptureManager::DeviceInfos& new_devices_info_cache) { |
683 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 751 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
684 UMA_HISTOGRAM_TIMES( | 752 UMA_HISTOGRAM_TIMES( |
685 "Media.VideoCaptureManager.GetAvailableDevicesInfoOnDeviceThreadTime", | 753 "Media.VideoCaptureManager.GetAvailableDevicesInfoOnDeviceThreadTime", |
686 timer->Elapsed()); | 754 timer->Elapsed()); |
687 devices_info_cache_ = device_infos; | 755 devices_info_cache_ = new_devices_info_cache; |
688 | 756 |
689 // Walk the |devices_info_cache_| and produce a | 757 // Walk the |devices_info_cache_| and produce a |
690 // media::VideoCaptureDeviceDescriptors for |client_callback|. | 758 // media::VideoCaptureDeviceDescriptors for return purposes. |
691 media::VideoCaptureDeviceDescriptors devices; | 759 media::VideoCaptureDeviceDescriptors devices; |
692 std::vector<std::tuple<media::VideoCaptureDeviceDescriptor, | 760 std::vector<std::tuple<media::VideoCaptureDeviceDescriptor, |
693 media::VideoCaptureFormats>> | 761 media::VideoCaptureFormats>> |
694 descriptors_and_formats; | 762 descriptors_and_formats; |
695 for (const auto& it : devices_info_cache_) { | 763 for (const auto& it : devices_info_cache_) { |
696 devices.emplace_back(it.descriptor); | 764 devices.emplace_back(it.descriptor); |
697 descriptors_and_formats.emplace_back(it.descriptor, it.supported_formats); | 765 descriptors_and_formats.emplace_back(it.descriptor, it.supported_formats); |
698 MediaInternals::GetInstance()->UpdateVideoCaptureDeviceCapabilities( | 766 MediaInternals::GetInstance()->UpdateVideoCaptureDeviceCapabilities( |
699 descriptors_and_formats); | 767 descriptors_and_formats); |
700 } | 768 } |
701 | 769 |
702 client_callback.Run(devices); | 770 client_callback.Run(devices); |
703 } | 771 } |
704 | 772 |
| 773 void VideoCaptureManager::ConsolidateDevicesInfoOnDeviceThread( |
| 774 base::Callback<void(const VideoCaptureManager::DeviceInfos&)> |
| 775 on_devices_enumerated_callback, |
| 776 const VideoCaptureManager::DeviceInfos& old_device_info_cache, |
| 777 std::unique_ptr<VideoCaptureDeviceDescriptors> descriptors_snapshot) { |
| 778 DCHECK(device_task_runner_->BelongsToCurrentThread()); |
| 779 // Construct |new_devices_info_cache| with the cached devices that are still |
| 780 // present in the system, and remove their names from |names_snapshot|, so we |
| 781 // keep there the truly new devices. |
| 782 VideoCaptureManager::DeviceInfos new_devices_info_cache; |
| 783 for (const auto& device_info : old_device_info_cache) { |
| 784 for (VideoCaptureDeviceDescriptors::iterator it = |
| 785 descriptors_snapshot->begin(); |
| 786 it != descriptors_snapshot->end(); ++it) { |
| 787 if (device_info.descriptor.device_id == it->device_id) { |
| 788 new_devices_info_cache.push_back(device_info); |
| 789 descriptors_snapshot->erase(it); |
| 790 break; |
| 791 } |
| 792 } |
| 793 } |
| 794 |
| 795 // Get the device info for the new devices in |names_snapshot|. |
| 796 for (const auto& it : *descriptors_snapshot) { |
| 797 DeviceInfo device_info(it); |
| 798 video_capture_device_factory_->GetSupportedFormats( |
| 799 it, &device_info.supported_formats); |
| 800 ConsolidateCaptureFormats(&device_info.supported_formats); |
| 801 new_devices_info_cache.push_back(device_info); |
| 802 } |
| 803 |
| 804 on_devices_enumerated_callback.Run(new_devices_info_cache); |
| 805 } |
| 806 |
705 void VideoCaptureManager::DestroyControllerIfNoClients( | 807 void VideoCaptureManager::DestroyControllerIfNoClients( |
706 VideoCaptureController* controller) { | 808 VideoCaptureController* controller) { |
707 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 809 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
708 // Removal of the last client stops the device. | 810 // Removal of the last client stops the device. |
709 if (!controller->HasActiveClient() && !controller->HasPausedClient()) { | 811 if (!controller->HasActiveClient() && !controller->HasPausedClient()) { |
710 DVLOG(1) << "VideoCaptureManager stopping device (type = " | 812 DVLOG(1) << "VideoCaptureManager stopping device (type = " |
711 << controller->stream_type() | 813 << controller->stream_type() |
712 << ", id = " << controller->device_id() << ")"; | 814 << ", id = " << controller->device_id() << ")"; |
713 | 815 |
714 // The VideoCaptureController is removed from |controllers_| immediately. | 816 // The VideoCaptureController is removed from |controllers_| immediately. |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
763 VideoCaptureController* controller) const { | 865 VideoCaptureController* controller) const { |
764 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 866 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
765 | 867 |
766 for (const auto& entry : controllers_) { | 868 for (const auto& entry : controllers_) { |
767 if (entry.get() == controller) | 869 if (entry.get() == controller) |
768 return entry; | 870 return entry; |
769 } | 871 } |
770 return nullptr; | 872 return nullptr; |
771 } | 873 } |
772 | 874 |
773 media::VideoCaptureDeviceInfo* VideoCaptureManager::GetDeviceInfoById( | 875 VideoCaptureManager::DeviceInfo* VideoCaptureManager::GetDeviceInfoById( |
774 const std::string& id) { | 876 const std::string& id) { |
775 for (auto& it : devices_info_cache_) { | 877 for (auto& it : devices_info_cache_) { |
776 if (it.descriptor.device_id == id) | 878 if (it.descriptor.device_id == id) |
777 return ⁢ | 879 return ⁢ |
778 } | 880 } |
779 return nullptr; | 881 return nullptr; |
780 } | 882 } |
781 | 883 |
782 VideoCaptureController* VideoCaptureManager::GetOrCreateController( | 884 VideoCaptureController* VideoCaptureManager::GetOrCreateController( |
783 media::VideoCaptureSessionId capture_session_id, | 885 media::VideoCaptureSessionId capture_session_id, |
(...skipping 10 matching lines...) Expand all Loading... |
794 VideoCaptureController* const existing_device = | 896 VideoCaptureController* const existing_device = |
795 LookupControllerByMediaTypeAndDeviceId(device_info.type, device_info.id); | 897 LookupControllerByMediaTypeAndDeviceId(device_info.type, device_info.id); |
796 if (existing_device) { | 898 if (existing_device) { |
797 DCHECK_EQ(device_info.type, existing_device->stream_type()); | 899 DCHECK_EQ(device_info.type, existing_device->stream_type()); |
798 return existing_device; | 900 return existing_device; |
799 } | 901 } |
800 | 902 |
801 VideoCaptureController* new_controller = new VideoCaptureController( | 903 VideoCaptureController* new_controller = new VideoCaptureController( |
802 device_info.id, device_info.type, params, | 904 device_info.id, device_info.type, params, |
803 base::MakeUnique<InProcessBuildableVideoCaptureDevice>( | 905 base::MakeUnique<InProcessBuildableVideoCaptureDevice>( |
804 device_task_runner_, video_capture_system_.get())); | 906 device_task_runner_, video_capture_device_factory_.get())); |
805 controllers_.emplace_back(new_controller); | 907 controllers_.emplace_back(new_controller); |
806 return new_controller; | 908 return new_controller; |
807 } | 909 } |
808 | 910 |
809 base::Optional<CameraCalibration> VideoCaptureManager::GetCameraCalibration( | 911 base::Optional<CameraCalibration> VideoCaptureManager::GetCameraCalibration( |
810 const std::string& device_id) { | 912 const std::string& device_id) { |
811 media::VideoCaptureDeviceInfo* info = GetDeviceInfoById(device_id); | 913 VideoCaptureManager::DeviceInfo* info = GetDeviceInfoById(device_id); |
812 if (!info) | 914 if (!info) |
813 return base::Optional<CameraCalibration>(); | 915 return base::Optional<CameraCalibration>(); |
814 return info->descriptor.camera_calibration; | 916 return info->descriptor.camera_calibration; |
815 } | 917 } |
816 | 918 |
817 #if defined(OS_ANDROID) | 919 #if defined(OS_ANDROID) |
818 void VideoCaptureManager::OnApplicationStateChange( | 920 void VideoCaptureManager::OnApplicationStateChange( |
819 base::android::ApplicationState state) { | 921 base::android::ApplicationState state) { |
820 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 922 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
821 | 923 |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
866 // Session ID is only valid for Screen capture. So we can fake it to | 968 // Session ID is only valid for Screen capture. So we can fake it to |
867 // resume video capture devices here. | 969 // resume video capture devices here. |
868 QueueStartDevice(kFakeSessionId, controller.get(), | 970 QueueStartDevice(kFakeSessionId, controller.get(), |
869 controller->parameters()); | 971 controller->parameters()); |
870 } | 972 } |
871 } | 973 } |
872 } | 974 } |
873 #endif // defined(OS_ANDROID) | 975 #endif // defined(OS_ANDROID) |
874 | 976 |
875 } // namespace content | 977 } // namespace content |
OLD | NEW |