/*
 *  Copyright (c) 2016 The WebRTC project authors. All Rights Reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

#include "modules/video_coding/rtp_vp9_ref_finder.h"

#include <utility>
#include <vector>

#include "modules/rtp_rtcp/source/frame_object.h"
#include "test/gmock.h"
#include "test/gtest.h"

using ::testing::Contains;
using ::testing::Matcher;
using ::testing::MatcherInterface;
using ::testing::Matches;
using ::testing::MatchResultListener;
using ::testing::Pointee;
using ::testing::Property;
using ::testing::SizeIs;
using ::testing::UnorderedElementsAreArray;

namespace webrtc {

namespace {
class Frame {
 public:
  Frame& SeqNum(uint16_t start, uint16_t end) {
    seq_num_start = start;
    seq_num_end = end;
    return *this;
  }

  Frame& AsKeyFrame(bool is_keyframe = true) {
    keyframe = is_keyframe;
    return *this;
  }

  Frame& Pid(int pid) {
    picture_id = pid;
    return *this;
  }

  Frame& SidAndTid(int sid, int tid) {
    spatial_id = sid;
    temporal_id = tid;
    return *this;
  }

  Frame& Tl0(int tl0) {
    tl0_idx = tl0;
    return *this;
  }

  Frame& AsUpswitch(bool is_up = true) {
    up_switch = is_up;
    return *this;
  }

  Frame& AsInterLayer(bool is_inter_layer = true) {
    inter_layer = is_inter_layer;
    return *this;
  }

  Frame& NotAsInterPic(bool is_inter_pic = false) {
    inter_pic = is_inter_pic;
    return *this;
  }

  Frame& Gof(GofInfoVP9* ss) {
    scalability_structure = ss;
    return *this;
  }

  Frame& FlexRefs(const std::vector<uint8_t>& refs) {
    flex_refs = refs;
    return *this;
  }

  operator std::unique_ptr<RtpFrameObject>() {
    RTPVideoHeaderVP9 vp9_header{};
    vp9_header.picture_id = *picture_id;
    vp9_header.temporal_idx = *temporal_id;
    vp9_header.spatial_idx = *spatial_id;
    if (tl0_idx.has_value()) {
      RTC_DCHECK(flex_refs.empty());
      vp9_header.flexible_mode = false;
      vp9_header.tl0_pic_idx = *tl0_idx;
    } else {
      vp9_header.flexible_mode = true;
      vp9_header.num_ref_pics = flex_refs.size();
      for (size_t i = 0; i < flex_refs.size(); ++i) {
        vp9_header.pid_diff[i] = flex_refs.at(i);
      }
    }
    vp9_header.temporal_up_switch = up_switch;
    vp9_header.inter_layer_predicted = inter_layer;
    vp9_header.inter_pic_predicted = inter_pic && !keyframe;
    if (scalability_structure != nullptr) {
      vp9_header.ss_data_available = true;
      vp9_header.gof = *scalability_structure;
    }

    RTPVideoHeader video_header;
    video_header.frame_type = keyframe ? VideoFrameType::kVideoFrameKey
                                       : VideoFrameType::kVideoFrameDelta;
    video_header.video_type_header = vp9_header;
    // clang-format off
    return std::make_unique<RtpFrameObject>(
        seq_num_start,
        seq_num_end,
        /*markerBit=*/true,
        /*times_nacked=*/0,
        /*first_packet_received_time=*/0,
        /*last_packet_received_time=*/0,
        /*rtp_timestamp=*/0,
        /*ntp_time_ms=*/0,
        VideoSendTiming(),
        /*payload_type=*/0,
        kVideoCodecVP9,
        kVideoRotation_0,
        VideoContentType::UNSPECIFIED,
        video_header,
        /*color_space=*/absl::nullopt,
        RtpPacketInfos(),
        EncodedImageBuffer::Create(/*size=*/0));
    // clang-format on
  }

 private:
  uint16_t seq_num_start = 0;
  uint16_t seq_num_end = 0;
  bool keyframe = false;
  absl::optional<int> picture_id;
  absl::optional<int> spatial_id;
  absl::optional<int> temporal_id;
  absl::optional<int> tl0_idx;
  bool up_switch = false;
  bool inter_layer = false;
  bool inter_pic = true;
  GofInfoVP9* scalability_structure = nullptr;
  std::vector<uint8_t> flex_refs;
};

