// 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 "media/capture/content/animated_content_sampler.h"

#include <stddef.h>
#include <stdint.h>

#include <cmath>
#include <memory>
#include <utility>
#include <vector>

#include "base/logging.h"
#include "base/time/time.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/gfx/geometry/rect.h"

namespace media {

namespace {

base::TimeTicks InitialTestTimeTicks() {
  return base::TimeTicks() + base::TimeDelta::FromSeconds(1);
}

base::TimeDelta FpsAsPeriod(int frame_rate) {
  return base::TimeDelta::FromSeconds(1) / frame_rate;
}

}  // namespace

class AnimatedContentSamplerTest : public ::testing::Test {
 public:
  AnimatedContentSamplerTest() {}
  ~AnimatedContentSamplerTest() override {}

  void SetUp() override {
    rand_seed_ = static_cast<int>(
        (InitialTestTimeTicks() - base::TimeTicks()).InMicroseconds());
    sampler_.reset(new AnimatedContentSampler(GetMinCapturePeriod()));
  }

 protected:
  // Overridden by subclass for parameterized tests.
  virtual base::TimeDelta GetMinCapturePeriod() const {
    return base::TimeDelta::FromSeconds(1) / 30;
  }

  AnimatedContentSampler* sampler() const { return sampler_.get(); }

  int GetRandomInRange(int begin, int end) {
    const int len = end - begin;
    const int rand_offset = (len == 0) ? 0 : (NextRandomInt() % (end - begin));
    return begin + rand_offset;
  }

  gfx::Rect GetRandomDamageRect() {
    return gfx::Rect(0, 0, GetRandomInRange(1, 100), GetRandomInRange(1, 100));
  }

  gfx::Rect GetContentDamageRect() {
    // This must be distinct from anything GetRandomDamageRect() could return.
    return gfx::Rect(0, 0, 1280, 720);
  }

  // Directly inject an observation.  Only used to test
  // ElectMajorityDamageRect().
  void ObserveDamageRect(const gfx::Rect& damage_rect) {
    sampler_->observations_.push_back(
        AnimatedContentSampler::Observation(damage_rect, base::TimeTicks()));
  }

  gfx::Rect ElectMajorityDamageRect() const {
    return sampler_->ElectMajorityDamageRect();
  }

  static base::TimeDelta ComputeSamplingPeriod(
      base::TimeDelta detected_period,
      base::TimeDelta target_sampling_period,
      base::TimeDelta min_capture_period) {
    return AnimatedContentSampler::ComputeSamplingPeriod(
        detected_period, target_sampling_period, min_capture_period);
  }

 private:
  // Note: Not using base::RandInt() because it is horribly slow on debug
  // builds.  The following is a very simple, deterministic LCG:
  int NextRandomInt() {
    rand_seed_ = (1103515245 * rand_seed_ + 12345) % (1 << 31);
    return rand_seed_;
  }

