| 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" |
| 11 #include "media/base/bind_to_loop.h" | 11 #include "media/base/bind_to_loop.h" |
| 12 #include "media/base/limits.h" | 12 #include "media/base/limits.h" |
| 13 | 13 |
| 14 namespace content { | 14 namespace content { |
| 15 | 15 |
| 16 class VideoCaptureImpl::ClientBuffer | 16 class VideoCaptureImpl::ClientBuffer |
| 17 : public base::RefCountedThreadSafe<ClientBuffer> { | 17 : public base::RefCountedThreadSafe<ClientBuffer> { |
| 18 public: | 18 public: |
| 19 ClientBuffer(scoped_ptr<base::SharedMemory> buffer, | 19 ClientBuffer(scoped_ptr<base::SharedMemory> buffer, |
| 20 size_t buffer_size, | 20 size_t buffer_size) |
| 21 int frame_width, | |
| 22 int frame_height, | |
| 23 int frame_stride) | |
| 24 : buffer(buffer.Pass()), | 21 : buffer(buffer.Pass()), |
| 25 buffer_size(buffer_size), | 22 buffer_size(buffer_size) {} |
| 26 frame_width(frame_width), | |
| 27 frame_height(frame_height), | |
| 28 frame_stride(frame_stride) {} | |
| 29 const scoped_ptr<base::SharedMemory> buffer; | 23 const scoped_ptr<base::SharedMemory> buffer; |
| 30 const size_t buffer_size; | 24 const size_t buffer_size; |
| 31 const int frame_width; // In pixels. | |
| 32 const int frame_height; // In pixels. | |
| 33 const int frame_stride; // In pixels. | |
| 34 | 25 |
| 35 private: | 26 private: |
| 36 friend class base::RefCountedThreadSafe<ClientBuffer>; | 27 friend class base::RefCountedThreadSafe<ClientBuffer>; |
| 37 | 28 |
| 38 virtual ~ClientBuffer() {} | 29 virtual ~ClientBuffer() {} |
| 39 | 30 |
| 40 DISALLOW_COPY_AND_ASSIGN(ClientBuffer); | 31 DISALLOW_COPY_AND_ASSIGN(ClientBuffer); |
| 41 }; | 32 }; |
| 42 | 33 |
| 43 bool VideoCaptureImpl::CaptureStarted() { | 34 bool VideoCaptureImpl::CaptureStarted() { |
| 44 return state_ == VIDEO_CAPTURE_STATE_STARTED; | 35 return state_ == VIDEO_CAPTURE_STATE_STARTED; |
| 45 } | 36 } |
| 46 | 37 |
| 47 int VideoCaptureImpl::CaptureWidth() { | |
| 48 return capture_format_.width; | |
| 49 } | |
| 50 | |
| 51 int VideoCaptureImpl::CaptureHeight() { | |
| 52 return capture_format_.height; | |
| 53 } | |
| 54 | |
| 55 int VideoCaptureImpl::CaptureFrameRate() { | 38 int VideoCaptureImpl::CaptureFrameRate() { |
| 56 return capture_format_.frame_rate; | 39 return last_frame_format_.frame_rate; |
| 57 } | 40 } |
| 58 | 41 |
| 59 VideoCaptureImpl::VideoCaptureImpl( | 42 VideoCaptureImpl::VideoCaptureImpl( |
| 60 const media::VideoCaptureSessionId id, | 43 const media::VideoCaptureSessionId session_id, |
| 61 base::MessageLoopProxy* capture_message_loop_proxy, | 44 base::MessageLoopProxy* capture_message_loop_proxy, |
| 62 VideoCaptureMessageFilter* filter) | 45 VideoCaptureMessageFilter* filter) |
| 63 : VideoCapture(), | 46 : VideoCapture(), |
| 64 message_filter_(filter), | 47 message_filter_(filter), |
| 65 capture_message_loop_proxy_(capture_message_loop_proxy), | 48 capture_message_loop_proxy_(capture_message_loop_proxy), |
| 66 io_message_loop_proxy_(ChildProcess::current()->io_message_loop_proxy()), | 49 io_message_loop_proxy_(ChildProcess::current()->io_message_loop_proxy()), |
| 67 device_id_(0), | 50 device_id_(0), |
| 51 session_id_(session_id), |
| 68 client_buffer_weak_this_factory_(this), | 52 client_buffer_weak_this_factory_(this), |
| 69 video_type_(media::PIXEL_FORMAT_I420), | |
| 70 device_info_available_(false), | |
| 71 suspended_(false), | 53 suspended_(false), |
| 72 state_(VIDEO_CAPTURE_STATE_STOPPED) { | 54 state_(VIDEO_CAPTURE_STATE_STOPPED) { |
| 73 DCHECK(filter); | 55 DCHECK(filter); |
| 74 capture_format_.session_id = id; | |
| 75 } | 56 } |
| 76 | 57 |
| 77 VideoCaptureImpl::~VideoCaptureImpl() {} | 58 VideoCaptureImpl::~VideoCaptureImpl() {} |
| 78 | 59 |
| 79 void VideoCaptureImpl::Init() { | 60 void VideoCaptureImpl::Init() { |
| 80 if (!io_message_loop_proxy_->BelongsToCurrentThread()) { | 61 if (!io_message_loop_proxy_->BelongsToCurrentThread()) { |
| 81 io_message_loop_proxy_->PostTask(FROM_HERE, | 62 io_message_loop_proxy_->PostTask(FROM_HERE, |
| 82 base::Bind(&VideoCaptureImpl::AddDelegateOnIOThread, | 63 base::Bind(&VideoCaptureImpl::AddDelegateOnIOThread, |
| 83 base::Unretained(this))); | 64 base::Unretained(this))); |
| 84 } else { | 65 } else { |
| 85 AddDelegateOnIOThread(); | 66 AddDelegateOnIOThread(); |
| 86 } | 67 } |
| 87 } | 68 } |
| 88 | 69 |
| 89 void VideoCaptureImpl::DeInit(base::Closure task) { | 70 void VideoCaptureImpl::DeInit(base::Closure task) { |
| 90 capture_message_loop_proxy_->PostTask(FROM_HERE, | 71 capture_message_loop_proxy_->PostTask(FROM_HERE, |
| 91 base::Bind(&VideoCaptureImpl::DoDeInitOnCaptureThread, | 72 base::Bind(&VideoCaptureImpl::DoDeInitOnCaptureThread, |
| 92 base::Unretained(this), task)); | 73 base::Unretained(this), task)); |
| 93 } | 74 } |
| 94 | 75 |
| 95 void VideoCaptureImpl::StartCapture( | 76 void VideoCaptureImpl::StartCapture( |
| 96 media::VideoCapture::EventHandler* handler, | 77 media::VideoCapture::EventHandler* handler, |
| 97 const media::VideoCaptureCapability& capability) { | 78 const media::VideoCaptureParams& params) { |
| 98 DCHECK_EQ(capability.color, media::PIXEL_FORMAT_I420); | |
| 99 | |
| 100 capture_message_loop_proxy_->PostTask(FROM_HERE, | 79 capture_message_loop_proxy_->PostTask(FROM_HERE, |
| 101 base::Bind(&VideoCaptureImpl::DoStartCaptureOnCaptureThread, | 80 base::Bind(&VideoCaptureImpl::DoStartCaptureOnCaptureThread, |
| 102 base::Unretained(this), handler, capability)); | 81 base::Unretained(this), handler, params)); |
| 103 } | 82 } |
| 104 | 83 |
| 105 void VideoCaptureImpl::StopCapture(media::VideoCapture::EventHandler* handler) { | 84 void VideoCaptureImpl::StopCapture(media::VideoCapture::EventHandler* handler) { |
| 106 capture_message_loop_proxy_->PostTask(FROM_HERE, | 85 capture_message_loop_proxy_->PostTask(FROM_HERE, |
| 107 base::Bind(&VideoCaptureImpl::DoStopCaptureOnCaptureThread, | 86 base::Bind(&VideoCaptureImpl::DoStopCaptureOnCaptureThread, |
| 108 base::Unretained(this), handler)); | 87 base::Unretained(this), handler)); |
| 109 } | 88 } |
| 110 | 89 |
| 111 void VideoCaptureImpl::OnBufferCreated( | 90 void VideoCaptureImpl::OnBufferCreated( |
| 112 base::SharedMemoryHandle handle, | 91 base::SharedMemoryHandle handle, |
| 113 int length, int buffer_id) { | 92 int length, int buffer_id) { |
| 114 capture_message_loop_proxy_->PostTask(FROM_HERE, | 93 capture_message_loop_proxy_->PostTask(FROM_HERE, |
| 115 base::Bind(&VideoCaptureImpl::DoBufferCreatedOnCaptureThread, | 94 base::Bind(&VideoCaptureImpl::DoBufferCreatedOnCaptureThread, |
| 116 base::Unretained(this), handle, length, buffer_id)); | 95 base::Unretained(this), handle, length, buffer_id)); |
| 117 } | 96 } |
| 118 | 97 |
| 119 void VideoCaptureImpl::OnBufferReceived(int buffer_id, base::Time timestamp) { | 98 void VideoCaptureImpl::OnBufferDestroyed(int buffer_id) { |
| 99 capture_message_loop_proxy_->PostTask(FROM_HERE, |
| 100 base::Bind(&VideoCaptureImpl::DoBufferDestroyedOnCaptureThread, |
| 101 base::Unretained(this), buffer_id)); |
| 102 } |
| 103 |
| 104 void VideoCaptureImpl::OnBufferReceived( |
| 105 int buffer_id, |
| 106 base::Time timestamp, |
| 107 const media::VideoCaptureFormat& format) { |
| 120 capture_message_loop_proxy_->PostTask(FROM_HERE, | 108 capture_message_loop_proxy_->PostTask(FROM_HERE, |
| 121 base::Bind(&VideoCaptureImpl::DoBufferReceivedOnCaptureThread, | 109 base::Bind(&VideoCaptureImpl::DoBufferReceivedOnCaptureThread, |
| 122 base::Unretained(this), buffer_id, timestamp)); | 110 base::Unretained(this), buffer_id, timestamp, format)); |
| 123 } | 111 } |
| 124 | 112 |
| 125 void VideoCaptureImpl::OnStateChanged(VideoCaptureState state) { | 113 void VideoCaptureImpl::OnStateChanged(VideoCaptureState state) { |
| 126 capture_message_loop_proxy_->PostTask(FROM_HERE, | 114 capture_message_loop_proxy_->PostTask(FROM_HERE, |
| 127 base::Bind(&VideoCaptureImpl::DoStateChangedOnCaptureThread, | 115 base::Bind(&VideoCaptureImpl::DoStateChangedOnCaptureThread, |
| 128 base::Unretained(this), state)); | 116 base::Unretained(this), state)); |
| 129 } | 117 } |
| 130 | 118 |
| 131 void VideoCaptureImpl::OnDeviceInfoReceived( | |
| 132 const media::VideoCaptureParams& device_info) { | |
| 133 capture_message_loop_proxy_->PostTask(FROM_HERE, | |
| 134 base::Bind(&VideoCaptureImpl::DoDeviceInfoReceivedOnCaptureThread, | |
| 135 base::Unretained(this), device_info)); | |
| 136 } | |
| 137 | |
| 138 void VideoCaptureImpl::OnDeviceInfoChanged( | |
| 139 const media::VideoCaptureParams& device_info) { | |
| 140 capture_message_loop_proxy_->PostTask(FROM_HERE, | |
| 141 base::Bind(&VideoCaptureImpl::DoDeviceInfoChangedOnCaptureThread, | |
| 142 base::Unretained(this), device_info)); | |
| 143 } | |
| 144 | |
| 145 void VideoCaptureImpl::OnDelegateAdded(int32 device_id) { | 119 void VideoCaptureImpl::OnDelegateAdded(int32 device_id) { |
| 146 capture_message_loop_proxy_->PostTask(FROM_HERE, | 120 capture_message_loop_proxy_->PostTask(FROM_HERE, |
| 147 base::Bind(&VideoCaptureImpl::DoDelegateAddedOnCaptureThread, | 121 base::Bind(&VideoCaptureImpl::DoDelegateAddedOnCaptureThread, |
| 148 base::Unretained(this), device_id)); | 122 base::Unretained(this), device_id)); |
| 149 } | 123 } |
| 150 | 124 |
| 151 void VideoCaptureImpl::SuspendCapture(bool suspend) { | 125 void VideoCaptureImpl::SuspendCapture(bool suspend) { |
| 152 capture_message_loop_proxy_->PostTask(FROM_HERE, | 126 capture_message_loop_proxy_->PostTask(FROM_HERE, |
| 153 base::Bind(&VideoCaptureImpl::DoSuspendCaptureOnCaptureThread, | 127 base::Bind(&VideoCaptureImpl::DoSuspendCaptureOnCaptureThread, |
| 154 base::Unretained(this), suspend)); | 128 base::Unretained(this), suspend)); |
| 155 } | 129 } |
| 156 | 130 |
| 157 void VideoCaptureImpl::DoDeInitOnCaptureThread(base::Closure task) { | 131 void VideoCaptureImpl::DoDeInitOnCaptureThread(base::Closure task) { |
| 158 if (state_ == VIDEO_CAPTURE_STATE_STARTED) | 132 if (state_ == VIDEO_CAPTURE_STATE_STARTED) |
| 159 Send(new VideoCaptureHostMsg_Stop(device_id_)); | 133 Send(new VideoCaptureHostMsg_Stop(device_id_)); |
| 160 | 134 |
| 161 io_message_loop_proxy_->PostTask(FROM_HERE, | 135 io_message_loop_proxy_->PostTask(FROM_HERE, |
| 162 base::Bind(&VideoCaptureImpl::RemoveDelegateOnIOThread, | 136 base::Bind(&VideoCaptureImpl::RemoveDelegateOnIOThread, |
| 163 base::Unretained(this), task)); | 137 base::Unretained(this), task)); |
| 164 } | 138 } |
| 165 | 139 |
| 166 void VideoCaptureImpl::DoStartCaptureOnCaptureThread( | 140 void VideoCaptureImpl::DoStartCaptureOnCaptureThread( |
| 167 media::VideoCapture::EventHandler* handler, | 141 media::VideoCapture::EventHandler* handler, |
| 168 const media::VideoCaptureCapability& capability) { | 142 const media::VideoCaptureParams& params) { |
| 169 DCHECK(capture_message_loop_proxy_->BelongsToCurrentThread()); | 143 DCHECK(capture_message_loop_proxy_->BelongsToCurrentThread()); |
| 170 | 144 |
| 171 if (state_ == VIDEO_CAPTURE_STATE_ERROR) { | 145 if (state_ == VIDEO_CAPTURE_STATE_ERROR) { |
| 172 handler->OnError(this, 1); | 146 handler->OnError(this, 1); |
| 173 handler->OnRemoved(this); | 147 handler->OnRemoved(this); |
| 174 } else if ((clients_pending_on_filter_.find(handler) != | 148 } else if ((clients_pending_on_filter_.find(handler) != |
| 175 clients_pending_on_filter_.end()) || | 149 clients_pending_on_filter_.end()) || |
| 176 (clients_pending_on_restart_.find(handler) != | 150 (clients_pending_on_restart_.find(handler) != |
| 177 clients_pending_on_restart_.end()) || | 151 clients_pending_on_restart_.end()) || |
| 178 clients_.find(handler) != clients_.end() ) { | 152 clients_.find(handler) != clients_.end() ) { |
| 179 // This client has started. | 153 // This client has started. |
| 180 } else if (!device_id_) { | 154 } else if (!device_id_) { |
| 181 clients_pending_on_filter_[handler] = capability; | 155 clients_pending_on_filter_[handler] = params; |
| 182 } else { | 156 } else { |
| 183 handler->OnStarted(this); | 157 handler->OnStarted(this); |
| 184 if (state_ == VIDEO_CAPTURE_STATE_STARTED) { | 158 if (state_ == VIDEO_CAPTURE_STATE_STARTED) { |
| 185 // TODO(wjia): Temporarily disable restarting till client supports | 159 clients_[handler] = params; |
| 186 // resampling. | |
| 187 #if 0 | |
| 188 if (capability.width > capture_format_.width || | |
| 189 capability.height > capture_format_.height) { | |
| 190 StopDevice(); | |
| 191 DVLOG(1) << "StartCapture: Got client with higher resolution (" | |
| 192 << capability.width << ", " << capability.height << ") " | |
| 193 << "after started, try to restart."; | |
| 194 clients_pending_on_restart_[handler] = capability; | |
| 195 } else { | |
| 196 #endif | |
| 197 { | |
| 198 if (device_info_available_) { | |
| 199 handler->OnDeviceInfoReceived(this, device_info_); | |
| 200 } | |
| 201 | |
| 202 clients_[handler] = capability; | |
| 203 } | |
| 204 } else if (state_ == VIDEO_CAPTURE_STATE_STOPPING) { | 160 } else if (state_ == VIDEO_CAPTURE_STATE_STOPPING) { |
| 205 clients_pending_on_restart_[handler] = capability; | 161 clients_pending_on_restart_[handler] = params; |
| 206 DVLOG(1) << "StartCapture: Got new resolution (" | 162 DVLOG(1) << "StartCapture: Got new resolution (" |
| 207 << capability.width << ", " << capability.height << ") " | 163 << params.requested_format.width << ", " |
| 164 << params.requested_format.height << ") " |
| 208 << ", during stopping."; | 165 << ", during stopping."; |
| 209 } else { | 166 } else { |
| 210 clients_[handler] = capability; | 167 DCHECK_EQ(params.session_id, 0); |
| 168 clients_[handler] = params; |
| 211 DCHECK_EQ(1ul, clients_.size()); | 169 DCHECK_EQ(1ul, clients_.size()); |
| 212 video_type_ = capability.color; | 170 params_ = params; |
| 213 int session_id = capture_format_.session_id; | 171 params_.session_id = session_id_; |
| 214 DCHECK_EQ(capability.session_id, 0); | 172 if (params_.requested_format.frame_rate > |
| 215 capture_format_ = capability; | 173 media::limits::kMaxFramesPerSecond) { |
| 216 capture_format_.session_id = session_id; | 174 params_.requested_format.frame_rate = |
| 217 if (capture_format_.frame_rate > media::limits::kMaxFramesPerSecond) | 175 media::limits::kMaxFramesPerSecond; |
| 218 capture_format_.frame_rate = media::limits::kMaxFramesPerSecond; | 176 } |
| 219 DVLOG(1) << "StartCapture: starting with first resolution (" | 177 DVLOG(1) << "StartCapture: starting with first resolution (" |
| 220 << capture_format_.width << "," << capture_format_.height << ")"; | 178 << params_.requested_format.width << "," |
| 179 << params_.requested_format.height << ")"; |
| 221 | 180 |
| 222 StartCaptureInternal(); | 181 StartCaptureInternal(); |
| 223 } | 182 } |
| 224 } | 183 } |
| 225 } | 184 } |
| 226 | 185 |
| 227 void VideoCaptureImpl::DoStopCaptureOnCaptureThread( | 186 void VideoCaptureImpl::DoStopCaptureOnCaptureThread( |
| 228 media::VideoCapture::EventHandler* handler) { | 187 media::VideoCapture::EventHandler* handler) { |
| 229 DCHECK(capture_message_loop_proxy_->BelongsToCurrentThread()); | 188 DCHECK(capture_message_loop_proxy_->BelongsToCurrentThread()); |
| 230 | 189 |
| (...skipping 17 matching lines...) Expand all Loading... |
| 248 int length, int buffer_id) { | 207 int length, int buffer_id) { |
| 249 DCHECK(capture_message_loop_proxy_->BelongsToCurrentThread()); | 208 DCHECK(capture_message_loop_proxy_->BelongsToCurrentThread()); |
| 250 | 209 |
| 251 // In case client calls StopCapture before the arrival of created buffer, | 210 // In case client calls StopCapture before the arrival of created buffer, |
| 252 // just close this buffer and return. | 211 // just close this buffer and return. |
| 253 if (state_ != VIDEO_CAPTURE_STATE_STARTED) { | 212 if (state_ != VIDEO_CAPTURE_STATE_STARTED) { |
| 254 base::SharedMemory::CloseHandle(handle); | 213 base::SharedMemory::CloseHandle(handle); |
| 255 return; | 214 return; |
| 256 } | 215 } |
| 257 | 216 |
| 258 DCHECK(device_info_available_); | |
| 259 | |
| 260 scoped_ptr<base::SharedMemory> shm(new base::SharedMemory(handle, false)); | 217 scoped_ptr<base::SharedMemory> shm(new base::SharedMemory(handle, false)); |
| 261 if (!shm->Map(length)) { | 218 if (!shm->Map(length)) { |
| 262 DLOG(ERROR) << "DoBufferCreatedOnCaptureThread: Map() failed."; | 219 DLOG(ERROR) << "DoBufferCreatedOnCaptureThread: Map() failed."; |
| 263 return; | 220 return; |
| 264 } | 221 } |
| 265 | 222 |
| 266 bool inserted = | 223 bool inserted = |
| 267 client_buffers_.insert(std::make_pair( | 224 client_buffers_.insert(std::make_pair( |
| 268 buffer_id, | 225 buffer_id, |
| 269 new ClientBuffer(shm.Pass(), | 226 new ClientBuffer(shm.Pass(), |
| 270 length, | 227 length))).second; |
| 271 device_info_.width, | |
| 272 device_info_.height, | |
| 273 device_info_.width))).second; | |
| 274 DCHECK(inserted); | 228 DCHECK(inserted); |
| 275 } | 229 } |
| 276 | 230 |
| 231 void VideoCaptureImpl::DoBufferDestroyedOnCaptureThread(int buffer_id) { |
| 232 DCHECK(capture_message_loop_proxy_->BelongsToCurrentThread()); |
| 233 |
| 234 ClientBufferMap::iterator iter = client_buffers_.find(buffer_id); |
| 235 if (iter == client_buffers_.end()) |
| 236 return; |
| 237 |
| 238 DCHECK(!iter->second || iter->second->HasOneRef()) |
| 239 << "Instructed to delete buffer we are still using."; |
| 240 client_buffers_.erase(iter); |
| 241 } |
| 242 |
| 277 void VideoCaptureImpl::DoBufferReceivedOnCaptureThread( | 243 void VideoCaptureImpl::DoBufferReceivedOnCaptureThread( |
| 278 int buffer_id, base::Time timestamp) { | 244 int buffer_id, |
| 245 base::Time timestamp, |
| 246 const media::VideoCaptureFormat& format) { |
| 279 DCHECK(capture_message_loop_proxy_->BelongsToCurrentThread()); | 247 DCHECK(capture_message_loop_proxy_->BelongsToCurrentThread()); |
| 280 | 248 |
| 281 if (state_ != VIDEO_CAPTURE_STATE_STARTED || suspended_) { | 249 if (state_ != VIDEO_CAPTURE_STATE_STARTED || suspended_) { |
| 282 Send(new VideoCaptureHostMsg_BufferReady(device_id_, buffer_id)); | 250 Send(new VideoCaptureHostMsg_BufferReady(device_id_, buffer_id)); |
| 283 return; | 251 return; |
| 284 } | 252 } |
| 285 | 253 |
| 254 last_frame_format_ = format; |
| 255 gfx::Size size(format.width, format.height); |
| 256 |
| 286 ClientBufferMap::iterator iter = client_buffers_.find(buffer_id); | 257 ClientBufferMap::iterator iter = client_buffers_.find(buffer_id); |
| 287 DCHECK(iter != client_buffers_.end()); | 258 DCHECK(iter != client_buffers_.end()); |
| 288 scoped_refptr<ClientBuffer> buffer = iter->second; | 259 scoped_refptr<ClientBuffer> buffer = iter->second; |
| 289 scoped_refptr<media::VideoFrame> frame = | 260 scoped_refptr<media::VideoFrame> frame = |
| 290 media::VideoFrame::WrapExternalSharedMemory( | 261 media::VideoFrame::WrapExternalSharedMemory( |
| 291 media::VideoFrame::I420, | 262 media::VideoFrame::I420, |
| 292 gfx::Size(buffer->frame_stride, buffer->frame_height), | 263 size, gfx::Rect(size), size, |
| 293 gfx::Rect(0, 0, buffer->frame_width, buffer->frame_height), | |
| 294 gfx::Size(buffer->frame_width, buffer->frame_height), | |
| 295 reinterpret_cast<uint8*>(buffer->buffer->memory()), | 264 reinterpret_cast<uint8*>(buffer->buffer->memory()), |
| 296 buffer->buffer_size, | 265 buffer->buffer_size, |
| 297 buffer->buffer->handle(), | 266 buffer->buffer->handle(), |
| 298 // TODO(sheu): convert VideoCaptureMessageFilter::Delegate to use | 267 // TODO(sheu): convert VideoCaptureMessageFilter::Delegate to use |
| 299 // base::TimeTicks instead of base::Time. http://crbug.com/249215 | 268 // base::TimeTicks instead of base::Time. http://crbug.com/249215 |
| 300 timestamp - base::Time::UnixEpoch(), | 269 timestamp - base::Time::UnixEpoch(), |
| 301 media::BindToLoop( | 270 media::BindToLoop( |
| 302 capture_message_loop_proxy_, | 271 capture_message_loop_proxy_, |
| 303 base::Bind( | 272 base::Bind( |
| 304 &VideoCaptureImpl::DoClientBufferFinishedOnCaptureThread, | 273 &VideoCaptureImpl::DoClientBufferFinishedOnCaptureThread, |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 355 it->first->OnRemoved(this); | 324 it->first->OnRemoved(this); |
| 356 } | 325 } |
| 357 clients_.clear(); | 326 clients_.clear(); |
| 358 state_ = VIDEO_CAPTURE_STATE_ENDED; | 327 state_ = VIDEO_CAPTURE_STATE_ENDED; |
| 359 break; | 328 break; |
| 360 default: | 329 default: |
| 361 break; | 330 break; |
| 362 } | 331 } |
| 363 } | 332 } |
| 364 | 333 |
| 365 void VideoCaptureImpl::DoDeviceInfoReceivedOnCaptureThread( | |
| 366 const media::VideoCaptureParams& device_info) { | |
| 367 DCHECK(capture_message_loop_proxy_->BelongsToCurrentThread()); | |
| 368 DCHECK(client_buffers_.empty()); | |
| 369 | |
| 370 device_info_ = device_info; | |
| 371 device_info_available_ = true; | |
| 372 for (ClientInfo::iterator it = clients_.begin(); it != clients_.end(); ++it) { | |
| 373 it->first->OnDeviceInfoReceived(this, device_info); | |
| 374 } | |
| 375 } | |
| 376 | |
| 377 void VideoCaptureImpl::DoDeviceInfoChangedOnCaptureThread( | |
| 378 const media::VideoCaptureParams& device_info) { | |
| 379 DCHECK(capture_message_loop_proxy_->BelongsToCurrentThread()); | |
| 380 | |
| 381 for (ClientInfo::iterator it = clients_.begin(); it != clients_.end(); ++it) { | |
| 382 it->first->OnDeviceInfoChanged(this, device_info); | |
| 383 } | |
| 384 } | |
| 385 | |
| 386 void VideoCaptureImpl::DoDelegateAddedOnCaptureThread(int32 device_id) { | 334 void VideoCaptureImpl::DoDelegateAddedOnCaptureThread(int32 device_id) { |
| 387 DVLOG(1) << "DoDelegateAdded: device_id " << device_id; | 335 DVLOG(1) << "DoDelegateAdded: device_id " << device_id; |
| 388 DCHECK(capture_message_loop_proxy_->BelongsToCurrentThread()); | 336 DCHECK(capture_message_loop_proxy_->BelongsToCurrentThread()); |
| 389 | 337 |
| 390 device_id_ = device_id; | 338 device_id_ = device_id; |
| 391 for (ClientInfo::iterator it = clients_pending_on_filter_.begin(); | 339 for (ClientInfo::iterator it = clients_pending_on_filter_.begin(); |
| 392 it != clients_pending_on_filter_.end(); ) { | 340 it != clients_pending_on_filter_.end(); ) { |
| 393 media::VideoCapture::EventHandler* handler = it->first; | 341 media::VideoCapture::EventHandler* handler = it->first; |
| 394 const media::VideoCaptureCapability capability = it->second; | 342 const media::VideoCaptureParams params = it->second; |
| 395 clients_pending_on_filter_.erase(it++); | 343 clients_pending_on_filter_.erase(it++); |
| 396 StartCapture(handler, capability); | 344 StartCapture(handler, params); |
| 397 } | 345 } |
| 398 } | 346 } |
| 399 | 347 |
| 400 void VideoCaptureImpl::DoSuspendCaptureOnCaptureThread(bool suspend) { | 348 void VideoCaptureImpl::DoSuspendCaptureOnCaptureThread(bool suspend) { |
| 401 DVLOG(1) << "DoSuspendCapture: suspend " << (suspend ? "yes" : "no"); | 349 DVLOG(1) << "DoSuspendCapture: suspend " << (suspend ? "yes" : "no"); |
| 402 DCHECK(capture_message_loop_proxy_->BelongsToCurrentThread()); | 350 DCHECK(capture_message_loop_proxy_->BelongsToCurrentThread()); |
| 403 | 351 |
| 404 suspended_ = suspend; | 352 suspended_ = suspend; |
| 405 } | 353 } |
| 406 | 354 |
| 407 void VideoCaptureImpl::StopDevice() { | 355 void VideoCaptureImpl::StopDevice() { |
| 408 DCHECK(capture_message_loop_proxy_->BelongsToCurrentThread()); | 356 DCHECK(capture_message_loop_proxy_->BelongsToCurrentThread()); |
| 409 | 357 |
| 410 device_info_available_ = false; | |
| 411 if (state_ == VIDEO_CAPTURE_STATE_STARTED) { | 358 if (state_ == VIDEO_CAPTURE_STATE_STARTED) { |
| 412 state_ = VIDEO_CAPTURE_STATE_STOPPING; | 359 state_ = VIDEO_CAPTURE_STATE_STOPPING; |
| 413 Send(new VideoCaptureHostMsg_Stop(device_id_)); | 360 Send(new VideoCaptureHostMsg_Stop(device_id_)); |
| 414 capture_format_.width = capture_format_.height = 0; | 361 params_.requested_format.width = params_.requested_format.height = 0; |
| 415 } | 362 } |
| 416 } | 363 } |
| 417 | 364 |
| 418 void VideoCaptureImpl::RestartCapture() { | 365 void VideoCaptureImpl::RestartCapture() { |
| 419 DCHECK(capture_message_loop_proxy_->BelongsToCurrentThread()); | 366 DCHECK(capture_message_loop_proxy_->BelongsToCurrentThread()); |
| 420 DCHECK_EQ(state_, VIDEO_CAPTURE_STATE_STOPPED); | 367 DCHECK_EQ(state_, VIDEO_CAPTURE_STATE_STOPPED); |
| 421 | 368 |
| 422 int width = 0; | 369 int width = 0; |
| 423 int height = 0; | 370 int height = 0; |
| 424 for (ClientInfo::iterator it = clients_.begin(); | 371 for (ClientInfo::iterator it = clients_.begin(); |
| 425 it != clients_.end(); ++it) { | 372 it != clients_.end(); ++it) { |
| 426 width = std::max(width, it->second.width); | 373 width = std::max(width, it->second.requested_format.width); |
| 427 height = std::max(height, it->second.height); | 374 height = std::max(height, it->second.requested_format.height); |
| 428 } | 375 } |
| 429 for (ClientInfo::iterator it = clients_pending_on_restart_.begin(); | 376 for (ClientInfo::iterator it = clients_pending_on_restart_.begin(); |
| 430 it != clients_pending_on_restart_.end(); ) { | 377 it != clients_pending_on_restart_.end(); ) { |
| 431 width = std::max(width, it->second.width); | 378 width = std::max(width, it->second.requested_format.width); |
| 432 height = std::max(height, it->second.height); | 379 height = std::max(height, it->second.requested_format.height); |
| 433 clients_[it->first] = it->second; | 380 clients_[it->first] = it->second; |
| 434 clients_pending_on_restart_.erase(it++); | 381 clients_pending_on_restart_.erase(it++); |
| 435 } | 382 } |
| 436 capture_format_.width = width; | 383 params_.requested_format.width = width; |
| 437 capture_format_.height = height; | 384 params_.requested_format.height = height; |
| 438 DVLOG(1) << "RestartCapture, " << capture_format_.width << ", " | 385 DVLOG(1) << "RestartCapture, " << params_.requested_format.width << ", " |
| 439 << capture_format_.height; | 386 << params_.requested_format.height; |
| 440 StartCaptureInternal(); | 387 StartCaptureInternal(); |
| 441 } | 388 } |
| 442 | 389 |
| 443 void VideoCaptureImpl::StartCaptureInternal() { | 390 void VideoCaptureImpl::StartCaptureInternal() { |
| 444 DCHECK(capture_message_loop_proxy_->BelongsToCurrentThread()); | 391 DCHECK(capture_message_loop_proxy_->BelongsToCurrentThread()); |
| 445 DCHECK(device_id_); | 392 DCHECK(device_id_); |
| 446 | 393 |
| 447 media::VideoCaptureParams capability_as_params_copy; | 394 Send(new VideoCaptureHostMsg_Start(device_id_, params_)); |
| 448 capability_as_params_copy.width = capture_format_.width; | |
| 449 capability_as_params_copy.height = capture_format_.height; | |
| 450 capability_as_params_copy.frame_rate = capture_format_.frame_rate; | |
| 451 capability_as_params_copy.session_id = capture_format_.session_id; | |
| 452 capability_as_params_copy.frame_size_type = capture_format_.frame_size_type; | |
| 453 Send(new VideoCaptureHostMsg_Start(device_id_, capability_as_params_copy)); | |
| 454 state_ = VIDEO_CAPTURE_STATE_STARTED; | 395 state_ = VIDEO_CAPTURE_STATE_STARTED; |
| 455 } | 396 } |
| 456 | 397 |
| 457 void VideoCaptureImpl::AddDelegateOnIOThread() { | 398 void VideoCaptureImpl::AddDelegateOnIOThread() { |
| 458 DCHECK(io_message_loop_proxy_->BelongsToCurrentThread()); | 399 DCHECK(io_message_loop_proxy_->BelongsToCurrentThread()); |
| 459 message_filter_->AddDelegate(this); | 400 message_filter_->AddDelegate(this); |
| 460 } | 401 } |
| 461 | 402 |
| 462 void VideoCaptureImpl::RemoveDelegateOnIOThread(base::Closure task) { | 403 void VideoCaptureImpl::RemoveDelegateOnIOThread(base::Closure task) { |
| 463 DCHECK(io_message_loop_proxy_->BelongsToCurrentThread()); | 404 DCHECK(io_message_loop_proxy_->BelongsToCurrentThread()); |
| (...skipping 17 matching lines...) Expand all Loading... |
| 481 if (it != clients->end()) { | 422 if (it != clients->end()) { |
| 482 handler->OnStopped(this); | 423 handler->OnStopped(this); |
| 483 handler->OnRemoved(this); | 424 handler->OnRemoved(this); |
| 484 clients->erase(it); | 425 clients->erase(it); |
| 485 found = true; | 426 found = true; |
| 486 } | 427 } |
| 487 return found; | 428 return found; |
| 488 } | 429 } |
| 489 | 430 |
| 490 } // namespace content | 431 } // namespace content |
| OLD | NEW |