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 #include "content/renderer/media/video_capture_impl.h" | 5 #include "content/renderer/media/video_capture_impl.h" |
| 6 | 6 |
| 7 #include "base/bind.h" | 7 #include "base/bind.h" |
| 8 #include "base/stl_util.h" | 8 #include "base/stl_util.h" |
| 9 #include "content/child/child_process.h" | 9 #include "content/child/child_process.h" |
| 10 #include "content/common/media/video_capture_messages.h" | 10 #include "content/common/media/video_capture_messages.h" |
| (...skipping 24 matching lines...) Expand all Loading... | |
| 35 bool VideoCaptureImpl::CaptureStarted() { | 35 bool VideoCaptureImpl::CaptureStarted() { |
| 36 return state_ == VIDEO_CAPTURE_STATE_STARTED; | 36 return state_ == VIDEO_CAPTURE_STATE_STARTED; |
| 37 } | 37 } |
| 38 | 38 |
| 39 int VideoCaptureImpl::CaptureFrameRate() { | 39 int VideoCaptureImpl::CaptureFrameRate() { |
| 40 return last_frame_format_.frame_rate; | 40 return last_frame_format_.frame_rate; |
| 41 } | 41 } |
| 42 | 42 |
| 43 VideoCaptureImpl::VideoCaptureImpl( | 43 VideoCaptureImpl::VideoCaptureImpl( |
| 44 const media::VideoCaptureSessionId session_id, | 44 const media::VideoCaptureSessionId session_id, |
| 45 base::MessageLoopProxy* capture_message_loop_proxy, | |
| 46 VideoCaptureMessageFilter* filter) | 45 VideoCaptureMessageFilter* filter) |
| 47 : VideoCapture(), | 46 : VideoCapture(), |
| 48 message_filter_(filter), | 47 message_filter_(filter), |
| 49 capture_message_loop_proxy_(capture_message_loop_proxy), | |
| 50 io_message_loop_proxy_(ChildProcess::current()->io_message_loop_proxy()), | 48 io_message_loop_proxy_(ChildProcess::current()->io_message_loop_proxy()), |
| 51 device_id_(0), | 49 device_id_(0), |
| 52 session_id_(session_id), | 50 session_id_(session_id), |
| 53 suspended_(false), | 51 suspended_(false), |
| 54 state_(VIDEO_CAPTURE_STATE_STOPPED), | 52 state_(VIDEO_CAPTURE_STATE_STOPPED), |
| 55 weak_this_factory_(this) { | 53 weak_this_factory_(this) { |
| 56 DCHECK(filter); | 54 DCHECK(filter); |
| 57 } | 55 } |
| 58 | 56 |
| 59 VideoCaptureImpl::~VideoCaptureImpl() {} | 57 VideoCaptureImpl::~VideoCaptureImpl() {} |
| 60 | 58 |
| 61 void VideoCaptureImpl::Init() { | 59 void VideoCaptureImpl::Init() { |
| 62 if (!io_message_loop_proxy_->BelongsToCurrentThread()) { | 60 if (!io_message_loop_proxy_->BelongsToCurrentThread()) { |
| 63 io_message_loop_proxy_->PostTask(FROM_HERE, | 61 io_message_loop_proxy_->PostTask(FROM_HERE, |
| 64 base::Bind(&VideoCaptureImpl::AddDelegateOnIOThread, | 62 base::Bind(&VideoCaptureImpl::Init, |
| 65 base::Unretained(this))); | 63 base::Unretained(this))); |
| 66 } else { | 64 return; |
| 67 AddDelegateOnIOThread(); | |
| 68 } | 65 } |
| 66 | |
| 67 DCHECK(io_message_loop_proxy_->BelongsToCurrentThread()); | |
| 68 message_filter_->AddDelegate(this); | |
| 69 } | 69 } |
| 70 | 70 |
| 71 void VideoCaptureImpl::DeInit(base::Closure task) { | 71 void VideoCaptureImpl::DeInit(base::Closure task) { |
| 72 capture_message_loop_proxy_->PostTask(FROM_HERE, | 72 if (!io_message_loop_proxy_->BelongsToCurrentThread()) { |
| 73 base::Bind(&VideoCaptureImpl::DoDeInitOnCaptureThread, | 73 io_message_loop_proxy_->PostTask(FROM_HERE, |
| 74 base::Unretained(this), task)); | 74 base::Bind(&VideoCaptureImpl::DeInit, |
| 75 base::Unretained(this), | |
| 76 task)); | |
| 77 return; | |
| 78 } | |
| 79 | |
| 80 DCHECK(io_message_loop_proxy_->BelongsToCurrentThread()); | |
| 81 if (state_ == VIDEO_CAPTURE_STATE_STARTED) | |
| 82 Send(new VideoCaptureHostMsg_Stop(device_id_)); | |
| 83 message_filter_->RemoveDelegate(this); | |
| 84 task.Run(); | |
| 85 } | |
| 86 | |
| 87 void VideoCaptureImpl::SuspendCapture(bool suspend) { | |
| 88 if (!io_message_loop_proxy_->BelongsToCurrentThread()) { | |
| 89 io_message_loop_proxy_->PostTask(FROM_HERE, | |
| 90 base::Bind(&VideoCaptureImpl::SuspendCapture, | |
| 91 base::Unretained(this), | |
| 92 suspend)); | |
| 93 return; | |
| 94 } | |
| 95 | |
| 96 DCHECK(io_message_loop_proxy_->BelongsToCurrentThread()); | |
| 97 suspended_ = suspend; | |
| 75 } | 98 } |
| 76 | 99 |
| 77 void VideoCaptureImpl::StartCapture( | 100 void VideoCaptureImpl::StartCapture( |
| 78 media::VideoCapture::EventHandler* handler, | 101 media::VideoCapture::EventHandler* handler, |
| 79 const media::VideoCaptureParams& params) { | 102 const media::VideoCaptureParams& params) { |
| 80 capture_message_loop_proxy_->PostTask(FROM_HERE, | 103 if (!io_message_loop_proxy_->BelongsToCurrentThread()) { |
| 81 base::Bind(&VideoCaptureImpl::DoStartCaptureOnCaptureThread, | 104 io_message_loop_proxy_->PostTask(FROM_HERE, |
| 82 base::Unretained(this), handler, params)); | 105 base::Bind(&VideoCaptureImpl::StartCapture, |
| 83 } | 106 base::Unretained(this), handler, params)); |
| 107 return; | |
| 108 } | |
| 84 | 109 |
| 85 void VideoCaptureImpl::StopCapture(media::VideoCapture::EventHandler* handler) { | 110 DCHECK(io_message_loop_proxy_->BelongsToCurrentThread()); |
| 86 capture_message_loop_proxy_->PostTask(FROM_HERE, | |
| 87 base::Bind(&VideoCaptureImpl::DoStopCaptureOnCaptureThread, | |
| 88 base::Unretained(this), handler)); | |
| 89 } | |
| 90 | |
| 91 void VideoCaptureImpl::OnBufferCreated( | |
| 92 base::SharedMemoryHandle handle, | |
| 93 int length, int buffer_id) { | |
| 94 capture_message_loop_proxy_->PostTask(FROM_HERE, | |
| 95 base::Bind(&VideoCaptureImpl::DoBufferCreatedOnCaptureThread, | |
| 96 base::Unretained(this), handle, length, buffer_id)); | |
| 97 } | |
| 98 | |
| 99 void VideoCaptureImpl::OnBufferDestroyed(int buffer_id) { | |
| 100 capture_message_loop_proxy_->PostTask(FROM_HERE, | |
| 101 base::Bind(&VideoCaptureImpl::DoBufferDestroyedOnCaptureThread, | |
| 102 base::Unretained(this), buffer_id)); | |
| 103 } | |
| 104 | |
| 105 void VideoCaptureImpl::OnBufferReceived( | |
| 106 int buffer_id, | |
| 107 base::Time timestamp, | |
| 108 const media::VideoCaptureFormat& format) { | |
| 109 capture_message_loop_proxy_->PostTask(FROM_HERE, | |
| 110 base::Bind(&VideoCaptureImpl::DoBufferReceivedOnCaptureThread, | |
| 111 base::Unretained(this), buffer_id, timestamp, format)); | |
| 112 } | |
| 113 | |
| 114 void VideoCaptureImpl::OnStateChanged(VideoCaptureState state) { | |
| 115 capture_message_loop_proxy_->PostTask(FROM_HERE, | |
| 116 base::Bind(&VideoCaptureImpl::DoStateChangedOnCaptureThread, | |
| 117 base::Unretained(this), state)); | |
| 118 } | |
| 119 | |
| 120 void VideoCaptureImpl::OnDelegateAdded(int32 device_id) { | |
| 121 capture_message_loop_proxy_->PostTask(FROM_HERE, | |
| 122 base::Bind(&VideoCaptureImpl::DoDelegateAddedOnCaptureThread, | |
| 123 base::Unretained(this), device_id)); | |
| 124 } | |
| 125 | |
| 126 void VideoCaptureImpl::SuspendCapture(bool suspend) { | |
| 127 capture_message_loop_proxy_->PostTask(FROM_HERE, | |
| 128 base::Bind(&VideoCaptureImpl::DoSuspendCaptureOnCaptureThread, | |
| 129 base::Unretained(this), suspend)); | |
| 130 } | |
| 131 | |
| 132 void VideoCaptureImpl::DoDeInitOnCaptureThread(base::Closure task) { | |
| 133 if (state_ == VIDEO_CAPTURE_STATE_STARTED) | |
| 134 Send(new VideoCaptureHostMsg_Stop(device_id_)); | |
| 135 | |
| 136 io_message_loop_proxy_->PostTask(FROM_HERE, | |
| 137 base::Bind(&VideoCaptureImpl::RemoveDelegateOnIOThread, | |
| 138 base::Unretained(this), task)); | |
| 139 } | |
| 140 | |
| 141 void VideoCaptureImpl::DoStartCaptureOnCaptureThread( | |
| 142 media::VideoCapture::EventHandler* handler, | |
| 143 const media::VideoCaptureParams& params) { | |
| 144 DCHECK(capture_message_loop_proxy_->BelongsToCurrentThread()); | |
| 145 | |
| 146 if (state_ == VIDEO_CAPTURE_STATE_ERROR) { | 111 if (state_ == VIDEO_CAPTURE_STATE_ERROR) { |
| 147 handler->OnError(this, 1); | 112 handler->OnError(this, 1); |
| 148 handler->OnRemoved(this); | 113 handler->OnRemoved(this); |
| 149 } else if ((clients_pending_on_filter_.find(handler) != | 114 } else if ((clients_pending_on_filter_.find(handler) != |
| 150 clients_pending_on_filter_.end()) || | 115 clients_pending_on_filter_.end()) || |
| 151 (clients_pending_on_restart_.find(handler) != | 116 (clients_pending_on_restart_.find(handler) != |
| 152 clients_pending_on_restart_.end()) || | 117 clients_pending_on_restart_.end()) || |
| 153 clients_.find(handler) != clients_.end() ) { | 118 clients_.find(handler) != clients_.end() ) { |
| 154 // This client has started. | 119 // This client has started. |
| 155 } else if (!device_id_) { | 120 } else if (!device_id_) { |
| (...skipping 20 matching lines...) Expand all Loading... | |
| 176 media::limits::kMaxFramesPerSecond; | 141 media::limits::kMaxFramesPerSecond; |
| 177 } | 142 } |
| 178 DVLOG(1) << "StartCapture: starting with first resolution " | 143 DVLOG(1) << "StartCapture: starting with first resolution " |
| 179 << params_.requested_format.frame_size.ToString(); | 144 << params_.requested_format.frame_size.ToString(); |
| 180 | 145 |
| 181 StartCaptureInternal(); | 146 StartCaptureInternal(); |
| 182 } | 147 } |
| 183 } | 148 } |
| 184 } | 149 } |
| 185 | 150 |
| 186 void VideoCaptureImpl::DoStopCaptureOnCaptureThread( | 151 void VideoCaptureImpl::StopCapture( |
| 187 media::VideoCapture::EventHandler* handler) { | 152 media::VideoCapture::EventHandler* handler) { |
| 188 DCHECK(capture_message_loop_proxy_->BelongsToCurrentThread()); | 153 if (!io_message_loop_proxy_->BelongsToCurrentThread()) { |
| 154 io_message_loop_proxy_->PostTask(FROM_HERE, | |
| 155 base::Bind(&VideoCaptureImpl::StopCapture, | |
| 156 base::Unretained(this), handler)); | |
| 157 return; | |
| 158 } | |
| 159 | |
| 160 DCHECK(io_message_loop_proxy_->BelongsToCurrentThread()); | |
| 189 | 161 |
| 190 // A handler can be in only one client list. | 162 // A handler can be in only one client list. |
| 191 // If this handler is in any client list, we can just remove it from | 163 // If this handler is in any client list, we can just remove it from |
| 192 // that client list and don't have to run the other following RemoveClient(). | 164 // that client list and don't have to run the other following RemoveClient(). |
| 193 RemoveClient(handler, &clients_pending_on_filter_) || | 165 RemoveClient(handler, &clients_pending_on_filter_) || |
| 194 RemoveClient(handler, &clients_pending_on_restart_) || | 166 RemoveClient(handler, &clients_pending_on_restart_) || |
| 195 RemoveClient(handler, &clients_); | 167 RemoveClient(handler, &clients_); |
| 196 | 168 |
| 197 if (clients_.empty()) { | 169 if (clients_.empty()) { |
| 198 DVLOG(1) << "StopCapture: No more client, stopping ..."; | 170 DVLOG(1) << "StopCapture: No more client, stopping ..."; |
| 199 StopDevice(); | 171 StopDevice(); |
| 200 client_buffers_.clear(); | 172 client_buffers_.clear(); |
| 201 weak_this_factory_.InvalidateWeakPtrs(); | 173 weak_this_factory_.InvalidateWeakPtrs(); |
| 202 } | 174 } |
| 203 } | 175 } |
| 204 | 176 |
| 205 void VideoCaptureImpl::DoBufferCreatedOnCaptureThread( | 177 void VideoCaptureImpl::OnBufferCreated( |
| 206 base::SharedMemoryHandle handle, | 178 base::SharedMemoryHandle handle, |
| 207 int length, int buffer_id) { | 179 int length, int buffer_id) { |
| 208 DCHECK(capture_message_loop_proxy_->BelongsToCurrentThread()); | 180 DCHECK(io_message_loop_proxy_->BelongsToCurrentThread()); |
| 209 | 181 |
| 210 // In case client calls StopCapture before the arrival of created buffer, | 182 // In case client calls StopCapture before the arrival of created buffer, |
| 211 // just close this buffer and return. | 183 // just close this buffer and return. |
| 212 if (state_ != VIDEO_CAPTURE_STATE_STARTED) { | 184 if (state_ != VIDEO_CAPTURE_STATE_STARTED) { |
| 213 base::SharedMemory::CloseHandle(handle); | 185 base::SharedMemory::CloseHandle(handle); |
| 214 return; | 186 return; |
| 215 } | 187 } |
| 216 | 188 |
| 217 scoped_ptr<base::SharedMemory> shm(new base::SharedMemory(handle, false)); | 189 scoped_ptr<base::SharedMemory> shm(new base::SharedMemory(handle, false)); |
| 218 if (!shm->Map(length)) { | 190 if (!shm->Map(length)) { |
| 219 DLOG(ERROR) << "DoBufferCreatedOnCaptureThread: Map() failed."; | 191 DLOG(ERROR) << "SharedMemory::Map() failed."; |
|
Jói
2013/12/27 13:34:35
nit: "OnBufferCreated: Map failed." might give mor
Alpha Left Google
2013/12/27 21:30:01
Done.
| |
| 220 return; | 192 return; |
| 221 } | 193 } |
| 222 | 194 |
| 223 bool inserted = | 195 bool inserted = |
| 224 client_buffers_.insert(std::make_pair( | 196 client_buffers_.insert(std::make_pair( |
| 225 buffer_id, | 197 buffer_id, |
| 226 new ClientBuffer(shm.Pass(), | 198 new ClientBuffer(shm.Pass(), |
| 227 length))).second; | 199 length))).second; |
| 228 DCHECK(inserted); | 200 DCHECK(inserted); |
| 229 } | 201 } |
| 230 | 202 |
| 231 void VideoCaptureImpl::DoBufferDestroyedOnCaptureThread(int buffer_id) { | 203 void VideoCaptureImpl::OnBufferDestroyed(int buffer_id) { |
| 232 DCHECK(capture_message_loop_proxy_->BelongsToCurrentThread()); | 204 DCHECK(io_message_loop_proxy_->BelongsToCurrentThread()); |
| 233 | 205 |
| 234 ClientBufferMap::iterator iter = client_buffers_.find(buffer_id); | 206 ClientBufferMap::iterator iter = client_buffers_.find(buffer_id); |
| 235 if (iter == client_buffers_.end()) | 207 if (iter == client_buffers_.end()) |
| 236 return; | 208 return; |
| 237 | 209 |
| 238 DCHECK(!iter->second || iter->second->HasOneRef()) | 210 DCHECK(!iter->second || iter->second->HasOneRef()) |
| 239 << "Instructed to delete buffer we are still using."; | 211 << "Instructed to delete buffer we are still using."; |
| 240 client_buffers_.erase(iter); | 212 client_buffers_.erase(iter); |
| 241 } | 213 } |
| 242 | 214 |
| 243 void VideoCaptureImpl::DoBufferReceivedOnCaptureThread( | 215 void VideoCaptureImpl::OnBufferReceived( |
| 244 int buffer_id, | 216 int buffer_id, |
| 245 base::Time timestamp, | 217 base::Time timestamp, |
| 246 const media::VideoCaptureFormat& format) { | 218 const media::VideoCaptureFormat& format) { |
| 247 DCHECK(capture_message_loop_proxy_->BelongsToCurrentThread()); | 219 DCHECK(io_message_loop_proxy_->BelongsToCurrentThread()); |
| 248 | 220 |
| 249 if (state_ != VIDEO_CAPTURE_STATE_STARTED || suspended_) { | 221 if (state_ != VIDEO_CAPTURE_STATE_STARTED || suspended_) { |
| 250 Send(new VideoCaptureHostMsg_BufferReady(device_id_, buffer_id)); | 222 Send(new VideoCaptureHostMsg_BufferReady(device_id_, buffer_id)); |
| 251 return; | 223 return; |
| 252 } | 224 } |
| 253 | 225 |
| 254 last_frame_format_ = format; | 226 last_frame_format_ = format; |
| 255 | 227 |
| 256 ClientBufferMap::iterator iter = client_buffers_.find(buffer_id); | 228 ClientBufferMap::iterator iter = client_buffers_.find(buffer_id); |
| 257 DCHECK(iter != client_buffers_.end()); | 229 DCHECK(iter != client_buffers_.end()); |
| 258 scoped_refptr<ClientBuffer> buffer = iter->second; | 230 scoped_refptr<ClientBuffer> buffer = iter->second; |
| 259 scoped_refptr<media::VideoFrame> frame = | 231 scoped_refptr<media::VideoFrame> frame = |
| 260 media::VideoFrame::WrapExternalPackedMemory( | 232 media::VideoFrame::WrapExternalPackedMemory( |
| 261 media::VideoFrame::I420, | 233 media::VideoFrame::I420, |
| 262 last_frame_format_.frame_size, | 234 last_frame_format_.frame_size, |
| 263 gfx::Rect(last_frame_format_.frame_size), | 235 gfx::Rect(last_frame_format_.frame_size), |
| 264 last_frame_format_.frame_size, | 236 last_frame_format_.frame_size, |
| 265 reinterpret_cast<uint8*>(buffer->buffer->memory()), | 237 reinterpret_cast<uint8*>(buffer->buffer->memory()), |
| 266 buffer->buffer_size, | 238 buffer->buffer_size, |
| 267 buffer->buffer->handle(), | 239 buffer->buffer->handle(), |
| 268 // TODO(sheu): convert VideoCaptureMessageFilter::Delegate to use | 240 // TODO(sheu): convert VideoCaptureMessageFilter::Delegate to use |
| 269 // base::TimeTicks instead of base::Time. http://crbug.com/249215 | 241 // base::TimeTicks instead of base::Time. http://crbug.com/249215 |
| 270 timestamp - base::Time::UnixEpoch(), | 242 timestamp - base::Time::UnixEpoch(), |
| 271 media::BindToLoop( | 243 media::BindToLoop( |
| 272 capture_message_loop_proxy_, | 244 io_message_loop_proxy_, |
| 273 base::Bind( | 245 base::Bind( |
| 274 &VideoCaptureImpl::DoClientBufferFinishedOnCaptureThread, | 246 &VideoCaptureImpl::OnClientBufferFinished, |
| 275 weak_this_factory_.GetWeakPtr(), | 247 weak_this_factory_.GetWeakPtr(), |
| 276 buffer_id, | 248 buffer_id, |
| 277 buffer))); | 249 buffer))); |
| 278 | 250 |
| 279 for (ClientInfo::iterator it = clients_.begin(); it != clients_.end(); ++it) | 251 for (ClientInfo::iterator it = clients_.begin(); it != clients_.end(); ++it) |
| 280 it->first->OnFrameReady(this, frame); | 252 it->first->OnFrameReady(this, frame); |
| 281 } | 253 } |
| 282 | 254 |
| 283 void VideoCaptureImpl::DoClientBufferFinishedOnCaptureThread( | 255 void VideoCaptureImpl::OnClientBufferFinished( |
| 284 int buffer_id, | 256 int buffer_id, |
| 285 const scoped_refptr<ClientBuffer>& buffer) { | 257 const scoped_refptr<ClientBuffer>& buffer) { |
| 286 DCHECK(capture_message_loop_proxy_->BelongsToCurrentThread()); | 258 DCHECK(io_message_loop_proxy_->BelongsToCurrentThread()); |
| 287 Send(new VideoCaptureHostMsg_BufferReady(device_id_, buffer_id)); | 259 Send(new VideoCaptureHostMsg_BufferReady(device_id_, buffer_id)); |
| 288 } | 260 } |
| 289 | 261 |
| 290 void VideoCaptureImpl::DoStateChangedOnCaptureThread(VideoCaptureState state) { | 262 void VideoCaptureImpl::OnStateChanged(VideoCaptureState state) { |
| 291 DCHECK(capture_message_loop_proxy_->BelongsToCurrentThread()); | 263 DCHECK(io_message_loop_proxy_->BelongsToCurrentThread()); |
| 292 | 264 |
| 293 switch (state) { | 265 switch (state) { |
| 294 case VIDEO_CAPTURE_STATE_STARTED: | 266 case VIDEO_CAPTURE_STATE_STARTED: |
| 295 break; | 267 break; |
| 296 case VIDEO_CAPTURE_STATE_STOPPED: | 268 case VIDEO_CAPTURE_STATE_STOPPED: |
| 297 state_ = VIDEO_CAPTURE_STATE_STOPPED; | 269 state_ = VIDEO_CAPTURE_STATE_STOPPED; |
| 298 DVLOG(1) << "OnStateChanged: stopped!, device_id = " << device_id_; | 270 DVLOG(1) << "OnStateChanged: stopped!, device_id = " << device_id_; |
| 299 client_buffers_.clear(); | 271 client_buffers_.clear(); |
| 300 weak_this_factory_.InvalidateWeakPtrs(); | 272 weak_this_factory_.InvalidateWeakPtrs(); |
| 301 if (!clients_.empty() || !clients_pending_on_restart_.empty()) | 273 if (!clients_.empty() || !clients_pending_on_restart_.empty()) |
| (...skipping 23 matching lines...) Expand all Loading... | |
| 325 it->first->OnRemoved(this); | 297 it->first->OnRemoved(this); |
| 326 } | 298 } |
| 327 clients_.clear(); | 299 clients_.clear(); |
| 328 state_ = VIDEO_CAPTURE_STATE_ENDED; | 300 state_ = VIDEO_CAPTURE_STATE_ENDED; |
| 329 break; | 301 break; |
| 330 default: | 302 default: |
| 331 break; | 303 break; |
| 332 } | 304 } |
| 333 } | 305 } |
| 334 | 306 |
| 335 void VideoCaptureImpl::DoDelegateAddedOnCaptureThread(int32 device_id) { | 307 void VideoCaptureImpl::OnDelegateAdded(int32 device_id) { |
| 336 DVLOG(1) << "DoDelegateAdded: device_id " << device_id; | 308 DVLOG(1) << "OnDelegateAdded: device_id " << device_id; |
| 337 DCHECK(capture_message_loop_proxy_->BelongsToCurrentThread()); | 309 DCHECK(io_message_loop_proxy_->BelongsToCurrentThread()); |
| 338 | 310 |
| 339 device_id_ = device_id; | 311 device_id_ = device_id; |
| 340 for (ClientInfo::iterator it = clients_pending_on_filter_.begin(); | 312 for (ClientInfo::iterator it = clients_pending_on_filter_.begin(); |
| 341 it != clients_pending_on_filter_.end(); ) { | 313 it != clients_pending_on_filter_.end(); ) { |
| 342 media::VideoCapture::EventHandler* handler = it->first; | 314 media::VideoCapture::EventHandler* handler = it->first; |
| 343 const media::VideoCaptureParams params = it->second; | 315 const media::VideoCaptureParams params = it->second; |
| 344 clients_pending_on_filter_.erase(it++); | 316 clients_pending_on_filter_.erase(it++); |
| 345 StartCapture(handler, params); | 317 StartCapture(handler, params); |
| 346 } | 318 } |
| 347 } | 319 } |
| 348 | 320 |
| 349 void VideoCaptureImpl::DoSuspendCaptureOnCaptureThread(bool suspend) { | |
| 350 DVLOG(1) << "DoSuspendCapture: suspend " << (suspend ? "yes" : "no"); | |
| 351 DCHECK(capture_message_loop_proxy_->BelongsToCurrentThread()); | |
| 352 | |
| 353 suspended_ = suspend; | |
| 354 } | |
| 355 | |
| 356 void VideoCaptureImpl::StopDevice() { | 321 void VideoCaptureImpl::StopDevice() { |
| 357 DCHECK(capture_message_loop_proxy_->BelongsToCurrentThread()); | 322 DCHECK(io_message_loop_proxy_->BelongsToCurrentThread()); |
| 358 | 323 |
| 359 if (state_ == VIDEO_CAPTURE_STATE_STARTED) { | 324 if (state_ == VIDEO_CAPTURE_STATE_STARTED) { |
| 360 state_ = VIDEO_CAPTURE_STATE_STOPPING; | 325 state_ = VIDEO_CAPTURE_STATE_STOPPING; |
| 361 Send(new VideoCaptureHostMsg_Stop(device_id_)); | 326 Send(new VideoCaptureHostMsg_Stop(device_id_)); |
| 362 params_.requested_format.frame_size.SetSize(0, 0); | 327 params_.requested_format.frame_size.SetSize(0, 0); |
| 363 } | 328 } |
| 364 } | 329 } |
| 365 | 330 |
| 366 void VideoCaptureImpl::RestartCapture() { | 331 void VideoCaptureImpl::RestartCapture() { |
| 367 DCHECK(capture_message_loop_proxy_->BelongsToCurrentThread()); | 332 DCHECK(io_message_loop_proxy_->BelongsToCurrentThread()); |
| 368 DCHECK_EQ(state_, VIDEO_CAPTURE_STATE_STOPPED); | 333 DCHECK_EQ(state_, VIDEO_CAPTURE_STATE_STOPPED); |
| 369 | 334 |
| 370 int width = 0; | 335 int width = 0; |
| 371 int height = 0; | 336 int height = 0; |
| 372 for (ClientInfo::iterator it = clients_.begin(); | 337 for (ClientInfo::iterator it = clients_.begin(); |
| 373 it != clients_.end(); ++it) { | 338 it != clients_.end(); ++it) { |
| 374 width = std::max(width, it->second.requested_format.frame_size.width()); | 339 width = std::max(width, it->second.requested_format.frame_size.width()); |
| 375 height = std::max(height, it->second.requested_format.frame_size.height()); | 340 height = std::max(height, it->second.requested_format.frame_size.height()); |
| 376 } | 341 } |
| 377 for (ClientInfo::iterator it = clients_pending_on_restart_.begin(); | 342 for (ClientInfo::iterator it = clients_pending_on_restart_.begin(); |
| 378 it != clients_pending_on_restart_.end(); ) { | 343 it != clients_pending_on_restart_.end(); ) { |
| 379 width = std::max(width, it->second.requested_format.frame_size.width()); | 344 width = std::max(width, it->second.requested_format.frame_size.width()); |
| 380 height = std::max(height, it->second.requested_format.frame_size.height()); | 345 height = std::max(height, it->second.requested_format.frame_size.height()); |
| 381 clients_[it->first] = it->second; | 346 clients_[it->first] = it->second; |
| 382 clients_pending_on_restart_.erase(it++); | 347 clients_pending_on_restart_.erase(it++); |
| 383 } | 348 } |
| 384 params_.requested_format.frame_size.SetSize(width, height); | 349 params_.requested_format.frame_size.SetSize(width, height); |
| 385 DVLOG(1) << "RestartCapture, " | 350 DVLOG(1) << "RestartCapture, " |
| 386 << params_.requested_format.frame_size.ToString(); | 351 << params_.requested_format.frame_size.ToString(); |
| 387 StartCaptureInternal(); | 352 StartCaptureInternal(); |
| 388 } | 353 } |
| 389 | 354 |
| 390 void VideoCaptureImpl::StartCaptureInternal() { | 355 void VideoCaptureImpl::StartCaptureInternal() { |
| 391 DCHECK(capture_message_loop_proxy_->BelongsToCurrentThread()); | 356 DCHECK(io_message_loop_proxy_->BelongsToCurrentThread()); |
| 392 DCHECK(device_id_); | 357 DCHECK(device_id_); |
| 393 | 358 |
| 394 Send(new VideoCaptureHostMsg_Start(device_id_, session_id_, params_)); | 359 Send(new VideoCaptureHostMsg_Start(device_id_, session_id_, params_)); |
| 395 state_ = VIDEO_CAPTURE_STATE_STARTED; | 360 state_ = VIDEO_CAPTURE_STATE_STARTED; |
| 396 } | 361 } |
| 397 | 362 |
| 398 void VideoCaptureImpl::AddDelegateOnIOThread() { | |
| 399 DCHECK(io_message_loop_proxy_->BelongsToCurrentThread()); | |
| 400 message_filter_->AddDelegate(this); | |
| 401 } | |
| 402 | |
| 403 void VideoCaptureImpl::RemoveDelegateOnIOThread(base::Closure task) { | |
| 404 DCHECK(io_message_loop_proxy_->BelongsToCurrentThread()); | |
| 405 message_filter_->RemoveDelegate(this); | |
| 406 capture_message_loop_proxy_->PostTask(FROM_HERE, task); | |
| 407 } | |
| 408 | |
| 409 void VideoCaptureImpl::Send(IPC::Message* message) { | 363 void VideoCaptureImpl::Send(IPC::Message* message) { |
| 410 io_message_loop_proxy_->PostTask(FROM_HERE, | 364 io_message_loop_proxy_->PostTask(FROM_HERE, |
| 411 base::Bind(base::IgnoreResult(&VideoCaptureMessageFilter::Send), | 365 base::Bind(base::IgnoreResult(&VideoCaptureMessageFilter::Send), |
| 412 message_filter_.get(), message)); | 366 message_filter_.get(), message)); |
| 413 } | 367 } |
| 414 | 368 |
| 415 bool VideoCaptureImpl::RemoveClient( | 369 bool VideoCaptureImpl::RemoveClient( |
| 416 media::VideoCapture::EventHandler* handler, | 370 media::VideoCapture::EventHandler* handler, |
| 417 ClientInfo* clients) { | 371 ClientInfo* clients) { |
| 418 DCHECK(capture_message_loop_proxy_->BelongsToCurrentThread()); | 372 DCHECK(io_message_loop_proxy_->BelongsToCurrentThread()); |
| 419 bool found = false; | 373 bool found = false; |
| 420 | 374 |
| 421 ClientInfo::iterator it = clients->find(handler); | 375 ClientInfo::iterator it = clients->find(handler); |
| 422 if (it != clients->end()) { | 376 if (it != clients->end()) { |
| 423 handler->OnStopped(this); | 377 handler->OnStopped(this); |
| 424 handler->OnRemoved(this); | 378 handler->OnRemoved(this); |
| 425 clients->erase(it); | 379 clients->erase(it); |
| 426 found = true; | 380 found = true; |
| 427 } | 381 } |
| 428 return found; | 382 return found; |
| 429 } | 383 } |
| 430 | 384 |
| 431 } // namespace content | 385 } // namespace content |
| OLD | NEW |