using FrameVector = std::vector<std::unique_ptr<EncodedFrame>>;

// Would have been nice to use the MATCHER_P3 macro instead, but when used it
// fails to infer the type of the vector if not explicitly given in the
class HasFrameMatcher : public MatcherInterface<const FrameVector&> {
 public:
  explicit HasFrameMatcher(int64_t frame_id,
                           const std::vector<int64_t>& expected_refs)
      : frame_id_(frame_id),
        expected_refs_(expected_refs) {}

  bool MatchAndExplain(const FrameVector& frames,
                       MatchResultListener* result_listener) const override {
    auto it = std::find_if(frames.begin(), frames.end(),
                           [this](const std::unique_ptr<EncodedFrame>& f) {
                             return f->Id() == frame_id_;
                           });
    if (it == frames.end()) {
      if (result_listener->IsInterested()) {
        *result_listener << "No frame with frame_id:" << frame_id_;
      }
      return false;
    }

    rtc::ArrayView<int64_t> actual_refs((*it)->references,
                                        (*it)->num_references);
    if (!Matches(UnorderedElementsAreArray(expected_refs_))(actual_refs)) {
      if (result_listener->IsInterested()) {
        *result_listener << "Frame with frame_id:" << frame_id_ << " and "
                         << actual_refs.size() << " references { ";
        for (auto r : actual_refs) {
          *result_listener << r << " ";
        }
        *result_listener << "}";
      }
      return false;
    }

    return true;
  }

  void DescribeTo(std::ostream* os) const override {
    *os << "frame with frame_id:" << frame_id_ << " and "
        << expected_refs_.size() << " references { ";
    for (auto r : expected_refs_) {
      *os << r << " ";
    }
    *os << "}";
  }

 private:
  const int64_t frame_id_;
  const std::vector<int64_t> expected_refs_;
};

}  // namespace

class RtpVp9RefFinderTest : public ::testing::Test {
 protected:
  RtpVp9RefFinderTest() : ref_finder_(std::make_unique<RtpVp9RefFinder>()) {}

  void Insert(std::unique_ptr<RtpFrameObject> frame) {
    for (auto& f : ref_finder_->ManageFrame(std::move(frame))) {
      frames_.push_back(std::move(f));
    }
  }

  std::unique_ptr<RtpVp9RefFinder> ref_finder_;
  FrameVector frames_;
};

Matcher<const FrameVector&> HasFrameWithIdAndRefs(int64_t frame_id,
                                                  std::vector<int64_t> refs) {
  return MakeMatcher(new HasFrameMatcher(frame_id, refs));
}

TEST_F(RtpVp9RefFinderTest, GofInsertOneFrame) {
  GofInfoVP9 ss;
  ss.SetGofInfoVP9(kTemporalStructureMode1);

  Insert(Frame().Pid(1).SidAndTid(0, 0).Tl0(0).AsKeyFrame().Gof(&ss));

  EXPECT_EQ(frames_.size(), 1UL);
  EXPECT_THAT(frames_, HasFrameWithIdAndRefs(5, {}));
}

TEST_F(RtpVp9RefFinderTest, GofTemporalLayers_0) {
  GofInfoVP9 ss;
  ss.SetGofInfoVP9(kTemporalStructureMode1);  // Only 1 spatial layer.

  Insert(Frame().Pid(1).SidAndTid(0, 0).Tl0(0).AsKeyFrame().Gof(&ss));
  Insert(Frame().Pid(2).SidAndTid(0, 0).Tl0(1));

  EXPECT_EQ(frames_.size(), 2UL);
  EXPECT_THAT(frames_, HasFrameWithIdAndRefs(5, {}));
  EXPECT_THAT(frames_, HasFrameWithIdAndRefs(10, {5}));
}

