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