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