| Index: content/renderer/media/video_track_adapter.cc
|
| diff --git a/content/renderer/media/video_track_adapter.cc b/content/renderer/media/video_track_adapter.cc
|
| index ada3502173ee794af8a2809facddb7689f114b82..0bbee8031728098eae4c8170d16c349730485264 100644
|
| --- a/content/renderer/media/video_track_adapter.cc
|
| +++ b/content/renderer/media/video_track_adapter.cc
|
| @@ -29,6 +29,8 @@ const float kNormalFrameTimeoutInFrameIntervals = 25.0f;
|
| // frame rate is specified.
|
| const int kMinTimeInMsBetweenFrames = 5;
|
|
|
| +const int kNumberOfFramesInFrameRateCalculation = 20;
|
| +
|
| // Empty method used for keeping a reference to the original media::VideoFrame
|
| // in VideoFrameResolutionAdapter::DeliverFrame if cropping is needed.
|
| // The reference to |frame| is kept in the closure that calls this method.
|
| @@ -105,6 +107,7 @@ class VideoTrackAdapter::VideoFrameResolutionAdapter
|
| double max_aspect_ratio_;
|
|
|
| double frame_rate_;
|
| + int number_of_dropped_frames_;
|
| base::TimeDelta last_time_stamp_;
|
| double max_frame_rate_;
|
| double keep_frame_counter_;
|
| @@ -337,9 +340,9 @@ VideoTrackAdapter::VideoTrackAdapter(
|
| : io_message_loop_(io_message_loop),
|
| renderer_task_runner_(base::MessageLoopProxy::current()),
|
| monitoring_frame_rate_(false),
|
| - muted_state_(false),
|
| frame_counter_(0),
|
| - source_frame_rate_(0.0f) {
|
| + source_frame_rate_(0.0f),
|
| + dropped_frames_counter_(0) {
|
| DCHECK(io_message_loop_.get());
|
| }
|
|
|
| @@ -402,12 +405,14 @@ void VideoTrackAdapter::RemoveTrack(const MediaStreamVideoTrack* track) {
|
|
|
| void VideoTrackAdapter::StartFrameMonitoring(
|
| double source_frame_rate,
|
| - const OnMutedCallback& on_muted_callback) {
|
| + const OnFrameRateCallback& on_muted_callback) {
|
| DCHECK(thread_checker_.CalledOnValidThread());
|
|
|
| - VideoTrackAdapter::OnMutedCallback bound_on_muted_callback =
|
| + VideoTrackAdapter::OnFrameRateCallback bound_on_muted_callback =
|
| media::BindToCurrentLoop(on_muted_callback);
|
|
|
| + media::BindToCurrentLoop(on_muted_callback);
|
| +
|
| io_message_loop_->PostTask(
|
| FROM_HERE,
|
| base::Bind(&VideoTrackAdapter::StartFrameMonitoringOnIO,
|
| @@ -415,7 +420,7 @@ void VideoTrackAdapter::StartFrameMonitoring(
|
| }
|
|
|
| void VideoTrackAdapter::StartFrameMonitoringOnIO(
|
| - const OnMutedCallback& on_muted_callback,
|
| + const OnFrameRateCallback& on_muted_callback,
|
| double source_frame_rate) {
|
| DCHECK(io_message_loop_->BelongsToCurrentThread());
|
| DCHECK(!monitoring_frame_rate_);
|
| @@ -425,12 +430,13 @@ void VideoTrackAdapter::StartFrameMonitoringOnIO(
|
| // If the source does not know the frame rate, set one by default.
|
| if (source_frame_rate == 0.0f)
|
| source_frame_rate = MediaStreamVideoSource::kDefaultFrameRate;
|
| +
|
| source_frame_rate_ = source_frame_rate;
|
| DVLOG(1) << "Monitoring frame creation, first (large) delay: "
|
| << (kFirstFrameTimeoutInFrameIntervals / source_frame_rate_) << "s";
|
| io_message_loop_->PostDelayedTask(FROM_HERE,
|
| base::Bind(&VideoTrackAdapter::CheckFramesReceivedOnIO, this,
|
| - on_muted_callback, frame_counter_),
|
| + on_muted_callback, frame_counter_, dropped_frames_counter_),
|
| base::TimeDelta::FromSecondsD(kFirstFrameTimeoutInFrameIntervals /
|
| source_frame_rate_));
|
| }
|
| @@ -466,15 +472,34 @@ void VideoTrackAdapter::DeliverFrameOnIO(
|
| DCHECK(io_message_loop_->BelongsToCurrentThread());
|
| TRACE_EVENT0("video", "VideoTrackAdapter::DeliverFrameOnIO");
|
| ++frame_counter_;
|
| + UpdateFrameRateOnIO(frame->timestamp());;
|
| + dropped_frames_counter_ = format.number_of_dropped_frames;
|
| +
|
| for (FrameAdapters::iterator it = adapters_.begin();
|
| it != adapters_.end(); ++it) {
|
| (*it)->DeliverFrame(frame, format, estimated_capture_time);
|
| }
|
| }
|
|
|
| +void VideoTrackAdapter::UpdateFrameRateOnIO(base::TimeDelta timestamp) {
|
| + DCHECK(io_message_loop_->BelongsToCurrentThread());
|
| +
|
| + frame_timestamps_.push(timestamp);
|
| + if (frame_timestamps_.size() > kNumberOfFramesInFrameRateCalculation)
|
| + frame_timestamps_.pop();
|
| +}
|
| +
|
| +float VideoTrackAdapter::GetFrameRateOnIO() {
|
| + if (frame_timestamps_.size() < 2)
|
| + return 0;
|
| + return frame_timestamps_.size() /
|
| + (frame_timestamps_.back() - frame_timestamps_.front()).InSecondsF();
|
| +}
|
| +
|
| void VideoTrackAdapter::CheckFramesReceivedOnIO(
|
| - const OnMutedCallback& set_muted_state_callback,
|
| - uint64 old_frame_counter_snapshot) {
|
| + const OnFrameRateCallback& set_muted_state_callback,
|
| + uint64 old_frame_counter_snapshot,
|
| + int old_dropped_frame_counter_snapshot) {
|
| DCHECK(io_message_loop_->BelongsToCurrentThread());
|
|
|
| if (!monitoring_frame_rate_)
|
| @@ -484,14 +509,16 @@ void VideoTrackAdapter::CheckFramesReceivedOnIO(
|
| << "No frames have passed, setting source as Muted.";
|
|
|
| bool muted_state = old_frame_counter_snapshot == frame_counter_;
|
| - if (muted_state_ != muted_state) {
|
| - set_muted_state_callback.Run(muted_state);
|
| - muted_state_ = muted_state;
|
| + if (muted_state) {
|
| + frame_timestamps_ = std::queue<base::TimeDelta>();
|
| }
|
| + set_muted_state_callback.Run(
|
| + GetFrameRateOnIO(),
|
| + dropped_frames_counter_ - old_dropped_frame_counter_snapshot);
|
|
|
| io_message_loop_->PostDelayedTask(FROM_HERE,
|
| base::Bind(&VideoTrackAdapter::CheckFramesReceivedOnIO, this,
|
| - set_muted_state_callback, frame_counter_),
|
| + set_muted_state_callback, frame_counter_, dropped_frames_counter_),
|
| base::TimeDelta::FromSecondsD(kNormalFrameTimeoutInFrameIntervals /
|
| source_frame_rate_));
|
| }
|
|
|