Chromium Code Reviews| 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 // Implementation notes about interactions with VideoCaptureImpl. | 5 // Implementation notes about interactions with VideoCaptureImpl. |
| 6 // | 6 // |
| 7 // How is VideoCaptureImpl used: | 7 // How is VideoCaptureImpl used: |
| 8 // | 8 // |
| 9 // VideoCaptureImpl is an IO thread object while VideoCaptureImplManager | 9 // VideoCaptureImpl is an IO thread object while VideoCaptureImplManager |
| 10 // lives only on the render thread. It is only possible to access an | 10 // lives only on the render thread. It is only possible to access an |
| (...skipping 18 matching lines...) Expand all Loading... | |
| 29 #include "content/child/child_process.h" | 29 #include "content/child/child_process.h" |
| 30 #include "content/renderer/media/video_capture_impl.h" | 30 #include "content/renderer/media/video_capture_impl.h" |
| 31 #include "content/renderer/media/video_capture_message_filter.h" | 31 #include "content/renderer/media/video_capture_message_filter.h" |
| 32 #include "media/base/bind_to_current_loop.h" | 32 #include "media/base/bind_to_current_loop.h" |
| 33 | 33 |
| 34 namespace content { | 34 namespace content { |
| 35 | 35 |
| 36 VideoCaptureImplManager::VideoCaptureImplManager() | 36 VideoCaptureImplManager::VideoCaptureImplManager() |
| 37 : next_client_id_(0), | 37 : next_client_id_(0), |
| 38 filter_(new VideoCaptureMessageFilter()), | 38 filter_(new VideoCaptureMessageFilter()), |
| 39 render_main_message_loop_(base::MessageLoopProxy::current()), | |
| 39 weak_factory_(this) { | 40 weak_factory_(this) { |
| 40 } | 41 } |
| 41 | 42 |
| 42 VideoCaptureImplManager::~VideoCaptureImplManager() { | 43 VideoCaptureImplManager::~VideoCaptureImplManager() { |
| 43 DCHECK(render_main_thread_checker_.CalledOnValidThread()); | 44 DCHECK(render_main_message_loop_->BelongsToCurrentThread()); |
| 44 if (devices_.empty()) | 45 if (devices_.empty()) |
| 45 return; | 46 return; |
| 46 // Forcibly release all video capture resources. | 47 // Forcibly release all video capture resources. |
| 47 for (const auto& device : devices_) { | 48 for (const auto& device : devices_) { |
| 48 VideoCaptureImpl* const impl = device.second.second; | 49 VideoCaptureImpl* const impl = device.second.second; |
| 49 ChildProcess::current()->io_message_loop_proxy()->PostTask( | 50 ChildProcess::current()->io_message_loop_proxy()->PostTask( |
| 50 FROM_HERE, | 51 FROM_HERE, |
| 51 base::Bind(&VideoCaptureImpl::DeInit, | 52 base::Bind(&VideoCaptureImpl::DeInit, |
| 52 base::Unretained(impl))); | 53 base::Unretained(impl))); |
| 53 ChildProcess::current()->io_message_loop_proxy()->DeleteSoon(FROM_HERE, | 54 ChildProcess::current()->io_message_loop_proxy()->DeleteSoon(FROM_HERE, |
| 54 impl); | 55 impl); |
| 55 } | 56 } |
| 56 devices_.clear(); | 57 devices_.clear(); |
| 57 } | 58 } |
| 58 | 59 |
| 59 base::Closure VideoCaptureImplManager::UseDevice( | 60 base::Closure VideoCaptureImplManager::UseDevice( |
| 60 media::VideoCaptureSessionId id) { | 61 media::VideoCaptureSessionId id) { |
| 61 DCHECK(render_main_thread_checker_.CalledOnValidThread()); | 62 DCHECK(render_main_message_loop_->BelongsToCurrentThread()); |
| 62 | 63 |
| 63 VideoCaptureImpl* impl = NULL; | 64 VideoCaptureImpl* impl = NULL; |
| 64 const VideoCaptureDeviceMap::iterator it = devices_.find(id); | 65 const VideoCaptureDeviceMap::iterator it = devices_.find(id); |
| 65 if (it == devices_.end()) { | 66 if (it == devices_.end()) { |
| 66 impl = CreateVideoCaptureImplForTesting(id, filter_.get()); | 67 impl = CreateVideoCaptureImplForTesting(id, filter_.get()); |
| 67 if (!impl) | 68 if (!impl) |
| 68 impl = new VideoCaptureImpl(id, filter_.get()); | 69 impl = new VideoCaptureImpl(id, filter_.get()); |
| 69 devices_[id] = std::make_pair(1, impl); | 70 devices_[id] = std::make_pair(1, impl); |
| 70 ChildProcess::current()->io_message_loop_proxy()->PostTask( | 71 ChildProcess::current()->io_message_loop_proxy()->PostTask( |
| 71 FROM_HERE, | 72 FROM_HERE, |
| 72 base::Bind(&VideoCaptureImpl::Init, | 73 base::Bind(&VideoCaptureImpl::Init, |
| 73 base::Unretained(impl))); | 74 base::Unretained(impl))); |
| 74 } else { | 75 } else { |
| 75 ++it->second.first; | 76 ++it->second.first; |
| 76 } | 77 } |
| 77 return base::Bind(&VideoCaptureImplManager::UnrefDevice, | 78 return base::Bind(&VideoCaptureImplManager::UnrefDevice, |
| 78 weak_factory_.GetWeakPtr(), id); | 79 weak_factory_.GetWeakPtr(), id); |
| 79 } | 80 } |
| 80 | 81 |
| 81 base::Closure VideoCaptureImplManager::StartCapture( | 82 base::Closure VideoCaptureImplManager::StartCapture( |
| 82 media::VideoCaptureSessionId id, | 83 media::VideoCaptureSessionId id, |
| 83 const media::VideoCaptureParams& params, | 84 const media::VideoCaptureParams& params, |
| 84 const VideoCaptureStateUpdateCB& state_update_cb, | 85 const VideoCaptureStateUpdateCB& state_update_cb, |
| 85 const VideoCaptureDeliverFrameCB& deliver_frame_cb) { | 86 const VideoCaptureDeliverFrameCB& deliver_frame_cb) { |
| 86 DCHECK(render_main_thread_checker_.CalledOnValidThread()); | 87 DCHECK(render_main_message_loop_->BelongsToCurrentThread()); |
| 87 const VideoCaptureDeviceMap::const_iterator it = devices_.find(id); | 88 const VideoCaptureDeviceMap::const_iterator it = devices_.find(id); |
| 88 DCHECK(it != devices_.end()); | 89 DCHECK(it != devices_.end()); |
| 89 VideoCaptureImpl* const impl = it->second.second; | 90 VideoCaptureImpl* const impl = it->second.second; |
| 90 | 91 |
| 91 // This ID is used to identify a client of VideoCaptureImpl. | 92 // This ID is used to identify a client of VideoCaptureImpl. |
| 92 const int client_id = ++next_client_id_; | 93 const int client_id = ++next_client_id_; |
| 93 | 94 |
| 94 ChildProcess::current()->io_message_loop_proxy()->PostTask( | 95 ChildProcess::current()->io_message_loop_proxy()->PostTask( |
| 95 FROM_HERE, | 96 FROM_HERE, |
| 96 base::Bind(&VideoCaptureImpl::StartCapture, | 97 base::Bind(&VideoCaptureImpl::StartCapture, |
| 97 base::Unretained(impl), | 98 base::Unretained(impl), |
| 98 client_id, | 99 client_id, |
| 99 params, | 100 params, |
| 100 state_update_cb, | 101 state_update_cb, |
| 101 deliver_frame_cb)); | 102 deliver_frame_cb)); |
| 102 return base::Bind(&VideoCaptureImplManager::StopCapture, | 103 return base::Bind(&VideoCaptureImplManager::StopCapture, |
| 103 weak_factory_.GetWeakPtr(), | 104 weak_factory_.GetWeakPtr(), |
| 104 client_id, id); | 105 client_id, id); |
| 105 } | 106 } |
| 106 | 107 |
| 107 void VideoCaptureImplManager::GetDeviceSupportedFormats( | 108 void VideoCaptureImplManager::GetDeviceSupportedFormats( |
| 108 media::VideoCaptureSessionId id, | 109 media::VideoCaptureSessionId id, |
| 109 const VideoCaptureDeviceFormatsCB& callback) { | 110 const VideoCaptureDeviceFormatsCB& callback) { |
| 110 DCHECK(render_main_thread_checker_.CalledOnValidThread()); | 111 DCHECK(render_main_message_loop_->BelongsToCurrentThread()); |
| 111 const VideoCaptureDeviceMap::const_iterator it = devices_.find(id); | 112 const VideoCaptureDeviceMap::const_iterator it = devices_.find(id); |
| 112 DCHECK(it != devices_.end()); | 113 DCHECK(it != devices_.end()); |
| 113 VideoCaptureImpl* const impl = it->second.second; | 114 VideoCaptureImpl* const impl = it->second.second; |
| 114 ChildProcess::current()->io_message_loop_proxy()->PostTask( | 115 ChildProcess::current()->io_message_loop_proxy()->PostTask( |
| 115 FROM_HERE, | 116 FROM_HERE, |
| 116 base::Bind(&VideoCaptureImpl::GetDeviceSupportedFormats, | 117 base::Bind(&VideoCaptureImpl::GetDeviceSupportedFormats, |
| 117 base::Unretained(impl), callback)); | 118 base::Unretained(impl), callback)); |
| 118 } | 119 } |
| 119 | 120 |
| 120 void VideoCaptureImplManager::GetDeviceFormatsInUse( | 121 void VideoCaptureImplManager::GetDeviceFormatsInUse( |
| 121 media::VideoCaptureSessionId id, | 122 media::VideoCaptureSessionId id, |
| 122 const VideoCaptureDeviceFormatsCB& callback) { | 123 const VideoCaptureDeviceFormatsCB& callback) { |
| 123 DCHECK(render_main_thread_checker_.CalledOnValidThread()); | 124 DCHECK(render_main_message_loop_->BelongsToCurrentThread()); |
| 124 const VideoCaptureDeviceMap::const_iterator it = devices_.find(id); | 125 const VideoCaptureDeviceMap::const_iterator it = devices_.find(id); |
| 125 DCHECK(it != devices_.end()); | 126 DCHECK(it != devices_.end()); |
| 126 VideoCaptureImpl* const impl = it->second.second; | 127 VideoCaptureImpl* const impl = it->second.second; |
| 127 ChildProcess::current()->io_message_loop_proxy()->PostTask( | 128 ChildProcess::current()->io_message_loop_proxy()->PostTask( |
| 128 FROM_HERE, | 129 FROM_HERE, |
| 129 base::Bind(&VideoCaptureImpl::GetDeviceFormatsInUse, | 130 base::Bind(&VideoCaptureImpl::GetDeviceFormatsInUse, |
| 130 base::Unretained(impl), callback)); | 131 base::Unretained(impl), callback)); |
| 131 } | 132 } |
| 132 | 133 |
| 133 VideoCaptureImpl* | 134 VideoCaptureImpl* |
| 134 VideoCaptureImplManager::CreateVideoCaptureImplForTesting( | 135 VideoCaptureImplManager::CreateVideoCaptureImplForTesting( |
| 135 media::VideoCaptureSessionId id, | 136 media::VideoCaptureSessionId id, |
| 136 VideoCaptureMessageFilter* filter) const { | 137 VideoCaptureMessageFilter* filter) const { |
| 137 return NULL; | 138 return NULL; |
| 138 } | 139 } |
| 139 | 140 |
| 140 void VideoCaptureImplManager::StopCapture( | 141 void VideoCaptureImplManager::StopCapture(int client_id, |
| 141 int client_id, media::VideoCaptureSessionId id) { | 142 media::VideoCaptureSessionId id) { |
| 142 DCHECK(render_main_thread_checker_.CalledOnValidThread()); | 143 DCHECK(render_main_message_loop_->BelongsToCurrentThread()); |
| 143 const VideoCaptureDeviceMap::const_iterator it = devices_.find(id); | 144 const VideoCaptureDeviceMap::const_iterator it = devices_.find(id); |
| 144 DCHECK(it != devices_.end()); | 145 DCHECK(it != devices_.end()); |
| 145 VideoCaptureImpl* const impl = it->second.second; | 146 VideoCaptureImpl* const impl = it->second.second; |
| 146 ChildProcess::current()->io_message_loop_proxy()->PostTask( | 147 ChildProcess::current()->io_message_loop_proxy()->PostTask( |
| 147 FROM_HERE, | 148 FROM_HERE, |
| 148 base::Bind(&VideoCaptureImpl::StopCapture, | 149 base::Bind(&VideoCaptureImpl::StopCapture, |
| 149 base::Unretained(impl), client_id)); | 150 base::Unretained(impl), client_id)); |
| 150 } | 151 } |
| 151 | 152 |
| 152 void VideoCaptureImplManager::UnrefDevice( | 153 void VideoCaptureImplManager::UnrefDevice( |
| 153 media::VideoCaptureSessionId id) { | 154 media::VideoCaptureSessionId id) { |
| 154 DCHECK(render_main_thread_checker_.CalledOnValidThread()); | 155 DCHECK(render_main_message_loop_->BelongsToCurrentThread()); |
|
mcasas
2015/03/16 20:34:06
Correct indent.
emircan
2015/03/19 00:40:44
Done.
| |
| 155 const VideoCaptureDeviceMap::iterator it = devices_.find(id); | 156 const VideoCaptureDeviceMap::iterator it = devices_.find(id); |
| 156 DCHECK(it != devices_.end()); | 157 DCHECK(it != devices_.end()); |
| 157 VideoCaptureImpl* const impl = it->second.second; | 158 VideoCaptureImpl* const impl = it->second.second; |
| 158 | 159 |
| 159 // Unref and destroy on the IO thread if there's no more client. | 160 // Unref and destroy on the IO thread if there's no more client. |
| 160 DCHECK(it->second.first); | 161 DCHECK(it->second.first); |
| 161 --it->second.first; | 162 --it->second.first; |
| 162 if (!it->second.first) { | 163 if (!it->second.first) { |
| 163 devices_.erase(id); | 164 devices_.erase(id); |
| 164 ChildProcess::current()->io_message_loop_proxy()->PostTask( | 165 ChildProcess::current()->io_message_loop_proxy()->PostTask( |
| 165 FROM_HERE, | 166 FROM_HERE, |
| 166 base::Bind(&VideoCaptureImpl::DeInit, | 167 base::Bind(&VideoCaptureImpl::DeInit, |
| 167 base::Unretained(impl))); | 168 base::Unretained(impl))); |
| 168 ChildProcess::current()->io_message_loop_proxy()->DeleteSoon(FROM_HERE, | 169 ChildProcess::current()->io_message_loop_proxy()->DeleteSoon(FROM_HERE, |
| 169 impl); | 170 impl); |
| 170 } | 171 } |
| 171 } | 172 } |
| 172 | 173 |
| 173 void VideoCaptureImplManager::SuspendDevices(bool suspend) { | 174 void VideoCaptureImplManager::SuspendDevices(bool suspend) { |
| 174 DCHECK(render_main_thread_checker_.CalledOnValidThread()); | 175 DCHECK(render_main_message_loop_->BelongsToCurrentThread()); |
| 175 for (const auto& device : devices_) { | 176 for (const auto& device : devices_) { |
| 176 VideoCaptureImpl* const impl = device.second.second; | 177 VideoCaptureImpl* const impl = device.second.second; |
| 177 ChildProcess::current()->io_message_loop_proxy()->PostTask( | 178 ChildProcess::current()->io_message_loop_proxy()->PostTask( |
| 178 FROM_HERE, | 179 FROM_HERE, base::Bind(&VideoCaptureImpl::SuspendCapture, |
| 179 base::Bind(&VideoCaptureImpl::SuspendCapture, | 180 base::Unretained(impl), suspend)); |
| 180 base::Unretained(impl), suspend)); | |
| 181 } | 181 } |
| 182 } | 182 } |
| 183 | 183 |
| 184 } // namespace content | 184 } // namespace content |
| OLD | NEW |