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

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: Fix a memory leak 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 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
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 VideoCaptureController::VideoCaptureController() 96 VideoCaptureController::VideoCaptureController()
97 : chopped_width_(0), 97 : frame_info_available_(false),
98 chopped_height_(0), 98 state_(VIDEO_CAPTURE_STATE_STARTED),
99 frame_info_available_(false), 99 weak_ptr_factory_(this) {
100 state_(VIDEO_CAPTURE_STATE_STARTED) {
101 memset(&current_params_, 0, sizeof(current_params_)); 100 memset(&current_params_, 0, sizeof(current_params_));
102 } 101 }
103 102
103 VideoCaptureController::VideoCaptureDeviceClient::VideoCaptureDeviceClient(
104 const base::WeakPtr<VideoCaptureController>& controller)
105 : controller_(controller),
106 chopped_width_(0),
107 chopped_height_(0) {}
108
109 VideoCaptureController::VideoCaptureDeviceClient::~VideoCaptureDeviceClient() {}
110
111 base::WeakPtr<VideoCaptureController> VideoCaptureController::AsWeakPtr() {
112 return weak_ptr_factory_.GetWeakPtr();
113 }
114
115 scoped_ptr<media::VideoCaptureDevice::EventHandler>
116 VideoCaptureController::NewDeviceClient() {
117 scoped_ptr<media::VideoCaptureDevice::EventHandler> result(
118 new VideoCaptureDeviceClient(this->AsWeakPtr()));
119 return result.Pass();
Ami GONE FROM CHROMIUM 2013/09/13 21:17:59 l.117-119 are equiv to return make_scoped_ptr(new
ncarter (slow) 2013/09/14 00:07:24 Actually, clang throws a hissy fit on that. Becaus
120 }
121
104 void VideoCaptureController::AddClient( 122 void VideoCaptureController::AddClient(
105 const VideoCaptureControllerID& id, 123 const VideoCaptureControllerID& id,
106 VideoCaptureControllerEventHandler* event_handler, 124 VideoCaptureControllerEventHandler* event_handler,
107 base::ProcessHandle render_process, 125 base::ProcessHandle render_process,
108 const media::VideoCaptureParams& params) { 126 const media::VideoCaptureParams& params) {
109 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 127 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
110 DVLOG(1) << "VideoCaptureController::AddClient, id " << id.device_id 128 DVLOG(1) << "VideoCaptureController::AddClient, id " << id.device_id
111 << ", (" << params.width 129 << ", (" << params.width
112 << ", " << params.height 130 << ", " << params.height
113 << ", " << params.frame_rate 131 << ", " << params.frame_rate
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
158 } 176 }
159 client->buffers.clear(); 177 client->buffers.clear();
160 178
161 int session_id = client->parameters.session_id; 179 int session_id = client->parameters.session_id;
162 controller_clients_.remove(client); 180 controller_clients_.remove(client);
163 delete client; 181 delete client;
164 182
165 return session_id; 183 return session_id;
166 } 184 }
167 185
168 void VideoCaptureController::StopSession( 186 void VideoCaptureController::StopSession(int session_id) {
169 int session_id) {
170 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 187 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
171 DVLOG(1) << "VideoCaptureController::StopSession, id " << session_id; 188 DVLOG(1) << "VideoCaptureController::StopSession, id " << session_id;
172 189
173 ControllerClient* client = FindClient(session_id, controller_clients_); 190 ControllerClient* client = FindClient(session_id, controller_clients_);
174 191
175 if (client) { 192 if (client) {
176 client->session_closed = true; 193 client->session_closed = true;
177 client->event_handler->OnEnded(client->controller_id); 194 client->event_handler->OnEnded(client->controller_id);
178 } 195 }
179 } 196 }
(...skipping 11 matching lines...) Expand all
191 if (!client || 208 if (!client ||
192 client->buffers.find(buffer_id) == client->buffers.end()) { 209 client->buffers.find(buffer_id) == client->buffers.end()) {
193 NOTREACHED(); 210 NOTREACHED();
194 return; 211 return;
195 } 212 }
196 213
197 client->buffers.erase(buffer_id); 214 client->buffers.erase(buffer_id);
198 buffer_pool_->RelinquishConsumerHold(buffer_id, 1); 215 buffer_pool_->RelinquishConsumerHold(buffer_id, 1);
199 } 216 }
200 217
201 scoped_refptr<media::VideoFrame> VideoCaptureController::ReserveOutputBuffer() { 218 scoped_refptr<media::VideoFrame>
202 base::AutoLock lock(buffer_pool_lock_); 219 VideoCaptureController::VideoCaptureDeviceClient::ReserveOutputBuffer() {
203 if (!buffer_pool_.get())
204 return NULL;
205 return buffer_pool_->ReserveI420VideoFrame(gfx::Size(frame_info_.width, 220 return buffer_pool_->ReserveI420VideoFrame(gfx::Size(frame_info_.width,
206 frame_info_.height), 221 frame_info_.height),
207 0); 222 0);
208 } 223 }
209 224
210 // Implements VideoCaptureDevice::EventHandler.
211 // OnIncomingCapturedFrame is called the thread running the capture device. 225 // OnIncomingCapturedFrame is called the thread running the capture device.
212 // I.e.- DirectShow thread on windows and v4l2_thread on Linux. 226 // I.e.- DirectShow thread on windows and v4l2_thread on Linux.
213 #if !defined(OS_IOS) && !defined(OS_ANDROID) 227 #if !defined(OS_IOS) && !defined(OS_ANDROID)
214 void VideoCaptureController::OnIncomingCapturedFrame( 228 void VideoCaptureController::VideoCaptureDeviceClient::OnIncomingCapturedFrame(
215 const uint8* data, 229 const uint8* data,
216 int length, 230 int length,
217 base::Time timestamp, 231 base::Time timestamp,
218 int rotation, 232 int rotation,
219 bool flip_vert, 233 bool flip_vert,
220 bool flip_horiz) { 234 bool flip_horiz) {
221 TRACE_EVENT0("video", "VideoCaptureController::OnIncomingCapturedFrame"); 235 TRACE_EVENT0("video", "VideoCaptureController::OnIncomingCapturedFrame");
222 236
223 scoped_refptr<media::VideoFrame> dst; 237 if (!buffer_pool_.get())
224 { 238 return;
225 base::AutoLock lock(buffer_pool_lock_); 239 scoped_refptr<media::VideoFrame> dst = buffer_pool_->ReserveI420VideoFrame(
226 if (!buffer_pool_.get()) 240 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 241
232 if (!dst.get()) 242 if (!dst.get())
233 return; 243 return;
234 244
235 uint8* yplane = dst->data(media::VideoFrame::kYPlane); 245 uint8* yplane = dst->data(media::VideoFrame::kYPlane);
236 uint8* uplane = dst->data(media::VideoFrame::kUPlane); 246 uint8* uplane = dst->data(media::VideoFrame::kUPlane);
237 uint8* vplane = dst->data(media::VideoFrame::kVPlane); 247 uint8* vplane = dst->data(media::VideoFrame::kVPlane);
238 int yplane_stride = frame_info_.width; 248 int yplane_stride = frame_info_.width;
239 int uv_plane_stride = (frame_info_.width + 1) / 2; 249 int uv_plane_stride = (frame_info_.width + 1) / 2;
240 int crop_x = 0; 250 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), 339 frame_info_.height * (flip_vert ^ flip_horiz ? -1 : 1),
330 frame_info_.width, 340 frame_info_.width,
331 frame_info_.height, 341 frame_info_.height,
332 rotation_mode, 342 rotation_mode,
333 origin_colorspace); 343 origin_colorspace);
334 } 344 }
335 BrowserThread::PostTask( 345 BrowserThread::PostTask(
336 BrowserThread::IO, 346 BrowserThread::IO,
337 FROM_HERE, 347 FROM_HERE,
338 base::Bind(&VideoCaptureController::DoIncomingCapturedFrameOnIOThread, 348 base::Bind(&VideoCaptureController::DoIncomingCapturedFrameOnIOThread,
339 this, 349 controller_,
340 dst, 350 dst,
341 timestamp)); 351 timestamp));
342 } 352 }
343 #else 353 #else
344 void VideoCaptureController::OnIncomingCapturedFrame( 354 void VideoCaptureController::VideoCaptureDeviceClient::OnIncomingCapturedFrame(
345 const uint8* data, 355 const uint8* data,
346 int length, 356 int length,
347 base::Time timestamp, 357 base::Time timestamp,
348 int rotation, 358 int rotation,
349 bool flip_vert, 359 bool flip_vert,
350 bool flip_horiz) { 360 bool flip_horiz) {
351 DCHECK(frame_info_.color == media::PIXEL_FORMAT_I420 || 361 DCHECK(frame_info_.color == media::PIXEL_FORMAT_I420 ||
352 frame_info_.color == media::PIXEL_FORMAT_YV12 || 362 frame_info_.color == media::PIXEL_FORMAT_YV12 ||
353 (rotation == 0 && !flip_vert && !flip_horiz)); 363 (rotation == 0 && !flip_vert && !flip_horiz));
354 364
355 TRACE_EVENT0("video", "VideoCaptureController::OnIncomingCapturedFrame"); 365 TRACE_EVENT0("video", "VideoCaptureController::OnIncomingCapturedFrame");
356 366
357 scoped_refptr<media::VideoFrame> dst; 367 if (!buffer_pool_)
Ami GONE FROM CHROMIUM 2013/09/13 21:17:59 There's a crbug to not need to defend against this
ncarter (slow) 2013/09/14 00:07:24 Yes. I've added the TODO to a different place in t
358 { 368 return;
359 base::AutoLock lock(buffer_pool_lock_); 369 scoped_refptr<media::VideoFrame> dst =
360 if (!buffer_pool_.get()) 370 buffer_pool_->ReserveI420VideoFrame(gfx::Size(frame_info_.width,
361 return; 371 frame_info_.height),
362 dst = buffer_pool_->ReserveI420VideoFrame(gfx::Size(frame_info_.width, 372 rotation);
363 frame_info_.height),
364 rotation);
365 }
366 373
367 if (!dst.get()) 374 if (!dst.get())
368 return; 375 return;
369 376
370 uint8* yplane = dst->data(media::VideoFrame::kYPlane); 377 uint8* yplane = dst->data(media::VideoFrame::kYPlane);
371 uint8* uplane = dst->data(media::VideoFrame::kUPlane); 378 uint8* uplane = dst->data(media::VideoFrame::kUPlane);
372 uint8* vplane = dst->data(media::VideoFrame::kVPlane); 379 uint8* vplane = dst->data(media::VideoFrame::kVPlane);
373 380
374 // Do color conversion from the camera format to I420. 381 // Do color conversion from the camera format to I420.
375 switch (frame_info_.color) { 382 switch (frame_info_.color) {
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
419 (frame_info_.width + chopped_width_) * 4, 426 (frame_info_.width + chopped_width_) * 4,
420 frame_info_.width, frame_info_.width / 2); 427 frame_info_.width, frame_info_.width / 2);
421 break; 428 break;
422 default: 429 default:
423 NOTREACHED(); 430 NOTREACHED();
424 } 431 }
425 432
426 BrowserThread::PostTask(BrowserThread::IO, 433 BrowserThread::PostTask(BrowserThread::IO,
427 FROM_HERE, 434 FROM_HERE,
428 base::Bind(&VideoCaptureController::DoIncomingCapturedFrameOnIOThread, 435 base::Bind(&VideoCaptureController::DoIncomingCapturedFrameOnIOThread,
429 this, dst, timestamp)); 436 controller_, dst, timestamp));
430 } 437 }
431 #endif // #if !defined(OS_IOS) && !defined(OS_ANDROID) 438 #endif // #if !defined(OS_IOS) && !defined(OS_ANDROID)
432 439
433 // OnIncomingCapturedVideoFrame is called the thread running the capture device. 440 // OnIncomingCapturedVideoFrame is called the thread running the capture device.
Ami GONE FROM CHROMIUM 2013/09/13 21:17:59 english
ncarter (slow) 2013/09/14 00:07:24 Deleted and elaborated the class comment.
434 void VideoCaptureController::OnIncomingCapturedVideoFrame( 441 void
442 VideoCaptureController::VideoCaptureDeviceClient::OnIncomingCapturedVideoFrame(
435 const scoped_refptr<media::VideoFrame>& frame, 443 const scoped_refptr<media::VideoFrame>& frame,
436 base::Time timestamp) { 444 base::Time timestamp) {
437 445
438 scoped_refptr<media::VideoFrame> target; 446 if (!buffer_pool_)
439 { 447 return;
440 base::AutoLock lock(buffer_pool_lock_);
441 448
442 if (!buffer_pool_.get()) 449 // If this is a frame that belongs to the buffer pool, we can forward it
443 return; 450 // directly to the IO thread and be done.
451 if (buffer_pool_->RecognizeReservedBuffer(
452 frame->shared_memory_handle()) >= 0) {
453 BrowserThread::PostTask(BrowserThread::IO,
454 FROM_HERE,
455 base::Bind(&VideoCaptureController::DoIncomingCapturedFrameOnIOThread,
456 controller_, frame, timestamp));
457 return;
458 }
444 459
445 // If this is a frame that belongs to the buffer pool, we can forward it 460 // Otherwise, this is a frame that belongs to the caller, and we must copy
446 // directly to the IO thread and be done. 461 // it to a frame from the buffer pool.
447 if (buffer_pool_->RecognizeReservedBuffer( 462 scoped_refptr<media::VideoFrame> target =
448 frame->shared_memory_handle()) >= 0) { 463 buffer_pool_->ReserveI420VideoFrame(gfx::Size(frame_info_.width,
449 BrowserThread::PostTask(BrowserThread::IO, 464 frame_info_.height),
450 FROM_HERE, 465 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 466
462 if (!target.get()) 467 if (!target.get())
463 return; 468 return;
464 469
465 // Validate the inputs. 470 // Validate the inputs.
466 if (frame->coded_size() != target->coded_size()) 471 if (frame->coded_size() != target->coded_size())
467 return; // Only exact copies are supported. 472 return; // Only exact copies are supported.
468 if (!(frame->format() == media::VideoFrame::I420 || 473 if (!(frame->format() == media::VideoFrame::I420 ||
469 frame->format() == media::VideoFrame::YV12 || 474 frame->format() == media::VideoFrame::YV12 ||
470 frame->format() == media::VideoFrame::RGB32)) { 475 frame->format() == media::VideoFrame::RGB32)) {
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
538 frame->stride(kRGBPlane), 543 frame->stride(kRGBPlane),
539 target->stride(kYPlane), 544 target->stride(kYPlane),
540 target->stride(kUPlane)); 545 target->stride(kUPlane));
541 break; 546 break;
542 } 547 }
543 } 548 }
544 549
545 BrowserThread::PostTask(BrowserThread::IO, 550 BrowserThread::PostTask(BrowserThread::IO,
546 FROM_HERE, 551 FROM_HERE,
547 base::Bind(&VideoCaptureController::DoIncomingCapturedFrameOnIOThread, 552 base::Bind(&VideoCaptureController::DoIncomingCapturedFrameOnIOThread,
548 this, target, timestamp)); 553 controller_, target, timestamp));
549 } 554 }
550 555
551 void VideoCaptureController::OnError() { 556 void VideoCaptureController::VideoCaptureDeviceClient::OnError() {
552 BrowserThread::PostTask(BrowserThread::IO, 557 BrowserThread::PostTask(BrowserThread::IO,
553 FROM_HERE, 558 FROM_HERE,
554 base::Bind(&VideoCaptureController::DoErrorOnIOThread, this)); 559 base::Bind(&VideoCaptureController::DoErrorOnIOThread, controller_));
555 } 560 }
556 561
557 void VideoCaptureController::OnFrameInfo( 562 void VideoCaptureController::VideoCaptureDeviceClient::OnFrameInfo(
558 const media::VideoCaptureCapability& info) { 563 const media::VideoCaptureCapability& info) {
559 frame_info_= info; 564 frame_info_ = info;
560 // Handle cases when |info| has odd numbers for width/height. 565 // Handle cases when |info| has odd numbers for width/height.
561 if (info.width & 1) { 566 if (info.width & 1) {
562 --frame_info_.width; 567 --frame_info_.width;
563 chopped_width_ = 1; 568 chopped_width_ = 1;
564 } else { 569 } else {
565 chopped_width_ = 0; 570 chopped_width_ = 0;
566 } 571 }
567 if (info.height & 1) { 572 if (info.height & 1) {
568 --frame_info_.height; 573 --frame_info_.height;
569 chopped_height_ = 1; 574 chopped_height_ = 1;
570 } else { 575 } else {
571 chopped_height_ = 0; 576 chopped_height_ = 0;
572 } 577 }
578
579 DCHECK(!buffer_pool_.get());
580
581 buffer_pool_ = new VideoCaptureBufferPool(
582 media::VideoFrame::AllocationSize(
583 media::VideoFrame::I420,
584 gfx::Size(frame_info_.width, frame_info_.height)),
585 kNoOfBuffers);
586
587 // Check whether all buffers were created successfully.
588 if (!buffer_pool_->Allocate()) {
589 // Transition to the error state.
590 buffer_pool_ = NULL;
591 OnError();
592 return;
593 }
594
573 BrowserThread::PostTask(BrowserThread::IO, 595 BrowserThread::PostTask(BrowserThread::IO,
574 FROM_HERE, 596 FROM_HERE,
575 base::Bind(&VideoCaptureController::DoFrameInfoOnIOThread, this)); 597 base::Bind(&VideoCaptureController::DoFrameInfoOnIOThread, controller_,
598 frame_info_, buffer_pool_));
576 } 599 }
577 600
578 void VideoCaptureController::OnFrameInfoChanged( 601 void VideoCaptureController::VideoCaptureDeviceClient::OnFrameInfoChanged(
579 const media::VideoCaptureCapability& info) { 602 const media::VideoCaptureCapability& info) {
580 BrowserThread::PostTask(BrowserThread::IO, 603 BrowserThread::PostTask(BrowserThread::IO,
581 FROM_HERE, 604 FROM_HERE,
582 base::Bind(&VideoCaptureController::DoFrameInfoChangedOnIOThread, 605 base::Bind(&VideoCaptureController::DoFrameInfoChangedOnIOThread,
583 this, info)); 606 controller_, info));
584 } 607 }
585 608
586 VideoCaptureController::~VideoCaptureController() { 609 VideoCaptureController::~VideoCaptureController() {
587 buffer_pool_ = NULL; // Release all buffers. 610 buffer_pool_ = NULL; // Release all buffers.
588 STLDeleteContainerPointers(controller_clients_.begin(), 611 STLDeleteContainerPointers(controller_clients_.begin(),
589 controller_clients_.end()); 612 controller_clients_.end());
590 } 613 }
591 614
592 void VideoCaptureController::DoIncomingCapturedFrameOnIOThread( 615 void VideoCaptureController::DoIncomingCapturedFrameOnIOThread(
593 const scoped_refptr<media::VideoFrame>& reserved_frame, 616 const scoped_refptr<media::VideoFrame>& reserved_frame,
(...skipping 20 matching lines...) Expand all
614 (*client_it)->event_handler->OnBufferReady((*client_it)->controller_id, 637 (*client_it)->event_handler->OnBufferReady((*client_it)->controller_id,
615 buffer_id, timestamp); 638 buffer_id, timestamp);
616 (*client_it)->buffers.insert(buffer_id); 639 (*client_it)->buffers.insert(buffer_id);
617 count++; 640 count++;
618 } 641 }
619 } 642 }
620 643
621 buffer_pool_->HoldForConsumers(buffer_id, count); 644 buffer_pool_->HoldForConsumers(buffer_id, count);
622 } 645 }
623 646
624 void VideoCaptureController::DoFrameInfoOnIOThread() { 647 void VideoCaptureController::DoFrameInfoOnIOThread(
648 const media::VideoCaptureCapability& frame_info,
649 const scoped_refptr<VideoCaptureBufferPool>& buffer_pool) {
625 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 650 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
626 DCHECK(!buffer_pool_.get()) << "Frame info should happen only once."; 651 DCHECK(!buffer_pool_.get()) << "Frame info should happen only once.";
627 652
628 // Allocate memory only when device has been started. 653 // Allocate memory only when device has been started.
629 if (state_ != VIDEO_CAPTURE_STATE_STARTED) 654 if (state_ != VIDEO_CAPTURE_STATE_STARTED)
630 return; 655 return;
631 656
632 scoped_refptr<VideoCaptureBufferPool> buffer_pool = 657 frame_info_ = frame_info;
633 new VideoCaptureBufferPool(
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; 658 frame_info_available_ = true;
659 buffer_pool_ = buffer_pool;
650 660
651 for (ControllerClients::iterator client_it = controller_clients_.begin(); 661 for (ControllerClients::iterator client_it = controller_clients_.begin();
652 client_it != controller_clients_.end(); ++client_it) { 662 client_it != controller_clients_.end(); ++client_it) {
653 if ((*client_it)->session_closed) 663 if ((*client_it)->session_closed)
654 continue; 664 continue;
655 665
656 SendFrameInfoAndBuffers(*client_it); 666 SendFrameInfoAndBuffers(*client_it);
657 } 667 }
658 } 668 }
659 669
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
731 } 741 }
732 return NULL; 742 return NULL;
733 } 743 }
734 744
735 int VideoCaptureController::GetClientCount() { 745 int VideoCaptureController::GetClientCount() {
736 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 746 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
737 return controller_clients_.size(); 747 return controller_clients_.size();
738 } 748 }
739 749
740 } // namespace content 750 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698