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

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: 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"
32 #endif 33 #endif
33 34
34 using media::VideoCaptureFormat; 35 using media::VideoCaptureFormat;
35 using media::VideoFrame; 36 using media::VideoFrame;
36 using media::VideoFrameMetadata; 37 using media::VideoFrameMetadata;
37 38
38 namespace content { 39 namespace content {
39 40
40 namespace { 41 namespace {
41 42
42 static const int kInfiniteRatio = 99999; 43 static const int kInfiniteRatio = 99999;
43 44
44 #define UMA_HISTOGRAM_ASPECT_RATIO(name, width, height) \ 45 #define UMA_HISTOGRAM_ASPECT_RATIO(name, width, height) \
45 UMA_HISTOGRAM_SPARSE_SLOWLY( \ 46 UMA_HISTOGRAM_SPARSE_SLOWLY( \
46 name, (height) ? ((width)*100) / (height) : kInfiniteRatio); 47 name, (height) ? ((width)*100) / (height) : kInfiniteRatio);
47 48
49 // This manual copy routine is needed because base::DictionaryValue does not
miu 2017/02/14 00:41:27 Maybe it'd be better to fix the mojo impl? Meaning
chfremer 2017/02/14 21:15:16 Excellent suggestion. I didn't fully realize how d
50 // allow the default copy operator.
51 media::mojom::VideoFrameInfoPtr CloneFrameInfo(
52 media::mojom::VideoFrameInfoPtr* frame_info) {
miu 2017/02/14 00:41:27 Seems that the type of this argument should be:
chfremer 2017/02/14 21:15:16 Done.
53 auto result = media::mojom::VideoFrameInfo::New();
54 result->timestamp = (*frame_info)->timestamp;
55 result->pixel_format = (*frame_info)->pixel_format;
56 result->storage_type = (*frame_info)->storage_type;
57 result->coded_size = (*frame_info)->coded_size;
58 result->visible_rect = (*frame_info)->visible_rect;
59 result->metadata = base::MakeUnique<base::DictionaryValue>();
60 result->metadata->MergeDictionary((*frame_info)->metadata.get());
61 return result;
62 }
63
48 } // anonymous namespace 64 } // anonymous namespace
49 65
50 struct VideoCaptureController::ControllerClient { 66 struct VideoCaptureController::ControllerClient {
51 ControllerClient(VideoCaptureControllerID id, 67 ControllerClient(VideoCaptureControllerID id,
52 VideoCaptureControllerEventHandler* handler, 68 VideoCaptureControllerEventHandler* handler,
53 media::VideoCaptureSessionId session_id, 69 media::VideoCaptureSessionId session_id,
54 const media::VideoCaptureParams& params) 70 const media::VideoCaptureParams& params)
55 : controller_id(id), 71 : controller_id(id),
56 event_handler(handler), 72 event_handler(handler),
57 session_id(session_id), 73 session_id(session_id),
(...skipping 28 matching lines...) Expand all
86 102
87 // Indicates whether the client is paused, if true, VideoCaptureController 103 // Indicates whether the client is paused, if true, VideoCaptureController
88 // stops updating its buffer. 104 // stops updating its buffer.
89 bool paused; 105 bool paused;
90 }; 106 };
91 107
92 VideoCaptureController::BufferContext::BufferContext( 108 VideoCaptureController::BufferContext::BufferContext(
93 int buffer_context_id, 109 int buffer_context_id,
94 int buffer_id, 110 int buffer_id,
95 media::VideoFrameConsumerFeedbackObserver* consumer_feedback_observer, 111 media::VideoFrameConsumerFeedbackObserver* consumer_feedback_observer,
96 media::FrameBufferPool* frame_buffer_pool) 112 mojo::ScopedSharedBufferHandle handle)
97 : buffer_context_id_(buffer_context_id), 113 : buffer_context_id_(buffer_context_id),
98 buffer_id_(buffer_id), 114 buffer_id_(buffer_id),
99 is_retired_(false), 115 is_retired_(false),
100 frame_feedback_id_(0), 116 frame_feedback_id_(0),
101 consumer_feedback_observer_(consumer_feedback_observer), 117 consumer_feedback_observer_(consumer_feedback_observer),
102 frame_buffer_pool_(frame_buffer_pool), 118 buffer_handle_(std::move(handle)),
103 max_consumer_utilization_( 119 max_consumer_utilization_(
104 media::VideoFrameConsumerFeedbackObserver::kNoUtilizationRecorded), 120 media::VideoFrameConsumerFeedbackObserver::kNoUtilizationRecorded),
105 consumer_hold_count_(0) {} 121 consumer_hold_count_(0) {}
106 122
107 VideoCaptureController::BufferContext::~BufferContext() = default; 123 VideoCaptureController::BufferContext::~BufferContext() = default;
108 124
109 VideoCaptureController::BufferContext::BufferContext( 125 VideoCaptureController::BufferContext::BufferContext(
110 const VideoCaptureController::BufferContext& other) = default; 126 VideoCaptureController::BufferContext&& other) = default;
111 127
112 VideoCaptureController::BufferContext& VideoCaptureController::BufferContext:: 128 VideoCaptureController::BufferContext& VideoCaptureController::BufferContext::
113 operator=(const BufferContext& other) = default; 129 operator=(BufferContext&& other) = default;
114 130
115 void VideoCaptureController::BufferContext::RecordConsumerUtilization( 131 void VideoCaptureController::BufferContext::RecordConsumerUtilization(
116 double utilization) { 132 double utilization) {
117 if (std::isfinite(utilization) && utilization >= 0.0) { 133 if (std::isfinite(utilization) && utilization >= 0.0) {
118 max_consumer_utilization_ = 134 max_consumer_utilization_ =
119 std::max(max_consumer_utilization_, utilization); 135 std::max(max_consumer_utilization_, utilization);
120 } 136 }
121 } 137 }
122 138
123 void VideoCaptureController::BufferContext::IncreaseConsumerCount() { 139 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_++; 140 consumer_hold_count_++;
128 } 141 }
129 142
130 void VideoCaptureController::BufferContext::DecreaseConsumerCount() { 143 void VideoCaptureController::BufferContext::DecreaseConsumerCount() {
131 consumer_hold_count_--; 144 consumer_hold_count_--;
132 if (consumer_hold_count_ == 0) { 145 if (consumer_hold_count_ == 0) {
133 if (consumer_feedback_observer_ != nullptr && 146 if (consumer_feedback_observer_ != nullptr &&
134 max_consumer_utilization_ != 147 max_consumer_utilization_ !=
135 media::VideoFrameConsumerFeedbackObserver::kNoUtilizationRecorded) { 148 media::VideoFrameConsumerFeedbackObserver::kNoUtilizationRecorded) {
136 consumer_feedback_observer_->OnUtilizationReport( 149 consumer_feedback_observer_->OnUtilizationReport(
137 frame_feedback_id_, max_consumer_utilization_); 150 frame_feedback_id_, max_consumer_utilization_);
138 } 151 }
139 if (frame_buffer_pool_ != nullptr) 152 buffer_read_permission_.reset();
140 frame_buffer_pool_->ReleaseBufferHold(buffer_id_);
141 max_consumer_utilization_ = 153 max_consumer_utilization_ =
142 media::VideoFrameConsumerFeedbackObserver::kNoUtilizationRecorded; 154 media::VideoFrameConsumerFeedbackObserver::kNoUtilizationRecorded;
143 } 155 }
144 } 156 }
145 157
146 bool VideoCaptureController::BufferContext::HasZeroConsumerHoldCount() { 158 bool VideoCaptureController::BufferContext::HasZeroConsumerHoldCount() {
147 return consumer_hold_count_ == 0; 159 return consumer_hold_count_ == 0;
148 } 160 }
149 161
162 mojo::ScopedSharedBufferHandle
163 VideoCaptureController::BufferContext::CreateHandleCopy() {
164 return buffer_handle_->Clone();
165 }
166
150 VideoCaptureController::VideoCaptureController() 167 VideoCaptureController::VideoCaptureController()
151 : frame_buffer_pool_(nullptr), 168 : consumer_feedback_observer_(nullptr),
152 consumer_feedback_observer_(nullptr),
153 state_(VIDEO_CAPTURE_STATE_STARTED), 169 state_(VIDEO_CAPTURE_STATE_STARTED),
154 has_received_frames_(false), 170 has_received_frames_(false),
155 weak_ptr_factory_(this) { 171 weak_ptr_factory_(this) {
156 DCHECK_CURRENTLY_ON(BrowserThread::IO); 172 DCHECK_CURRENTLY_ON(BrowserThread::IO);
157 } 173 }
158 174
159 VideoCaptureController::~VideoCaptureController() = default; 175 VideoCaptureController::~VideoCaptureController() = default;
160 176
161 base::WeakPtr<VideoCaptureController> 177 base::WeakPtr<VideoCaptureController>
162 VideoCaptureController::GetWeakPtrForIOThread() { 178 VideoCaptureController::GetWeakPtrForIOThread() {
163 return weak_ptr_factory_.GetWeakPtr(); 179 return weak_ptr_factory_.GetWeakPtr();
164 } 180 }
165 181
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( 182 void VideoCaptureController::SetConsumerFeedbackObserver(
176 std::unique_ptr<media::VideoFrameConsumerFeedbackObserver> 183 std::unique_ptr<media::VideoFrameConsumerFeedbackObserver>
177 consumer_feedback_observer) { 184 consumer_feedback_observer) {
178 DCHECK_CURRENTLY_ON(BrowserThread::IO); 185 DCHECK_CURRENTLY_ON(BrowserThread::IO);
179 consumer_feedback_observer_ = std::move(consumer_feedback_observer); 186 consumer_feedback_observer_ = std::move(consumer_feedback_observer);
180 // Update existing BufferContext entries. 187 // Update existing BufferContext entries.
181 for (auto& entry : buffer_contexts_) 188 for (auto& entry : buffer_contexts_)
182 entry.set_consumer_feedback_observer(consumer_feedback_observer_.get()); 189 entry.set_consumer_feedback_observer(consumer_feedback_observer_.get());
183 } 190 }
184 191
(...skipping 167 matching lines...) Expand 10 before | Expand all | Expand 10 after
352 OnClientFinishedConsumingBuffer(client, buffer_id, 359 OnClientFinishedConsumingBuffer(client, buffer_id,
353 consumer_resource_utilization); 360 consumer_resource_utilization);
354 } 361 }
355 362
356 const media::VideoCaptureFormat& VideoCaptureController::GetVideoCaptureFormat() 363 const media::VideoCaptureFormat& VideoCaptureController::GetVideoCaptureFormat()
357 const { 364 const {
358 DCHECK_CURRENTLY_ON(BrowserThread::IO); 365 DCHECK_CURRENTLY_ON(BrowserThread::IO);
359 return video_capture_format_; 366 return video_capture_format_;
360 } 367 }
361 368
362 void VideoCaptureController::OnIncomingCapturedVideoFrame( 369 void VideoCaptureController::OnNewBufferHandle(
363 media::VideoCaptureDevice::Client::Buffer buffer, 370 int buffer_id,
364 scoped_refptr<VideoFrame> frame) { 371 std::unique_ptr<media::VideoCaptureDevice::Client::Buffer::HandleProvider>
372 handle_provider) {
365 DCHECK_CURRENTLY_ON(BrowserThread::IO); 373 DCHECK_CURRENTLY_ON(BrowserThread::IO);
366 const int buffer_id_from_producer = buffer.id(); 374 DCHECK(FindUnretiredBufferContextFromBufferId(buffer_id) ==
367 DCHECK_NE(buffer_id_from_producer, media::VideoCaptureBufferPool::kInvalidId); 375 buffer_contexts_.end());
368 auto buffer_context_iter = 376 buffer_contexts_.emplace_back(
369 FindUnretiredBufferContextFromBufferId(buffer_id_from_producer); 377 next_buffer_context_id_++, buffer_id, consumer_feedback_observer_.get(),
370 if (buffer_context_iter == buffer_contexts_.end()) { 378 handle_provider->GetHandleForInterProcessTransit());
371 // A new buffer has been shared with us. Create new BufferContext. 379 }
372 buffer_contexts_.emplace_back( 380
373 next_buffer_context_id_++, buffer_id_from_producer, 381 void VideoCaptureController::OnFrameReadyInBuffer(
374 consumer_feedback_observer_.get(), frame_buffer_pool_.get()); 382 int buffer_id,
375 buffer_context_iter = buffer_contexts_.end() - 1; 383 int frame_feedback_id,
376 } 384 std::unique_ptr<
377 buffer_context_iter->set_frame_feedback_id(buffer.frame_feedback_id()); 385 media::VideoCaptureDevice::Client::Buffer::ScopedAccessPermission>
386 buffer_read_permission,
387 media::mojom::VideoFrameInfoPtr frame_info) {
388 DCHECK_CURRENTLY_ON(BrowserThread::IO);
389 DCHECK_NE(buffer_id, media::VideoCaptureBufferPool::kInvalidId);
390
391 auto buffer_context_iter = FindUnretiredBufferContextFromBufferId(buffer_id);
392 DCHECK(buffer_context_iter != buffer_contexts_.end());
393 buffer_context_iter->set_frame_feedback_id(frame_feedback_id);
378 DCHECK(buffer_context_iter->HasZeroConsumerHoldCount()); 394 DCHECK(buffer_context_iter->HasZeroConsumerHoldCount());
379 395
380 if (state_ == VIDEO_CAPTURE_STATE_STARTED) { 396 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(); 397 const int buffer_context_id = buffer_context_iter->buffer_context_id();
404 for (const auto& client : controller_clients_) { 398 for (const auto& client : controller_clients_) {
405 if (client->session_closed || client->paused) 399 if (client->session_closed || client->paused)
406 continue; 400 continue;
407 401
408 // On the first use of a BufferContext on a client, share the memory 402 // On the first use of a BufferContext on a client, call
403 // OnBufferCreated().
409 // handles. 404 // handles.
410 auto known_buffers_entry_iter = std::find( 405 auto known_buffers_entry_iter = std::find(
411 std::begin(client->known_buffer_context_ids), 406 std::begin(client->known_buffer_context_ids),
412 std::end(client->known_buffer_context_ids), buffer_context_id); 407 std::end(client->known_buffer_context_ids), buffer_context_id);
413 bool is_new_buffer = false; 408 bool is_new_buffer = false;
414 if (known_buffers_entry_iter == 409 if (known_buffers_entry_iter ==
415 std::end(client->known_buffer_context_ids)) { 410 std::end(client->known_buffer_context_ids)) {
416 client->known_buffer_context_ids.push_back(buffer_context_id); 411 client->known_buffer_context_ids.push_back(buffer_context_id);
417 is_new_buffer = true; 412 is_new_buffer = true;
418 } 413 }
419 if (is_new_buffer) { 414 if (is_new_buffer) {
420 mojo::ScopedSharedBufferHandle handle = 415 size_t mapped_size =
421 buffer.handle_provider()->GetHandleForInterProcessTransit(); 416 media::VideoCaptureFormat(frame_info->coded_size, 0.0f,
417 frame_info->pixel_format,
418 frame_info->storage_type)
419 .ImageAllocationSize();
422 client->event_handler->OnBufferCreated( 420 client->event_handler->OnBufferCreated(
423 client->controller_id, std::move(handle), 421 client->controller_id, buffer_context_iter->CreateHandleCopy(),
424 buffer_access->mapped_size(), buffer_context_id); 422 mapped_size, buffer_context_id);
425 } 423 }
426 client->event_handler->OnBufferReady(client->controller_id, 424
427 buffer_context_id, frame); 425 auto frame_info_copy = CloneFrameInfo(&frame_info);
miu 2017/02/14 00:41:27 nit: You could just do: client->event_handler->
chfremer 2017/02/14 21:15:16 Done.
426 client->event_handler->OnBufferReady(
427 client->controller_id, buffer_context_id, std::move(frame_info_copy));
428 428
429 auto buffers_in_use_entry_iter = 429 auto buffers_in_use_entry_iter =
430 std::find(std::begin(client->buffers_in_use), 430 std::find(std::begin(client->buffers_in_use),
431 std::end(client->buffers_in_use), buffer_context_id); 431 std::end(client->buffers_in_use), buffer_context_id);
432 if (buffers_in_use_entry_iter == std::end(client->buffers_in_use)) 432 if (buffers_in_use_entry_iter == std::end(client->buffers_in_use))
433 client->buffers_in_use.push_back(buffer_context_id); 433 client->buffers_in_use.push_back(buffer_context_id);
434 else 434 else
435 DCHECK(false) << "Unexpected duplicate buffer: " << buffer_context_id; 435 DCHECK(false) << "Unexpected duplicate buffer: " << buffer_context_id;
436
437 // Use if-check, because we are in a loop and only want to do this
miu 2017/02/14 00:41:27 style nit: Don't use 2nd person in comments (i.e.,
chfremer 2017/02/14 21:15:16 Done.
438 // move operation once.
439 if (buffer_read_permission) {
440 buffer_context_iter->set_read_permission(
miu 2017/02/14 00:41:27 Perhaps this could be simplified by just calling s
chfremer 2017/02/14 21:15:16 Thanks. Moving the check to after the loop makes i
441 std::move(buffer_read_permission));
442 }
436 buffer_context_iter->IncreaseConsumerCount(); 443 buffer_context_iter->IncreaseConsumerCount();
437 } 444 }
438 } 445 }
439 446
440 if (!has_received_frames_) { 447 if (!has_received_frames_) {
441 UMA_HISTOGRAM_COUNTS("Media.VideoCapture.Width", 448 UMA_HISTOGRAM_COUNTS("Media.VideoCapture.Width",
442 frame->visible_rect().width()); 449 frame_info->coded_size.width());
443 UMA_HISTOGRAM_COUNTS("Media.VideoCapture.Height", 450 UMA_HISTOGRAM_COUNTS("Media.VideoCapture.Height",
444 frame->visible_rect().height()); 451 frame_info->coded_size.height());
445 UMA_HISTOGRAM_ASPECT_RATIO("Media.VideoCapture.AspectRatio", 452 UMA_HISTOGRAM_ASPECT_RATIO("Media.VideoCapture.AspectRatio",
446 frame->visible_rect().width(), 453 frame_info->coded_size.width(),
447 frame->visible_rect().height()); 454 frame_info->coded_size.height());
448 double frame_rate = 0.0f; 455 double frame_rate = 0.0f;
449 if (!frame->metadata()->GetDouble(VideoFrameMetadata::FRAME_RATE, 456 media::VideoFrameMetadata metadata;
450 &frame_rate)) { 457 metadata.MergeInternalValuesFrom(*frame_info->metadata);
458 if (!metadata.GetDouble(VideoFrameMetadata::FRAME_RATE, &frame_rate)) {
451 frame_rate = video_capture_format_.frame_rate; 459 frame_rate = video_capture_format_.frame_rate;
452 } 460 }
453 UMA_HISTOGRAM_COUNTS("Media.VideoCapture.FrameRate", frame_rate); 461 UMA_HISTOGRAM_COUNTS("Media.VideoCapture.FrameRate", frame_rate);
454 has_received_frames_ = true; 462 has_received_frames_ = true;
455 } 463 }
456 } 464 }
457 465
466 void VideoCaptureController::OnBufferRetired(int buffer_id) {
467 DCHECK_CURRENTLY_ON(BrowserThread::IO);
468
469 auto buffer_context_iter = FindUnretiredBufferContextFromBufferId(buffer_id);
470 DCHECK(buffer_context_iter != buffer_contexts_.end());
471
472 // If there are any clients still using the buffer, we need to allow them
473 // to finish up. We need to hold on to the BufferContext entry until then,
474 // because it contains the consumer hold.
475 if (buffer_context_iter->HasZeroConsumerHoldCount())
476 ReleaseBufferContext(buffer_context_iter);
477 else
478 buffer_context_iter->set_is_retired();
479 }
480
458 void VideoCaptureController::OnError() { 481 void VideoCaptureController::OnError() {
459 DCHECK_CURRENTLY_ON(BrowserThread::IO); 482 DCHECK_CURRENTLY_ON(BrowserThread::IO);
460 state_ = VIDEO_CAPTURE_STATE_ERROR; 483 state_ = VIDEO_CAPTURE_STATE_ERROR;
461 484
462 for (const auto& client : controller_clients_) { 485 for (const auto& client : controller_clients_) {
463 if (client->session_closed) 486 if (client->session_closed)
464 continue; 487 continue;
465 client->event_handler->OnError(client->controller_id); 488 client->event_handler->OnError(client->controller_id);
466 } 489 }
467 } 490 }
468 491
469 void VideoCaptureController::OnLog(const std::string& message) { 492 void VideoCaptureController::OnLog(const std::string& message) {
470 DCHECK_CURRENTLY_ON(BrowserThread::IO); 493 DCHECK_CURRENTLY_ON(BrowserThread::IO);
471 MediaStreamManager::SendMessageToNativeLog("Video capture: " + message); 494 MediaStreamManager::SendMessageToNativeLog("Video capture: " + message);
472 } 495 }
473 496
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( 497 VideoCaptureController::ControllerClient* VideoCaptureController::FindClient(
490 VideoCaptureControllerID id, 498 VideoCaptureControllerID id,
491 VideoCaptureControllerEventHandler* handler, 499 VideoCaptureControllerEventHandler* handler,
492 const ControllerClients& clients) { 500 const ControllerClients& clients) {
493 for (const auto& client : clients) { 501 for (const auto& client : clients) {
494 if (client->controller_id == id && client->event_handler == handler) 502 if (client->controller_id == id && client->event_handler == handler)
495 return client.get(); 503 return client.get();
496 } 504 }
497 return nullptr; 505 return nullptr;
498 } 506 }
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
552 if (entry_iter != std::end(client->known_buffer_context_ids)) { 560 if (entry_iter != std::end(client->known_buffer_context_ids)) {
553 client->known_buffer_context_ids.erase(entry_iter); 561 client->known_buffer_context_ids.erase(entry_iter);
554 client->event_handler->OnBufferDestroyed( 562 client->event_handler->OnBufferDestroyed(
555 client->controller_id, buffer_context_iter->buffer_context_id()); 563 client->controller_id, buffer_context_iter->buffer_context_id());
556 } 564 }
557 } 565 }
558 buffer_contexts_.erase(buffer_context_iter); 566 buffer_contexts_.erase(buffer_context_iter);
559 } 567 }
560 568
561 } // namespace content 569 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698