TEST_F(RtpVp9RefFinderTest, GofSpatialLayers_2) {
  GofInfoVP9 ss;
  ss.SetGofInfoVP9(kTemporalStructureMode1);  // Only 1 spatial layer.

  Insert(Frame().Pid(1).SidAndTid(0, 0).Tl0(0).AsKeyFrame().Gof(&ss));
  Insert(Frame().Pid(2).SidAndTid(0, 0).Tl0(1));
  Insert(Frame().Pid(2).SidAndTid(1, 0).Tl0(1).NotAsInterPic());
  Insert(Frame().Pid(3).SidAndTid(0, 0).Tl0(2));
  Insert(Frame().Pid(3).SidAndTid(1, 0).Tl0(2));

  EXPECT_EQ(frames_.size(), 5UL);
  EXPECT_THAT(frames_, HasFrameWithIdAndRefs(5, {}));
  EXPECT_THAT(frames_, HasFrameWithIdAndRefs(10, {5}));
  EXPECT_THAT(frames_, HasFrameWithIdAndRefs(11, {}));
  EXPECT_THAT(frames_, HasFrameWithIdAndRefs(15, {10}));
  EXPECT_THAT(frames_, HasFrameWithIdAndRefs(16, {11}));
}

TEST_F(RtpVp9RefFinderTest, GofTemporalLayersReordered_0) {
  GofInfoVP9 ss;
  ss.SetGofInfoVP9(kTemporalStructureMode1);  // Only 1 spatial layer.

  Insert(Frame().Pid(2).SidAndTid(0, 0).Tl0(1));
  Insert(Frame().Pid(2).SidAndTid(1, 0).Tl0(1).NotAsInterPic());
  Insert(Frame().Pid(1).SidAndTid(0, 0).Tl0(0).AsKeyFrame().Gof(&ss));
  Insert(Frame().Pid(3).SidAndTid(0, 0).Tl0(2));
  Insert(Frame().Pid(3).SidAndTid(1, 0).Tl0(2));
  Insert(Frame().Pid(4).SidAndTid(0, 0).Tl0(3));
  Insert(Frame().Pid(5).SidAndTid(1, 0).Tl0(4));
  Insert(Frame().Pid(4).SidAndTid(1, 0).Tl0(3));
  Insert(Frame().Pid(5).SidAndTid(0, 0).Tl0(4));

  EXPECT_EQ(frames_.size(), 9UL);
  EXPECT_THAT(frames_, HasFrameWithIdAndRefs(5, {}));
  EXPECT_THAT(frames_, HasFrameWithIdAndRefs(10, {5}));
  EXPECT_THAT(frames_, HasFrameWithIdAndRefs(11, {}));
  EXPECT_THAT(frames_, HasFrameWithIdAndRefs(15, {10}));
  EXPECT_THAT(frames_, HasFrameWithIdAndRefs(16, {11}));
  EXPECT_THAT(frames_, HasFrameWithIdAndRefs(20, {15}));
  EXPECT_THAT(frames_, HasFrameWithIdAndRefs(21, {16}));
  EXPECT_THAT(frames_, HasFrameWithIdAndRefs(25, {20}));
  EXPECT_THAT(frames_, HasFrameWithIdAndRefs(26, {21}));
}

TEST_F(RtpVp9RefFinderTest, GofSkipFramesTemporalLayers_01) {
  GofInfoVP9 ss;
  ss.SetGofInfoVP9(kTemporalStructureMode2);  // 0101 pattern

  Insert(Frame().Pid(0).SidAndTid(0, 0).Tl0(0).AsKeyFrame().NotAsInterPic().Gof(
      &ss));
  Insert(Frame().Pid(1).SidAndTid(0, 1).Tl0(0));
  // Skip GOF with tl0 1
  Insert(Frame().Pid(4).SidAndTid(0, 0).Tl0(2).AsKeyFrame().Gof(&ss));
  Insert(Frame().Pid(5).SidAndTid(0, 1).Tl0(2));
  // Skip GOF with tl0 3
  // Skip GOF with tl0 4
  Insert(Frame().Pid(10).SidAndTid(0, 0).Tl0(5).Gof(&ss));
  Insert(Frame().Pid(11).SidAndTid(0, 1).Tl0(5));

  ASSERT_EQ(6UL, frames_.size());
  EXPECT_THAT(frames_, HasFrameWithIdAndRefs(0, {}));
  EXPECT_THAT(frames_, HasFrameWithIdAndRefs(5, {0}));
  EXPECT_THAT(frames_, HasFrameWithIdAndRefs(20, {}));
  EXPECT_THAT(frames_, HasFrameWithIdAndRefs(25, {20}));
  EXPECT_THAT(frames_, HasFrameWithIdAndRefs(50, {40}));
  EXPECT_THAT(frames_, HasFrameWithIdAndRefs(55, {50}));
}

