Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(24)

Side by Side Diff: content/renderer/media/video_capture_impl.cc

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

Powered by Google App Engine
This is Rietveld 408576698