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

Side by Side Diff: content/browser/renderer_host/media/video_capture_controller.cc

Issue 24133002: Make VideoCaptureController single-threaded and not ref counted. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: git pull Created 7 years, 3 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 4
5 #include "content/browser/renderer_host/media/video_capture_controller.h" 5 #include "content/browser/renderer_host/media/video_capture_controller.h"
6 6
7 #include <set> 7 #include <set>
8 8
9 #include "base/bind.h" 9 #include "base/bind.h"
10 #include "base/debug/trace_event.h" 10 #include "base/debug/trace_event.h"
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
86 // VideoCaptureController* pointer, its ControllerClient entry lives on until 86 // VideoCaptureController* pointer, its ControllerClient entry lives on until
87 // it unregisters itself via RemoveClient(), which may happen asynchronously. 87 // it unregisters itself via RemoveClient(), which may happen asynchronously.
88 // 88 //
89 // TODO(nick): If we changed the semantics of VideoCaptureHost so that 89 // TODO(nick): If we changed the semantics of VideoCaptureHost so that
90 // OnEnded() events were processed synchronously (with the RemoveClient() done 90 // OnEnded() events were processed synchronously (with the RemoveClient() done
91 // implicitly), we could avoid tracking this state here in the Controller, and 91 // implicitly), we could avoid tracking this state here in the Controller, and
92 // simplify the code in both places. 92 // simplify the code in both places.
93 bool session_closed; 93 bool session_closed;
94 }; 94 };
95 95
96 // Receives events from the VideoCaptureDevice and posts them to a
97 // VideoCaptureController on the IO thread. An instance of this class may safely
98 // outlive its target VideoCaptureController.
99 //
100 // Methods of this class may be called from any thread, and in practice will
101 // often be called on some auxiliary thread depending on the platform and the
102 // device type; including, for example, the DirectShow thread on Windows, the
103 // v4l2_thread on Linux, and the UI thread for tab capture.
104 class VideoCaptureController::VideoCaptureDeviceClient
105 : public media::VideoCaptureDevice::EventHandler {
106 public:
107 explicit VideoCaptureDeviceClient(
108 const base::WeakPtr<VideoCaptureController>& controller);
109 virtual ~VideoCaptureDeviceClient();
110
111 // VideoCaptureDevice::EventHandler implementation.
112 virtual scoped_refptr<media::VideoFrame> ReserveOutputBuffer() OVERRIDE;
113 virtual void OnIncomingCapturedFrame(const uint8* data,
114 int length,
115 base::Time timestamp,
116 int rotation,
117 bool flip_vert,
118 bool flip_horiz) OVERRIDE;
119 virtual void OnIncomingCapturedVideoFrame(
120 const scoped_refptr<media::VideoFrame>& frame,
121 base::Time timestamp) OVERRIDE;
122 virtual void OnError() OVERRIDE;
123 virtual void OnFrameInfo(
124 const media::VideoCaptureCapability& info) OVERRIDE;
125 virtual void OnFrameInfoChanged(
126 const media::VideoCaptureCapability& info) OVERRIDE;
127
128 private:
129 // The controller to which we post events.
130 const base::WeakPtr<VideoCaptureController> controller_;
131
132 // The pool of shared-memory buffers used for capturing.
133 scoped_refptr<VideoCaptureBufferPool> buffer_pool_;
134
135 // Chopped pixels in width/height in case video capture device has odd
136 // numbers for width/height.
137 int chopped_width_;
138 int chopped_height_;
139
140 // Tracks the current frame format.
141 media::VideoCaptureCapability frame_info_;
142 };
143
96 VideoCaptureController::VideoCaptureController() 144 VideoCaptureController::VideoCaptureController()
97 : chopped_width_(0), 145 : state_(VIDEO_CAPTURE_STATE_STARTED),
wjia(left Chromium) 2013/09/18 01:29:02 |state_| is not really needed any more since there
98 chopped_height_(0), 146 weak_ptr_factory_(this) {
99 frame_info_available_(false),
100 state_(VIDEO_CAPTURE_STATE_STARTED) {
101 memset(&current_params_, 0, sizeof(current_params_)); 147 memset(&current_params_, 0, sizeof(current_params_));
102 } 148 }
103 149
150 VideoCaptureController::VideoCaptureDeviceClient::VideoCaptureDeviceClient(
151 const base::WeakPtr<VideoCaptureController>& controller)
152 : controller_(controller),
153 chopped_width_(0),
154 chopped_height_(0) {}
155
156 VideoCaptureController::VideoCaptureDeviceClient::~VideoCaptureDeviceClient() {}
157
158 base::WeakPtr<VideoCaptureController> VideoCaptureController::GetWeakPtr() {
159 return weak_ptr_factory_.GetWeakPtr();
160 }
161
162 scoped_ptr<media::VideoCaptureDevice::EventHandler>
163 VideoCaptureController::NewDeviceClient() {
164 scoped_ptr<media::VideoCaptureDevice::EventHandler> result(
165 new VideoCaptureDeviceClient(this->GetWeakPtr()));
166 return result.Pass();
167 }
168
104 void VideoCaptureController::AddClient( 169 void VideoCaptureController::AddClient(
105 const VideoCaptureControllerID& id, 170 const VideoCaptureControllerID& id,
106 VideoCaptureControllerEventHandler* event_handler, 171 VideoCaptureControllerEventHandler* event_handler,
107 base::ProcessHandle render_process, 172 base::ProcessHandle render_process,
108 const media::VideoCaptureParams& params) { 173 const media::VideoCaptureParams& params) {
109 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 174 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
110 DVLOG(1) << "VideoCaptureController::AddClient, id " << id.device_id 175 DVLOG(1) << "VideoCaptureController::AddClient, id " << id.device_id
111 << ", (" << params.width 176 << ", (" << params.width
112 << ", " << params.height 177 << ", " << params.height
113 << ", " << params.frame_rate 178 << ", " << params.frame_rate
114 << ", " << params.session_id 179 << ", " << params.session_id
115 << ")"; 180 << ")";
116 181
117 // Signal error in case device is already in error state. 182 // Signal error in case device is already in error state.
118 if (state_ == VIDEO_CAPTURE_STATE_ERROR) { 183 if (state_ == VIDEO_CAPTURE_STATE_ERROR) {
119 event_handler->OnError(id); 184 event_handler->OnError(id);
120 return; 185 return;
121 } 186 }
122 187
123 // Do nothing if this client has called AddClient before. 188 // Do nothing if this client has called AddClient before.
124 if (FindClient(id, event_handler, controller_clients_)) 189 if (FindClient(id, event_handler, controller_clients_))
125 return; 190 return;
126 191
127 ControllerClient* client = new ControllerClient(id, event_handler, 192 ControllerClient* client = new ControllerClient(id, event_handler,
128 render_process, params); 193 render_process, params);
129 // If we already have gotten frame_info from the device, repeat it to the new 194 // If we already have gotten frame_info from the device, repeat it to the new
130 // client. 195 // client.
131 if (state_ == VIDEO_CAPTURE_STATE_STARTED) { 196 if (state_ == VIDEO_CAPTURE_STATE_STARTED) {
132 if (frame_info_available_) { 197 if (frame_info_.IsValid()) {
133 SendFrameInfoAndBuffers(client); 198 SendFrameInfoAndBuffers(client);
134 } 199 }
135 controller_clients_.push_back(client); 200 controller_clients_.push_back(client);
136 return; 201 return;
137 } 202 }
138 } 203 }
139 204
140 int VideoCaptureController::RemoveClient( 205 int VideoCaptureController::RemoveClient(
141 const VideoCaptureControllerID& id, 206 const VideoCaptureControllerID& id,
142 VideoCaptureControllerEventHandler* event_handler) { 207 VideoCaptureControllerEventHandler* event_handler) {
(...skipping 15 matching lines...) Expand all
158 } 223 }
159 client->buffers.clear(); 224 client->buffers.clear();
160 225
161 int session_id = client->parameters.session_id; 226 int session_id = client->parameters.session_id;
162 controller_clients_.remove(client); 227 controller_clients_.remove(client);
163 delete client; 228 delete client;
164 229
165 return session_id; 230 return session_id;
166 } 231 }
167 232
168 void VideoCaptureController::StopSession( 233 void VideoCaptureController::StopSession(int session_id) {
169 int session_id) {
170 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 234 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
171 DVLOG(1) << "VideoCaptureController::StopSession, id " << session_id; 235 DVLOG(1) << "VideoCaptureController::StopSession, id " << session_id;
172 236
173 ControllerClient* client = FindClient(session_id, controller_clients_); 237 ControllerClient* client = FindClient(session_id, controller_clients_);
174 238
175 if (client) { 239 if (client) {
176 client->session_closed = true; 240 client->session_closed = true;
177 client->event_handler->OnEnded(client->controller_id); 241 client->event_handler->OnEnded(client->controller_id);
178 } 242 }
179 } 243 }
(...skipping 11 matching lines...) Expand all
191 if (!client || 255 if (!client ||
192 client->buffers.find(buffer_id) == client->buffers.end()) { 256 client->buffers.find(buffer_id) == client->buffers.end()) {
193 NOTREACHED(); 257 NOTREACHED();
194 return; 258 return;
195 } 259 }
196 260
197 client->buffers.erase(buffer_id); 261 client->buffers.erase(buffer_id);
198 buffer_pool_->RelinquishConsumerHold(buffer_id, 1); 262 buffer_pool_->RelinquishConsumerHold(buffer_id, 1);
199 } 263 }
200 264
201 scoped_refptr<media::VideoFrame> VideoCaptureController::ReserveOutputBuffer() { 265 scoped_refptr<media::VideoFrame>
202 base::AutoLock lock(buffer_pool_lock_); 266 VideoCaptureController::VideoCaptureDeviceClient::ReserveOutputBuffer() {
203 if (!buffer_pool_.get())
204 return NULL;
205 return buffer_pool_->ReserveI420VideoFrame(gfx::Size(frame_info_.width, 267 return buffer_pool_->ReserveI420VideoFrame(gfx::Size(frame_info_.width,
206 frame_info_.height), 268 frame_info_.height),
207 0); 269 0);
208 } 270 }
209 271
210 // Implements VideoCaptureDevice::EventHandler.
211 // OnIncomingCapturedFrame is called the thread running the capture device.
212 // I.e.- DirectShow thread on windows and v4l2_thread on Linux.
213 #if !defined(OS_IOS) && !defined(OS_ANDROID) 272 #if !defined(OS_IOS) && !defined(OS_ANDROID)
214 void VideoCaptureController::OnIncomingCapturedFrame( 273 void VideoCaptureController::VideoCaptureDeviceClient::OnIncomingCapturedFrame(
215 const uint8* data, 274 const uint8* data,
216 int length, 275 int length,
217 base::Time timestamp, 276 base::Time timestamp,
218 int rotation, 277 int rotation,
219 bool flip_vert, 278 bool flip_vert,
220 bool flip_horiz) { 279 bool flip_horiz) {
221 TRACE_EVENT0("video", "VideoCaptureController::OnIncomingCapturedFrame"); 280 TRACE_EVENT0("video", "VideoCaptureController::OnIncomingCapturedFrame");
222 281
223 scoped_refptr<media::VideoFrame> dst; 282 if (!buffer_pool_.get())
224 { 283 return;
225 base::AutoLock lock(buffer_pool_lock_); 284 scoped_refptr<media::VideoFrame> dst = buffer_pool_->ReserveI420VideoFrame(
226 if (!buffer_pool_.get()) 285 gfx::Size(frame_info_.width, frame_info_.height), rotation);
227 return;
228 dst = buffer_pool_->ReserveI420VideoFrame(
229 gfx::Size(frame_info_.width, frame_info_.height), rotation);
230 }
231 286
232 if (!dst.get()) 287 if (!dst.get())
233 return; 288 return;
234 289
235 uint8* yplane = dst->data(media::VideoFrame::kYPlane); 290 uint8* yplane = dst->data(media::VideoFrame::kYPlane);
236 uint8* uplane = dst->data(media::VideoFrame::kUPlane); 291 uint8* uplane = dst->data(media::VideoFrame::kUPlane);
237 uint8* vplane = dst->data(media::VideoFrame::kVPlane); 292 uint8* vplane = dst->data(media::VideoFrame::kVPlane);
238 int yplane_stride = frame_info_.width; 293 int yplane_stride = frame_info_.width;
239 int uv_plane_stride = (frame_info_.width + 1) / 2; 294 int uv_plane_stride = (frame_info_.width + 1) / 2;
240 int crop_x = 0; 295 int crop_x = 0;
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after
329 frame_info_.height * (flip_vert ^ flip_horiz ? -1 : 1), 384 frame_info_.height * (flip_vert ^ flip_horiz ? -1 : 1),
330 frame_info_.width, 385 frame_info_.width,
331 frame_info_.height, 386 frame_info_.height,
332 rotation_mode, 387 rotation_mode,
333 origin_colorspace); 388 origin_colorspace);
334 } 389 }
335 BrowserThread::PostTask( 390 BrowserThread::PostTask(
336 BrowserThread::IO, 391 BrowserThread::IO,
337 FROM_HERE, 392 FROM_HERE,
338 base::Bind(&VideoCaptureController::DoIncomingCapturedFrameOnIOThread, 393 base::Bind(&VideoCaptureController::DoIncomingCapturedFrameOnIOThread,
339 this, 394 controller_,
340 dst, 395 dst,
341 timestamp)); 396 timestamp));
342 } 397 }
343 #else 398 #else
344 void VideoCaptureController::OnIncomingCapturedFrame( 399 void VideoCaptureController::VideoCaptureDeviceClient::OnIncomingCapturedFrame(
345 const uint8* data, 400 const uint8* data,
346 int length, 401 int length,
347 base::Time timestamp, 402 base::Time timestamp,
348 int rotation, 403 int rotation,
349 bool flip_vert, 404 bool flip_vert,
350 bool flip_horiz) { 405 bool flip_horiz) {
351 DCHECK(frame_info_.color == media::PIXEL_FORMAT_I420 || 406 DCHECK(frame_info_.color == media::PIXEL_FORMAT_I420 ||
352 frame_info_.color == media::PIXEL_FORMAT_YV12 || 407 frame_info_.color == media::PIXEL_FORMAT_YV12 ||
353 (rotation == 0 && !flip_vert && !flip_horiz)); 408 (rotation == 0 && !flip_vert && !flip_horiz));
354 409
355 TRACE_EVENT0("video", "VideoCaptureController::OnIncomingCapturedFrame"); 410 TRACE_EVENT0("video", "VideoCaptureController::OnIncomingCapturedFrame");
356 411
357 scoped_refptr<media::VideoFrame> dst; 412 if (!buffer_pool_)
358 { 413 return;
359 base::AutoLock lock(buffer_pool_lock_); 414 scoped_refptr<media::VideoFrame> dst =
360 if (!buffer_pool_.get()) 415 buffer_pool_->ReserveI420VideoFrame(gfx::Size(frame_info_.width,
361 return; 416 frame_info_.height),
362 dst = buffer_pool_->ReserveI420VideoFrame(gfx::Size(frame_info_.width, 417 rotation);
363 frame_info_.height),
364 rotation);
365 }
366 418
367 if (!dst.get()) 419 if (!dst.get())
368 return; 420 return;
369 421
370 uint8* yplane = dst->data(media::VideoFrame::kYPlane); 422 uint8* yplane = dst->data(media::VideoFrame::kYPlane);
371 uint8* uplane = dst->data(media::VideoFrame::kUPlane); 423 uint8* uplane = dst->data(media::VideoFrame::kUPlane);
372 uint8* vplane = dst->data(media::VideoFrame::kVPlane); 424 uint8* vplane = dst->data(media::VideoFrame::kVPlane);
373 425
374 // Do color conversion from the camera format to I420. 426 // Do color conversion from the camera format to I420.
375 switch (frame_info_.color) { 427 switch (frame_info_.color) {
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
419 (frame_info_.width + chopped_width_) * 4, 471 (frame_info_.width + chopped_width_) * 4,
420 frame_info_.width, frame_info_.width / 2); 472 frame_info_.width, frame_info_.width / 2);
421 break; 473 break;
422 default: 474 default:
423 NOTREACHED(); 475 NOTREACHED();
424 } 476 }
425 477
426 BrowserThread::PostTask(BrowserThread::IO, 478 BrowserThread::PostTask(BrowserThread::IO,
427 FROM_HERE, 479 FROM_HERE,
428 base::Bind(&VideoCaptureController::DoIncomingCapturedFrameOnIOThread, 480 base::Bind(&VideoCaptureController::DoIncomingCapturedFrameOnIOThread,
429 this, dst, timestamp)); 481 controller_, dst, timestamp));
430 } 482 }
431 #endif // #if !defined(OS_IOS) && !defined(OS_ANDROID) 483 #endif // #if !defined(OS_IOS) && !defined(OS_ANDROID)
432 484
433 // OnIncomingCapturedVideoFrame is called the thread running the capture device. 485 void
434 void VideoCaptureController::OnIncomingCapturedVideoFrame( 486 VideoCaptureController::VideoCaptureDeviceClient::OnIncomingCapturedVideoFrame(
435 const scoped_refptr<media::VideoFrame>& frame, 487 const scoped_refptr<media::VideoFrame>& frame,
436 base::Time timestamp) { 488 base::Time timestamp) {
437 489
438 scoped_refptr<media::VideoFrame> target; 490 if (!buffer_pool_)
439 { 491 return;
440 base::AutoLock lock(buffer_pool_lock_);
441 492
442 if (!buffer_pool_.get()) 493 // If this is a frame that belongs to the buffer pool, we can forward it
443 return; 494 // directly to the IO thread and be done.
495 if (buffer_pool_->RecognizeReservedBuffer(
496 frame->shared_memory_handle()) >= 0) {
497 BrowserThread::PostTask(BrowserThread::IO,
498 FROM_HERE,
499 base::Bind(&VideoCaptureController::DoIncomingCapturedFrameOnIOThread,
500 controller_, frame, timestamp));
501 return;
502 }
444 503
445 // If this is a frame that belongs to the buffer pool, we can forward it 504 // Otherwise, this is a frame that belongs to the caller, and we must copy
446 // directly to the IO thread and be done. 505 // it to a frame from the buffer pool.
447 if (buffer_pool_->RecognizeReservedBuffer( 506 scoped_refptr<media::VideoFrame> target =
448 frame->shared_memory_handle()) >= 0) { 507 buffer_pool_->ReserveI420VideoFrame(gfx::Size(frame_info_.width,
449 BrowserThread::PostTask(BrowserThread::IO, 508 frame_info_.height),
450 FROM_HERE, 509 0);
451 base::Bind(&VideoCaptureController::DoIncomingCapturedFrameOnIOThread,
452 this, frame, timestamp));
453 return;
454 }
455 // Otherwise, this is a frame that belongs to the caller, and we must copy
456 // it to a frame from the buffer pool.
457 target = buffer_pool_->ReserveI420VideoFrame(gfx::Size(frame_info_.width,
458 frame_info_.height),
459 0);
460 }
461 510
462 if (!target.get()) 511 if (!target.get())
463 return; 512 return;
464 513
465 // Validate the inputs. 514 // Validate the inputs.
466 if (frame->coded_size() != target->coded_size()) 515 if (frame->coded_size() != target->coded_size())
467 return; // Only exact copies are supported. 516 return; // Only exact copies are supported.
468 if (!(frame->format() == media::VideoFrame::I420 || 517 if (!(frame->format() == media::VideoFrame::I420 ||
469 frame->format() == media::VideoFrame::YV12 || 518 frame->format() == media::VideoFrame::YV12 ||
470 frame->format() == media::VideoFrame::RGB32)) { 519 frame->format() == media::VideoFrame::RGB32)) {
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
538 frame->stride(kRGBPlane), 587 frame->stride(kRGBPlane),
539 target->stride(kYPlane), 588 target->stride(kYPlane),
540 target->stride(kUPlane)); 589 target->stride(kUPlane));
541 break; 590 break;
542 } 591 }
543 } 592 }
544 593
545 BrowserThread::PostTask(BrowserThread::IO, 594 BrowserThread::PostTask(BrowserThread::IO,
546 FROM_HERE, 595 FROM_HERE,
547 base::Bind(&VideoCaptureController::DoIncomingCapturedFrameOnIOThread, 596 base::Bind(&VideoCaptureController::DoIncomingCapturedFrameOnIOThread,
548 this, target, timestamp)); 597 controller_, target, timestamp));
549 } 598 }
550 599
551 void VideoCaptureController::OnError() { 600 void VideoCaptureController::VideoCaptureDeviceClient::OnError() {
552 BrowserThread::PostTask(BrowserThread::IO, 601 BrowserThread::PostTask(BrowserThread::IO,
553 FROM_HERE, 602 FROM_HERE,
554 base::Bind(&VideoCaptureController::DoErrorOnIOThread, this)); 603 base::Bind(&VideoCaptureController::DoErrorOnIOThread, controller_));
555 } 604 }
556 605
557 void VideoCaptureController::OnFrameInfo( 606 void VideoCaptureController::VideoCaptureDeviceClient::OnFrameInfo(
558 const media::VideoCaptureCapability& info) { 607 const media::VideoCaptureCapability& info) {
559 frame_info_= info; 608 frame_info_ = info;
560 // Handle cases when |info| has odd numbers for width/height. 609 // Handle cases when |info| has odd numbers for width/height.
561 if (info.width & 1) { 610 if (info.width & 1) {
562 --frame_info_.width; 611 --frame_info_.width;
563 chopped_width_ = 1; 612 chopped_width_ = 1;
564 } else { 613 } else {
565 chopped_width_ = 0; 614 chopped_width_ = 0;
566 } 615 }
567 if (info.height & 1) { 616 if (info.height & 1) {
568 --frame_info_.height; 617 --frame_info_.height;
569 chopped_height_ = 1; 618 chopped_height_ = 1;
570 } else { 619 } else {
571 chopped_height_ = 0; 620 chopped_height_ = 0;
572 } 621 }
622
623 DCHECK(!buffer_pool_.get());
624
625 // TODO(nick): Give BufferPool the same lifetime as the controller, have it
626 // support frame size changes, and stop checking it for NULL everywhere.
627 // http://crbug.com/266082
628 buffer_pool_ = new VideoCaptureBufferPool(
629 media::VideoFrame::AllocationSize(
630 media::VideoFrame::I420,
631 gfx::Size(frame_info_.width, frame_info_.height)),
632 kNoOfBuffers);
633
634 // Check whether all buffers were created successfully.
635 if (!buffer_pool_->Allocate()) {
636 // Transition to the error state.
637 buffer_pool_ = NULL;
638 OnError();
639 return;
640 }
641
573 BrowserThread::PostTask(BrowserThread::IO, 642 BrowserThread::PostTask(BrowserThread::IO,
574 FROM_HERE, 643 FROM_HERE,
575 base::Bind(&VideoCaptureController::DoFrameInfoOnIOThread, this)); 644 base::Bind(&VideoCaptureController::DoFrameInfoOnIOThread, controller_,
645 frame_info_, buffer_pool_));
576 } 646 }
577 647
578 void VideoCaptureController::OnFrameInfoChanged( 648 void VideoCaptureController::VideoCaptureDeviceClient::OnFrameInfoChanged(
579 const media::VideoCaptureCapability& info) { 649 const media::VideoCaptureCapability& info) {
580 BrowserThread::PostTask(BrowserThread::IO, 650 BrowserThread::PostTask(BrowserThread::IO,
581 FROM_HERE, 651 FROM_HERE,
582 base::Bind(&VideoCaptureController::DoFrameInfoChangedOnIOThread, 652 base::Bind(&VideoCaptureController::DoFrameInfoChangedOnIOThread,
583 this, info)); 653 controller_, info));
584 } 654 }
585 655
586 VideoCaptureController::~VideoCaptureController() { 656 VideoCaptureController::~VideoCaptureController() {
587 buffer_pool_ = NULL; // Release all buffers. 657 buffer_pool_ = NULL; // Release all buffers.
588 STLDeleteContainerPointers(controller_clients_.begin(), 658 STLDeleteContainerPointers(controller_clients_.begin(),
589 controller_clients_.end()); 659 controller_clients_.end());
590 } 660 }
591 661
592 void VideoCaptureController::DoIncomingCapturedFrameOnIOThread( 662 void VideoCaptureController::DoIncomingCapturedFrameOnIOThread(
593 const scoped_refptr<media::VideoFrame>& reserved_frame, 663 const scoped_refptr<media::VideoFrame>& reserved_frame,
594 base::Time timestamp) { 664 base::Time timestamp) {
595 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 665 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
596 666
597 if (!buffer_pool_.get()) 667 if (!buffer_pool_.get())
598 return; 668 return;
599 669
600 int buffer_id = buffer_pool_->RecognizeReservedBuffer( 670 int buffer_id = buffer_pool_->RecognizeReservedBuffer(
601 reserved_frame->shared_memory_handle()); 671 reserved_frame->shared_memory_handle());
wjia(left Chromium) 2013/09/18 01:29:02 In case number of live clients (i.e., the |count|
602 if (buffer_id < 0) { 672 if (buffer_id < 0) {
603 NOTREACHED(); 673 NOTREACHED();
604 return; 674 return;
605 } 675 }
606 676
607 int count = 0; 677 int count = 0;
608 if (state_ == VIDEO_CAPTURE_STATE_STARTED) { 678 if (state_ == VIDEO_CAPTURE_STATE_STARTED) {
609 for (ControllerClients::iterator client_it = controller_clients_.begin(); 679 for (ControllerClients::iterator client_it = controller_clients_.begin();
610 client_it != controller_clients_.end(); ++client_it) { 680 client_it != controller_clients_.end(); ++client_it) {
611 if ((*client_it)->session_closed) 681 if ((*client_it)->session_closed)
612 continue; 682 continue;
613 683
614 (*client_it)->event_handler->OnBufferReady((*client_it)->controller_id, 684 (*client_it)->event_handler->OnBufferReady((*client_it)->controller_id,
615 buffer_id, timestamp); 685 buffer_id, timestamp);
616 (*client_it)->buffers.insert(buffer_id); 686 (*client_it)->buffers.insert(buffer_id);
617 count++; 687 count++;
618 } 688 }
619 } 689 }
620 690
621 buffer_pool_->HoldForConsumers(buffer_id, count); 691 buffer_pool_->HoldForConsumers(buffer_id, count);
622 } 692 }
623 693
624 void VideoCaptureController::DoFrameInfoOnIOThread() { 694 void VideoCaptureController::DoFrameInfoOnIOThread(
695 const media::VideoCaptureCapability& frame_info,
696 const scoped_refptr<VideoCaptureBufferPool>& buffer_pool) {
625 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 697 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
626 DCHECK(!buffer_pool_.get()) << "Frame info should happen only once."; 698 DCHECK(!buffer_pool_.get()) << "Frame info should happen only once.";
627 699
628 // Allocate memory only when device has been started. 700 // Allocate memory only when device has been started.
wjia(left Chromium) 2013/09/18 01:29:02 This would be changed to "Allocate memory only whe
629 if (state_ != VIDEO_CAPTURE_STATE_STARTED) 701 if (state_ != VIDEO_CAPTURE_STATE_STARTED)
630 return; 702 return;
631 703
632 scoped_refptr<VideoCaptureBufferPool> buffer_pool = 704 frame_info_ = frame_info;
633 new VideoCaptureBufferPool( 705 buffer_pool_ = buffer_pool;
634 media::VideoFrame::AllocationSize(
635 media::VideoFrame::I420,
636 gfx::Size(frame_info_.width, frame_info_.height)),
637 kNoOfBuffers);
638
639 // Check whether all buffers were created successfully.
640 if (!buffer_pool->Allocate()) {
641 DoErrorOnIOThread();
642 return;
643 }
644
645 {
646 base::AutoLock lock(buffer_pool_lock_);
647 buffer_pool_ = buffer_pool;
648 }
649 frame_info_available_ = true;
650 706
651 for (ControllerClients::iterator client_it = controller_clients_.begin(); 707 for (ControllerClients::iterator client_it = controller_clients_.begin();
652 client_it != controller_clients_.end(); ++client_it) { 708 client_it != controller_clients_.end(); ++client_it) {
653 if ((*client_it)->session_closed) 709 if ((*client_it)->session_closed)
654 continue; 710 continue;
655 711
656 SendFrameInfoAndBuffers(*client_it); 712 SendFrameInfoAndBuffers(*client_it);
657 } 713 }
658 } 714 }
659 715
(...skipping 23 matching lines...) Expand all
683 client_it != controller_clients_.end(); ++client_it) { 739 client_it != controller_clients_.end(); ++client_it) {
684 if ((*client_it)->session_closed) 740 if ((*client_it)->session_closed)
685 continue; 741 continue;
686 742
687 (*client_it)->event_handler->OnError((*client_it)->controller_id); 743 (*client_it)->event_handler->OnError((*client_it)->controller_id);
688 } 744 }
689 } 745 }
690 746
691 void VideoCaptureController::SendFrameInfoAndBuffers(ControllerClient* client) { 747 void VideoCaptureController::SendFrameInfoAndBuffers(ControllerClient* client) {
692 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 748 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
693 DCHECK(frame_info_available_); 749 DCHECK(frame_info_.IsValid());
694 client->event_handler->OnFrameInfo(client->controller_id, 750 client->event_handler->OnFrameInfo(client->controller_id,
695 frame_info_); 751 frame_info_);
696 for (int buffer_id = 0; buffer_id < buffer_pool_->count(); ++buffer_id) { 752 for (int buffer_id = 0; buffer_id < buffer_pool_->count(); ++buffer_id) {
697 base::SharedMemoryHandle remote_handle = 753 base::SharedMemoryHandle remote_handle =
698 buffer_pool_->ShareToProcess(buffer_id, client->render_process_handle); 754 buffer_pool_->ShareToProcess(buffer_id, client->render_process_handle);
699 755
700 client->event_handler->OnBufferCreated(client->controller_id, 756 client->event_handler->OnBufferCreated(client->controller_id,
701 remote_handle, 757 remote_handle,
702 buffer_pool_->GetMemorySize(), 758 buffer_pool_->GetMemorySize(),
703 buffer_id); 759 buffer_id);
(...skipping 27 matching lines...) Expand all
731 } 787 }
732 return NULL; 788 return NULL;
733 } 789 }
734 790
735 int VideoCaptureController::GetClientCount() { 791 int VideoCaptureController::GetClientCount() {
736 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 792 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
737 return controller_clients_.size(); 793 return controller_clients_.size();
738 } 794 }
739 795
740 } // namespace content 796 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698