TEST_F(RtpVp9RefFinderTest, GofSkipFramesTemporalLayers_0212) {
  GofInfoVP9 ss;
  ss.SetGofInfoVP9(kTemporalStructureMode3);  // 02120212 pattern

  Insert(Frame().Pid(0).SidAndTid(0, 0).Tl0(0).AsKeyFrame().NotAsInterPic().Gof(
      &ss));
  Insert(Frame().Pid(1).SidAndTid(0, 2).Tl0(0));
  Insert(Frame().Pid(2).SidAndTid(0, 1).Tl0(0));
  Insert(Frame().Pid(3).SidAndTid(0, 2).Tl0(0));

  ASSERT_EQ(4UL, frames_.size());
  EXPECT_THAT(frames_, HasFrameWithIdAndRefs(0, {}));
  EXPECT_THAT(frames_, HasFrameWithIdAndRefs(5, {0}));
  EXPECT_THAT(frames_, HasFrameWithIdAndRefs(10, {0}));
  EXPECT_THAT(frames_, HasFrameWithIdAndRefs(15, {10}));

  // Skip frames with tl0 = 1

  Insert(Frame().Pid(8).SidAndTid(0, 0).Tl0(2).AsKeyFrame().NotAsInterPic().Gof(
      &ss));
  Insert(Frame().Pid(9).SidAndTid(0, 2).Tl0(2));
  Insert(Frame().Pid(10).SidAndTid(0, 1).Tl0(2));
  Insert(Frame().Pid(11).SidAndTid(0, 2).Tl0(2));

  ASSERT_EQ(8UL, frames_.size());
  EXPECT_THAT(frames_, HasFrameWithIdAndRefs(40, {}));
  EXPECT_THAT(frames_, HasFrameWithIdAndRefs(45, {40}));
  EXPECT_THAT(frames_, HasFrameWithIdAndRefs(50, {40}));
  EXPECT_THAT(frames_, HasFrameWithIdAndRefs(55, {50}));

  // Now insert frames with tl0 = 1
  Insert(Frame().Pid(4).SidAndTid(0, 0).Tl0(1).AsKeyFrame().Gof(&ss));
  Insert(Frame().Pid(7).SidAndTid(0, 2).Tl0(1));

  ASSERT_EQ(9UL, frames_.size());
  EXPECT_THAT(frames_, HasFrameWithIdAndRefs(20, {}));

  Insert(Frame().Pid(5).SidAndTid(0, 2).Tl0(1));
  Insert(Frame().Pid(6).SidAndTid(0, 1).Tl0(1));

  ASSERT_EQ(12UL, frames_.size());
  EXPECT_THAT(frames_, HasFrameWithIdAndRefs(25, {20}));
  EXPECT_THAT(frames_, HasFrameWithIdAndRefs(30, {20}));
  EXPECT_THAT(frames_, HasFrameWithIdAndRefs(35, {30}));
}

TEST_F(RtpVp9RefFinderTest, GofTemporalLayers_01) {
  GofInfoVP9 ss;
  ss.SetGofInfoVP9(kTemporalStructureMode2);  // 0101 pattern

  Insert(Frame().Pid(0).SidAndTid(0, 0).Tl0(0).AsKeyFrame().NotAsInterPic().Gof(
      &ss));
  Insert(Frame().Pid(1).SidAndTid(0, 1).Tl0(0));
  Insert(Frame().Pid(2).SidAndTid(0, 0).Tl0(1));
  Insert(Frame().Pid(3).SidAndTid(0, 1).Tl0(1));

  ASSERT_EQ(4UL, frames_.size());
  EXPECT_THAT(frames_, HasFrameWithIdAndRefs(0, {}));
  EXPECT_THAT(frames_, HasFrameWithIdAndRefs(5, {0}));
  EXPECT_THAT(frames_, HasFrameWithIdAndRefs(10, {0}));
  EXPECT_THAT(frames_, HasFrameWithIdAndRefs(15, {10}));
}

