Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(353)

Side by Side Diff: content/browser/renderer_host/media/video_capture_manager.cc

Issue 2729783003: [Mojo Video Capture] Add content_browsertest for exercising video capture (Closed)
Patch Set: incorporated miu@'s suggestions Created 3 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 283 matching lines...) Expand 10 before | Expand all | Expand 10 after
294 : serial_id_(serial_id), 294 : serial_id_(serial_id),
295 session_id_(session_id), 295 session_id_(session_id),
296 params_(params), 296 params_(params),
297 abort_start_(false) { 297 abort_start_(false) {
298 } 298 }
299 299
300 VideoCaptureManager::VideoCaptureManager( 300 VideoCaptureManager::VideoCaptureManager(
301 std::unique_ptr<media::VideoCaptureDeviceFactory> factory, 301 std::unique_ptr<media::VideoCaptureDeviceFactory> factory,
302 scoped_refptr<base::SingleThreadTaskRunner> device_task_runner) 302 scoped_refptr<base::SingleThreadTaskRunner> device_task_runner)
303 : device_task_runner_(std::move(device_task_runner)), 303 : device_task_runner_(std::move(device_task_runner)),
304 listener_(nullptr),
305 new_capture_session_id_(1), 304 new_capture_session_id_(1),
306 video_capture_device_factory_(std::move(factory)) {} 305 video_capture_device_factory_(std::move(factory)) {}
307 306
308 VideoCaptureManager::~VideoCaptureManager() { 307 VideoCaptureManager::~VideoCaptureManager() {
309 DCHECK(devices_.empty()); 308 DCHECK(devices_.empty());
310 DCHECK(device_start_queue_.empty()); 309 DCHECK(device_start_queue_.empty());
311 } 310 }
312 311
313 void VideoCaptureManager::AddVideoCaptureObserver( 312 void VideoCaptureManager::AddVideoCaptureObserver(
314 media::VideoCaptureObserver* observer) { 313 media::VideoCaptureObserver* observer) {
315 DCHECK(observer); 314 DCHECK(observer);
316 DCHECK_CURRENTLY_ON(BrowserThread::IO); 315 DCHECK_CURRENTLY_ON(BrowserThread::IO);
317 capture_observers_.AddObserver(observer); 316 capture_observers_.AddObserver(observer);
318 } 317 }
319 318
320 void VideoCaptureManager::RemoveAllVideoCaptureObservers() { 319 void VideoCaptureManager::RemoveAllVideoCaptureObservers() {
321 DCHECK_CURRENTLY_ON(BrowserThread::IO); 320 DCHECK_CURRENTLY_ON(BrowserThread::IO);
322 capture_observers_.Clear(); 321 capture_observers_.Clear();
323 } 322 }
324 323
325 void VideoCaptureManager::RegisterListener( 324 void VideoCaptureManager::RegisterListener(
326 MediaStreamProviderListener* listener) { 325 MediaStreamProviderListener* listener) {
327 DCHECK_CURRENTLY_ON(BrowserThread::IO); 326 DCHECK_CURRENTLY_ON(BrowserThread::IO);
328 DCHECK(!listener_); 327 DCHECK(listener);
329 DCHECK(device_task_runner_); 328 DCHECK(device_task_runner_);
330 listener_ = listener; 329 listeners_.AddObserver(listener);
331 #if defined(OS_ANDROID) 330 #if defined(OS_ANDROID)
332 application_state_has_running_activities_ = true; 331 application_state_has_running_activities_ = true;
333 app_status_listener_.reset(new base::android::ApplicationStatusListener( 332 app_status_listener_.reset(new base::android::ApplicationStatusListener(
334 base::Bind(&VideoCaptureManager::OnApplicationStateChange, 333 base::Bind(&VideoCaptureManager::OnApplicationStateChange,
335 base::Unretained(this)))); 334 base::Unretained(this))));
336 #endif 335 #endif
337 } 336 }
338 337
339 void VideoCaptureManager::UnregisterListener() { 338 void VideoCaptureManager::UnregisterListener(
339 MediaStreamProviderListener* listener) {
340 DCHECK_CURRENTLY_ON(BrowserThread::IO); 340 DCHECK_CURRENTLY_ON(BrowserThread::IO);
341 DCHECK(listener_); 341 listeners_.RemoveObserver(listener);
342 listener_ = nullptr;
343 } 342 }
344 343
345 void VideoCaptureManager::EnumerateDevices( 344 void VideoCaptureManager::EnumerateDevices(
346 const EnumerationCallback& client_callback) { 345 const EnumerationCallback& client_callback) {
347 DCHECK_CURRENTLY_ON(BrowserThread::IO); 346 DCHECK_CURRENTLY_ON(BrowserThread::IO);
348 DVLOG(1) << "VideoCaptureManager::EnumerateDevices"; 347 DVLOG(1) << "VideoCaptureManager::EnumerateDevices";
349 348
350 // Bind a callback to ConsolidateDevicesInfoOnDeviceThread() with an argument 349 // Bind a callback to ConsolidateDevicesInfoOnDeviceThread() with an argument
351 // for another callback to OnDevicesInfoEnumerated() to be run in the current 350 // for another callback to OnDevicesInfoEnumerated() to be run in the current
352 // loop, i.e. IO loop. Pass a timer for UMA histogram collection. 351 // loop, i.e. IO loop. Pass a timer for UMA histogram collection.
353 base::Callback<void(std::unique_ptr<VideoCaptureDeviceDescriptors>)> 352 base::Callback<void(std::unique_ptr<VideoCaptureDeviceDescriptors>)>
354 devices_enumerated_callback = base::Bind( 353 devices_enumerated_callback = base::Bind(
355 &VideoCaptureManager::ConsolidateDevicesInfoOnDeviceThread, this, 354 &VideoCaptureManager::ConsolidateDevicesInfoOnDeviceThread, this,
356 media::BindToCurrentLoop(base::Bind( 355 media::BindToCurrentLoop(base::Bind(
357 &VideoCaptureManager::OnDevicesInfoEnumerated, this, 356 &VideoCaptureManager::OnDevicesInfoEnumerated, this,
358 base::Owned(new base::ElapsedTimer()), client_callback)), 357 base::Owned(new base::ElapsedTimer()), client_callback)),
359 devices_info_cache_); 358 devices_info_cache_);
360 // OK to use base::Unretained() since we own the VCDFactory and |this| is 359 // OK to use base::Unretained() since we own the VCDFactory and |this| is
361 // bound in |devices_enumerated_callback|. 360 // bound in |devices_enumerated_callback|.
362 device_task_runner_->PostTask( 361 device_task_runner_->PostTask(
363 FROM_HERE, 362 FROM_HERE,
364 base::Bind(&media::VideoCaptureDeviceFactory::EnumerateDeviceDescriptors, 363 base::Bind(&media::VideoCaptureDeviceFactory::EnumerateDeviceDescriptors,
365 base::Unretained(video_capture_device_factory_.get()), 364 base::Unretained(video_capture_device_factory_.get()),
366 devices_enumerated_callback)); 365 devices_enumerated_callback));
367 } 366 }
368 367
369 int VideoCaptureManager::Open(const StreamDeviceInfo& device_info) { 368 int VideoCaptureManager::Open(const MediaStreamDevice& device) {
370 DCHECK_CURRENTLY_ON(BrowserThread::IO); 369 DCHECK_CURRENTLY_ON(BrowserThread::IO);
371 DCHECK(listener_);
372 370
373 // Generate a new id for the session being opened. 371 // Generate a new id for the session being opened.
374 const media::VideoCaptureSessionId capture_session_id = 372 const media::VideoCaptureSessionId capture_session_id =
375 new_capture_session_id_++; 373 new_capture_session_id_++;
376 374
377 DCHECK(sessions_.find(capture_session_id) == sessions_.end()); 375 DCHECK(sessions_.find(capture_session_id) == sessions_.end());
378 DVLOG(1) << "VideoCaptureManager::Open, id " << capture_session_id; 376 DVLOG(1) << "VideoCaptureManager::Open, id " << capture_session_id;
379 377
380 // We just save the stream info for processing later. 378 // We just save the stream info for processing later.
381 sessions_[capture_session_id] = device_info.device; 379 sessions_[capture_session_id] = device;
382 380
383 // Notify our listener asynchronously; this ensures that we return 381 // Notify our listener asynchronously; this ensures that we return
384 // |capture_session_id| to the caller of this function before using that same 382 // |capture_session_id| to the caller of this function before using that same
385 // id in a listener event. 383 // id in a listener event.
386 base::ThreadTaskRunnerHandle::Get()->PostTask( 384 base::ThreadTaskRunnerHandle::Get()->PostTask(
387 FROM_HERE, base::Bind(&VideoCaptureManager::OnOpened, this, 385 FROM_HERE, base::Bind(&VideoCaptureManager::OnOpened, this, device.type,
388 device_info.device.type, capture_session_id)); 386 capture_session_id));
389 return capture_session_id; 387 return capture_session_id;
390 } 388 }
391 389
392 void VideoCaptureManager::Close(int capture_session_id) { 390 void VideoCaptureManager::Close(int capture_session_id) {
393 DCHECK_CURRENTLY_ON(BrowserThread::IO); 391 DCHECK_CURRENTLY_ON(BrowserThread::IO);
394 DCHECK(listener_);
395 DVLOG(1) << "VideoCaptureManager::Close, id " << capture_session_id; 392 DVLOG(1) << "VideoCaptureManager::Close, id " << capture_session_id;
396 393
397 SessionMap::iterator session_it = sessions_.find(capture_session_id); 394 SessionMap::iterator session_it = sessions_.find(capture_session_id);
398 if (session_it == sessions_.end()) { 395 if (session_it == sessions_.end()) {
399 NOTREACHED(); 396 NOTREACHED();
400 return; 397 return;
401 } 398 }
402 399
403 DeviceEntry* const existing_device = 400 DeviceEntry* const existing_device =
404 GetDeviceEntryByTypeAndId(session_it->second.type, session_it->second.id); 401 GetDeviceEntryByTypeAndId(session_it->second.type, session_it->second.id);
(...skipping 355 matching lines...) Expand 10 before | Expand all | Expand 10 after
760 LogVideoCaptureEvent( 757 LogVideoCaptureEvent(
761 VIDEO_CAPTURE_STOP_CAPTURE_OK_NO_FRAMES_PRODUCED_BY_DEVICE); 758 VIDEO_CAPTURE_STOP_CAPTURE_OK_NO_FRAMES_PRODUCED_BY_DEVICE);
762 } else { 759 } else {
763 LogVideoCaptureEvent( 760 LogVideoCaptureEvent(
764 VIDEO_CAPTURE_STOP_CAPTURE_OK_NO_FRAMES_PRODUCED_BY_DESKTOP_OR_TAB); 761 VIDEO_CAPTURE_STOP_CAPTURE_OK_NO_FRAMES_PRODUCED_BY_DESKTOP_OR_TAB);
765 } 762 }
766 } else { 763 } else {
767 LogVideoCaptureEvent(VIDEO_CAPTURE_STOP_CAPTURE_DUE_TO_ERROR); 764 LogVideoCaptureEvent(VIDEO_CAPTURE_STOP_CAPTURE_DUE_TO_ERROR);
768 for (auto it : sessions_) { 765 for (auto it : sessions_) {
769 if (it.second.type == entry->stream_type && it.second.id == entry->id) { 766 if (it.second.type == entry->stream_type && it.second.id == entry->id) {
770 listener_->Aborted(it.second.type, it.first); 767 for (auto& listener : listeners_)
768 listener.Aborted(it.second.type, it.first);
771 // Aborted() call might synchronously destroy |entry|, recheck. 769 // Aborted() call might synchronously destroy |entry|, recheck.
772 entry = GetDeviceEntryByController(controller); 770 entry = GetDeviceEntryByController(controller);
773 if (!entry) 771 if (!entry)
774 return; 772 return;
775 break; 773 break;
776 } 774 }
777 } 775 }
778 } 776 }
779 777
780 // Detach client from controller. 778 // Detach client from controller.
(...skipping 253 matching lines...) Expand 10 before | Expand all | Expand 10 after
1034 SCOPED_UMA_HISTOGRAM_TIMER("Media.VideoCaptureManager.StopDeviceTime"); 1032 SCOPED_UMA_HISTOGRAM_TIMER("Media.VideoCaptureManager.StopDeviceTime");
1035 DCHECK(IsOnDeviceThread()); 1033 DCHECK(IsOnDeviceThread());
1036 device->StopAndDeAllocate(); 1034 device->StopAndDeAllocate();
1037 DVLOG(3) << "DoStopDeviceOnDeviceThread"; 1035 DVLOG(3) << "DoStopDeviceOnDeviceThread";
1038 } 1036 }
1039 1037
1040 void VideoCaptureManager::OnOpened( 1038 void VideoCaptureManager::OnOpened(
1041 MediaStreamType stream_type, 1039 MediaStreamType stream_type,
1042 media::VideoCaptureSessionId capture_session_id) { 1040 media::VideoCaptureSessionId capture_session_id) {
1043 DCHECK_CURRENTLY_ON(BrowserThread::IO); 1041 DCHECK_CURRENTLY_ON(BrowserThread::IO);
1044 if (!listener_) { 1042 for (auto& listener : listeners_)
1045 // Listener has been removed. 1043 listener.Opened(stream_type, capture_session_id);
1046 return;
1047 }
1048 listener_->Opened(stream_type, capture_session_id);
1049 } 1044 }
1050 1045
1051 void VideoCaptureManager::OnClosed( 1046 void VideoCaptureManager::OnClosed(
1052 MediaStreamType stream_type, 1047 MediaStreamType stream_type,
1053 media::VideoCaptureSessionId capture_session_id) { 1048 media::VideoCaptureSessionId capture_session_id) {
1054 DCHECK_CURRENTLY_ON(BrowserThread::IO); 1049 DCHECK_CURRENTLY_ON(BrowserThread::IO);
1055 if (!listener_) { 1050 for (auto& listener : listeners_)
1056 // Listener has been removed. 1051 listener.Closed(stream_type, capture_session_id);
1057 return;
1058 }
1059 listener_->Closed(stream_type, capture_session_id);
1060 } 1052 }
1061 1053
1062 void VideoCaptureManager::OnDevicesInfoEnumerated( 1054 void VideoCaptureManager::OnDevicesInfoEnumerated(
1063 base::ElapsedTimer* timer, 1055 base::ElapsedTimer* timer,
1064 const EnumerationCallback& client_callback, 1056 const EnumerationCallback& client_callback,
1065 const VideoCaptureManager::DeviceInfos& new_devices_info_cache) { 1057 const VideoCaptureManager::DeviceInfos& new_devices_info_cache) {
1066 DCHECK_CURRENTLY_ON(BrowserThread::IO); 1058 DCHECK_CURRENTLY_ON(BrowserThread::IO);
1067 UMA_HISTOGRAM_TIMES( 1059 UMA_HISTOGRAM_TIMES(
1068 "Media.VideoCaptureManager.GetAvailableDevicesInfoOnDeviceThreadTime", 1060 "Media.VideoCaptureManager.GetAvailableDevicesInfoOnDeviceThreadTime",
1069 timer->Elapsed()); 1061 timer->Elapsed());
(...skipping 266 matching lines...) Expand 10 before | Expand all | Expand 10 after
1336 if (!device_in_queue) { 1328 if (!device_in_queue) {
1337 // Session ID is only valid for Screen capture. So we can fake it to 1329 // Session ID is only valid for Screen capture. So we can fake it to
1338 // resume video capture devices here. 1330 // resume video capture devices here.
1339 QueueStartDevice(kFakeSessionId, entry.get(), entry->parameters); 1331 QueueStartDevice(kFakeSessionId, entry.get(), entry->parameters);
1340 } 1332 }
1341 } 1333 }
1342 } 1334 }
1343 #endif // defined(OS_ANDROID) 1335 #endif // defined(OS_ANDROID)
1344 1336
1345 } // namespace content 1337 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698