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/renderer/media/video_capture_impl_manager.h" | 5 #include "content/renderer/media/video_capture_impl_manager.h" |
6 | 6 |
7 #include "base/bind.h" | 7 #include "base/bind.h" |
8 #include "base/stl_util.h" | 8 #include "base/bind_helpers.h" |
9 #include "content/public/renderer/render_thread.h" | |
9 #include "content/renderer/media/video_capture_impl.h" | 10 #include "content/renderer/media/video_capture_impl.h" |
10 #include "content/renderer/media/video_capture_message_filter.h" | 11 #include "content/renderer/media/video_capture_message_filter.h" |
12 #include "media/base/bind_to_loop.h" | |
11 | 13 |
12 namespace content { | 14 namespace content { |
13 | 15 |
14 VideoCaptureImplManager::VideoCaptureImplManager() | 16 VideoCaptureHandle::VideoCaptureHandle( |
15 : thread_("VC manager") { | 17 media::VideoCapture* impl, base::Closure destruction_cb) |
16 thread_.Start(); | 18 : impl_(impl), destruction_cb_(destruction_cb) { |
17 message_loop_proxy_ = thread_.message_loop_proxy(); | |
18 filter_ = new VideoCaptureMessageFilter(); | |
19 } | 19 } |
20 | 20 |
21 media::VideoCapture* VideoCaptureImplManager::AddDevice( | 21 VideoCaptureHandle::~VideoCaptureHandle() { |
22 media::VideoCaptureSessionId id, | 22 destruction_cb_.Run(); |
23 media::VideoCapture::EventHandler* handler) { | 23 } |
24 DCHECK(handler); | |
25 | 24 |
26 base::AutoLock auto_lock(lock_); | 25 void VideoCaptureHandle::StartCapture( |
27 Devices::iterator it = devices_.find(id); | 26 EventHandler* handler, |
27 const media::VideoCaptureParams& params) { | |
28 impl_->StartCapture(handler, params); | |
29 } | |
30 | |
31 void VideoCaptureHandle::StopCapture(EventHandler* handler) { | |
32 impl_->StopCapture(handler); | |
33 } | |
34 | |
35 bool VideoCaptureHandle::CaptureStarted() { | |
36 return impl_->CaptureStarted(); | |
37 } | |
38 | |
39 int VideoCaptureHandle::CaptureFrameRate() { | |
40 return impl_->CaptureFrameRate(); | |
41 } | |
42 | |
43 VideoCaptureImplManager::VideoCaptureImplManager() | |
44 : filter_(new VideoCaptureMessageFilter()), | |
45 weak_factory_(this) { | |
46 } | |
47 | |
48 VideoCaptureImplManager::~VideoCaptureImplManager() { | |
49 DCHECK(thread_checker_.CalledOnValidThread()); | |
50 } | |
51 | |
52 scoped_ptr<VideoCaptureHandle> VideoCaptureImplManager::UseDevice( | |
53 media::VideoCaptureSessionId id) { | |
54 DCHECK(thread_checker_.CalledOnValidThread()); | |
55 | |
56 VideoCaptureImpl* video_capture_device = NULL; | |
57 VideoCaptureDeviceMap::iterator it = devices_.find(id); | |
28 if (it == devices_.end()) { | 58 if (it == devices_.end()) { |
29 VideoCaptureImpl* vc = | 59 video_capture_device = new VideoCaptureImpl(id, filter_.get()); |
30 new VideoCaptureImpl(id, message_loop_proxy_.get(), filter_.get()); | 60 devices_[id] = |
31 devices_[id] = new Device(vc, handler); | 61 std::make_pair(1, linked_ptr<VideoCaptureImpl>(video_capture_device)); |
32 vc->Init(); | 62 video_capture_device->Init(); |
33 return vc; | 63 } else { |
64 ++it->second.first; | |
65 video_capture_device = it->second.second.get(); | |
34 } | 66 } |
35 | 67 |
36 devices_[id]->clients.push_front(handler); | 68 // This callback ensures UnrefDevice() happens on the render thread. |
37 return it->second->vc; | 69 return scoped_ptr<VideoCaptureHandle>( |
70 new VideoCaptureHandle( | |
71 video_capture_device, | |
72 media::BindToCurrentLoop( | |
73 base::Bind( | |
74 &VideoCaptureImplManager::UnrefDevice, | |
75 weak_factory_.GetWeakPtr(), | |
76 id)))); | |
77 } | |
78 | |
79 void VideoCaptureImplManager::UnrefDevice( | |
80 media::VideoCaptureSessionId id) { | |
81 DCHECK(thread_checker_.CalledOnValidThread()); | |
82 VideoCaptureDeviceMap::iterator it = devices_.find(id); | |
83 DCHECK(it != devices_.end()); | |
84 | |
85 DCHECK(it->second.first); | |
86 if (--it->second.first) { | |
Ami GONE FROM CHROMIUM
2014/01/08 01:43:58
is this test backwards?
Alpha Left Google
2014/01/08 22:30:50
Good catch. I've separated it into two lines (just
| |
87 VideoCaptureImpl* impl = it->second.second.release(); | |
88 devices_.erase(id); | |
89 impl->DeInit(base::Bind(&base::DeletePointer<VideoCaptureImpl>, impl)); | |
Ami GONE FROM CHROMIUM
2014/01/08 01:43:58
Why that trailing ",impl"??
Alpha Left Google
2014/01/08 22:30:50
I see what you mean now. But I would need a method
| |
90 } | |
38 } | 91 } |
39 | 92 |
40 void VideoCaptureImplManager::SuspendDevices(bool suspend) { | 93 void VideoCaptureImplManager::SuspendDevices(bool suspend) { |
41 base::AutoLock auto_lock(lock_); | 94 DCHECK(thread_checker_.CalledOnValidThread()); |
42 for (Devices::iterator it = devices_.begin(); it != devices_.end(); ++it) | 95 for (VideoCaptureDeviceMap::iterator it = devices_.begin(); |
43 it->second->vc->SuspendCapture(suspend); | 96 it != devices_.end(); ++it) |
97 it->second.second->SuspendCapture(suspend); | |
44 } | 98 } |
45 | 99 |
46 void VideoCaptureImplManager::RemoveDevice( | |
47 media::VideoCaptureSessionId id, | |
48 media::VideoCapture::EventHandler* handler) { | |
49 DCHECK(handler); | |
50 | |
51 base::AutoLock auto_lock(lock_); | |
52 Devices::iterator it = devices_.find(id); | |
53 if (it == devices_.end()) | |
54 return; | |
55 | |
56 size_t size = it->second->clients.size(); | |
57 it->second->clients.remove(handler); | |
58 | |
59 if (size == it->second->clients.size() || size > 1) | |
60 return; | |
61 | |
62 devices_[id]->vc->DeInit(base::Bind(&VideoCaptureImplManager::FreeDevice, | |
63 this, devices_[id]->vc)); | |
64 delete devices_[id]; | |
65 devices_.erase(id); | |
66 } | |
67 | |
68 void VideoCaptureImplManager::FreeDevice(VideoCaptureImpl* vc) { | |
69 delete vc; | |
70 } | |
71 | |
72 VideoCaptureImplManager::~VideoCaptureImplManager() { | |
73 thread_.Stop(); | |
74 // TODO(wjia): uncomment the line below after collecting enough info for | |
75 // crbug.com/152418. | |
76 // STLDeleteContainerPairSecondPointers(devices_.begin(), devices_.end()); | |
77 } | |
78 | |
79 VideoCaptureImplManager::Device::Device( | |
80 VideoCaptureImpl* device, | |
81 media::VideoCapture::EventHandler* handler) | |
82 : vc(device) { | |
83 clients.push_front(handler); | |
84 } | |
85 | |
86 VideoCaptureImplManager::Device::~Device() {} | |
87 | |
88 } // namespace content | 100 } // namespace content |
OLD | NEW |