TEST_F(RtpVp9RefFinderTest, GofTemporalLayersReordered_01) {
  GofInfoVP9 ss;
  ss.SetGofInfoVP9(kTemporalStructureMode2);  // 01 pattern

  Insert(Frame().Pid(1).SidAndTid(0, 1).Tl0(0));
  Insert(Frame().Pid(0).SidAndTid(0, 0).Tl0(0).AsKeyFrame().NotAsInterPic().Gof(
      &ss));
  Insert(Frame().Pid(2).SidAndTid(0, 0).Tl0(1));
  Insert(Frame().Pid(4).SidAndTid(0, 0).Tl0(2));
  Insert(Frame().Pid(3).SidAndTid(0, 1).Tl0(1));
  Insert(Frame().Pid(5).SidAndTid(0, 1).Tl0(2));
  Insert(Frame().Pid(7).SidAndTid(0, 1).Tl0(3));
  Insert(Frame().Pid(6).SidAndTid(0, 0).Tl0(3));
  Insert(Frame().Pid(8).SidAndTid(0, 0).Tl0(4));
  Insert(Frame().Pid(9).SidAndTid(0, 1).Tl0(4));

  ASSERT_EQ(10UL, frames_.size());
  EXPECT_THAT(frames_, HasFrameWithIdAndRefs(0, {}));
  EXPECT_THAT(frames_, HasFrameWithIdAndRefs(5, {0}));
  EXPECT_THAT(frames_, HasFrameWithIdAndRefs(10, {0}));
  EXPECT_THAT(frames_, HasFrameWithIdAndRefs(15, {10}));
  EXPECT_THAT(frames_, HasFrameWithIdAndRefs(20, {10}));
  EXPECT_THAT(frames_, HasFrameWithIdAndRefs(25, {20}));
  EXPECT_THAT(frames_, HasFrameWithIdAndRefs(30, {20}));
  EXPECT_THAT(frames_, HasFrameWithIdAndRefs(35, {30}));
  EXPECT_THAT(frames_, HasFrameWithIdAndRefs(40, {30}));
  EXPECT_THAT(frames_, HasFrameWithIdAndRefs(45, {40}));
}

TEST_F(RtpVp9RefFinderTest, GofTemporalLayers_0212) {
  GofInfoVP9 ss;
  ss.SetGofInfoVP9(kTemporalStructureMode3);  // 0212 pattern

  Insert(Frame().Pid(0).SidAndTid(0, 0).Tl0(0).AsKeyFrame().NotAsInterPic().Gof(
      &ss));
  Insert(Frame().Pid(1).SidAndTid(0, 2).Tl0(0));
  Insert(Frame().Pid(2).SidAndTid(0, 1).Tl0(0));
  Insert(Frame().Pid(3).SidAndTid(0, 2).Tl0(0));
  Insert(Frame().Pid(4).SidAndTid(0, 0).Tl0(1));
  Insert(Frame().Pid(5).SidAndTid(0, 2).Tl0(1));
  Insert(Frame().Pid(6).SidAndTid(0, 1).Tl0(1));
  Insert(Frame().Pid(7).SidAndTid(0, 2).Tl0(1));

  ASSERT_EQ(8UL, frames_.size());
  EXPECT_THAT(frames_, HasFrameWithIdAndRefs(0, {}));
  EXPECT_THAT(frames_, HasFrameWithIdAndRefs(5, {0}));
  EXPECT_THAT(frames_, HasFrameWithIdAndRefs(10, {0}));
  EXPECT_THAT(frames_, HasFrameWithIdAndRefs(15, {10}));
  EXPECT_THAT(frames_, HasFrameWithIdAndRefs(20, {0}));
  EXPECT_THAT(frames_, HasFrameWithIdAndRefs(25, {20}));
  EXPECT_THAT(frames_, HasFrameWithIdAndRefs(30, {20}));
  EXPECT_THAT(frames_, HasFrameWithIdAndRefs(35, {30}));
}

