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 |