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