TEST_F(RtpVp9RefFinderTest, GofTemporalLayersReordered_0212) {
  GofInfoVP9 ss;
  ss.SetGofInfoVP9(kTemporalStructureMode3);  // 0212 pattern

  Insert(Frame().Pid(2).SidAndTid(0, 1).Tl0(0));
  Insert(Frame().Pid(1).SidAndTid(0, 2).Tl0(0));
  Insert(Frame().Pid(0).SidAndTid(0, 0).Tl0(0).AsKeyFrame().NotAsInterPic().Gof(
      &ss));
  Insert(Frame().Pid(3).SidAndTid(0, 2).Tl0(0));
  Insert(Frame().Pid(6).SidAndTid(0, 1).Tl0(1));
  Insert(Frame().Pid(5).SidAndTid(0, 2).Tl0(1));
  Insert(Frame().Pid(4).SidAndTid(0, 0).Tl0(1));
  Insert(Frame().Pid(9).SidAndTid(0, 2).Tl0(2));
  Insert(Frame().Pid(7).SidAndTid(0, 2).Tl0(1));
  Insert(Frame().Pid(8).SidAndTid(0, 0).Tl0(2));
  Insert(Frame().Pid(11).SidAndTid(0, 2).Tl0(2));
  Insert(Frame().Pid(10).SidAndTid(0, 1).Tl0(2));

  ASSERT_EQ(12UL, frames_.size());
  EXPECT_THAT(frames_, HasFrameWithIdAndRefs(0, {}));
  EXPECT_THAT(frames_, HasFrameWithIdAndRefs(5, {0}));
  EXPECT_THAT(frames_, HasFrameWithIdAndRefs(10, {0}));
  EXPECT_THAT(frames_, HasFrameWithIdAndRefs(15, {10}));
  EXPECT_THAT(frames_, HasFrameWithIdAndRefs(20, {0}));
  EXPECT_THAT(frames_, HasFrameWithIdAndRefs(25, {20}));
  EXPECT_THAT(frames_, HasFrameWithIdAndRefs(30, {20}));
  EXPECT_THAT(frames_, HasFrameWithIdAndRefs(35, {30}));
  EXPECT_THAT(frames_, HasFrameWithIdAndRefs(40, {20}));
  EXPECT_THAT(frames_, HasFrameWithIdAndRefs(45, {40}));
  EXPECT_THAT(frames_, HasFrameWithIdAndRefs(50, {40}));
  EXPECT_THAT(frames_, HasFrameWithIdAndRefs(55, {50}));
}

TEST_F(RtpVp9RefFinderTest, GofTemporalLayersReordered_01_0212) {
  GofInfoVP9 ss;
  ss.SetGofInfoVP9(kTemporalStructureMode2);  // 01 pattern

  Insert(Frame().Pid(1).SidAndTid(0, 1).Tl0(0));
  Insert(Frame().Pid(0).SidAndTid(0, 0).Tl0(0).AsKeyFrame().NotAsInterPic().Gof(
      &ss));
  Insert(Frame().Pid(3).SidAndTid(0, 1).Tl0(1));
  Insert(Frame().Pid(6).SidAndTid(0, 1).Tl0(2));
  ss.SetGofInfoVP9(kTemporalStructureMode3);  // 0212 pattern
  Insert(Frame().Pid(4).SidAndTid(0, 0).Tl0(2).Gof(&ss));
  Insert(Frame().Pid(2).SidAndTid(0, 0).Tl0(1));
  Insert(Frame().Pid(5).SidAndTid(0, 2).Tl0(2));
  Insert(Frame().Pid(8).SidAndTid(0, 0).Tl0(3));
  Insert(Frame().Pid(10).SidAndTid(0, 1).Tl0(3));
  Insert(Frame().Pid(7).SidAndTid(0, 2).Tl0(2));
  Insert(Frame().Pid(11).SidAndTid(0, 2).Tl0(3));
  Insert(Frame().Pid(9).SidAndTid(0, 2).Tl0(3));

  ASSERT_EQ(12UL, frames_.size());
  EXPECT_THAT(frames_, HasFrameWithIdAndRefs(0, {}));
  EXPECT_THAT(frames_, HasFrameWithIdAndRefs(5, {0}));
  EXPECT_THAT(frames_, HasFrameWithIdAndRefs(10, {0}));
  EXPECT_THAT(frames_, HasFrameWithIdAndRefs(15, {10}));
  EXPECT_THAT(frames_, HasFrameWithIdAndRefs(20, {0}));
  EXPECT_THAT(frames_, HasFrameWithIdAndRefs(25, {20}));
  EXPECT_THAT(frames_, HasFrameWithIdAndRefs(30, {20}));
  EXPECT_THAT(frames_, HasFrameWithIdAndRefs(35, {30}));
  EXPECT_THAT(frames_, HasFrameWithIdAndRefs(40, {20}));
  EXPECT_THAT(frames_, HasFrameWithIdAndRefs(45, {40}));
  EXPECT_THAT(frames_, HasFrameWithIdAndRefs(50, {40}));
  EXPECT_THAT(frames_, HasFrameWithIdAndRefs(55, {50}));
}

