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

Unified Diff: content/browser/media/capture/animated_content_sampler.cc

Issue 1109603003: Clean-up: Break sampler classes into their own files. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years, 8 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 side-by-side diff with in-line comments
Download patch
Index: content/browser/media/capture/animated_content_sampler.cc
diff --git a/content/browser/media/capture/video_capture_oracle.cc b/content/browser/media/capture/animated_content_sampler.cc
similarity index 52%
copy from content/browser/media/capture/video_capture_oracle.cc
copy to content/browser/media/capture/animated_content_sampler.cc
index 3cddc38b0c2fa33360901c8d7b046690eacf7d4e..a30364b0e97d215acfc836442698112180b452a0 100644
--- a/content/browser/media/capture/video_capture_oracle.cc
+++ b/content/browser/media/capture/animated_content_sampler.cc
@@ -1,30 +1,15 @@
-// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Copyright (c) 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "content/browser/media/capture/video_capture_oracle.h"
+#include "content/browser/media/capture/animated_content_sampler.h"
#include <algorithm>
-#include "base/format_macros.h"
-#include "base/strings/stringprintf.h"
-#include "base/trace_event/trace_event.h"
-
namespace content {
namespace {
-// This value controls how many redundant, timer-base captures occur when the
-// content is static. Redundantly capturing the same frame allows iterative
-// quality enhancement, and also allows the buffer to fill in "buffered mode".
-//
-// TODO(nick): Controlling this here is a hack and a layering violation, since
-// it's a strategy specific to the WebRTC consumer, and probably just papers
-// over some frame dropping and quality bugs. It should either be controlled at
-// a higher level, or else redundant frame generation should be pushed down
-// further into the WebRTC encoding stack.
-const int kNumRedundantCapturesOfStaticContent = 200;
-
// These specify the minimum/maximum amount of recent event history to examine
// to detect animated content. If the values are too low, there is a greater
// risk of false-positive detections and low accuracy. If they are too high,
@@ -52,199 +37,8 @@ const int kMaxLockInPeriodMicros = 83333; // 12 FPS
// value, the higher the variance in frame timestamps.
const int kDriftCorrectionMillis = 2000;
-// Given the amount of time between frames, compare to the expected amount of
-// time between frames at |frame_rate| and return the fractional difference.
-double FractionFromExpectedFrameRate(base::TimeDelta delta, int frame_rate) {
- DCHECK_GT(frame_rate, 0);
- const base::TimeDelta expected_delta =
- base::TimeDelta::FromSeconds(1) / frame_rate;
- return (delta - expected_delta).InMillisecondsF() /
- expected_delta.InMillisecondsF();
-}
-
} // anonymous namespace
-VideoCaptureOracle::VideoCaptureOracle(base::TimeDelta min_capture_period)
- : frame_number_(0),
- last_delivered_frame_number_(-1),
- smoothing_sampler_(min_capture_period,
- kNumRedundantCapturesOfStaticContent),
- content_sampler_(min_capture_period) {
-}
-
-VideoCaptureOracle::~VideoCaptureOracle() {}
-
-bool VideoCaptureOracle::ObserveEventAndDecideCapture(
- Event event,
- const gfx::Rect& damage_rect,
- base::TimeTicks event_time) {
- DCHECK_GE(event, 0);
- DCHECK_LT(event, kNumEvents);
- if (event_time < last_event_time_[event]) {
- LOG(WARNING) << "Event time is not monotonically non-decreasing. "
- << "Deciding not to capture this frame.";
- return false;
- }
- last_event_time_[event] = event_time;
-
- bool should_sample;
- switch (event) {
- case kCompositorUpdate:
- smoothing_sampler_.ConsiderPresentationEvent(event_time);
- content_sampler_.ConsiderPresentationEvent(damage_rect, event_time);
- if (content_sampler_.HasProposal()) {
- should_sample = content_sampler_.ShouldSample();
- if (should_sample)
- event_time = content_sampler_.frame_timestamp();
- } else {
- should_sample = smoothing_sampler_.ShouldSample();
- }
- break;
- default:
- should_sample = smoothing_sampler_.IsOverdueForSamplingAt(event_time);
- break;
- }
-
- SetFrameTimestamp(frame_number_, event_time);
- return should_sample;
-}
-
-int VideoCaptureOracle::RecordCapture() {
- smoothing_sampler_.RecordSample();
- content_sampler_.RecordSample(GetFrameTimestamp(frame_number_));
- return frame_number_++;
-}
-
-bool VideoCaptureOracle::CompleteCapture(int frame_number,
- base::TimeTicks* frame_timestamp) {
- // Drop frame if previous frame number is higher.
- if (last_delivered_frame_number_ > frame_number) {
- LOG(WARNING) << "Out of order frame delivery detected (have #"
- << frame_number << ", last was #"
- << last_delivered_frame_number_ << "). Dropping frame.";
- return false;
- }
- last_delivered_frame_number_ = frame_number;
-
- *frame_timestamp = GetFrameTimestamp(frame_number);
-
- // If enabled, log a measurement of how this frame timestamp has incremented
- // in relation to an ideal increment.
- if (VLOG_IS_ON(2) && frame_number > 0) {
- const base::TimeDelta delta =
- *frame_timestamp - GetFrameTimestamp(frame_number - 1);
- if (content_sampler_.HasProposal()) {
- const double estimated_frame_rate =
- 1000000.0 / content_sampler_.detected_period().InMicroseconds();
- const int rounded_frame_rate =
- static_cast<int>(estimated_frame_rate + 0.5);
- VLOG(2) << base::StringPrintf(
- "Captured #%d: delta=%" PRId64 " usec"
- ", now locked into {%s}, %+0.1f%% slower than %d FPS",
- frame_number,
- delta.InMicroseconds(),
- content_sampler_.detected_region().ToString().c_str(),
- 100.0 * FractionFromExpectedFrameRate(delta, rounded_frame_rate),
- rounded_frame_rate);
- } else {
- VLOG(2) << base::StringPrintf(
- "Captured #%d: delta=%" PRId64 " usec"
- ", d/30fps=%+0.1f%%, d/25fps=%+0.1f%%, d/24fps=%+0.1f%%",
- frame_number,
- delta.InMicroseconds(),
- 100.0 * FractionFromExpectedFrameRate(delta, 30),
- 100.0 * FractionFromExpectedFrameRate(delta, 25),
- 100.0 * FractionFromExpectedFrameRate(delta, 24));
- }
- }
-
- return !frame_timestamp->is_null();
-}
-
-base::TimeTicks VideoCaptureOracle::GetFrameTimestamp(int frame_number) const {
- DCHECK_LE(frame_number, frame_number_);
- DCHECK_LT(frame_number_ - frame_number, kMaxFrameTimestamps);
- return frame_timestamps_[frame_number % kMaxFrameTimestamps];
-}
-
-void VideoCaptureOracle::SetFrameTimestamp(int frame_number,
- base::TimeTicks timestamp) {
- frame_timestamps_[frame_number % kMaxFrameTimestamps] = timestamp;
-}
-
-SmoothEventSampler::SmoothEventSampler(base::TimeDelta min_capture_period,
- int redundant_capture_goal)
- : min_capture_period_(min_capture_period),
- redundant_capture_goal_(redundant_capture_goal),
- token_bucket_capacity_(min_capture_period + min_capture_period / 2),
- overdue_sample_count_(0),
- token_bucket_(token_bucket_capacity_) {
- DCHECK_GT(min_capture_period_.InMicroseconds(), 0);
-}
-
-void SmoothEventSampler::ConsiderPresentationEvent(base::TimeTicks event_time) {
- DCHECK(!event_time.is_null());
-
- // Add tokens to the bucket based on advancement in time. Then, re-bound the
- // number of tokens in the bucket. Overflow occurs when there is too much
- // time between events (a common case), or when RecordSample() is not being
- // called often enough (a bug). On the other hand, if RecordSample() is being
- // called too often (e.g., as a reaction to IsOverdueForSamplingAt()), the
- // bucket will underflow.
- if (!current_event_.is_null()) {
- if (current_event_ < event_time) {
- token_bucket_ += event_time - current_event_;
- if (token_bucket_ > token_bucket_capacity_)
- token_bucket_ = token_bucket_capacity_;
- }
- TRACE_COUNTER1("gpu.capture",
- "MirroringTokenBucketUsec",
- std::max<int64>(0, token_bucket_.InMicroseconds()));
- }
- current_event_ = event_time;
-}
-
-bool SmoothEventSampler::ShouldSample() const {
- return token_bucket_ >= min_capture_period_;
-}
-
-void SmoothEventSampler::RecordSample() {
- token_bucket_ -= min_capture_period_;
- if (token_bucket_ < base::TimeDelta())
- token_bucket_ = base::TimeDelta();
- TRACE_COUNTER1("gpu.capture",
- "MirroringTokenBucketUsec",
- std::max<int64>(0, token_bucket_.InMicroseconds()));
-
- if (HasUnrecordedEvent()) {
- last_sample_ = current_event_;
- overdue_sample_count_ = 0;
- } else {
- ++overdue_sample_count_;
- }
-}
-
-bool SmoothEventSampler::IsOverdueForSamplingAt(base::TimeTicks event_time)
- const {
- DCHECK(!event_time.is_null());
-
- if (!HasUnrecordedEvent() && overdue_sample_count_ >= redundant_capture_goal_)
- return false; // Not dirty.
-
- if (last_sample_.is_null())
- return true;
-
- // If we're dirty but not yet old, then we've recently gotten updates, so we
- // won't request a sample just yet.
- base::TimeDelta dirty_interval = event_time - last_sample_;
- return dirty_interval >=
- base::TimeDelta::FromMilliseconds(kNonAnimatingThresholdMillis);
-}
-
-bool SmoothEventSampler::HasUnrecordedEvent() const {
- return !current_event_.is_null() && current_event_ != last_sample_;
-}
-
AnimatedContentSampler::AnimatedContentSampler(
base::TimeDelta min_capture_period)
: min_capture_period_(min_capture_period) {}

Powered by Google App Engine
This is Rietveld 408576698