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 14 matching lines...) Expand all Loading... | |
25 const size_t buffer_size; | 25 const size_t buffer_size; |
26 | 26 |
27 private: | 27 private: |
28 friend class base::RefCountedThreadSafe<ClientBuffer>; | 28 friend class base::RefCountedThreadSafe<ClientBuffer>; |
29 | 29 |
30 virtual ~ClientBuffer() {} | 30 virtual ~ClientBuffer() {} |
31 | 31 |
32 DISALLOW_COPY_AND_ASSIGN(ClientBuffer); | 32 DISALLOW_COPY_AND_ASSIGN(ClientBuffer); |
33 }; | 33 }; |
34 | 34 |
35 bool VideoCaptureImpl::CaptureStarted() { | 35 VideoCaptureImpl::ClientInfo::ClientInfo() {} |
36 return state_ == VIDEO_CAPTURE_STATE_STARTED; | 36 VideoCaptureImpl::ClientInfo::~ClientInfo() {} |
37 } | |
38 | 37 |
39 int VideoCaptureImpl::CaptureFrameRate() { | 38 int VideoCaptureImpl::CaptureFrameRate() { |
40 return last_frame_format_.frame_rate; | 39 return last_frame_format_.frame_rate; |
41 } | 40 } |
42 | 41 |
43 VideoCaptureImpl::VideoCaptureImpl( | 42 VideoCaptureImpl::VideoCaptureImpl( |
44 const media::VideoCaptureSessionId session_id, | 43 const media::VideoCaptureSessionId session_id, |
45 VideoCaptureMessageFilter* filter) | 44 VideoCaptureMessageFilter* filter) |
46 : VideoCapture(), | 45 : message_filter_(filter), |
47 message_filter_(filter), | |
48 io_message_loop_proxy_(ChildProcess::current()->io_message_loop_proxy()), | |
49 device_id_(0), | 46 device_id_(0), |
50 session_id_(session_id), | 47 session_id_(session_id), |
51 suspended_(false), | 48 suspended_(false), |
52 state_(VIDEO_CAPTURE_STATE_STOPPED), | 49 state_(VIDEO_CAPTURE_STATE_STOPPED), |
53 weak_factory_(this) { | 50 weak_factory_(this) { |
54 DCHECK(filter); | 51 DCHECK(filter); |
52 thread_checker_.DetachFromThread(); | |
55 } | 53 } |
56 | 54 |
57 VideoCaptureImpl::~VideoCaptureImpl() {} | 55 VideoCaptureImpl::~VideoCaptureImpl() { |
56 DCHECK(thread_checker_.CalledOnValidThread()); | |
57 } | |
58 | 58 |
59 void VideoCaptureImpl::Init() { | 59 void VideoCaptureImpl::Init() { |
60 io_message_loop_proxy_->PostTask(FROM_HERE, | 60 DCHECK(thread_checker_.CalledOnValidThread()); |
61 base::Bind(&VideoCaptureImpl::InitOnIOThread, | 61 message_filter_->AddDelegate(this); |
62 base::Unretained(this))); | |
63 } | 62 } |
64 | 63 |
65 void VideoCaptureImpl::DeInit(base::Closure done_cb) { | 64 void VideoCaptureImpl::DeInit() { |
66 io_message_loop_proxy_->PostTask(FROM_HERE, | 65 DCHECK(thread_checker_.CalledOnValidThread()); |
67 base::Bind(&VideoCaptureImpl::DeInitOnIOThread, | 66 if (state_ == VIDEO_CAPTURE_STATE_STARTED) |
68 base::Unretained(this), | 67 Send(new VideoCaptureHostMsg_Stop(device_id_)); |
69 done_cb)); | 68 message_filter_->RemoveDelegate(this); |
70 } | 69 } |
71 | 70 |
72 void VideoCaptureImpl::SuspendCapture(bool suspend) { | 71 void VideoCaptureImpl::SuspendCapture(bool suspend) { |
73 io_message_loop_proxy_->PostTask(FROM_HERE, | 72 DCHECK(thread_checker_.CalledOnValidThread()); |
74 base::Bind(&VideoCaptureImpl::SuspendCaptureOnIOThread, | 73 suspended_ = suspend; |
75 base::Unretained(this), | |
76 suspend)); | |
77 } | 74 } |
78 | 75 |
79 void VideoCaptureImpl::StartCapture( | 76 void VideoCaptureImpl::StartCapture( |
80 media::VideoCapture::EventHandler* handler, | 77 int client_id, |
81 const media::VideoCaptureParams& params) { | 78 const media::VideoCaptureParams& params, |
82 io_message_loop_proxy_->PostTask(FROM_HERE, | 79 const VideoCaptureStateUpdateCB& state_update_cb, |
83 base::Bind(&VideoCaptureImpl::StartCaptureOnIOThread, | 80 const VideoCaptureDeliverFrameCB& deliver_frame_cb) { |
84 base::Unretained(this), handler, params)); | 81 DCHECK(thread_checker_.CalledOnValidThread()); |
85 } | 82 ClientInfo client_info; |
83 client_info.params = params; | |
84 client_info.state_update_cb = state_update_cb; | |
85 client_info.deliver_frame_cb = deliver_frame_cb; | |
86 | 86 |
87 void VideoCaptureImpl::StopCapture( | |
88 media::VideoCapture::EventHandler* handler) { | |
89 io_message_loop_proxy_->PostTask(FROM_HERE, | |
90 base::Bind(&VideoCaptureImpl::StopCaptureOnIOThread, | |
91 base::Unretained(this), handler)); | |
92 } | |
93 | |
94 void VideoCaptureImpl::GetDeviceSupportedFormats( | |
95 const DeviceFormatsCallback& callback) { | |
96 DCHECK(!callback.is_null()); | |
97 io_message_loop_proxy_->PostTask(FROM_HERE, | |
98 base::Bind(&VideoCaptureImpl::GetDeviceSupportedFormatsOnIOThread, | |
99 base::Unretained(this), media::BindToCurrentLoop(callback))); | |
100 } | |
101 | |
102 void VideoCaptureImpl::GetDeviceFormatsInUse( | |
103 const DeviceFormatsInUseCallback& callback) { | |
104 DCHECK(!callback.is_null()); | |
105 io_message_loop_proxy_->PostTask(FROM_HERE, | |
106 base::Bind(&VideoCaptureImpl::GetDeviceFormatsInUseOnIOThread, | |
107 base::Unretained(this), media::BindToCurrentLoop(callback))); | |
108 } | |
109 | |
110 void VideoCaptureImpl::InitOnIOThread() { | |
111 DCHECK(io_message_loop_proxy_->BelongsToCurrentThread()); | |
112 message_filter_->AddDelegate(this); | |
113 } | |
114 | |
115 void VideoCaptureImpl::DeInitOnIOThread(base::Closure done_cb) { | |
116 DCHECK(io_message_loop_proxy_->BelongsToCurrentThread()); | |
117 if (state_ == VIDEO_CAPTURE_STATE_STARTED) | |
118 Send(new VideoCaptureHostMsg_Stop(device_id_)); | |
119 message_filter_->RemoveDelegate(this); | |
120 done_cb.Run(); | |
121 } | |
122 | |
123 void VideoCaptureImpl::SuspendCaptureOnIOThread(bool suspend) { | |
124 DCHECK(io_message_loop_proxy_->BelongsToCurrentThread()); | |
125 suspended_ = suspend; | |
126 } | |
127 | |
128 void VideoCaptureImpl::StartCaptureOnIOThread( | |
129 media::VideoCapture::EventHandler* handler, | |
130 const media::VideoCaptureParams& params) { | |
131 DCHECK(io_message_loop_proxy_->BelongsToCurrentThread()); | |
132 if (state_ == VIDEO_CAPTURE_STATE_ERROR) { | 87 if (state_ == VIDEO_CAPTURE_STATE_ERROR) { |
133 handler->OnError(this, 1); | 88 state_update_cb.Run(VIDEO_CAPTURE_STATE_ERROR); |
134 handler->OnRemoved(this); | 89 } else if ((clients_pending_on_filter_.find(client_id) != |
Ami GONE FROM CHROMIUM
2014/04/21 23:42:53
map_.find(foo) != map_.end()
is shorter to write a
Alpha Left Google
2014/04/23 18:48:33
Done.
| |
135 } else if ((clients_pending_on_filter_.find(handler) != | |
136 clients_pending_on_filter_.end()) || | 90 clients_pending_on_filter_.end()) || |
137 (clients_pending_on_restart_.find(handler) != | 91 (clients_pending_on_restart_.find(client_id) != |
138 clients_pending_on_restart_.end()) || | 92 clients_pending_on_restart_.end()) || |
139 clients_.find(handler) != clients_.end() ) { | 93 clients_.find(client_id) != clients_.end() ) { |
140 // This client has started. | 94 // This client has started. |
Ami GONE FROM CHROMIUM
2014/04/21 23:42:53
what about the callbacks? This seems like it shou
Alpha Left Google
2014/04/23 18:48:33
Done.
| |
141 } else if (!device_id_) { | 95 } else if (!device_id_) { |
142 clients_pending_on_filter_[handler] = params; | 96 clients_pending_on_filter_[client_id] = client_info; |
143 } else { | 97 } else { |
144 handler->OnStarted(this); | 98 // Note: |state_| might not be started at this point. But we tell |
99 // client that we have started. | |
100 state_update_cb.Run(VIDEO_CAPTURE_STATE_STARTED); | |
145 if (state_ == VIDEO_CAPTURE_STATE_STARTED) { | 101 if (state_ == VIDEO_CAPTURE_STATE_STARTED) { |
146 clients_[handler] = params; | 102 clients_[client_id] = client_info; |
147 // TODO(sheu): Allowing resolution change will require that all | 103 // TODO(sheu): Allowing resolution change will require that all |
148 // outstanding clients of a capture session support resolution change. | 104 // outstanding clients of a capture session support resolution change. |
149 DCHECK_EQ(params_.allow_resolution_change, | 105 DCHECK_EQ(params_.allow_resolution_change, |
150 params.allow_resolution_change); | 106 params.allow_resolution_change); |
151 } else if (state_ == VIDEO_CAPTURE_STATE_STOPPING) { | 107 } else if (state_ == VIDEO_CAPTURE_STATE_STOPPING) { |
152 clients_pending_on_restart_[handler] = params; | 108 clients_pending_on_restart_[client_id] = client_info; |
153 DVLOG(1) << "StartCapture: Got new resolution " | 109 DVLOG(1) << "StartCapture: Got new resolution " |
154 << params.requested_format.frame_size.ToString() | 110 << params.requested_format.frame_size.ToString() |
155 << " during stopping."; | 111 << " during stopping."; |
156 } else { | 112 } else { |
157 clients_[handler] = params; | 113 clients_[client_id] = client_info; |
158 DCHECK_EQ(1ul, clients_.size()); | 114 DCHECK_EQ(1ul, clients_.size()); |
Ami GONE FROM CHROMIUM
2014/04/21 23:42:53
'l' should not be necessary here.
Ami GONE FROM CHROMIUM
2014/04/21 23:42:53
what prevents two clients from registering almost-
Alpha Left Google
2014/04/23 18:48:33
Done.
Alpha Left Google
2014/04/23 18:48:33
I *think* the intention in this code is to verify
| |
159 params_ = params; | 115 params_ = params; |
160 if (params_.requested_format.frame_rate > | 116 if (params_.requested_format.frame_rate > |
161 media::limits::kMaxFramesPerSecond) { | 117 media::limits::kMaxFramesPerSecond) { |
162 params_.requested_format.frame_rate = | 118 params_.requested_format.frame_rate = |
163 media::limits::kMaxFramesPerSecond; | 119 media::limits::kMaxFramesPerSecond; |
164 } | 120 } |
165 DVLOG(1) << "StartCapture: starting with first resolution " | 121 DVLOG(1) << "StartCapture: starting with first resolution " |
166 << params_.requested_format.frame_size.ToString(); | 122 << params_.requested_format.frame_size.ToString(); |
167 first_frame_timestamp_ = base::TimeTicks(); | 123 first_frame_timestamp_ = base::TimeTicks(); |
168 StartCaptureInternal(); | 124 StartCaptureInternal(); |
169 } | 125 } |
170 } | 126 } |
171 } | 127 } |
172 | 128 |
173 void VideoCaptureImpl::StopCaptureOnIOThread( | 129 void VideoCaptureImpl::StopCapture(int client_id) { |
174 media::VideoCapture::EventHandler* handler) { | 130 DCHECK(thread_checker_.CalledOnValidThread()); |
175 DCHECK(io_message_loop_proxy_->BelongsToCurrentThread()); | |
176 | 131 |
177 // A handler can be in only one client list. | 132 // A client ID can be in only one client list. |
178 // If this handler is in any client list, we can just remove it from | 133 // If this ID is in any client list, we can just remove it from |
179 // that client list and don't have to run the other following RemoveClient(). | 134 // that client list and don't have to run the other following RemoveClient(). |
180 RemoveClient(handler, &clients_pending_on_filter_) || | 135 RemoveClient(client_id, &clients_pending_on_filter_) || |
181 RemoveClient(handler, &clients_pending_on_restart_) || | 136 RemoveClient(client_id, &clients_pending_on_restart_) || |
182 RemoveClient(handler, &clients_); | 137 RemoveClient(client_id, &clients_); |
Ami GONE FROM CHROMIUM
2014/04/21 23:42:53
ick to using boolean short-cutting like this (in a
Alpha Left Google
2014/04/23 18:48:33
RemoveClient actually calls the client and give it
| |
183 | 138 |
184 if (clients_.empty()) { | 139 if (clients_.empty()) { |
185 DVLOG(1) << "StopCapture: No more client, stopping ..."; | 140 DVLOG(1) << "StopCapture: No more client, stopping ..."; |
186 StopDevice(); | 141 StopDevice(); |
187 client_buffers_.clear(); | 142 client_buffers_.clear(); |
188 weak_factory_.InvalidateWeakPtrs(); | 143 weak_factory_.InvalidateWeakPtrs(); |
189 } | 144 } |
190 } | 145 } |
191 | 146 |
192 void VideoCaptureImpl::GetDeviceSupportedFormatsOnIOThread( | 147 void VideoCaptureImpl::GetDeviceSupportedFormats( |
193 const DeviceFormatsCallback& callback) { | 148 const VideoCaptureDeviceFormatsCB& callback) { |
194 DCHECK(io_message_loop_proxy_->BelongsToCurrentThread()); | 149 DCHECK(thread_checker_.CalledOnValidThread()); |
195 device_formats_callback_queue_.push_back(callback); | 150 device_formats_cb_queue_.push_back(callback); |
196 if (device_formats_callback_queue_.size() == 1) | 151 if (device_formats_cb_queue_.size() == 1) |
197 Send(new VideoCaptureHostMsg_GetDeviceSupportedFormats(device_id_, | 152 Send(new VideoCaptureHostMsg_GetDeviceSupportedFormats(device_id_, |
198 session_id_)); | 153 session_id_)); |
199 } | 154 } |
200 | 155 |
201 void VideoCaptureImpl::GetDeviceFormatsInUseOnIOThread( | 156 void VideoCaptureImpl::GetDeviceFormatsInUse( |
202 const DeviceFormatsInUseCallback& callback) { | 157 const VideoCaptureDeviceFormatsCB& callback) { |
203 DCHECK(io_message_loop_proxy_->BelongsToCurrentThread()); | 158 DCHECK(thread_checker_.CalledOnValidThread()); |
204 device_formats_in_use_callback_queue_.push_back(callback); | 159 device_formats_in_use_cb_queue_.push_back(callback); |
205 if (device_formats_in_use_callback_queue_.size() == 1) | 160 if (device_formats_in_use_cb_queue_.size() == 1) |
206 Send( | 161 Send( |
207 new VideoCaptureHostMsg_GetDeviceFormatsInUse(device_id_, session_id_)); | 162 new VideoCaptureHostMsg_GetDeviceFormatsInUse(device_id_, session_id_)); |
208 } | 163 } |
209 | 164 |
210 void VideoCaptureImpl::OnBufferCreated( | 165 void VideoCaptureImpl::OnBufferCreated( |
211 base::SharedMemoryHandle handle, | 166 base::SharedMemoryHandle handle, |
212 int length, int buffer_id) { | 167 int length, int buffer_id) { |
213 DCHECK(io_message_loop_proxy_->BelongsToCurrentThread()); | 168 DCHECK(thread_checker_.CalledOnValidThread()); |
214 | 169 |
215 // In case client calls StopCapture before the arrival of created buffer, | 170 // In case client calls StopCapture before the arrival of created buffer, |
216 // just close this buffer and return. | 171 // just close this buffer and return. |
217 if (state_ != VIDEO_CAPTURE_STATE_STARTED) { | 172 if (state_ != VIDEO_CAPTURE_STATE_STARTED) { |
218 base::SharedMemory::CloseHandle(handle); | 173 base::SharedMemory::CloseHandle(handle); |
219 return; | 174 return; |
220 } | 175 } |
221 | 176 |
222 scoped_ptr<base::SharedMemory> shm(new base::SharedMemory(handle, false)); | 177 scoped_ptr<base::SharedMemory> shm(new base::SharedMemory(handle, false)); |
223 if (!shm->Map(length)) { | 178 if (!shm->Map(length)) { |
224 DLOG(ERROR) << "OnBufferCreated: Map failed."; | 179 DLOG(ERROR) << "OnBufferCreated: Map failed."; |
225 return; | 180 return; |
226 } | 181 } |
227 | 182 |
228 bool inserted = | 183 bool inserted = |
229 client_buffers_.insert(std::make_pair( | 184 client_buffers_.insert(std::make_pair( |
230 buffer_id, | 185 buffer_id, |
231 new ClientBuffer(shm.Pass(), | 186 new ClientBuffer(shm.Pass(), |
232 length))).second; | 187 length))).second; |
233 DCHECK(inserted); | 188 DCHECK(inserted); |
234 } | 189 } |
235 | 190 |
236 void VideoCaptureImpl::OnBufferDestroyed(int buffer_id) { | 191 void VideoCaptureImpl::OnBufferDestroyed(int buffer_id) { |
237 DCHECK(io_message_loop_proxy_->BelongsToCurrentThread()); | 192 DCHECK(thread_checker_.CalledOnValidThread()); |
238 | 193 |
239 ClientBufferMap::iterator iter = client_buffers_.find(buffer_id); | 194 ClientBufferMap::iterator iter = client_buffers_.find(buffer_id); |
240 if (iter == client_buffers_.end()) | 195 if (iter == client_buffers_.end()) |
241 return; | 196 return; |
242 | 197 |
243 DCHECK(!iter->second || iter->second->HasOneRef()) | 198 DCHECK(!iter->second || iter->second->HasOneRef()) |
244 << "Instructed to delete buffer we are still using."; | 199 << "Instructed to delete buffer we are still using."; |
245 client_buffers_.erase(iter); | 200 client_buffers_.erase(iter); |
246 } | 201 } |
247 | 202 |
248 void VideoCaptureImpl::OnBufferReceived(int buffer_id, | 203 void VideoCaptureImpl::OnBufferReceived(int buffer_id, |
249 const media::VideoCaptureFormat& format, | 204 const media::VideoCaptureFormat& format, |
250 base::TimeTicks timestamp) { | 205 base::TimeTicks timestamp) { |
251 DCHECK(io_message_loop_proxy_->BelongsToCurrentThread()); | 206 DCHECK(thread_checker_.CalledOnValidThread()); |
252 | 207 |
253 // The capture pipeline supports only I420 for now. | 208 // The capture pipeline supports only I420 for now. |
254 DCHECK_EQ(format.pixel_format, media::PIXEL_FORMAT_I420); | 209 DCHECK_EQ(format.pixel_format, media::PIXEL_FORMAT_I420); |
255 | 210 |
256 if (state_ != VIDEO_CAPTURE_STATE_STARTED || suspended_) { | 211 if (state_ != VIDEO_CAPTURE_STATE_STARTED || suspended_) { |
257 Send(new VideoCaptureHostMsg_BufferReady(device_id_, buffer_id, 0)); | 212 Send(new VideoCaptureHostMsg_BufferReady(device_id_, buffer_id, 0)); |
258 return; | 213 return; |
259 } | 214 } |
260 | 215 |
261 last_frame_format_ = format; | 216 last_frame_format_ = format; |
(...skipping 20 matching lines...) Expand all Loading... | |
282 buffer->buffer_size, | 237 buffer->buffer_size, |
283 buffer->buffer->handle(), | 238 buffer->buffer->handle(), |
284 timestamp - first_frame_timestamp_, | 239 timestamp - first_frame_timestamp_, |
285 media::BindToCurrentLoop(base::Bind( | 240 media::BindToCurrentLoop(base::Bind( |
286 &VideoCaptureImpl::OnClientBufferFinished, | 241 &VideoCaptureImpl::OnClientBufferFinished, |
287 weak_factory_.GetWeakPtr(), | 242 weak_factory_.GetWeakPtr(), |
288 buffer_id, | 243 buffer_id, |
289 buffer, | 244 buffer, |
290 base::Passed(scoped_ptr<gpu::MailboxHolder>().Pass())))); | 245 base::Passed(scoped_ptr<gpu::MailboxHolder>().Pass())))); |
291 | 246 |
292 for (ClientInfo::iterator it = clients_.begin(); it != clients_.end(); ++it) | 247 for (ClientInfoMap::iterator it = clients_.begin(); it != clients_.end(); |
293 it->first->OnFrameReady(this, frame); | 248 ++it) { |
249 it->second.deliver_frame_cb.Run(frame, format, timestamp); | |
250 } | |
294 } | 251 } |
295 | 252 |
296 static void NullReadPixelsCB(const SkBitmap& bitmap) { NOTIMPLEMENTED(); } | 253 static void NullReadPixelsCB(const SkBitmap& bitmap) { NOTIMPLEMENTED(); } |
297 | 254 |
298 void VideoCaptureImpl::OnMailboxBufferReceived( | 255 void VideoCaptureImpl::OnMailboxBufferReceived( |
299 int buffer_id, | 256 int buffer_id, |
300 const gpu::MailboxHolder& mailbox_holder, | 257 const gpu::MailboxHolder& mailbox_holder, |
301 const media::VideoCaptureFormat& format, | 258 const media::VideoCaptureFormat& format, |
302 base::TimeTicks timestamp) { | 259 base::TimeTicks timestamp) { |
303 DCHECK(io_message_loop_proxy_->BelongsToCurrentThread()); | 260 DCHECK(thread_checker_.CalledOnValidThread()); |
304 | 261 |
305 if (state_ != VIDEO_CAPTURE_STATE_STARTED || suspended_) { | 262 if (state_ != VIDEO_CAPTURE_STATE_STARTED || suspended_) { |
306 Send(new VideoCaptureHostMsg_BufferReady( | 263 Send(new VideoCaptureHostMsg_BufferReady( |
307 device_id_, buffer_id, mailbox_holder.sync_point)); | 264 device_id_, buffer_id, mailbox_holder.sync_point)); |
308 return; | 265 return; |
309 } | 266 } |
310 | 267 |
311 last_frame_format_ = format; | 268 last_frame_format_ = format; |
312 if (first_frame_timestamp_.is_null()) | 269 if (first_frame_timestamp_.is_null()) |
313 first_frame_timestamp_ = timestamp; | 270 first_frame_timestamp_ = timestamp; |
314 | 271 |
315 scoped_refptr<media::VideoFrame> frame = media::VideoFrame::WrapNativeTexture( | 272 scoped_refptr<media::VideoFrame> frame = media::VideoFrame::WrapNativeTexture( |
316 make_scoped_ptr(new gpu::MailboxHolder(mailbox_holder)), | 273 make_scoped_ptr(new gpu::MailboxHolder(mailbox_holder)), |
317 media::BindToCurrentLoop( | 274 media::BindToCurrentLoop( |
318 base::Bind(&VideoCaptureImpl::OnClientBufferFinished, | 275 base::Bind(&VideoCaptureImpl::OnClientBufferFinished, |
319 weak_factory_.GetWeakPtr(), | 276 weak_factory_.GetWeakPtr(), |
320 buffer_id, | 277 buffer_id, |
321 scoped_refptr<ClientBuffer>())), | 278 scoped_refptr<ClientBuffer>())), |
322 last_frame_format_.frame_size, | 279 last_frame_format_.frame_size, |
323 gfx::Rect(last_frame_format_.frame_size), | 280 gfx::Rect(last_frame_format_.frame_size), |
324 last_frame_format_.frame_size, | 281 last_frame_format_.frame_size, |
325 timestamp - first_frame_timestamp_, | 282 timestamp - first_frame_timestamp_, |
326 base::Bind(&NullReadPixelsCB)); | 283 base::Bind(&NullReadPixelsCB)); |
327 | 284 |
328 for (ClientInfo::iterator it = clients_.begin(); it != clients_.end(); ++it) | 285 for (ClientInfoMap::iterator it = clients_.begin(); it != clients_.end(); |
329 it->first->OnFrameReady(this, frame); | 286 ++it) { |
287 it->second.deliver_frame_cb.Run(frame, format, timestamp); | |
288 } | |
330 } | 289 } |
331 | 290 |
332 void VideoCaptureImpl::OnClientBufferFinished( | 291 void VideoCaptureImpl::OnClientBufferFinished( |
333 int buffer_id, | 292 int buffer_id, |
334 const scoped_refptr<ClientBuffer>& /* ignored_buffer */, | 293 const scoped_refptr<ClientBuffer>& /* ignored_buffer */, |
335 scoped_ptr<gpu::MailboxHolder> mailbox_holder) { | 294 scoped_ptr<gpu::MailboxHolder> mailbox_holder) { |
336 DCHECK(io_message_loop_proxy_->BelongsToCurrentThread()); | 295 DCHECK(thread_checker_.CalledOnValidThread()); |
337 const uint32 sync_point = (mailbox_holder ? mailbox_holder->sync_point : 0); | 296 const uint32 sync_point = (mailbox_holder ? mailbox_holder->sync_point : 0); |
338 Send(new VideoCaptureHostMsg_BufferReady(device_id_, buffer_id, sync_point)); | 297 Send(new VideoCaptureHostMsg_BufferReady(device_id_, buffer_id, sync_point)); |
339 } | 298 } |
340 | 299 |
341 void VideoCaptureImpl::OnStateChanged(VideoCaptureState state) { | 300 void VideoCaptureImpl::OnStateChanged(VideoCaptureState state) { |
342 DCHECK(io_message_loop_proxy_->BelongsToCurrentThread()); | 301 DCHECK(thread_checker_.CalledOnValidThread()); |
343 | 302 |
344 switch (state) { | 303 switch (state) { |
345 case VIDEO_CAPTURE_STATE_STARTED: | 304 case VIDEO_CAPTURE_STATE_STARTED: |
Ami GONE FROM CHROMIUM
2014/04/21 23:42:53
seems strange that this is a no-op.
Alpha Left Google
2014/04/23 18:48:33
Added a comment.
| |
346 break; | 305 break; |
347 case VIDEO_CAPTURE_STATE_STOPPED: | 306 case VIDEO_CAPTURE_STATE_STOPPED: |
348 state_ = VIDEO_CAPTURE_STATE_STOPPED; | 307 state_ = VIDEO_CAPTURE_STATE_STOPPED; |
349 DVLOG(1) << "OnStateChanged: stopped!, device_id = " << device_id_; | 308 DVLOG(1) << "OnStateChanged: stopped!, device_id = " << device_id_; |
350 client_buffers_.clear(); | 309 client_buffers_.clear(); |
351 weak_factory_.InvalidateWeakPtrs(); | 310 weak_factory_.InvalidateWeakPtrs(); |
352 if (!clients_.empty() || !clients_pending_on_restart_.empty()) | 311 if (!clients_.empty() || !clients_pending_on_restart_.empty()) |
353 RestartCapture(); | 312 RestartCapture(); |
354 break; | 313 break; |
355 case VIDEO_CAPTURE_STATE_PAUSED: | 314 case VIDEO_CAPTURE_STATE_PAUSED: |
356 for (ClientInfo::iterator it = clients_.begin(); | 315 for (ClientInfoMap::iterator it = clients_.begin(); |
357 it != clients_.end(); ++it) { | 316 it != clients_.end(); ++it) { |
358 it->first->OnPaused(this); | 317 it->second.state_update_cb.Run(VIDEO_CAPTURE_STATE_PAUSED); |
359 } | 318 } |
360 break; | 319 break; |
361 case VIDEO_CAPTURE_STATE_ERROR: | 320 case VIDEO_CAPTURE_STATE_ERROR: |
362 DVLOG(1) << "OnStateChanged: error!, device_id = " << device_id_; | 321 DVLOG(1) << "OnStateChanged: error!, device_id = " << device_id_; |
363 for (ClientInfo::iterator it = clients_.begin(); | 322 for (ClientInfoMap::iterator it = clients_.begin(); |
364 it != clients_.end(); ++it) { | 323 it != clients_.end(); ++it) { |
365 // TODO(wjia): browser process would send error code. | 324 it->second.state_update_cb.Run(VIDEO_CAPTURE_STATE_ERROR); |
366 it->first->OnError(this, 1); | |
367 it->first->OnRemoved(this); | |
368 } | 325 } |
369 clients_.clear(); | 326 clients_.clear(); |
370 state_ = VIDEO_CAPTURE_STATE_ERROR; | 327 state_ = VIDEO_CAPTURE_STATE_ERROR; |
371 break; | 328 break; |
372 case VIDEO_CAPTURE_STATE_ENDED: | 329 case VIDEO_CAPTURE_STATE_ENDED: |
373 DVLOG(1) << "OnStateChanged: ended!, device_id = " << device_id_; | 330 DVLOG(1) << "OnStateChanged: ended!, device_id = " << device_id_; |
374 for (ClientInfo::iterator it = clients_.begin(); | 331 for (ClientInfoMap::iterator it = clients_.begin(); |
375 it != clients_.end(); ++it) { | 332 it != clients_.end(); ++it) { |
376 it->first->OnRemoved(this); | 333 // We'll only notify the client that the stream has stopped. |
334 it->second.state_update_cb.Run(VIDEO_CAPTURE_STATE_STOPPED); | |
377 } | 335 } |
378 clients_.clear(); | 336 clients_.clear(); |
379 state_ = VIDEO_CAPTURE_STATE_ENDED; | 337 state_ = VIDEO_CAPTURE_STATE_ENDED; |
380 break; | 338 break; |
381 default: | 339 default: |
382 break; | 340 break; |
383 } | 341 } |
384 } | 342 } |
385 | 343 |
386 void VideoCaptureImpl::OnDeviceSupportedFormatsEnumerated( | 344 void VideoCaptureImpl::OnDeviceSupportedFormatsEnumerated( |
387 const media::VideoCaptureFormats& supported_formats) { | 345 const media::VideoCaptureFormats& supported_formats) { |
388 DCHECK(io_message_loop_proxy_->BelongsToCurrentThread()); | 346 DCHECK(thread_checker_.CalledOnValidThread()); |
389 for (size_t i = 0; i < device_formats_callback_queue_.size(); ++i) | 347 for (size_t i = 0; i < device_formats_cb_queue_.size(); ++i) |
390 device_formats_callback_queue_[i].Run(supported_formats); | 348 device_formats_cb_queue_[i].Run(supported_formats); |
391 device_formats_callback_queue_.clear(); | 349 device_formats_cb_queue_.clear(); |
392 } | 350 } |
393 | 351 |
394 void VideoCaptureImpl::OnDeviceFormatsInUseReceived( | 352 void VideoCaptureImpl::OnDeviceFormatsInUseReceived( |
395 const media::VideoCaptureFormats& formats_in_use) { | 353 const media::VideoCaptureFormats& formats_in_use) { |
396 DCHECK(io_message_loop_proxy_->BelongsToCurrentThread()); | 354 DCHECK(thread_checker_.CalledOnValidThread()); |
397 for (size_t i = 0; i < device_formats_in_use_callback_queue_.size(); ++i) | 355 for (size_t i = 0; i < device_formats_in_use_cb_queue_.size(); ++i) |
398 device_formats_in_use_callback_queue_[i].Run(formats_in_use); | 356 device_formats_in_use_cb_queue_[i].Run(formats_in_use); |
399 device_formats_in_use_callback_queue_.clear(); | 357 device_formats_in_use_cb_queue_.clear(); |
400 } | 358 } |
401 | 359 |
402 void VideoCaptureImpl::OnDelegateAdded(int32 device_id) { | 360 void VideoCaptureImpl::OnDelegateAdded(int32 device_id) { |
361 DCHECK(thread_checker_.CalledOnValidThread()); | |
403 DVLOG(1) << "OnDelegateAdded: device_id " << device_id; | 362 DVLOG(1) << "OnDelegateAdded: device_id " << device_id; |
404 DCHECK(io_message_loop_proxy_->BelongsToCurrentThread()); | |
405 | 363 |
406 device_id_ = device_id; | 364 device_id_ = device_id; |
407 for (ClientInfo::iterator it = clients_pending_on_filter_.begin(); | 365 for (ClientInfoMap::iterator it = clients_pending_on_filter_.begin(); |
408 it != clients_pending_on_filter_.end(); ) { | 366 it != clients_pending_on_filter_.end(); ) { |
409 media::VideoCapture::EventHandler* handler = it->first; | 367 int client_id = it->first; |
410 const media::VideoCaptureParams params = it->second; | 368 VideoCaptureStateUpdateCB state_update_cb = |
369 it->second.state_update_cb; | |
370 VideoCaptureDeliverFrameCB deliver_frame_cb = | |
371 it->second.deliver_frame_cb; | |
372 const media::VideoCaptureParams params = it->second.params; | |
411 clients_pending_on_filter_.erase(it++); | 373 clients_pending_on_filter_.erase(it++); |
412 StartCapture(handler, params); | 374 StartCapture(client_id, params, state_update_cb, |
375 deliver_frame_cb); | |
413 } | 376 } |
414 } | 377 } |
415 | 378 |
416 void VideoCaptureImpl::StopDevice() { | 379 void VideoCaptureImpl::StopDevice() { |
417 DCHECK(io_message_loop_proxy_->BelongsToCurrentThread()); | 380 DCHECK(thread_checker_.CalledOnValidThread()); |
418 | 381 |
419 if (state_ == VIDEO_CAPTURE_STATE_STARTED) { | 382 if (state_ == VIDEO_CAPTURE_STATE_STARTED) { |
420 state_ = VIDEO_CAPTURE_STATE_STOPPING; | 383 state_ = VIDEO_CAPTURE_STATE_STOPPING; |
421 Send(new VideoCaptureHostMsg_Stop(device_id_)); | 384 Send(new VideoCaptureHostMsg_Stop(device_id_)); |
422 params_.requested_format.frame_size.SetSize(0, 0); | 385 params_.requested_format.frame_size.SetSize(0, 0); |
423 } | 386 } |
424 } | 387 } |
425 | 388 |
426 void VideoCaptureImpl::RestartCapture() { | 389 void VideoCaptureImpl::RestartCapture() { |
427 DCHECK(io_message_loop_proxy_->BelongsToCurrentThread()); | 390 DCHECK(thread_checker_.CalledOnValidThread()); |
428 DCHECK_EQ(state_, VIDEO_CAPTURE_STATE_STOPPED); | 391 DCHECK_EQ(state_, VIDEO_CAPTURE_STATE_STOPPED); |
429 | 392 |
430 int width = 0; | 393 int width = 0; |
431 int height = 0; | 394 int height = 0; |
432 for (ClientInfo::iterator it = clients_.begin(); | 395 for (ClientInfoMap::iterator it = clients_.begin(); |
433 it != clients_.end(); ++it) { | 396 it != clients_.end(); ++it) { |
434 width = std::max(width, it->second.requested_format.frame_size.width()); | 397 width = std::max(width, |
435 height = std::max(height, it->second.requested_format.frame_size.height()); | 398 it->second.params.requested_format.frame_size.width()); |
399 height = std::max(height, | |
400 it->second.params.requested_format.frame_size.height()); | |
436 } | 401 } |
437 for (ClientInfo::iterator it = clients_pending_on_restart_.begin(); | 402 for (ClientInfoMap::iterator it = clients_pending_on_restart_.begin(); |
438 it != clients_pending_on_restart_.end(); ) { | 403 it != clients_pending_on_restart_.end(); ) { |
439 width = std::max(width, it->second.requested_format.frame_size.width()); | 404 width = std::max(width, |
440 height = std::max(height, it->second.requested_format.frame_size.height()); | 405 it->second.params.requested_format.frame_size.width()); |
406 height = std::max(height, | |
407 it->second.params.requested_format.frame_size.height()); | |
441 clients_[it->first] = it->second; | 408 clients_[it->first] = it->second; |
442 clients_pending_on_restart_.erase(it++); | 409 clients_pending_on_restart_.erase(it++); |
443 } | 410 } |
Ami GONE FROM CHROMIUM
2014/04/21 23:42:53
if you did
clients_.insert(clients_pending_on_res
Alpha Left Google
2014/04/23 18:48:33
Done.
| |
444 params_.requested_format.frame_size.SetSize(width, height); | 411 params_.requested_format.frame_size.SetSize(width, height); |
445 DVLOG(1) << "RestartCapture, " | 412 DVLOG(1) << "RestartCapture, " |
446 << params_.requested_format.frame_size.ToString(); | 413 << params_.requested_format.frame_size.ToString(); |
447 StartCaptureInternal(); | 414 StartCaptureInternal(); |
448 } | 415 } |
449 | 416 |
450 void VideoCaptureImpl::StartCaptureInternal() { | 417 void VideoCaptureImpl::StartCaptureInternal() { |
451 DCHECK(io_message_loop_proxy_->BelongsToCurrentThread()); | 418 DCHECK(thread_checker_.CalledOnValidThread()); |
452 DCHECK(device_id_); | 419 DCHECK(device_id_); |
453 | 420 |
454 Send(new VideoCaptureHostMsg_Start(device_id_, session_id_, params_)); | 421 Send(new VideoCaptureHostMsg_Start(device_id_, session_id_, params_)); |
455 state_ = VIDEO_CAPTURE_STATE_STARTED; | 422 state_ = VIDEO_CAPTURE_STATE_STARTED; |
456 } | 423 } |
457 | 424 |
458 void VideoCaptureImpl::Send(IPC::Message* message) { | 425 void VideoCaptureImpl::Send(IPC::Message* message) { |
459 io_message_loop_proxy_->PostTask(FROM_HERE, | 426 DCHECK(thread_checker_.CalledOnValidThread()); |
460 base::Bind(base::IgnoreResult(&VideoCaptureMessageFilter::Send), | 427 message_filter_->Send(message); |
461 message_filter_.get(), message)); | |
462 } | 428 } |
463 | 429 |
464 bool VideoCaptureImpl::RemoveClient( | 430 bool VideoCaptureImpl::RemoveClient(int client_id, ClientInfoMap* clients) { |
465 media::VideoCapture::EventHandler* handler, | 431 DCHECK(thread_checker_.CalledOnValidThread()); |
466 ClientInfo* clients) { | |
467 DCHECK(io_message_loop_proxy_->BelongsToCurrentThread()); | |
468 bool found = false; | 432 bool found = false; |
469 | 433 |
470 ClientInfo::iterator it = clients->find(handler); | 434 ClientInfoMap::iterator it = clients->find(client_id); |
471 if (it != clients->end()) { | 435 if (it != clients->end()) { |
472 handler->OnStopped(this); | 436 it->second.state_update_cb.Run(VIDEO_CAPTURE_STATE_STOPPED); |
473 handler->OnRemoved(this); | |
474 clients->erase(it); | 437 clients->erase(it); |
475 found = true; | 438 found = true; |
476 } | 439 } |
477 return found; | 440 return found; |
Ami GONE FROM CHROMIUM
2014/04/21 23:42:53
l.432-440 can be replaced with
return clients->era
Alpha Left Google
2014/04/23 18:48:33
I still need it to send the client the stopped sig
| |
478 } | 441 } |
479 | 442 |
480 } // namespace content | 443 } // namespace content |
OLD | NEW |