TEST_F(RtpVp9RefFinderTest, FlexibleModeOneFrame) {
  Insert(Frame().Pid(0).SidAndTid(0, 0).AsKeyFrame());

  ASSERT_EQ(1UL, frames_.size());
  EXPECT_THAT(frames_, HasFrameWithIdAndRefs(0, {}));
}

TEST_F(RtpVp9RefFinderTest, FlexibleModeTwoSpatialLayers) {
  Insert(Frame().Pid(0).SidAndTid(0, 0).AsKeyFrame());
  Insert(Frame().Pid(0).SidAndTid(1, 0).AsKeyFrame().AsInterLayer());
  Insert(Frame().Pid(1).SidAndTid(1, 0).FlexRefs({1}));
  Insert(Frame().Pid(2).SidAndTid(0, 0).FlexRefs({2}));
  Insert(Frame().Pid(2).SidAndTid(1, 0).FlexRefs({1}));
  Insert(Frame().Pid(3).SidAndTid(1, 0).FlexRefs({1}));
  Insert(Frame().Pid(4).SidAndTid(0, 0).FlexRefs({2}));
  Insert(Frame().Pid(4).SidAndTid(1, 0).FlexRefs({1}));

  ASSERT_EQ(8UL, frames_.size());
  EXPECT_THAT(frames_, HasFrameWithIdAndRefs(0, {}));
  EXPECT_THAT(frames_, HasFrameWithIdAndRefs(1, {0}));
  EXPECT_THAT(frames_, HasFrameWithIdAndRefs(6, {1}));
  EXPECT_THAT(frames_, HasFrameWithIdAndRefs(10, {0}));
  EXPECT_THAT(frames_, HasFrameWithIdAndRefs(11, {6}));
  EXPECT_THAT(frames_, HasFrameWithIdAndRefs(16, {11}));
  EXPECT_THAT(frames_, HasFrameWithIdAndRefs(20, {10}));
  EXPECT_THAT(frames_, HasFrameWithIdAndRefs(21, {16}));
}

TEST_F(RtpVp9RefFinderTest, FlexibleModeTwoSpatialLayersReordered) {
  Insert(Frame().Pid(0).SidAndTid(1, 0).AsKeyFrame().AsInterLayer());
  Insert(Frame().Pid(1).SidAndTid(1, 0).FlexRefs({1}));
  Insert(Frame().Pid(0).SidAndTid(0, 0).AsKeyFrame());
  Insert(Frame().Pid(2).SidAndTid(1, 0).FlexRefs({1}));
  Insert(Frame().Pid(3).SidAndTid(1, 0).FlexRefs({1}));
  Insert(Frame().Pid(2).SidAndTid(0, 0).FlexRefs({2}));
  Insert(Frame().Pid(4).SidAndTid(1, 0).FlexRefs({1}));
  Insert(Frame().Pid(4).SidAndTid(0, 0).FlexRefs({2}));

  ASSERT_EQ(8UL, frames_.size());
  EXPECT_THAT(frames_, HasFrameWithIdAndRefs(0, {}));
  EXPECT_THAT(frames_, HasFrameWithIdAndRefs(1, {0}));
  EXPECT_THAT(frames_, HasFrameWithIdAndRefs(6, {1}));
  EXPECT_THAT(frames_, HasFrameWithIdAndRefs(10, {0}));
  EXPECT_THAT(frames_, HasFrameWithIdAndRefs(11, {6}));
  EXPECT_THAT(frames_, HasFrameWithIdAndRefs(16, {11}));
  EXPECT_THAT(frames_, HasFrameWithIdAndRefs(20, {10}));
  EXPECT_THAT(frames_, HasFrameWithIdAndRefs(21, {16}));
}