  int rand_seed_;
  std::unique_ptr<AnimatedContentSampler> sampler_;
};

TEST_F(AnimatedContentSamplerTest, ElectsNoneFromZeroDamageRects) {
  EXPECT_EQ(gfx::Rect(), ElectMajorityDamageRect());
}

TEST_F(AnimatedContentSamplerTest, ElectsMajorityFromOneDamageRect) {
  const gfx::Rect the_one_rect(0, 0, 1, 1);
  ObserveDamageRect(the_one_rect);
  EXPECT_EQ(the_one_rect, ElectMajorityDamageRect());
}

TEST_F(AnimatedContentSamplerTest, ElectsNoneFromTwoDamageRectsOfSameArea) {
  const gfx::Rect one_rect(0, 0, 1, 1);
  const gfx::Rect another_rect(1, 1, 1, 1);
  ObserveDamageRect(one_rect);
  ObserveDamageRect(another_rect);
  EXPECT_EQ(gfx::Rect(), ElectMajorityDamageRect());
}

TEST_F(AnimatedContentSamplerTest, ElectsLargerOfTwoDamageRects_1) {
  const gfx::Rect one_rect(0, 0, 1, 1);
  const gfx::Rect another_rect(0, 0, 2, 2);
  ObserveDamageRect(one_rect);
  ObserveDamageRect(another_rect);
  EXPECT_EQ(another_rect, ElectMajorityDamageRect());
}

TEST_F(AnimatedContentSamplerTest, ElectsLargerOfTwoDamageRects_2) {
  const gfx::Rect one_rect(0, 0, 2, 2);
  const gfx::Rect another_rect(0, 0, 1, 1);
  ObserveDamageRect(one_rect);
  ObserveDamageRect(another_rect);
  EXPECT_EQ(one_rect, ElectMajorityDamageRect());
}

TEST_F(AnimatedContentSamplerTest, ElectsSameAsMooreDemonstration) {
  // A more complex sequence (from Moore's web site): Three different Rects with
  // the same area, but occurring a different number of times.  C should win the
  // vote.
  const gfx::Rect rect_a(0, 0, 1, 4);
  const gfx::Rect rect_b(1, 1, 4, 1);
  const gfx::Rect rect_c(2, 2, 2, 2);
  for (int i = 0; i < 3; ++i)
    ObserveDamageRect(rect_a);
  for (int i = 0; i < 2; ++i)
    ObserveDamageRect(rect_c);
  for (int i = 0; i < 2; ++i)
    ObserveDamageRect(rect_b);
  for (int i = 0; i < 3; ++i)
    ObserveDamageRect(rect_c);
  ObserveDamageRect(rect_b);
  for (int i = 0; i < 2; ++i)
    ObserveDamageRect(rect_c);
  EXPECT_EQ(rect_c, ElectMajorityDamageRect());
}

TEST_F(AnimatedContentSamplerTest, Elects24FpsVideoInsteadOf48FpsSpinner) {
  // Scenario: 24 FPS 720x480 Video versus 48 FPS 96x96 "Busy Spinner"
  const gfx::Rect video_rect(100, 100, 720, 480);
  const gfx::Rect spinner_rect(360, 0, 96, 96);
  for (int i = 0; i < 100; ++i) {
    // |video_rect| occurs once for every two |spinner_rect|.  Vary the order
    // of events between the two:
    ObserveDamageRect(video_rect);
    ObserveDamageRect(spinner_rect);
    ObserveDamageRect(spinner_rect);
    ObserveDamageRect(video_rect);
    ObserveDamageRect(spinner_rect);
    ObserveDamageRect(spinner_rect);
    ObserveDamageRect(spinner_rect);
    ObserveDamageRect(video_rect);
    ObserveDamageRect(spinner_rect);
    ObserveDamageRect(spinner_rect);
    ObserveDamageRect(video_rect);
    ObserveDamageRect(spinner_rect);
  }
  EXPECT_EQ(video_rect, ElectMajorityDamageRect());
}

TEST_F(AnimatedContentSamplerTest, TargetsSamplingPeriod) {
  struct Helper {
    static void RunTargetSamplingPeriodTest(int target_fps) {
      const base::TimeDelta min_capture_period = FpsAsPeriod(60);
      const base::TimeDelta target_sampling_period = FpsAsPeriod(target_fps);

      for (int content_fps = 1; content_fps <= 60; ++content_fps) {
        const base::TimeDelta content_period = FpsAsPeriod(content_fps);
        const base::TimeDelta sampling_period = ComputeSamplingPeriod(
            content_period, target_sampling_period, min_capture_period);
        if (content_period >= target_sampling_period) {
          ASSERT_EQ(content_period, sampling_period);
        } else {
          ASSERT_LE(min_capture_period, sampling_period);

          // Check that the sampling rate is as close (or closer) to the target
          // sampling rate than any integer-subsampling of the content frame
          // rate.
          const double absolute_diff =
              std::abs(1.0 / sampling_period.InSecondsF() - target_fps);
          const double fudge_for_acceptable_rounding_error = 0.005;
          for (double divisor = 1; divisor < 4; ++divisor) {
            SCOPED_TRACE(::testing::Message() << "target_fps=" << target_fps
                                              << ", content_fps=" << content_fps
                                              << ", divisor=" << divisor);
            ASSERT_GE(std::abs(content_fps / divisor - target_fps),
                      absolute_diff - fudge_for_acceptable_rounding_error);
          }
        }
      }
    }
  };

  for (int target_fps = 1; target_fps <= 60; ++target_fps)
    Helper::RunTargetSamplingPeriodTest(target_fps);
}

namespace {

// A test scenario for AnimatedContentSamplerParameterizedTest.
struct Scenario {
  base::TimeDelta vsync_interval;      // Reflects compositor's update rate.
  base::TimeDelta min_capture_period;  // Reflects maximum capture rate.
  base::TimeDelta content_period;      // Reflects content animation rate.
  base::TimeDelta target_sampling_period;

