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