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

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

Issue 2583603002: [Mojo Video Capture] Split OnIncomingCapturedVideoFrame() to OnNewBuffer() + OnFrameReadyInBuffer() (Closed)
Patch Set: Improve naming and fix Android background issue Created 3 years, 11 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, \ 47 name, \
47 (height) ? ((width) * 100) / (height) : kInfiniteRatio); 48 (height) ? ((width) * 100) / (height) : kInfiniteRatio);
48 49
50 // This manual copy routine is needed because base::DictionaryValue does not
51 // allow the default copy operator.
52 media::mojom::VideoFrameInfoPtr CloneFrameInfo(
53 media::mojom::VideoFrameInfoPtr* frame_info) {
54 auto result = media::mojom::VideoFrameInfo::New();
55 result->timestamp = (*frame_info)->timestamp;
56 result->pixel_format = (*frame_info)->pixel_format;
57 result->storage_type = (*frame_info)->storage_type;
58 result->coded_size = (*frame_info)->coded_size;
59 result->visible_rect = (*frame_info)->visible_rect;
60 result->metadata = base::MakeUnique<base::DictionaryValue>();
61 result->metadata->MergeDictionary((*frame_info)->metadata.get());
62 return result;
63 }
64
49 } // anonymous namespace 65 } // anonymous namespace
50 66
51 struct VideoCaptureController::ControllerClient { 67 struct VideoCaptureController::ControllerClient {
52 ControllerClient(VideoCaptureControllerID id, 68 ControllerClient(VideoCaptureControllerID id,
53 VideoCaptureControllerEventHandler* handler, 69 VideoCaptureControllerEventHandler* handler,
54 media::VideoCaptureSessionId session_id, 70 media::VideoCaptureSessionId session_id,
55 const media::VideoCaptureParams& params) 71 const media::VideoCaptureParams& params)
56 : controller_id(id), 72 : controller_id(id),
57 event_handler(handler), 73 event_handler(handler),
58 session_id(session_id), 74 session_id(session_id),
(...skipping 28 matching lines...) Expand all
87 // simplify the code in both places. 103 // simplify the code in both places.
88 bool session_closed; 104 bool session_closed;
89 105
90 // Indicates whether the client is paused, if true, VideoCaptureController 106 // Indicates whether the client is paused, if true, VideoCaptureController
91 // stops updating its buffer. 107 // stops updating its buffer.
92 bool paused; 108 bool paused;
93 }; 109 };
94 110
95 VideoCaptureController::BufferState::BufferState( 111 VideoCaptureController::BufferState::BufferState(
96 int buffer_id, 112 int buffer_id,
97 int frame_feedback_id,
98 media::VideoFrameConsumerFeedbackObserver* consumer_feedback_observer, 113 media::VideoFrameConsumerFeedbackObserver* consumer_feedback_observer,
99 media::FrameBufferPool* frame_buffer_pool) 114 mojo::ScopedSharedBufferHandle handle)
100 : buffer_id_(buffer_id), 115 : buffer_id_(buffer_id),
101 frame_feedback_id_(frame_feedback_id), 116 frame_feedback_id_(0),
102 consumer_feedback_observer_(consumer_feedback_observer), 117 consumer_feedback_observer_(consumer_feedback_observer),
103 frame_buffer_pool_(frame_buffer_pool), 118 buffer_handle_(std::move(handle)),
104 max_consumer_utilization_( 119 max_consumer_utilization_(
105 media::VideoFrameConsumerFeedbackObserver::kNoUtilizationRecorded), 120 media::VideoFrameConsumerFeedbackObserver::kNoUtilizationRecorded),
106 consumer_hold_count_(0) {} 121 consumer_hold_count_(0) {}
107 122
108 VideoCaptureController::BufferState::~BufferState() = default; 123 VideoCaptureController::BufferState::~BufferState() = default;
109 124
110 VideoCaptureController::BufferState::BufferState( 125 VideoCaptureController::BufferState::BufferState(
111 const VideoCaptureController::BufferState& other) = default; 126 VideoCaptureController::BufferState&& other) = default;
127
128 VideoCaptureController::BufferState& VideoCaptureController::BufferState::
129 operator=(BufferState&& other) = default;
130
131 void VideoCaptureController::BufferState::set_read_permission(
132 std::unique_ptr<media::Ownership> buffer_read_permission) {
133 buffer_read_permission_ = std::move(buffer_read_permission);
134 }
135
136 void VideoCaptureController::BufferState::set_frame_feedback_id(
137 int frame_feedback_id) {
138 frame_feedback_id_ = frame_feedback_id;
139 }
112 140
113 void VideoCaptureController::BufferState::RecordConsumerUtilization( 141 void VideoCaptureController::BufferState::RecordConsumerUtilization(
114 double utilization) { 142 double utilization) {
115 if (std::isfinite(utilization) && utilization >= 0.0) { 143 if (std::isfinite(utilization) && utilization >= 0.0) {
116 max_consumer_utilization_ = 144 max_consumer_utilization_ =
117 std::max(max_consumer_utilization_, utilization); 145 std::max(max_consumer_utilization_, utilization);
118 } 146 }
119 } 147 }
120 148
121 void VideoCaptureController::BufferState::IncreaseConsumerCount() { 149 void VideoCaptureController::BufferState::IncreaseConsumerCount() {
122 if (consumer_hold_count_ == 0)
123 if (frame_buffer_pool_ != nullptr)
124 frame_buffer_pool_->SetBufferHold(buffer_id_);
125 consumer_hold_count_++; 150 consumer_hold_count_++;
126 } 151 }
127 152
128 void VideoCaptureController::BufferState::DecreaseConsumerCount() { 153 void VideoCaptureController::BufferState::DecreaseConsumerCount() {
154 LOG(ERROR) << "1";
129 consumer_hold_count_--; 155 consumer_hold_count_--;
130 if (consumer_hold_count_ == 0) { 156 if (consumer_hold_count_ == 0) {
131 if (consumer_feedback_observer_ != nullptr && 157 if (consumer_feedback_observer_ != nullptr &&
132 max_consumer_utilization_ != 158 max_consumer_utilization_ !=
133 media::VideoFrameConsumerFeedbackObserver::kNoUtilizationRecorded) { 159 media::VideoFrameConsumerFeedbackObserver::kNoUtilizationRecorded) {
134 consumer_feedback_observer_->OnUtilizationReport( 160 consumer_feedback_observer_->OnUtilizationReport(
135 frame_feedback_id_, max_consumer_utilization_); 161 frame_feedback_id_, max_consumer_utilization_);
136 } 162 }
137 if (frame_buffer_pool_ != nullptr) 163 buffer_read_permission_.reset();
138 frame_buffer_pool_->ReleaseBufferHold(buffer_id_);
139 max_consumer_utilization_ = 164 max_consumer_utilization_ =
140 media::VideoFrameConsumerFeedbackObserver::kNoUtilizationRecorded; 165 media::VideoFrameConsumerFeedbackObserver::kNoUtilizationRecorded;
141 } 166 }
142 } 167 }
143 168
144 bool VideoCaptureController::BufferState::HasZeroConsumerHoldCount() { 169 bool VideoCaptureController::BufferState::HasZeroConsumerHoldCount() {
145 return consumer_hold_count_ == 0; 170 return consumer_hold_count_ == 0;
146 } 171 }
147 172
173 mojo::ScopedSharedBufferHandle
174 VideoCaptureController::BufferState::CreateHandleCopy() {
175 return buffer_handle_->Clone();
176 }
177
148 void VideoCaptureController::BufferState::SetConsumerFeedbackObserver( 178 void VideoCaptureController::BufferState::SetConsumerFeedbackObserver(
149 media::VideoFrameConsumerFeedbackObserver* consumer_feedback_observer) { 179 media::VideoFrameConsumerFeedbackObserver* consumer_feedback_observer) {
150 consumer_feedback_observer_ = consumer_feedback_observer; 180 consumer_feedback_observer_ = consumer_feedback_observer;
151 } 181 }
152 182
153 void VideoCaptureController::BufferState::SetFrameBufferPool(
154 media::FrameBufferPool* frame_buffer_pool) {
155 frame_buffer_pool_ = frame_buffer_pool;
156 }
157
158 VideoCaptureController::VideoCaptureController() 183 VideoCaptureController::VideoCaptureController()
159 : frame_buffer_pool_(nullptr), 184 : consumer_feedback_observer_(nullptr),
160 consumer_feedback_observer_(nullptr),
161 state_(VIDEO_CAPTURE_STATE_STARTED), 185 state_(VIDEO_CAPTURE_STATE_STARTED),
162 has_received_frames_(false), 186 has_received_frames_(false),
163 weak_ptr_factory_(this) { 187 weak_ptr_factory_(this) {
164 DCHECK_CURRENTLY_ON(BrowserThread::IO); 188 DCHECK_CURRENTLY_ON(BrowserThread::IO);
165 } 189 }
166 190
167 VideoCaptureController::~VideoCaptureController() = default; 191 VideoCaptureController::~VideoCaptureController() = default;
168 192
169 base::WeakPtr<VideoCaptureController> 193 base::WeakPtr<VideoCaptureController>
170 VideoCaptureController::GetWeakPtrForIOThread() { 194 VideoCaptureController::GetWeakPtrForIOThread() {
171 return weak_ptr_factory_.GetWeakPtr(); 195 return weak_ptr_factory_.GetWeakPtr();
172 } 196 }
173 197
174 void VideoCaptureController::SetFrameBufferPool(
175 std::unique_ptr<media::FrameBufferPool> frame_buffer_pool) {
176 DCHECK_CURRENTLY_ON(BrowserThread::IO);
177 frame_buffer_pool_ = std::move(frame_buffer_pool);
178 // Update existing BufferState entries.
179 for (auto& entry : buffer_id_to_state_map_)
180 entry.second.SetFrameBufferPool(frame_buffer_pool_.get());
181 }
182
183 void VideoCaptureController::SetConsumerFeedbackObserver( 198 void VideoCaptureController::SetConsumerFeedbackObserver(
184 std::unique_ptr<media::VideoFrameConsumerFeedbackObserver> 199 std::unique_ptr<media::VideoFrameConsumerFeedbackObserver>
185 consumer_feedback_observer) { 200 consumer_feedback_observer) {
186 DCHECK_CURRENTLY_ON(BrowserThread::IO); 201 DCHECK_CURRENTLY_ON(BrowserThread::IO);
187 consumer_feedback_observer_ = std::move(consumer_feedback_observer); 202 consumer_feedback_observer_ = std::move(consumer_feedback_observer);
188 // Update existing BufferState entries. 203 // Update existing BufferState entries.
189 for (auto& entry : buffer_id_to_state_map_) 204 for (auto& entry : buffer_states_)
190 entry.second.SetConsumerFeedbackObserver(consumer_feedback_observer_.get()); 205 entry.SetConsumerFeedbackObserver(consumer_feedback_observer_.get());
191 } 206 }
192 207
193 void VideoCaptureController::AddClient( 208 void VideoCaptureController::AddClient(
194 VideoCaptureControllerID id, 209 VideoCaptureControllerID id,
195 VideoCaptureControllerEventHandler* event_handler, 210 VideoCaptureControllerEventHandler* event_handler,
196 media::VideoCaptureSessionId session_id, 211 media::VideoCaptureSessionId session_id,
197 const media::VideoCaptureParams& params) { 212 const media::VideoCaptureParams& params) {
198 DCHECK_CURRENTLY_ON(BrowserThread::IO); 213 DCHECK_CURRENTLY_ON(BrowserThread::IO);
199 DVLOG(1) << "VideoCaptureController::AddClient() -- id=" << id 214 DVLOG(1) << "VideoCaptureController::AddClient() -- id=" << id
200 << ", session_id=" << session_id 215 << ", session_id=" << session_id
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
242 int VideoCaptureController::RemoveClient( 257 int VideoCaptureController::RemoveClient(
243 VideoCaptureControllerID id, 258 VideoCaptureControllerID id,
244 VideoCaptureControllerEventHandler* event_handler) { 259 VideoCaptureControllerEventHandler* event_handler) {
245 DCHECK_CURRENTLY_ON(BrowserThread::IO); 260 DCHECK_CURRENTLY_ON(BrowserThread::IO);
246 DVLOG(1) << "VideoCaptureController::RemoveClient, id " << id; 261 DVLOG(1) << "VideoCaptureController::RemoveClient, id " << id;
247 262
248 ControllerClient* client = FindClient(id, event_handler, controller_clients_); 263 ControllerClient* client = FindClient(id, event_handler, controller_clients_);
249 if (!client) 264 if (!client)
250 return kInvalidMediaCaptureSessionId; 265 return kInvalidMediaCaptureSessionId;
251 266
252 // Take back all buffers held by the |client|. 267 for (const auto& buffer_id : client->buffers_in_use) {
253 for (const auto& buffer_id : client->buffers_in_use) 268 OnClientFinishedConsumingBuffer(
254 buffer_id_to_state_map_.at(buffer_id).DecreaseConsumerCount(); 269 client, buffer_id,
270 media::VideoFrameConsumerFeedbackObserver::kNoUtilizationRecorded);
271 }
255 client->buffers_in_use.clear(); 272 client->buffers_in_use.clear();
256 273
257 int session_id = client->session_id; 274 int session_id = client->session_id;
258 controller_clients_.remove_if( 275 controller_clients_.remove_if(
259 [client](const std::unique_ptr<ControllerClient>& ptr) { 276 [client](const std::unique_ptr<ControllerClient>& ptr) {
260 return ptr.get() == client; 277 return ptr.get() == client;
261 }); 278 });
262 279
263 return session_id; 280 return session_id;
264 } 281 }
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after
348 NOTREACHED(); 365 NOTREACHED();
349 return; 366 return;
350 } 367 }
351 auto buffers_in_use_entry_iter = 368 auto buffers_in_use_entry_iter =
352 std::find(std::begin(client->buffers_in_use), 369 std::find(std::begin(client->buffers_in_use),
353 std::end(client->buffers_in_use), buffer_id); 370 std::end(client->buffers_in_use), buffer_id);
354 if (buffers_in_use_entry_iter == std::end(client->buffers_in_use)) { 371 if (buffers_in_use_entry_iter == std::end(client->buffers_in_use)) {
355 NOTREACHED(); 372 NOTREACHED();
356 return; 373 return;
357 } 374 }
375 client->buffers_in_use.erase(buffers_in_use_entry_iter);
358 376
359 BufferState& buffer_state = buffer_id_to_state_map_.at(buffer_id); 377 OnClientFinishedConsumingBuffer(client, buffer_id,
360 buffer_state.RecordConsumerUtilization(consumer_resource_utilization); 378 consumer_resource_utilization);
361 buffer_state.DecreaseConsumerCount();
362 client->buffers_in_use.erase(buffers_in_use_entry_iter);
363 } 379 }
364 380
365 const media::VideoCaptureFormat& 381 const media::VideoCaptureFormat&
366 VideoCaptureController::GetVideoCaptureFormat() const { 382 VideoCaptureController::GetVideoCaptureFormat() const {
367 DCHECK_CURRENTLY_ON(BrowserThread::IO); 383 DCHECK_CURRENTLY_ON(BrowserThread::IO);
368 return video_capture_format_; 384 return video_capture_format_;
369 } 385 }
370 386
371 void VideoCaptureController::OnIncomingCapturedVideoFrame( 387 void VideoCaptureController::OnNewBufferHandle(
372 media::VideoCaptureDevice::Client::Buffer buffer, 388 int buffer_id,
373 scoped_refptr<VideoFrame> frame) { 389 std::unique_ptr<media::BufferHandleProvider> handle_provider) {
374 DCHECK_CURRENTLY_ON(BrowserThread::IO); 390 DCHECK_CURRENTLY_ON(BrowserThread::IO);
375 const int buffer_id = buffer.id(); 391 DCHECK(std::find_if(buffer_states_.begin(), buffer_states_.end(),
392 [buffer_id](const BufferState& entry) {
393 return entry.buffer_id() == buffer_id;
394 }) == buffer_states_.end());
395 buffer_states_.emplace_back(
396 buffer_id, consumer_feedback_observer_.get(),
397 handle_provider->GetHandleForInterProcessTransit());
398 }
399
400 void VideoCaptureController::OnFrameReadyInBuffer(
401 int buffer_id,
402 int frame_feedback_id,
403 std::unique_ptr<media::Ownership> buffer_read_permission,
404 media::mojom::VideoFrameInfoPtr frame_info) {
405 DCHECK_CURRENTLY_ON(BrowserThread::IO);
376 DCHECK_NE(buffer_id, media::VideoCaptureBufferPool::kInvalidId); 406 DCHECK_NE(buffer_id, media::VideoCaptureBufferPool::kInvalidId);
377 407
378 // Insert if not exists. 408 auto buffer_state_iter =
379 const auto it = 409 std::find_if(buffer_states_.begin(), buffer_states_.end(),
380 buffer_id_to_state_map_ 410 [buffer_id](const BufferState& entry) {
381 .insert(std::make_pair( 411 return entry.buffer_id() == buffer_id;
382 buffer_id, BufferState(buffer_id, buffer.frame_feedback_id(), 412 });
383 consumer_feedback_observer_.get(), 413 DCHECK(buffer_state_iter != buffer_states_.end());
384 frame_buffer_pool_.get()))) 414 DCHECK(buffer_state_iter->HasZeroConsumerHoldCount());
385 .first; 415 buffer_state_iter->set_frame_feedback_id(frame_feedback_id);
386 BufferState& buffer_state = it->second;
387 DCHECK(buffer_state.HasZeroConsumerHoldCount());
388 416
389 if (state_ == VIDEO_CAPTURE_STATE_STARTED) { 417 if (state_ == VIDEO_CAPTURE_STATE_STARTED) {
390 if (!frame->metadata()->HasKey(VideoFrameMetadata::FRAME_RATE)) {
391 frame->metadata()->SetDouble(VideoFrameMetadata::FRAME_RATE,
392 video_capture_format_.frame_rate);
393 }
394 std::unique_ptr<base::DictionaryValue> metadata =
395 frame->metadata()->CopyInternalValues();
396
397 // Only I420 and Y16 pixel formats are currently supported.
398 DCHECK(frame->format() == media::PIXEL_FORMAT_I420 ||
399 frame->format() == media::PIXEL_FORMAT_Y16)
400 << "Unsupported pixel format: "
401 << media::VideoPixelFormatToString(frame->format());
402
403 // Sanity-checks to confirm |frame| is actually being backed by |buffer|.
404 auto buffer_access = buffer.handle_provider->GetHandleForInProcessAccess();
405 DCHECK(frame->storage_type() == media::VideoFrame::STORAGE_SHMEM);
406 DCHECK(frame->data(media::VideoFrame::kYPlane) >= buffer_access->data() &&
407 (frame->data(media::VideoFrame::kYPlane) <
408 (buffer_access->data() + buffer_access->mapped_size())))
409 << "VideoFrame does not appear to be backed by Buffer";
410
411 for (const auto& client : controller_clients_) { 418 for (const auto& client : controller_clients_) {
412 if (client->session_closed || client->paused) 419 if (client->session_closed || client->paused)
413 continue; 420 continue;
414 421
415 // On the first use of a buffer on a client, share the memory handles. 422 // On the first use of a buffer on a client, call OnBufferCreated().
416 auto known_buffers_entry_iter = 423 auto known_buffers_entry_iter =
417 std::find(std::begin(client->known_buffers), 424 std::find(std::begin(client->known_buffers),
418 std::end(client->known_buffers), buffer_id); 425 std::end(client->known_buffers), buffer_id);
419 bool is_new_buffer = false; 426 bool is_new_buffer = false;
420 if (known_buffers_entry_iter == std::end(client->known_buffers)) { 427 if (known_buffers_entry_iter == std::end(client->known_buffers)) {
421 client->known_buffers.push_back(buffer_id); 428 client->known_buffers.push_back(buffer_id);
422 is_new_buffer = true; 429 is_new_buffer = true;
423 } 430 }
424 if (is_new_buffer) { 431 if (is_new_buffer) {
425 mojo::ScopedSharedBufferHandle handle = 432 size_t mapped_size =
426 buffer.handle_provider->GetHandleForInterProcessTransit(); 433 media::VideoCaptureFormat(frame_info->coded_size, 0.0f,
434 frame_info->pixel_format,
435 frame_info->storage_type)
436 .ImageAllocationSize();
427 client->event_handler->OnBufferCreated( 437 client->event_handler->OnBufferCreated(
428 client->controller_id, std::move(handle), 438 client->controller_id, buffer_state_iter->CreateHandleCopy(),
429 buffer_access->mapped_size(), buffer_id); 439 mapped_size, buffer_id);
430 } 440 }
441
442 auto frame_info_copy = CloneFrameInfo(&frame_info);
431 client->event_handler->OnBufferReady(client->controller_id, buffer_id, 443 client->event_handler->OnBufferReady(client->controller_id, buffer_id,
432 frame); 444 std::move(frame_info_copy));
433
434 auto buffers_in_use_entry_iter = 445 auto buffers_in_use_entry_iter =
435 std::find(std::begin(client->buffers_in_use), 446 std::find(std::begin(client->buffers_in_use),
436 std::end(client->buffers_in_use), buffer_id); 447 std::end(client->buffers_in_use), buffer_id);
437 if (buffers_in_use_entry_iter == std::end(client->buffers_in_use)) 448 if (buffers_in_use_entry_iter == std::end(client->buffers_in_use))
438 client->buffers_in_use.push_back(buffer_id); 449 client->buffers_in_use.push_back(buffer_id);
439 else 450 else
440 DCHECK(false) << "Unexpected duplicate buffer: " << buffer_id; 451 DCHECK(false) << "Unexpected duplicate buffer: " << buffer_id;
441 buffer_state.IncreaseConsumerCount(); 452 // Use if-check, because we are in a loop and only want to do this
453 // move operation once.
454 if (buffer_read_permission) {
455 buffer_state_iter->set_read_permission(
456 std::move(buffer_read_permission));
457 }
458 buffer_state_iter->IncreaseConsumerCount();
442 } 459 }
443 } 460 }
444 461
445 if (!has_received_frames_) { 462 if (!has_received_frames_) {
446 UMA_HISTOGRAM_COUNTS("Media.VideoCapture.Width", 463 UMA_HISTOGRAM_COUNTS("Media.VideoCapture.Width",
447 frame->visible_rect().width()); 464 frame_info->coded_size.width());
448 UMA_HISTOGRAM_COUNTS("Media.VideoCapture.Height", 465 UMA_HISTOGRAM_COUNTS("Media.VideoCapture.Height",
449 frame->visible_rect().height()); 466 frame_info->coded_size.height());
450 UMA_HISTOGRAM_ASPECT_RATIO("Media.VideoCapture.AspectRatio", 467 UMA_HISTOGRAM_ASPECT_RATIO("Media.VideoCapture.AspectRatio",
451 frame->visible_rect().width(), 468 frame_info->coded_size.width(),
452 frame->visible_rect().height()); 469 frame_info->coded_size.height());
453 double frame_rate = 0.0f; 470 double frame_rate = 0.0f;
454 if (!frame->metadata()->GetDouble(VideoFrameMetadata::FRAME_RATE, 471 media::VideoFrameMetadata metadata;
455 &frame_rate)) { 472 metadata.MergeInternalValuesFrom(*frame_info->metadata);
473 if (!metadata.GetDouble(VideoFrameMetadata::FRAME_RATE, &frame_rate)) {
456 frame_rate = video_capture_format_.frame_rate; 474 frame_rate = video_capture_format_.frame_rate;
457 } 475 }
458 UMA_HISTOGRAM_COUNTS("Media.VideoCapture.FrameRate", frame_rate); 476 UMA_HISTOGRAM_COUNTS("Media.VideoCapture.FrameRate", frame_rate);
459 has_received_frames_ = true; 477 has_received_frames_ = true;
460 } 478 }
461 } 479 }
462 480
481 void VideoCaptureController::OnBufferRetired(int buffer_id) {
482 DCHECK_CURRENTLY_ON(BrowserThread::IO);
483
484 auto buffer_state_iter =
485 std::find_if(buffer_states_.begin(), buffer_states_.end(),
486 [buffer_id](const BufferState& entry) {
487 return entry.buffer_id() == buffer_id;
488 });
489 DCHECK(buffer_state_iter != buffer_states_.end());
490
491 // If there are any clients still using the buffer, we need to allow them
492 // to finish up. We need to hold on to the BufferState entry until then,
493 // because it contains the |read_access_permission|.
494 if (buffer_state_iter->HasZeroConsumerHoldCount()) {
495 ReleaseBufferState(buffer_state_iter);
496 } else {
497 buffer_state_iter->set_is_retired();
498 }
499 }
500
463 void VideoCaptureController::OnError() { 501 void VideoCaptureController::OnError() {
464 DCHECK_CURRENTLY_ON(BrowserThread::IO); 502 DCHECK_CURRENTLY_ON(BrowserThread::IO);
465 state_ = VIDEO_CAPTURE_STATE_ERROR; 503 state_ = VIDEO_CAPTURE_STATE_ERROR;
466 504
467 for (const auto& client : controller_clients_) { 505 for (const auto& client : controller_clients_) {
468 if (client->session_closed) 506 if (client->session_closed)
469 continue; 507 continue;
470 client->event_handler->OnError(client->controller_id); 508 client->event_handler->OnError(client->controller_id);
471 } 509 }
472 } 510 }
473 511
474 void VideoCaptureController::OnLog(const std::string& message) { 512 void VideoCaptureController::OnLog(const std::string& message) {
475 DCHECK_CURRENTLY_ON(BrowserThread::IO); 513 DCHECK_CURRENTLY_ON(BrowserThread::IO);
476 MediaStreamManager::SendMessageToNativeLog("Video capture: " + message); 514 MediaStreamManager::SendMessageToNativeLog("Video capture: " + message);
477 } 515 }
478 516
479 void VideoCaptureController::OnBufferDestroyed(int buffer_id_to_drop) {
480 DCHECK_CURRENTLY_ON(BrowserThread::IO);
481
482 for (const auto& client : controller_clients_) {
483 if (client->session_closed)
484 continue;
485
486 auto known_buffers_entry_iter =
487 std::find(std::begin(client->known_buffers),
488 std::end(client->known_buffers), buffer_id_to_drop);
489 if (known_buffers_entry_iter != std::end(client->known_buffers)) {
490 client->known_buffers.erase(known_buffers_entry_iter);
491 client->event_handler->OnBufferDestroyed(client->controller_id,
492 buffer_id_to_drop);
493 }
494 }
495
496 buffer_id_to_state_map_.erase(buffer_id_to_drop);
497 }
498
499 VideoCaptureController::ControllerClient* VideoCaptureController::FindClient( 517 VideoCaptureController::ControllerClient* VideoCaptureController::FindClient(
500 VideoCaptureControllerID id, 518 VideoCaptureControllerID id,
501 VideoCaptureControllerEventHandler* handler, 519 VideoCaptureControllerEventHandler* handler,
502 const ControllerClients& clients) { 520 const ControllerClients& clients) {
503 for (const auto& client : clients) { 521 for (const auto& client : clients) {
504 if (client->controller_id == id && client->event_handler == handler) 522 if (client->controller_id == id && client->event_handler == handler)
505 return client.get(); 523 return client.get();
506 } 524 }
507 return nullptr; 525 return nullptr;
508 } 526 }
509 527
510 VideoCaptureController::ControllerClient* VideoCaptureController::FindClient( 528 VideoCaptureController::ControllerClient* VideoCaptureController::FindClient(
511 int session_id, 529 int session_id,
512 const ControllerClients& clients) { 530 const ControllerClients& clients) {
513 for (const auto& client : clients) { 531 for (const auto& client : clients) {
514 if (client->session_id == session_id) 532 if (client->session_id == session_id)
515 return client.get(); 533 return client.get();
516 } 534 }
517 return nullptr; 535 return nullptr;
518 } 536 }
519 537
538 void VideoCaptureController::OnClientFinishedConsumingBuffer(
539 ControllerClient* client,
540 int buffer_id,
541 double consumer_resource_utilization) {
542 auto buffer_state_iter =
543 std::find_if(buffer_states_.begin(), buffer_states_.end(),
544 [buffer_id](const BufferState& entry) {
545 return entry.buffer_id() == buffer_id;
546 });
547 DCHECK(buffer_state_iter != buffer_states_.end());
548
549 buffer_state_iter->RecordConsumerUtilization(consumer_resource_utilization);
550 buffer_state_iter->DecreaseConsumerCount();
551 if (buffer_state_iter->HasZeroConsumerHoldCount() &&
552 buffer_state_iter->is_retired()) {
553 ReleaseBufferState(buffer_state_iter);
554 }
555 }
556
557 void VideoCaptureController::ReleaseBufferState(
558 const std::vector<BufferState>::iterator& buffer_state_iter) {
559 for (const auto& client : controller_clients_) {
560 if (client->session_closed)
561 continue;
562
563 auto known_buffers_entry_iter = std::find(std::begin(client->known_buffers),
564 std::end(client->known_buffers),
565 buffer_state_iter->buffer_id());
566 if (known_buffers_entry_iter != std::end(client->known_buffers)) {
567 client->known_buffers.erase(known_buffers_entry_iter);
568 client->event_handler->OnBufferDestroyed(client->controller_id,
569 buffer_state_iter->buffer_id());
570 }
571 }
572 buffer_states_.erase(buffer_state_iter);
573 }
574
520 } // namespace content 575 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698