  Scenario(int compositor_frequency, int max_frame_rate, int content_frame_rate)
      : vsync_interval(FpsAsPeriod(compositor_frequency)),
        min_capture_period(FpsAsPeriod(max_frame_rate)),
        content_period(FpsAsPeriod(content_frame_rate)) {
    CHECK(content_period >= vsync_interval)
        << "Bad test params: Impossible to animate faster than the compositor.";
  }

  Scenario(int compositor_frequency,
           int max_frame_rate,
           int content_frame_rate,
           int target_sampling_rate)
      : vsync_interval(FpsAsPeriod(compositor_frequency)),
        min_capture_period(FpsAsPeriod(max_frame_rate)),
        content_period(FpsAsPeriod(content_frame_rate)),
        target_sampling_period(FpsAsPeriod(target_sampling_rate)) {
    CHECK(content_period >= vsync_interval)
        << "Bad test params: Impossible to animate faster than the compositor.";
  }
};

// Value printer for Scenario.
::std::ostream& operator<<(::std::ostream& os, const Scenario& s) {
  return os << "{ vsync_interval=" << s.vsync_interval.InMicroseconds()
            << ", min_capture_period=" << s.min_capture_period.InMicroseconds()
            << ", content_period=" << s.content_period.InMicroseconds() << " }";
}

}  // namespace

class AnimatedContentSamplerParameterizedTest
    : public AnimatedContentSamplerTest,
      public ::testing::WithParamInterface<Scenario> {
 public:
  AnimatedContentSamplerParameterizedTest()
      : count_dropped_frames_(0), count_sampled_frames_(0) {}
  virtual ~AnimatedContentSamplerParameterizedTest() {}

  void SetUp() override {
    AnimatedContentSamplerTest::SetUp();
    sampler()->SetTargetSamplingPeriod(GetParam().target_sampling_period);
  }

 protected:
  typedef std::pair<gfx::Rect, base::TimeTicks> Event;

  base::TimeDelta GetMinCapturePeriod() const override {
    return GetParam().min_capture_period;
  }

  base::TimeDelta ComputeExpectedSamplingPeriod() const {
    return AnimatedContentSamplerTest::ComputeSamplingPeriod(
        GetParam().content_period, GetParam().target_sampling_period,
        GetParam().min_capture_period);
  }

  // Generate a sequence of events from the compositor pipeline.  The event
  // times will all be at compositor vsync boundaries.
  std::vector<Event> GenerateEventSequence(base::TimeTicks begin,
                                           base::TimeTicks end,
                                           bool include_content_frame_events,
                                           bool include_random_events,
                                           base::TimeTicks* next_begin_time) {
    DCHECK(GetParam().content_period >= GetParam().vsync_interval);
    base::TimeTicks next_content_time = begin;
    std::vector<Event> events;
    base::TimeTicks compositor_time;
    for (compositor_time = begin; compositor_time < end;
         compositor_time += GetParam().vsync_interval) {
      if (next_content_time <= compositor_time) {
        next_content_time += GetParam().content_period;
        if (include_content_frame_events) {
          events.push_back(Event(GetContentDamageRect(), compositor_time));
          continue;
        }
      }
      if (include_random_events && GetRandomInRange(0, 1) == 0) {
        events.push_back(Event(GetRandomDamageRect(), compositor_time));
      }
    }

    if (next_begin_time) {
      while (compositor_time < next_content_time)
        compositor_time += GetParam().vsync_interval;
      *next_begin_time = compositor_time;
    }

    DCHECK(!events.empty());
    return events;
  }

  // Feed |events| through the sampler, and detect whether the expected
  // lock-in/out transition occurs.  Also, track and measure the frame drop
  // ratio and check it against the expected drop rate.
  void RunEventSequence(const std::vector<Event> events,
                        bool was_detecting_before,
                        bool is_detecting_after,
                        bool simulate_pipeline_back_pressure,
                        const char* description) {
    SCOPED_TRACE(::testing::Message() << "Description: " << description);

    gfx::Rect first_detected_region;

    EXPECT_EQ(was_detecting_before, sampler()->HasProposal());
    bool has_detection_switched = false;
    bool has_detection_flip_flopped_once = false;
    ResetFrameCounters();
    for (std::vector<Event>::const_iterator i = events.begin();
         i != events.end(); ++i) {
      sampler()->ConsiderPresentationEvent(i->first, i->second);

      // Detect when the sampler locks in/out, and that it stays that way for
      // all further iterations of this loop.  It is permissible for the lock-in
      // to flip-flop once, but no more than that.
      if (!has_detection_switched &&
          was_detecting_before != sampler()->HasProposal()) {
        has_detection_switched = true;
      } else if (has_detection_switched &&
                 is_detecting_after != sampler()->HasProposal()) {
        ASSERT_FALSE(has_detection_flip_flopped_once);
        has_detection_flip_flopped_once = true;
        has_detection_switched = false;
      }
      ASSERT_EQ(
          has_detection_switched ? is_detecting_after : was_detecting_before,
          sampler()->HasProposal());

      if (sampler()->HasProposal()) {
        // Make sure the sampler doesn't flip-flop and keep proposing sampling
        // based on locking into different regions.
        if (first_detected_region.IsEmpty()) {
          first_detected_region = sampler()->detected_region();
          ASSERT_FALSE(first_detected_region.IsEmpty());
        } else {
          EXPECT_EQ(first_detected_region, sampler()->detected_region());
        }

        if (simulate_pipeline_back_pressure && GetRandomInRange(0, 2) == 0)
          ClientCannotSampleFrame(*i);
        else
          ClientDoesWhatSamplerProposes(*i);
      } else {
        EXPECT_FALSE(sampler()->ShouldSample());
        if (!simulate_pipeline_back_pressure || GetRandomInRange(0, 2) == 1)
          sampler()->RecordSample(i->second);
      }
    }
    EXPECT_EQ(is_detecting_after, sampler()->HasProposal());
    ExpectFrameDropRatioIsCorrect();
  }

  void ResetFrameCounters() {
    count_dropped_frames_ = 0;
    count_sampled_frames_ = 0;
  }

  // Keep track what the sampler is proposing, and call RecordSample() if it
  // proposes sampling |event|.
  void ClientDoesWhatSamplerProposes(const Event& event) {
    if (sampler()->ShouldSample()) {
      EXPECT_EQ(GetContentDamageRect(), event.first);
      sampler()->RecordSample(sampler()->frame_timestamp());
      ++count_sampled_frames_;
    } else if (event.first == GetContentDamageRect()) {
      ++count_dropped_frames_;
    }
  }

  // RecordSample() is not called, but for testing, keep track of what the
  // sampler is proposing for |event|.
  void ClientCannotSampleFrame(const Event& event) {
    if (sampler()->ShouldSample()) {
      EXPECT_EQ(GetContentDamageRect(), event.first);
      ++count_sampled_frames_;
    } else if (event.first == GetContentDamageRect()) {
      ++count_dropped_frames_;
    }
  }

  // Confirm the AnimatedContentSampler is not dropping more frames than
  // expected, given current test parameters.
  void ExpectFrameDropRatioIsCorrect() {
    if (count_sampled_frames_ == 0) {
      EXPECT_EQ(0, count_dropped_frames_);
      return;
    }
    const double expected_sampling_ratio =
        GetParam().content_period.InSecondsF() /
        ComputeExpectedSamplingPeriod().InSecondsF();
    const int total_frames = count_dropped_frames_ + count_sampled_frames_;
    EXPECT_NEAR(total_frames * expected_sampling_ratio, count_sampled_frames_,
                1.5);
    EXPECT_NEAR(total_frames * (1.0 - expected_sampling_ratio),
                count_dropped_frames_, 1.5);
  }

 private:
  // These counters only include the frames with the desired content.
  int count_dropped_frames_;
  int count_sampled_frames_;
};

// Tests that the implementation locks in/out of frames containing stable
// animated content, whether or not random events are also simultaneously
// present.
TEST_P(AnimatedContentSamplerParameterizedTest, DetectsAnimatedContent) {
  // |begin| refers to the start of an event sequence in terms of the
  // Compositor's clock.
  base::TimeTicks begin = InitialTestTimeTicks();

  // Provide random events and expect no lock-in.
  RunEventSequence(
      GenerateEventSequence(begin, begin + base::TimeDelta::FromSeconds(5),
                            false, true, &begin),
      false, false, false, "Provide random events and expect no lock-in.");
  if (HasFailure())
    return;

  // Provide content frame events with some random events mixed-in, and expect
  // the sampler to lock-in.
  RunEventSequence(
      GenerateEventSequence(begin, begin + base::TimeDelta::FromSeconds(5),
                            true, true, &begin),
      false, true, false,
      "Provide content frame events with some random events mixed-in, and "
      "expect the sampler to lock-in.");
  if (HasFailure())
    return;

  // Continue providing content frame events without the random events mixed-in
  // and expect the lock-in to hold.
  RunEventSequence(
      GenerateEventSequence(begin, begin + base::TimeDelta::FromSeconds(5),
                            true, false, &begin),
      true, true, false,
      "Continue providing content frame events without the random events "
      "mixed-in and expect the lock-in to hold.");
  if (HasFailure())
    return;

  // Continue providing just content frame events and expect the lock-in to
  // hold.  Also simulate the capture pipeline experiencing back pressure.
  RunEventSequence(
      GenerateEventSequence(begin, begin + base::TimeDelta::FromSeconds(20),
                            true, false, &begin),
      true, true, true,
      "Continue providing just content frame events and expect the lock-in to "
      "hold.  Also simulate the capture pipeline experiencing back pressure.");
  if (HasFailure())
    return;

  // Provide a half-second of random events only, and expect the lock-in to be
  // broken.
  RunEventSequence(
      GenerateEventSequence(begin,
                            begin + base::TimeDelta::FromMilliseconds(500),
                            false, true, &begin),
      true, false, false,
      "Provide a half-second of random events only, and expect the lock-in to "
      "be broken.");
  if (HasFailure())
    return;

  // Now, go back to providing content frame events, and expect the sampler to
  // lock-in once again.
  RunEventSequence(
      GenerateEventSequence(begin, begin + base::TimeDelta::FromSeconds(5),
                            true, false, &begin),
      false, true, false,
      "Now, go back to providing content frame events, and expect the sampler "
      "to lock-in once again.");
}

// Tests that AnimatedContentSampler won't lock in to, nor flip-flop between,
// two animations of the same pixel change rate.  VideoCaptureOracle should
// revert to using the SmoothEventSampler for these kinds of situations, as
// there is no "right answer" as to which animation to lock into.
TEST_P(AnimatedContentSamplerParameterizedTest,
       DoesNotLockInToTwoCompetingAnimations) {
  // Don't test when the event stream cannot indicate two separate content
  // animations under the current test parameters.
  if (GetParam().content_period < 2 * GetParam().vsync_interval)
    return;

  // Start the first animation and run for a bit, and expect the sampler to
  // lock-in.
  base::TimeTicks begin = InitialTestTimeTicks();
  RunEventSequence(
      GenerateEventSequence(begin, begin + base::TimeDelta::FromSeconds(5),
                            true, false, &begin),
      false, true, false,
      "Start the first animation and run for a bit, and expect the sampler to "
      "lock-in.");
  if (HasFailure())
    return;

  // Now, keep the first animation and blend in a second animation of the same
  // size and frame rate, but at a different position.  This will should cause
  // the sampler to enter an "undetected" state since it's unclear which
  // animation should be locked into.
  std::vector<Event> first_animation_events = GenerateEventSequence(
      begin, begin + base::TimeDelta::FromSeconds(20), true, false, &begin);
  gfx::Rect second_animation_rect(
      gfx::Point(0, GetContentDamageRect().height()),
      GetContentDamageRect().size());
  std::vector<Event> both_animations_events;
  base::TimeDelta second_animation_offset = GetParam().vsync_interval;
  for (std::vector<Event>::const_iterator i = first_animation_events.begin();
       i != first_animation_events.end(); ++i) {
    both_animations_events.push_back(*i);
    both_animations_events.push_back(
        Event(second_animation_rect, i->second + second_animation_offset));
  }
  RunEventSequence(
      both_animations_events, true, false, false,
      "Now, blend-in a second animation of the same size and frame rate, but "
      "at a different position.");
  if (HasFailure())
    return;

  // Now, run just the first animation, and expect the sampler to lock-in once
  // again.
  RunEventSequence(
      GenerateEventSequence(begin, begin + base::TimeDelta::FromSeconds(5),
                            true, false, &begin),
      false, true, false,
      "Now, run just the first animation, and expect the sampler to lock-in "
      "once again.");
  if (HasFailure())
    return;

  // Now, blend in the second animation again, but it has half the frame rate of
  // the first animation and damage Rects with twice the area.  This will should
  // cause the sampler to enter an "undetected" state again.  This tests that
  // pixel-weighting is being accounted for in the sampler's logic.
  first_animation_events = GenerateEventSequence(
      begin, begin + base::TimeDelta::FromSeconds(20), true, false, &begin);
  second_animation_rect.set_width(second_animation_rect.width() * 2);
  both_animations_events.clear();
  bool include_second_animation_frame = true;
  for (std::vector<Event>::const_iterator i = first_animation_events.begin();
       i != first_animation_events.end(); ++i) {
    both_animations_events.push_back(*i);
    if (include_second_animation_frame) {
      both_animations_events.push_back(
          Event(second_animation_rect, i->second + second_animation_offset));
    }
    include_second_animation_frame = !include_second_animation_frame;
  }
  RunEventSequence(
      both_animations_events, true, false, false,
      "Now, blend in the second animation again, but it has half the frame "
      "rate of the first animation and damage Rects with twice the area.");
}

// Tests that the frame timestamps are smooth; meaning, that when run through a
// simulated compositor, each frame is held displayed for the right number of
// v-sync intervals.
TEST_P(AnimatedContentSamplerParameterizedTest, FrameTimestampsAreSmooth) {
  // Generate 30 seconds of animated content events, run the events through
  // AnimatedContentSampler, and record all frame timestamps being proposed
  // once lock-in is continuous.
  const base::TimeTicks begin = InitialTestTimeTicks();
  std::vector<Event> events = GenerateEventSequence(
      begin, begin + base::TimeDelta::FromSeconds(20), true, false, nullptr);
  typedef std::vector<base::TimeTicks> Timestamps;
  Timestamps frame_timestamps;
  for (std::vector<Event>::const_iterator i = events.begin(); i != events.end();
       ++i) {
    sampler()->ConsiderPresentationEvent(i->first, i->second);
    if (sampler()->HasProposal()) {
      if (sampler()->ShouldSample()) {
        frame_timestamps.push_back(sampler()->frame_timestamp());
        sampler()->RecordSample(sampler()->frame_timestamp());
      }
    } else {
      frame_timestamps.clear();  // Reset until continuous lock-in.
    }
  }
  ASSERT_LE(2u, frame_timestamps.size());

  // Iterate through the |frame_timestamps|, building a histogram counting the
  // number of times each frame was displayed k times.  For example, 10 frames
  // of 30 Hz content on a 60 Hz v-sync interval should result in
  // display_counts[2] == 10.  Quit early if any one frame was obviously
  // repeated too many times.
  const int64_t max_expected_repeats_per_frame =
      1 + ComputeExpectedSamplingPeriod() / GetParam().vsync_interval;
  std::vector<size_t> display_counts(max_expected_repeats_per_frame + 1, 0);
  base::TimeTicks last_present_time = frame_timestamps.front();
  for (Timestamps::const_iterator i = frame_timestamps.begin() + 1;
       i != frame_timestamps.end(); ++i) {
    const size_t num_vsync_intervals = static_cast<size_t>(
        (*i - last_present_time) / GetParam().vsync_interval);
    ASSERT_LT(0u, num_vsync_intervals);
    ASSERT_GT(display_counts.size(), num_vsync_intervals);  // Quit early.
    ++display_counts[num_vsync_intervals];
    last_present_time += num_vsync_intervals * GetParam().vsync_interval;
  }

  // Analyze the histogram for an expected result pattern.  If the frame
  // timestamps are smooth, there should only be one or two buckets with
  // non-zero counts and they should be next to each other.  Because the clock
  // precision for the event_times provided to the sampler is very granular
  // (i.e., the vsync_interval), it's okay if other buckets have a tiny "stray"
  // count in this test.
  size_t highest_count = 0;
  size_t second_highest_count = 0;
  for (size_t repeats = 1; repeats < display_counts.size(); ++repeats) {
    DVLOG(1) << "display_counts[" << repeats << "] is "
             << display_counts[repeats];
    if (display_counts[repeats] >= highest_count) {
      second_highest_count = highest_count;
      highest_count = display_counts[repeats];
    } else if (display_counts[repeats] > second_highest_count) {
      second_highest_count = display_counts[repeats];
    }
  }
  size_t stray_count_remaining =
      (frame_timestamps.size() - 1) - (highest_count + second_highest_count);
  // Expect no more than 0.75% of frames fall outside the two main buckets.
  EXPECT_GT(frame_timestamps.size() * 75 / 10000, stray_count_remaining);
  for (size_t repeats = 1; repeats < display_counts.size() - 1; ++repeats) {
    if (display_counts[repeats] == highest_count) {
      EXPECT_EQ(second_highest_count, display_counts[repeats + 1]);
      ++repeats;
    } else if (second_highest_count > 0 &&
               display_counts[repeats] == second_highest_count) {
      EXPECT_EQ(highest_count, display_counts[repeats + 1]);
      ++repeats;
    } else {
      EXPECT_GE(stray_count_remaining, display_counts[repeats]);
      stray_count_remaining -= display_counts[repeats];
    }
  }
}

// Tests that frame timestamps are "lightly pushed" back towards the original
// presentation event times, which tells us the AnimatedContentSampler can
// account for sources of timestamp drift and correct the drift.
TEST_P(AnimatedContentSamplerParameterizedTest,
       FrameTimestampsConvergeTowardsEventTimes) {
  const int max_drift_increment_millis = 3;

  // Generate a full minute of events.
  const base::TimeTicks begin = InitialTestTimeTicks();
  std::vector<Event> events = GenerateEventSequence(
      begin, begin + base::TimeDelta::FromMinutes(1), true, false, nullptr);

  // Modify the event sequence so that 1-3 ms of additional drift is suddenly
  // present every 100 events.  This is meant to simulate that, external to
  // AnimatedContentSampler, the video hardware vsync timebase is being
  // refreshed and is showing severe drift from the system clock.
  base::TimeDelta accumulated_drift;
  for (size_t i = 1; i < events.size(); ++i) {
    if (i % 100 == 0) {
      accumulated_drift += base::TimeDelta::FromMilliseconds(
          GetRandomInRange(1, max_drift_increment_millis + 1));
    }
    events[i].second += accumulated_drift;
  }

  // Run all the events through the sampler and track the last rewritten frame
  // timestamp.
  base::TimeTicks last_frame_timestamp;
  for (std::vector<Event>::const_iterator i = events.begin(); i != events.end();
       ++i) {
    sampler()->ConsiderPresentationEvent(i->first, i->second);
    if (sampler()->ShouldSample())
      last_frame_timestamp = sampler()->frame_timestamp();
  }

  // If drift was accounted for, the |last_frame_timestamp| should be close to
  // the last event's timestamp.
  const base::TimeDelta total_error =
      events.back().second - last_frame_timestamp;
  const base::TimeDelta max_acceptable_error =
      GetParam().min_capture_period +
      base::TimeDelta::FromMilliseconds(max_drift_increment_millis);
  EXPECT_NEAR(0.0, total_error.InMicroseconds(),
              max_acceptable_error.InMicroseconds());
}

INSTANTIATE_TEST_CASE_P(
    ,
    AnimatedContentSamplerParameterizedTest,
    ::testing::Values(
        // Typical frame rate content: Compositor runs at 60 Hz, capture at 30
        // Hz, and content video animates at 30, 25, or 24 Hz.
        Scenario(60, 30, 30),
        Scenario(60, 30, 25),
        Scenario(60, 30, 24),

        // High frame rate content that leverages the Compositor's
        // capabilities, but capture is still at 30 Hz.
        Scenario(60, 30, 60),
        Scenario(60, 30, 50),
        Scenario(60, 30, 48),

        // High frame rate content that leverages the Compositor's
        // capabilities, and capture is also a buttery 60 Hz.
        Scenario(60, 60, 60),
        Scenario(60, 60, 50),
        Scenario(60, 60, 48),

        // High frame rate content that leverages the Compositor's
        // capabilities, but the client has disabled HFR sampling.
        Scenario(60, 60, 60, 30),
        Scenario(60, 60, 50, 30),
        Scenario(60, 60, 48, 30),

        // On some platforms, the Compositor runs at 50 Hz.
        Scenario(50, 30, 30),
        Scenario(50, 30, 25),
        Scenario(50, 30, 24),
        Scenario(50, 30, 50),
        Scenario(50, 30, 48),

        // Stable, but non-standard content frame rates.
        Scenario(60, 30, 16),
        Scenario(60, 30, 20),
        Scenario(60, 30, 23),
        Scenario(60, 30, 26),
        Scenario(60, 30, 27),
        Scenario(60, 30, 28),
        Scenario(60, 30, 29),
        Scenario(60, 30, 31),
        Scenario(60, 30, 32),
        Scenario(60, 30, 33)));

}  // namespace media
