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

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

Issue 2686763002: [Mojo Video Capture] Split OnIncomingCapturedVideoFrame() to OnNewBuffer() and OnFrameReadyInBuffer( (Closed)
Patch Set: rebase Created 3 years, 10 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
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 <stddef.h> 7 #include <stddef.h>
8 #include <stdint.h> 8 #include <stdint.h>
9 9
10 #include <map> 10 #include <map>
11 #include <set> 11 #include <set>
12 12
13 #include "base/bind.h" 13 #include "base/bind.h"
14 #include "base/command_line.h" 14 #include "base/command_line.h"
15 #include "base/memory/ptr_util.h" 15 #include "base/memory/ptr_util.h"
16 #include "base/metrics/histogram_macros.h" 16 #include "base/metrics/histogram_macros.h"
17 #include "base/metrics/sparse_histogram.h" 17 #include "base/metrics/sparse_histogram.h"
18 #include "build/build_config.h" 18 #include "build/build_config.h"
19 #include "components/display_compositor/gl_helper.h" 19 #include "components/display_compositor/gl_helper.h"
20 #include "content/browser/renderer_host/media/media_stream_manager.h" 20 #include "content/browser/renderer_host/media/media_stream_manager.h"
21 #include "content/browser/renderer_host/media/video_capture_manager.h" 21 #include "content/browser/renderer_host/media/video_capture_manager.h"
22 #include "content/common/video_capture.mojom.h"
22 #include "content/public/browser/browser_thread.h" 23 #include "content/public/browser/browser_thread.h"
23 #include "content/public/common/content_switches.h" 24 #include "content/public/common/content_switches.h"
24 #include "media/base/video_frame.h" 25 #include "media/base/video_frame.h"
25 #include "media/capture/video/video_capture_buffer_pool.h" 26 #include "media/capture/video/video_capture_buffer_pool.h"
26 #include "media/capture/video/video_capture_buffer_tracker_factory_impl.h" 27 #include "media/capture/video/video_capture_buffer_tracker_factory_impl.h"
27 #include "media/capture/video/video_capture_device_client.h" 28 #include "media/capture/video/video_capture_device_client.h"
28 #include "mojo/public/cpp/system/platform_handle.h" 29 #include "mojo/public/cpp/system/platform_handle.h"
29 30
30 #if !defined(OS_ANDROID) 31 #if !defined(OS_ANDROID)
31 #include "content/browser/compositor/image_transport_factory.h" 32 #include "content/browser/compositor/image_transport_factory.h"
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
86 87
87 // Indicates whether the client is paused, if true, VideoCaptureController 88 // Indicates whether the client is paused, if true, VideoCaptureController
88 // stops updating its buffer. 89 // stops updating its buffer.
89 bool paused; 90 bool paused;
90 }; 91 };
91 92
92 VideoCaptureController::BufferContext::BufferContext( 93 VideoCaptureController::BufferContext::BufferContext(
93 int buffer_context_id, 94 int buffer_context_id,
94 int buffer_id, 95 int buffer_id,
95 media::VideoFrameConsumerFeedbackObserver* consumer_feedback_observer, 96 media::VideoFrameConsumerFeedbackObserver* consumer_feedback_observer,
96 media::FrameBufferPool* frame_buffer_pool) 97 mojo::ScopedSharedBufferHandle handle)
97 : buffer_context_id_(buffer_context_id), 98 : buffer_context_id_(buffer_context_id),
98 buffer_id_(buffer_id), 99 buffer_id_(buffer_id),
99 is_retired_(false), 100 is_retired_(false),
100 frame_feedback_id_(0), 101 frame_feedback_id_(0),
101 consumer_feedback_observer_(consumer_feedback_observer), 102 consumer_feedback_observer_(consumer_feedback_observer),
102 frame_buffer_pool_(frame_buffer_pool), 103 buffer_handle_(std::move(handle)),
103 max_consumer_utilization_( 104 max_consumer_utilization_(
104 media::VideoFrameConsumerFeedbackObserver::kNoUtilizationRecorded), 105 media::VideoFrameConsumerFeedbackObserver::kNoUtilizationRecorded),
105 consumer_hold_count_(0) {} 106 consumer_hold_count_(0) {}
106 107
107 VideoCaptureController::BufferContext::~BufferContext() = default; 108 VideoCaptureController::BufferContext::~BufferContext() = default;
108 109
109 VideoCaptureController::BufferContext::BufferContext( 110 VideoCaptureController::BufferContext::BufferContext(
110 const VideoCaptureController::BufferContext& other) = default; 111 VideoCaptureController::BufferContext&& other) = default;
111 112
112 VideoCaptureController::BufferContext& VideoCaptureController::BufferContext:: 113 VideoCaptureController::BufferContext& VideoCaptureController::BufferContext::
113 operator=(const BufferContext& other) = default; 114 operator=(BufferContext&& other) = default;
114 115
115 void VideoCaptureController::BufferContext::RecordConsumerUtilization( 116 void VideoCaptureController::BufferContext::RecordConsumerUtilization(
116 double utilization) { 117 double utilization) {
117 if (std::isfinite(utilization) && utilization >= 0.0) { 118 if (std::isfinite(utilization) && utilization >= 0.0) {
118 max_consumer_utilization_ = 119 max_consumer_utilization_ =
119 std::max(max_consumer_utilization_, utilization); 120 std::max(max_consumer_utilization_, utilization);
120 } 121 }
121 } 122 }
122 123
123 void VideoCaptureController::BufferContext::IncreaseConsumerCount() { 124 void VideoCaptureController::BufferContext::IncreaseConsumerCount() {
124 if (consumer_hold_count_ == 0)
125 if (frame_buffer_pool_ != nullptr)
126 frame_buffer_pool_->SetBufferHold(buffer_id_);
127 consumer_hold_count_++; 125 consumer_hold_count_++;
128 } 126 }
129 127
130 void VideoCaptureController::BufferContext::DecreaseConsumerCount() { 128 void VideoCaptureController::BufferContext::DecreaseConsumerCount() {
131 consumer_hold_count_--; 129 consumer_hold_count_--;
132 if (consumer_hold_count_ == 0) { 130 if (consumer_hold_count_ == 0) {
133 if (consumer_feedback_observer_ != nullptr && 131 if (consumer_feedback_observer_ != nullptr &&
134 max_consumer_utilization_ != 132 max_consumer_utilization_ !=
135 media::VideoFrameConsumerFeedbackObserver::kNoUtilizationRecorded) { 133 media::VideoFrameConsumerFeedbackObserver::kNoUtilizationRecorded) {
136 consumer_feedback_observer_->OnUtilizationReport( 134 consumer_feedback_observer_->OnUtilizationReport(
137 frame_feedback_id_, max_consumer_utilization_); 135 frame_feedback_id_, max_consumer_utilization_);
138 } 136 }
139 if (frame_buffer_pool_ != nullptr) 137 buffer_read_permission_.reset();
140 frame_buffer_pool_->ReleaseBufferHold(buffer_id_);
141 max_consumer_utilization_ = 138 max_consumer_utilization_ =
142 media::VideoFrameConsumerFeedbackObserver::kNoUtilizationRecorded; 139 media::VideoFrameConsumerFeedbackObserver::kNoUtilizationRecorded;
143 } 140 }
144 } 141 }
145 142
146 bool VideoCaptureController::BufferContext::HasZeroConsumerHoldCount() { 143 mojo::ScopedSharedBufferHandle
147 return consumer_hold_count_ == 0; 144 VideoCaptureController::BufferContext::CloneHandle() {
145 return buffer_handle_->Clone();
148 } 146 }
149 147
150 VideoCaptureController::VideoCaptureController() 148 VideoCaptureController::VideoCaptureController()
151 : frame_buffer_pool_(nullptr), 149 : consumer_feedback_observer_(nullptr),
152 consumer_feedback_observer_(nullptr),
153 state_(VIDEO_CAPTURE_STATE_STARTED), 150 state_(VIDEO_CAPTURE_STATE_STARTED),
154 has_received_frames_(false), 151 has_received_frames_(false),
155 weak_ptr_factory_(this) { 152 weak_ptr_factory_(this) {
156 DCHECK_CURRENTLY_ON(BrowserThread::IO); 153 DCHECK_CURRENTLY_ON(BrowserThread::IO);
157 } 154 }
158 155
159 VideoCaptureController::~VideoCaptureController() = default; 156 VideoCaptureController::~VideoCaptureController() = default;
160 157
161 base::WeakPtr<VideoCaptureController> 158 base::WeakPtr<VideoCaptureController>
162 VideoCaptureController::GetWeakPtrForIOThread() { 159 VideoCaptureController::GetWeakPtrForIOThread() {
163 return weak_ptr_factory_.GetWeakPtr(); 160 return weak_ptr_factory_.GetWeakPtr();
164 } 161 }
165 162
166 void VideoCaptureController::SetFrameBufferPool(
167 std::unique_ptr<media::FrameBufferPool> frame_buffer_pool) {
168 DCHECK_CURRENTLY_ON(BrowserThread::IO);
169 frame_buffer_pool_ = std::move(frame_buffer_pool);
170 // Update existing BufferContext entries.
171 for (auto& entry : buffer_contexts_)
172 entry.set_frame_buffer_pool(frame_buffer_pool_.get());
173 }
174
175 void VideoCaptureController::SetConsumerFeedbackObserver( 163 void VideoCaptureController::SetConsumerFeedbackObserver(
176 std::unique_ptr<media::VideoFrameConsumerFeedbackObserver> 164 std::unique_ptr<media::VideoFrameConsumerFeedbackObserver>
177 consumer_feedback_observer) { 165 consumer_feedback_observer) {
178 DCHECK_CURRENTLY_ON(BrowserThread::IO); 166 DCHECK_CURRENTLY_ON(BrowserThread::IO);
179 consumer_feedback_observer_ = std::move(consumer_feedback_observer); 167 consumer_feedback_observer_ = std::move(consumer_feedback_observer);
180 // Update existing BufferContext entries. 168 // Update existing BufferContext entries.
181 for (auto& entry : buffer_contexts_) 169 for (auto& entry : buffer_contexts_)
182 entry.set_consumer_feedback_observer(consumer_feedback_observer_.get()); 170 entry.set_consumer_feedback_observer(consumer_feedback_observer_.get());
183 } 171 }
184 172
(...skipping 167 matching lines...) Expand 10 before | Expand all | Expand 10 after
352 OnClientFinishedConsumingBuffer(client, buffer_id, 340 OnClientFinishedConsumingBuffer(client, buffer_id,
353 consumer_resource_utilization); 341 consumer_resource_utilization);
354 } 342 }
355 343
356 const media::VideoCaptureFormat& VideoCaptureController::GetVideoCaptureFormat() 344 const media::VideoCaptureFormat& VideoCaptureController::GetVideoCaptureFormat()
357 const { 345 const {
358 DCHECK_CURRENTLY_ON(BrowserThread::IO); 346 DCHECK_CURRENTLY_ON(BrowserThread::IO);
359 return video_capture_format_; 347 return video_capture_format_;
360 } 348 }
361 349
362 void VideoCaptureController::OnIncomingCapturedVideoFrame( 350 void VideoCaptureController::OnNewBufferHandle(
363 media::VideoCaptureDevice::Client::Buffer buffer, 351 int buffer_id,
364 scoped_refptr<VideoFrame> frame) { 352 std::unique_ptr<media::VideoCaptureDevice::Client::Buffer::HandleProvider>
353 handle_provider) {
365 DCHECK_CURRENTLY_ON(BrowserThread::IO); 354 DCHECK_CURRENTLY_ON(BrowserThread::IO);
366 const int buffer_id_from_producer = buffer.id(); 355 DCHECK(FindUnretiredBufferContextFromBufferId(buffer_id) ==
367 DCHECK_NE(buffer_id_from_producer, media::VideoCaptureBufferPool::kInvalidId); 356 buffer_contexts_.end());
368 auto buffer_context_iter = 357 buffer_contexts_.emplace_back(
369 FindUnretiredBufferContextFromBufferId(buffer_id_from_producer); 358 next_buffer_context_id_++, buffer_id, consumer_feedback_observer_.get(),
370 if (buffer_context_iter == buffer_contexts_.end()) { 359 handle_provider->GetHandleForInterProcessTransit());
371 // A new buffer has been shared with us. Create new BufferContext. 360 }
372 buffer_contexts_.emplace_back( 361
373 next_buffer_context_id_++, buffer_id_from_producer, 362 void VideoCaptureController::OnFrameReadyInBuffer(
374 consumer_feedback_observer_.get(), frame_buffer_pool_.get()); 363 int buffer_id,
375 buffer_context_iter = buffer_contexts_.end() - 1; 364 int frame_feedback_id,
376 } 365 std::unique_ptr<
377 buffer_context_iter->set_frame_feedback_id(buffer.frame_feedback_id()); 366 media::VideoCaptureDevice::Client::Buffer::ScopedAccessPermission>
378 DCHECK(buffer_context_iter->HasZeroConsumerHoldCount()); 367 buffer_read_permission,
368 media::mojom::VideoFrameInfoPtr frame_info) {
369 DCHECK_CURRENTLY_ON(BrowserThread::IO);
370 DCHECK_NE(buffer_id, media::VideoCaptureBufferPool::kInvalidId);
371
372 auto buffer_context_iter = FindUnretiredBufferContextFromBufferId(buffer_id);
373 DCHECK(buffer_context_iter != buffer_contexts_.end());
374 buffer_context_iter->set_frame_feedback_id(frame_feedback_id);
375 DCHECK(!buffer_context_iter->HasConsumers());
379 376
380 if (state_ == VIDEO_CAPTURE_STATE_STARTED) { 377 if (state_ == VIDEO_CAPTURE_STATE_STARTED) {
381 if (!frame->metadata()->HasKey(VideoFrameMetadata::FRAME_RATE)) {
382 frame->metadata()->SetDouble(VideoFrameMetadata::FRAME_RATE,
383 video_capture_format_.frame_rate);
384 }
385 std::unique_ptr<base::DictionaryValue> metadata =
386 frame->metadata()->CopyInternalValues();
387
388 // Only I420 and Y16 pixel formats are currently supported.
389 DCHECK(frame->format() == media::PIXEL_FORMAT_I420 ||
390 frame->format() == media::PIXEL_FORMAT_Y16)
391 << "Unsupported pixel format: "
392 << media::VideoPixelFormatToString(frame->format());
393
394 // Sanity-checks to confirm |frame| is actually being backed by |buffer|.
395 auto buffer_access =
396 buffer.handle_provider()->GetHandleForInProcessAccess();
397 DCHECK(frame->storage_type() == media::VideoFrame::STORAGE_SHMEM);
398 DCHECK(frame->data(media::VideoFrame::kYPlane) >= buffer_access->data() &&
399 (frame->data(media::VideoFrame::kYPlane) <
400 (buffer_access->data() + buffer_access->mapped_size())))
401 << "VideoFrame does not appear to be backed by Buffer";
402
403 const int buffer_context_id = buffer_context_iter->buffer_context_id(); 378 const int buffer_context_id = buffer_context_iter->buffer_context_id();
404 for (const auto& client : controller_clients_) { 379 for (const auto& client : controller_clients_) {
405 if (client->session_closed || client->paused) 380 if (client->session_closed || client->paused)
406 continue; 381 continue;
407 382
408 // On the first use of a BufferContext on a client, share the memory 383 // On the first use of a BufferContext for a particular client, call
409 // handles. 384 // OnBufferCreated().
410 auto known_buffers_entry_iter = std::find( 385 if (!base::ContainsValue(client->known_buffer_context_ids,
411 std::begin(client->known_buffer_context_ids), 386 buffer_context_id)) {
412 std::end(client->known_buffer_context_ids), buffer_context_id);
413 bool is_new_buffer = false;
414 if (known_buffers_entry_iter ==
415 std::end(client->known_buffer_context_ids)) {
416 client->known_buffer_context_ids.push_back(buffer_context_id); 387 client->known_buffer_context_ids.push_back(buffer_context_id);
417 is_new_buffer = true; 388 const size_t mapped_size =
389 media::VideoCaptureFormat(frame_info->coded_size, 0.0f,
390 frame_info->pixel_format,
391 frame_info->storage_type)
392 .ImageAllocationSize();
393 client->event_handler->OnBufferCreated(
394 client->controller_id, buffer_context_iter->CloneHandle(),
395 mapped_size, buffer_context_id);
418 } 396 }
419 if (is_new_buffer) { 397
420 mojo::ScopedSharedBufferHandle handle =
421 buffer.handle_provider()->GetHandleForInterProcessTransit();
422 client->event_handler->OnBufferCreated(
423 client->controller_id, std::move(handle),
424 buffer_access->mapped_size(), buffer_context_id);
425 }
426 client->event_handler->OnBufferReady(client->controller_id, 398 client->event_handler->OnBufferReady(client->controller_id,
427 buffer_context_id, frame); 399 buffer_context_id, frame_info);
428 400
429 auto buffers_in_use_entry_iter = 401 if (!base::ContainsValue(client->buffers_in_use, buffer_context_id))
430 std::find(std::begin(client->buffers_in_use),
431 std::end(client->buffers_in_use), buffer_context_id);
432 if (buffers_in_use_entry_iter == std::end(client->buffers_in_use))
433 client->buffers_in_use.push_back(buffer_context_id); 402 client->buffers_in_use.push_back(buffer_context_id);
434 else 403 else
435 DCHECK(false) << "Unexpected duplicate buffer: " << buffer_context_id; 404 NOTREACHED() << "Unexpected duplicate buffer: " << buffer_context_id;
405
436 buffer_context_iter->IncreaseConsumerCount(); 406 buffer_context_iter->IncreaseConsumerCount();
437 } 407 }
408 if (buffer_context_iter->HasConsumers()) {
409 buffer_context_iter->set_read_permission(
410 std::move(buffer_read_permission));
411 }
438 } 412 }
439 413
440 if (!has_received_frames_) { 414 if (!has_received_frames_) {
441 UMA_HISTOGRAM_COUNTS("Media.VideoCapture.Width", 415 UMA_HISTOGRAM_COUNTS("Media.VideoCapture.Width",
442 frame->visible_rect().width()); 416 frame_info->coded_size.width());
443 UMA_HISTOGRAM_COUNTS("Media.VideoCapture.Height", 417 UMA_HISTOGRAM_COUNTS("Media.VideoCapture.Height",
444 frame->visible_rect().height()); 418 frame_info->coded_size.height());
445 UMA_HISTOGRAM_ASPECT_RATIO("Media.VideoCapture.AspectRatio", 419 UMA_HISTOGRAM_ASPECT_RATIO("Media.VideoCapture.AspectRatio",
446 frame->visible_rect().width(), 420 frame_info->coded_size.width(),
447 frame->visible_rect().height()); 421 frame_info->coded_size.height());
448 double frame_rate = 0.0f; 422 double frame_rate = 0.0f;
449 if (!frame->metadata()->GetDouble(VideoFrameMetadata::FRAME_RATE, 423 media::VideoFrameMetadata metadata;
450 &frame_rate)) { 424 metadata.MergeInternalValuesFrom(*frame_info->metadata);
425 if (!metadata.GetDouble(VideoFrameMetadata::FRAME_RATE, &frame_rate)) {
451 frame_rate = video_capture_format_.frame_rate; 426 frame_rate = video_capture_format_.frame_rate;
452 } 427 }
453 UMA_HISTOGRAM_COUNTS("Media.VideoCapture.FrameRate", frame_rate); 428 UMA_HISTOGRAM_COUNTS("Media.VideoCapture.FrameRate", frame_rate);
454 has_received_frames_ = true; 429 has_received_frames_ = true;
455 } 430 }
456 } 431 }
457 432
433 void VideoCaptureController::OnBufferRetired(int buffer_id) {
434 DCHECK_CURRENTLY_ON(BrowserThread::IO);
435
436 auto buffer_context_iter = FindUnretiredBufferContextFromBufferId(buffer_id);
437 DCHECK(buffer_context_iter != buffer_contexts_.end());
438
439 // If there are any clients still using the buffer, we need to allow them
440 // to finish up. We need to hold on to the BufferContext entry until then,
441 // because it contains the consumer hold.
442 if (!buffer_context_iter->HasConsumers())
443 ReleaseBufferContext(buffer_context_iter);
444 else
445 buffer_context_iter->set_is_retired();
446 }
447
458 void VideoCaptureController::OnError() { 448 void VideoCaptureController::OnError() {
459 DCHECK_CURRENTLY_ON(BrowserThread::IO); 449 DCHECK_CURRENTLY_ON(BrowserThread::IO);
460 state_ = VIDEO_CAPTURE_STATE_ERROR; 450 state_ = VIDEO_CAPTURE_STATE_ERROR;
461 451
462 for (const auto& client : controller_clients_) { 452 for (const auto& client : controller_clients_) {
463 if (client->session_closed) 453 if (client->session_closed)
464 continue; 454 continue;
465 client->event_handler->OnError(client->controller_id); 455 client->event_handler->OnError(client->controller_id);
466 } 456 }
467 } 457 }
468 458
469 void VideoCaptureController::OnLog(const std::string& message) { 459 void VideoCaptureController::OnLog(const std::string& message) {
470 DCHECK_CURRENTLY_ON(BrowserThread::IO); 460 DCHECK_CURRENTLY_ON(BrowserThread::IO);
471 MediaStreamManager::SendMessageToNativeLog("Video capture: " + message); 461 MediaStreamManager::SendMessageToNativeLog("Video capture: " + message);
472 } 462 }
473 463
474 void VideoCaptureController::OnBufferRetired(int buffer_id) {
475 DCHECK_CURRENTLY_ON(BrowserThread::IO);
476
477 auto buffer_context_iter = FindUnretiredBufferContextFromBufferId(buffer_id);
478 DCHECK(buffer_context_iter != buffer_contexts_.end());
479
480 // If there are any clients still using the buffer, we need to allow them
481 // to finish up. We need to hold on to the BufferContext entry until then,
482 // because it contains the consumer hold.
483 if (buffer_context_iter->HasZeroConsumerHoldCount())
484 ReleaseBufferContext(buffer_context_iter);
485 else
486 buffer_context_iter->set_is_retired();
487 }
488
489 VideoCaptureController::ControllerClient* VideoCaptureController::FindClient( 464 VideoCaptureController::ControllerClient* VideoCaptureController::FindClient(
490 VideoCaptureControllerID id, 465 VideoCaptureControllerID id,
491 VideoCaptureControllerEventHandler* handler, 466 VideoCaptureControllerEventHandler* handler,
492 const ControllerClients& clients) { 467 const ControllerClients& clients) {
493 for (const auto& client : clients) { 468 for (const auto& client : clients) {
494 if (client->controller_id == id && client->event_handler == handler) 469 if (client->controller_id == id && client->event_handler == handler)
495 return client.get(); 470 return client.get();
496 } 471 }
497 return nullptr; 472 return nullptr;
498 } 473 }
(...skipping 29 matching lines...) Expand all
528 void VideoCaptureController::OnClientFinishedConsumingBuffer( 503 void VideoCaptureController::OnClientFinishedConsumingBuffer(
529 ControllerClient* client, 504 ControllerClient* client,
530 int buffer_context_id, 505 int buffer_context_id,
531 double consumer_resource_utilization) { 506 double consumer_resource_utilization) {
532 auto buffer_context_iter = 507 auto buffer_context_iter =
533 FindBufferContextFromBufferContextId(buffer_context_id); 508 FindBufferContextFromBufferContextId(buffer_context_id);
534 DCHECK(buffer_context_iter != buffer_contexts_.end()); 509 DCHECK(buffer_context_iter != buffer_contexts_.end());
535 510
536 buffer_context_iter->RecordConsumerUtilization(consumer_resource_utilization); 511 buffer_context_iter->RecordConsumerUtilization(consumer_resource_utilization);
537 buffer_context_iter->DecreaseConsumerCount(); 512 buffer_context_iter->DecreaseConsumerCount();
538 if (buffer_context_iter->HasZeroConsumerHoldCount() && 513 if (!buffer_context_iter->HasConsumers() &&
539 buffer_context_iter->is_retired()) { 514 buffer_context_iter->is_retired()) {
540 ReleaseBufferContext(buffer_context_iter); 515 ReleaseBufferContext(buffer_context_iter);
541 } 516 }
542 } 517 }
543 518
544 void VideoCaptureController::ReleaseBufferContext( 519 void VideoCaptureController::ReleaseBufferContext(
545 const std::vector<BufferContext>::iterator& buffer_context_iter) { 520 const std::vector<BufferContext>::iterator& buffer_context_iter) {
546 for (const auto& client : controller_clients_) { 521 for (const auto& client : controller_clients_) {
547 if (client->session_closed) 522 if (client->session_closed)
548 continue; 523 continue;
549 auto entry_iter = std::find(std::begin(client->known_buffer_context_ids), 524 auto entry_iter = std::find(std::begin(client->known_buffer_context_ids),
550 std::end(client->known_buffer_context_ids), 525 std::end(client->known_buffer_context_ids),
551 buffer_context_iter->buffer_context_id()); 526 buffer_context_iter->buffer_context_id());
552 if (entry_iter != std::end(client->known_buffer_context_ids)) { 527 if (entry_iter != std::end(client->known_buffer_context_ids)) {
553 client->known_buffer_context_ids.erase(entry_iter); 528 client->known_buffer_context_ids.erase(entry_iter);
554 client->event_handler->OnBufferDestroyed( 529 client->event_handler->OnBufferDestroyed(
555 client->controller_id, buffer_context_iter->buffer_context_id()); 530 client->controller_id, buffer_context_iter->buffer_context_id());
556 } 531 }
557 } 532 }
558 buffer_contexts_.erase(buffer_context_iter); 533 buffer_contexts_.erase(buffer_context_iter);
559 } 534 }
560 535
561 } // namespace content 536 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698