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

Side by Side Diff: content/renderer/media/video_track_adapter.cc

Issue 509873002: Refactor MediaStreamTrack video onmute event. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Fixed nits. Created 6 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
« no previous file with comments | « content/renderer/media/video_track_adapter.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 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/renderer/media/video_track_adapter.h" 5 #include "content/renderer/media/video_track_adapter.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <limits> 8 #include <limits>
9 #include <utility> 9 #include <utility>
10 10
11 #include "base/bind.h" 11 #include "base/bind.h"
12 #include "base/debug/trace_event.h" 12 #include "base/debug/trace_event.h"
13 #include "base/location.h" 13 #include "base/location.h"
14 #include "base/metrics/histogram.h" 14 #include "base/metrics/histogram.h"
15 #include "media/base/bind_to_current_loop.h"
15 #include "media/base/video_util.h" 16 #include "media/base/video_util.h"
16 17
17 namespace content { 18 namespace content {
18 19
19 namespace { 20 namespace {
20 21
21 // Amount of frame intervals to wait before considering the source as muted, for 22 // Amount of frame intervals to wait before considering the source as muted, for
22 // the first frame and under normal conditions, respectively. First frame might 23 // the first frame and under normal conditions, respectively. First frame might
23 // take longer to arrive due to source startup. 24 // take longer to arrive due to source startup.
24 const float kFirstFrameTimeoutInFrameIntervals = 100.0f; 25 const float kFirstFrameTimeoutInFrameIntervals = 100.0f;
(...skipping 201 matching lines...) Expand 10 before | Expand all | Expand 10 after
226 227
227 bool VideoTrackAdapter::VideoFrameResolutionAdapter::MaybeDropFrame( 228 bool VideoTrackAdapter::VideoFrameResolutionAdapter::MaybeDropFrame(
228 const scoped_refptr<media::VideoFrame>& frame, 229 const scoped_refptr<media::VideoFrame>& frame,
229 float source_frame_rate) { 230 float source_frame_rate) {
230 DCHECK(io_thread_checker_.CalledOnValidThread()); 231 DCHECK(io_thread_checker_.CalledOnValidThread());
231 232
232 // Do not drop frames if max frame rate hasn't been specified or the source 233 // Do not drop frames if max frame rate hasn't been specified or the source
233 // frame rate is known and is lower than max. 234 // frame rate is known and is lower than max.
234 if (max_frame_rate_ == 0.0f || 235 if (max_frame_rate_ == 0.0f ||
235 (source_frame_rate > 0 && 236 (source_frame_rate > 0 &&
236 source_frame_rate <= max_frame_rate_)) 237 source_frame_rate <= max_frame_rate_)) {
237 return false; 238 return false;
239 }
238 240
239 base::TimeDelta delta = frame->timestamp() - last_time_stamp_; 241 base::TimeDelta delta = frame->timestamp() - last_time_stamp_;
240 if (delta.InMilliseconds() < kMinTimeInMsBetweenFrames) { 242 if (delta.InMilliseconds() < kMinTimeInMsBetweenFrames) {
241 // We have seen video frames being delivered from camera devices back to 243 // We have seen video frames being delivered from camera devices back to
242 // back. The simple AR filter for frame rate calculation is too short to 244 // back. The simple AR filter for frame rate calculation is too short to
243 // handle that. http://crbug/394315 245 // handle that. http://crbug/394315
244 // TODO(perkj): Can we come up with a way to fix the times stamps and the 246 // TODO(perkj): Can we come up with a way to fix the times stamps and the
245 // timing when frames are delivered so all frames can be used? 247 // timing when frames are delivered so all frames can be used?
246 // The time stamps are generated by Chrome and not the actual device. 248 // The time stamps are generated by Chrome and not the actual device.
247 // Most likely the back to back problem is caused by software and not the 249 // Most likely the back to back problem is caused by software and not the
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
327 329
328 bool VideoTrackAdapter::VideoFrameResolutionAdapter::IsEmpty() const { 330 bool VideoTrackAdapter::VideoFrameResolutionAdapter::IsEmpty() const {
329 DCHECK(io_thread_checker_.CalledOnValidThread()); 331 DCHECK(io_thread_checker_.CalledOnValidThread());
330 return callbacks_.empty(); 332 return callbacks_.empty();
331 } 333 }
332 334
333 VideoTrackAdapter::VideoTrackAdapter( 335 VideoTrackAdapter::VideoTrackAdapter(
334 const scoped_refptr<base::MessageLoopProxy>& io_message_loop) 336 const scoped_refptr<base::MessageLoopProxy>& io_message_loop)
335 : io_message_loop_(io_message_loop), 337 : io_message_loop_(io_message_loop),
336 renderer_task_runner_(base::MessageLoopProxy::current()), 338 renderer_task_runner_(base::MessageLoopProxy::current()),
339 monitoring_frame_rate_(false),
340 muted_state_(false),
337 frame_counter_(0), 341 frame_counter_(0),
338 source_frame_rate_(0.0f) { 342 source_frame_rate_(0.0f) {
339 DCHECK(io_message_loop_.get()); 343 DCHECK(io_message_loop_.get());
340 } 344 }
341 345
342 VideoTrackAdapter::~VideoTrackAdapter() { 346 VideoTrackAdapter::~VideoTrackAdapter() {
343 DCHECK(adapters_.empty()); 347 DCHECK(adapters_.empty());
344 UMA_HISTOGRAM_BOOLEAN("Media.VideoTrackAdapter.FramesReceived", 348 UMA_HISTOGRAM_BOOLEAN("Media.VideoTrackAdapter.FramesReceived",
345 frame_counter_ > 0); 349 frame_counter_ > 0);
346 } 350 }
347 351
348 void VideoTrackAdapter::AddTrack( 352 void VideoTrackAdapter::AddTrack(
349 const MediaStreamVideoTrack* track, 353 const MediaStreamVideoTrack* track,
350 VideoCaptureDeliverFrameCB frame_callback, 354 VideoCaptureDeliverFrameCB frame_callback,
351 int max_width, 355 int max_width,
352 int max_height, 356 int max_height,
353 double min_aspect_ratio, 357 double min_aspect_ratio,
354 double max_aspect_ratio, 358 double max_aspect_ratio,
355 double max_frame_rate, 359 double max_frame_rate) {
356 double source_frame_rate,
357 const OnMutedCallback& on_muted_state_callback) {
358 DCHECK(thread_checker_.CalledOnValidThread()); 360 DCHECK(thread_checker_.CalledOnValidThread());
359 // Track monitoring should be scheduled before AddTrackOnIO() so it can find 361
360 // |adapters_| empty.
361 io_message_loop_->PostTask(
362 FROM_HERE,
363 base::Bind(&VideoTrackAdapter::StartTrackMonitoringOnIO,
364 this, on_muted_state_callback, source_frame_rate));
365 io_message_loop_->PostTask( 362 io_message_loop_->PostTask(
366 FROM_HERE, 363 FROM_HERE,
367 base::Bind(&VideoTrackAdapter::AddTrackOnIO, 364 base::Bind(&VideoTrackAdapter::AddTrackOnIO,
368 this, track, frame_callback, gfx::Size(max_width, max_height), 365 this, track, frame_callback, gfx::Size(max_width, max_height),
369 min_aspect_ratio, max_aspect_ratio, max_frame_rate)); 366 min_aspect_ratio, max_aspect_ratio, max_frame_rate));
370 } 367 }
371 368
372 void VideoTrackAdapter::AddTrackOnIO( 369 void VideoTrackAdapter::AddTrackOnIO(
373 const MediaStreamVideoTrack* track, 370 const MediaStreamVideoTrack* track,
374 VideoCaptureDeliverFrameCB frame_callback, 371 VideoCaptureDeliverFrameCB frame_callback,
(...skipping 23 matching lines...) Expand all
398 adapter->AddCallback(track, frame_callback); 395 adapter->AddCallback(track, frame_callback);
399 } 396 }
400 397
401 void VideoTrackAdapter::RemoveTrack(const MediaStreamVideoTrack* track) { 398 void VideoTrackAdapter::RemoveTrack(const MediaStreamVideoTrack* track) {
402 DCHECK(thread_checker_.CalledOnValidThread()); 399 DCHECK(thread_checker_.CalledOnValidThread());
403 io_message_loop_->PostTask( 400 io_message_loop_->PostTask(
404 FROM_HERE, 401 FROM_HERE,
405 base::Bind(&VideoTrackAdapter::RemoveTrackOnIO, this, track)); 402 base::Bind(&VideoTrackAdapter::RemoveTrackOnIO, this, track));
406 } 403 }
407 404
408 void VideoTrackAdapter::StartTrackMonitoringOnIO( 405 void VideoTrackAdapter::StartFrameMonitoring(
409 const OnMutedCallback& on_muted_state_callback, 406 double source_frame_rate,
407 const OnMutedCallback& on_muted_callback) {
408 DCHECK(thread_checker_.CalledOnValidThread());
409
410 VideoTrackAdapter::OnMutedCallback bound_on_muted_callback =
411 media::BindToCurrentLoop(on_muted_callback);
412
413 io_message_loop_->PostTask(
414 FROM_HERE,
415 base::Bind(&VideoTrackAdapter::StartFrameMonitoringOnIO,
416 this, bound_on_muted_callback, source_frame_rate));
417 }
418
419 void VideoTrackAdapter::StartFrameMonitoringOnIO(
420 const OnMutedCallback& on_muted_callback,
410 double source_frame_rate) { 421 double source_frame_rate) {
411 DCHECK(io_message_loop_->BelongsToCurrentThread()); 422 DCHECK(io_message_loop_->BelongsToCurrentThread());
412 // Only trigger monitoring for the first Track. 423 DCHECK(!monitoring_frame_rate_);
413 if (!adapters_.empty()) 424
414 return; 425 monitoring_frame_rate_ = true;
426
415 // If the source does not know the frame rate, set one by default. 427 // If the source does not know the frame rate, set one by default.
416 if (source_frame_rate == 0.0f) 428 if (source_frame_rate == 0.0f)
417 source_frame_rate = MediaStreamVideoSource::kDefaultFrameRate; 429 source_frame_rate = MediaStreamVideoSource::kDefaultFrameRate;
418 source_frame_rate_ = source_frame_rate; 430 source_frame_rate_ = source_frame_rate;
419 DVLOG(1) << "Monitoring frame creation, first (large) delay: " 431 DVLOG(1) << "Monitoring frame creation, first (large) delay: "
420 << (kFirstFrameTimeoutInFrameIntervals / source_frame_rate_) << "s"; 432 << (kFirstFrameTimeoutInFrameIntervals / source_frame_rate_) << "s";
421 io_message_loop_->PostDelayedTask(FROM_HERE, 433 io_message_loop_->PostDelayedTask(FROM_HERE,
422 base::Bind(&VideoTrackAdapter::CheckFramesReceivedOnIO, this, 434 base::Bind(&VideoTrackAdapter::CheckFramesReceivedOnIO, this,
423 on_muted_state_callback, frame_counter_), 435 on_muted_callback, frame_counter_),
424 base::TimeDelta::FromSecondsD(kFirstFrameTimeoutInFrameIntervals / 436 base::TimeDelta::FromSecondsD(kFirstFrameTimeoutInFrameIntervals /
425 source_frame_rate_)); 437 source_frame_rate_));
426 } 438 }
427 439
440 void VideoTrackAdapter::StopFrameMonitoring() {
441 DCHECK(thread_checker_.CalledOnValidThread());
442 io_message_loop_->PostTask(
443 FROM_HERE,
444 base::Bind(&VideoTrackAdapter::StopFrameMonitoringOnIO, this));
445 }
446
447 void VideoTrackAdapter::StopFrameMonitoringOnIO() {
448 DCHECK(io_message_loop_->BelongsToCurrentThread());
449 monitoring_frame_rate_ = false;
450 }
451
428 void VideoTrackAdapter::RemoveTrackOnIO(const MediaStreamVideoTrack* track) { 452 void VideoTrackAdapter::RemoveTrackOnIO(const MediaStreamVideoTrack* track) {
429 DCHECK(io_message_loop_->BelongsToCurrentThread()); 453 DCHECK(io_message_loop_->BelongsToCurrentThread());
430 for (FrameAdapters::iterator it = adapters_.begin(); 454 for (FrameAdapters::iterator it = adapters_.begin();
431 it != adapters_.end(); ++it) { 455 it != adapters_.end(); ++it) {
432 (*it)->RemoveCallback(track); 456 (*it)->RemoveCallback(track);
433 if ((*it)->IsEmpty()) { 457 if ((*it)->IsEmpty()) {
434 adapters_.erase(it); 458 adapters_.erase(it);
435 break; 459 break;
436 } 460 }
437 } 461 }
438 } 462 }
439 463
440 void VideoTrackAdapter::DeliverFrameOnIO( 464 void VideoTrackAdapter::DeliverFrameOnIO(
441 const scoped_refptr<media::VideoFrame>& frame, 465 const scoped_refptr<media::VideoFrame>& frame,
442 const media::VideoCaptureFormat& format, 466 const media::VideoCaptureFormat& format,
443 const base::TimeTicks& estimated_capture_time) { 467 const base::TimeTicks& estimated_capture_time) {
444 DCHECK(io_message_loop_->BelongsToCurrentThread()); 468 DCHECK(io_message_loop_->BelongsToCurrentThread());
445 TRACE_EVENT0("video", "VideoTrackAdapter::DeliverFrameOnIO"); 469 TRACE_EVENT0("video", "VideoTrackAdapter::DeliverFrameOnIO");
446 ++frame_counter_; 470 ++frame_counter_;
447 for (FrameAdapters::iterator it = adapters_.begin(); 471 for (FrameAdapters::iterator it = adapters_.begin();
448 it != adapters_.end(); ++it) { 472 it != adapters_.end(); ++it) {
449 (*it)->DeliverFrame(frame, format, estimated_capture_time); 473 (*it)->DeliverFrame(frame, format, estimated_capture_time);
450 } 474 }
451 } 475 }
452 476
453 void VideoTrackAdapter::CheckFramesReceivedOnIO( 477 void VideoTrackAdapter::CheckFramesReceivedOnIO(
454 const OnMutedCallback& set_muted_state_callback, 478 const OnMutedCallback& set_muted_state_callback,
455 uint64 old_frame_counter_snapshot) { 479 uint64 old_frame_counter_snapshot) {
456 DCHECK(io_message_loop_->BelongsToCurrentThread()); 480 DCHECK(io_message_loop_->BelongsToCurrentThread());
481
482 if (!monitoring_frame_rate_)
483 return;
484
457 DVLOG_IF(1, old_frame_counter_snapshot == frame_counter_) 485 DVLOG_IF(1, old_frame_counter_snapshot == frame_counter_)
458 << "No frames have passed, setting source as Muted."; 486 << "No frames have passed, setting source as Muted.";
459 set_muted_state_callback.Run(old_frame_counter_snapshot == frame_counter_);
460 487
461 // Rearm the monitoring while there are active Tracks, i.e. as long as the 488 bool muted_state = old_frame_counter_snapshot == frame_counter_;
462 // owner MediaStreamSource is active. 489 if (muted_state_ != muted_state) {
490 set_muted_state_callback.Run(muted_state);
491 muted_state_ = muted_state;
492 }
493
463 io_message_loop_->PostDelayedTask(FROM_HERE, 494 io_message_loop_->PostDelayedTask(FROM_HERE,
464 base::Bind(&VideoTrackAdapter::CheckFramesReceivedOnIO, this, 495 base::Bind(&VideoTrackAdapter::CheckFramesReceivedOnIO, this,
465 set_muted_state_callback, frame_counter_), 496 set_muted_state_callback, frame_counter_),
466 base::TimeDelta::FromSecondsD(kNormalFrameTimeoutInFrameIntervals / 497 base::TimeDelta::FromSecondsD(kNormalFrameTimeoutInFrameIntervals /
467 source_frame_rate_)); 498 source_frame_rate_));
468 } 499 }
469 500
470 } // namespace content 501 } // namespace content
OLDNEW
« no previous file with comments | « content/renderer/media/video_track_adapter.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698