TEST_F(RtpVp9RefFinderTest, WrappingFlexReference) {
  Insert(Frame().Pid(0).SidAndTid(0, 0).FlexRefs({1}));

  ASSERT_EQ(1UL, frames_.size());
  const EncodedFrame& frame = *frames_[0];

  ASSERT_EQ(frame.Id() - frame.references[0], 5);
}

TEST_F(RtpVp9RefFinderTest, GofPidJump) {
  GofInfoVP9 ss;
  ss.SetGofInfoVP9(kTemporalStructureMode3);

  Insert(Frame().Pid(0).SidAndTid(0, 0).Tl0(0).AsKeyFrame().NotAsInterPic().Gof(
      &ss));
  Insert(Frame().Pid(1000).SidAndTid(0, 0).Tl0(1));
}

TEST_F(RtpVp9RefFinderTest, GofTl0Jump) {
  GofInfoVP9 ss;
  ss.SetGofInfoVP9(kTemporalStructureMode3);

  Insert(Frame()
             .Pid(0)
             .SidAndTid(0, 0)
             .Tl0(125)
             .AsUpswitch()
             .AsKeyFrame()
             .NotAsInterPic()
             .Gof(&ss));
  Insert(Frame().Pid(1).SidAndTid(0, 0).Tl0(0).Gof(&ss));
}

TEST_F(RtpVp9RefFinderTest, GofTidTooHigh) {
  const int kMaxTemporalLayers = 5;
  GofInfoVP9 ss;
  ss.SetGofInfoVP9(kTemporalStructureMode2);
  ss.temporal_idx[1] = kMaxTemporalLayers;

  Insert(Frame().Pid(0).SidAndTid(0, 0).Tl0(0).AsKeyFrame().NotAsInterPic().Gof(
      &ss));
  Insert(Frame().Pid(1).SidAndTid(0, 0).Tl0(1));

  ASSERT_EQ(1UL, frames_.size());
  EXPECT_THAT(frames_, HasFrameWithIdAndRefs(0, {}));
}

TEST_F(RtpVp9RefFinderTest, GofZeroFrames) {
  GofInfoVP9 ss;
  ss.num_frames_in_gof = 0;

  Insert(Frame().Pid(0).SidAndTid(0, 0).Tl0(0).AsKeyFrame().NotAsInterPic().Gof(
      &ss));
  Insert(Frame().Pid(1).SidAndTid(0, 0).Tl0(1));

  ASSERT_EQ(2UL, frames_.size());
  EXPECT_THAT(frames_, HasFrameWithIdAndRefs(0, {}));
  EXPECT_THAT(frames_, HasFrameWithIdAndRefs(5, {0}));
}

TEST_F(RtpVp9RefFinderTest, SpatialIndex) {
  Insert(Frame().Pid(0).SidAndTid(0, 0).AsKeyFrame());
  Insert(Frame().Pid(0).SidAndTid(1, 0).AsKeyFrame());
  Insert(Frame().Pid(0).SidAndTid(2, 0).AsKeyFrame());

  ASSERT_EQ(3UL, frames_.size());
  EXPECT_THAT(frames_,
              Contains(Pointee(Property(&EncodedFrame::SpatialIndex, 0))));
  EXPECT_THAT(frames_,
              Contains(Pointee(Property(&EncodedFrame::SpatialIndex, 1))));
  EXPECT_THAT(frames_,
              Contains(Pointee(Property(&EncodedFrame::SpatialIndex, 2))));
}

TEST_F(RtpVp9RefFinderTest, StashedFramesDoNotWrapTl0Backwards) {
  GofInfoVP9 ss;
  ss.SetGofInfoVP9(kTemporalStructureMode1);

  Insert(Frame().Pid(0).SidAndTid(0, 0).Tl0(0));
  EXPECT_THAT(frames_, SizeIs(0));

  Insert(Frame().Pid(128).SidAndTid(0, 0).Tl0(128).AsKeyFrame().Gof(&ss));
  EXPECT_THAT(frames_, SizeIs(1));
  Insert(Frame().Pid(129).SidAndTid(0, 0).Tl0(129));
  EXPECT_THAT(frames_, SizeIs(2));
}

}  // namespace webrtc
