/*  Copyright (c) 2013 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/receiver.h"

#include <string.h>

#include <cstdint>
#include <memory>
#include <queue>
#include <vector>

#include "modules/video_coding/encoded_frame.h"
#include "modules/video_coding/jitter_buffer_common.h"
#include "modules/video_coding/packet.h"
#include "modules/video_coding/test/stream_generator.h"
#include "modules/video_coding/timing/timing.h"
#include "rtc_base/checks.h"
#include "system_wrappers/include/clock.h"
#include "test/gtest.h"
#include "test/scoped_key_value_config.h"

namespace webrtc {

class TestVCMReceiver : public ::testing::Test {
 protected:
  TestVCMReceiver()
      : clock_(0),
        timing_(&clock_, field_trials_),
        receiver_(&timing_, &clock_, field_trials_),
        stream_generator_(0, clock_.TimeInMilliseconds()) {}

  int32_t InsertPacket(int index) {
    VCMPacket packet;
    bool packet_available = stream_generator_.GetPacket(&packet, index);
    EXPECT_TRUE(packet_available);
    if (!packet_available)
      return kGeneralError;  // Return here to avoid crashes below.
    return receiver_.InsertPacket(packet);
  }

  int32_t InsertPacketAndPop(int index) {
    VCMPacket packet;
    bool packet_available = stream_generator_.PopPacket(&packet, index);
    EXPECT_TRUE(packet_available);
    if (!packet_available)
      return kGeneralError;  // Return here to avoid crashes below.
    return receiver_.InsertPacket(packet);
  }

  int32_t InsertFrame(VideoFrameType frame_type, bool complete) {
    int num_of_packets = complete ? 1 : 2;
    stream_generator_.GenerateFrame(
        frame_type,
        (frame_type != VideoFrameType::kEmptyFrame) ? num_of_packets : 0,
        (frame_type == VideoFrameType::kEmptyFrame) ? 1 : 0,
        clock_.TimeInMilliseconds());
    int32_t ret = InsertPacketAndPop(0);
    if (!complete) {
      // Drop the second packet.
      VCMPacket packet;
      stream_generator_.PopPacket(&packet, 0);
    }
    clock_.AdvanceTimeMilliseconds(kDefaultFramePeriodMs);
    return ret;
  }

  bool DecodeNextFrame() {
    VCMEncodedFrame* frame = receiver_.FrameForDecoding(0, false);
    if (!frame)
      return false;
    receiver_.ReleaseFrame(frame);
    return true;
  }

  test::ScopedKeyValueConfig field_trials_;
  SimulatedClock clock_;
  VCMTiming timing_;
  VCMReceiver receiver_;
  StreamGenerator stream_generator_;
};

TEST_F(TestVCMReceiver, NonDecodableDuration_Empty) {
  const size_t kMaxNackListSize = 1000;
  const int kMaxPacketAgeToNack = 1000;
  const int kMaxNonDecodableDuration = 500;
  const int kMinDelayMs = 500;
  receiver_.SetNackSettings(kMaxNackListSize, kMaxPacketAgeToNack,
                            kMaxNonDecodableDuration);
  EXPECT_GE(InsertFrame(VideoFrameType::kVideoFrameKey, true), kNoError);
  // Advance time until it's time to decode the key frame.
  clock_.AdvanceTimeMilliseconds(kMinDelayMs);
  EXPECT_TRUE(DecodeNextFrame());
  bool request_key_frame = false;
  std::vector<uint16_t> nack_list = receiver_.NackList(&request_key_frame);
  EXPECT_FALSE(request_key_frame);
}

TEST_F(TestVCMReceiver, NonDecodableDuration_NoKeyFrame) {
  const size_t kMaxNackListSize = 1000;
  const int kMaxPacketAgeToNack = 1000;
  const int kMaxNonDecodableDuration = 500;
  receiver_.SetNackSettings(kMaxNackListSize, kMaxPacketAgeToNack,
                            kMaxNonDecodableDuration);
  const int kNumFrames = kDefaultFrameRate * kMaxNonDecodableDuration / 1000;
  for (int i = 0; i < kNumFrames; ++i) {
    EXPECT_GE(InsertFrame(VideoFrameType::kVideoFrameDelta, true), kNoError);
  }
  bool request_key_frame = false;
  std::vector<uint16_t> nack_list = receiver_.NackList(&request_key_frame);
  EXPECT_TRUE(request_key_frame);
}

TEST_F(TestVCMReceiver, NonDecodableDuration_OneIncomplete) {
  const size_t kMaxNackListSize = 1000;
  const int kMaxPacketAgeToNack = 1000;
  const int kMaxNonDecodableDuration = 500;
  const int kMaxNonDecodableDurationFrames =
      (kDefaultFrameRate * kMaxNonDecodableDuration + 500) / 1000;
  const int kMinDelayMs = 500;
  receiver_.SetNackSettings(kMaxNackListSize, kMaxPacketAgeToNack,
                            kMaxNonDecodableDuration);
  timing_.set_min_playout_delay(TimeDelta::Millis(kMinDelayMs));
  int64_t key_frame_inserted = clock_.TimeInMilliseconds();
  EXPECT_GE(InsertFrame(VideoFrameType::kVideoFrameKey, true), kNoError);
  // Insert an incomplete frame.
  EXPECT_GE(InsertFrame(VideoFrameType::kVideoFrameDelta, false), kNoError);
  // Insert enough frames to have too long non-decodable sequence.
  for (int i = 0; i < kMaxNonDecodableDurationFrames; ++i) {
    EXPECT_GE(InsertFrame(VideoFrameType::kVideoFrameDelta, true), kNoError);
  }
  // Advance time until it's time to decode the key frame.
  clock_.AdvanceTimeMilliseconds(kMinDelayMs - clock_.TimeInMilliseconds() -
                                 key_frame_inserted);
  EXPECT_TRUE(DecodeNextFrame());
  // Make sure we get a key frame request.
  bool request_key_frame = false;
  std::vector<uint16_t> nack_list = receiver_.NackList(&request_key_frame);
  EXPECT_TRUE(request_key_frame);
}

TEST_F(TestVCMReceiver, NonDecodableDuration_NoTrigger) {
  const size_t kMaxNackListSize = 1000;
  const int kMaxPacketAgeToNack = 1000;
  const int kMaxNonDecodableDuration = 500;
  const int kMaxNonDecodableDurationFrames =
      (kDefaultFrameRate * kMaxNonDecodableDuration + 500) / 1000;
  const int kMinDelayMs = 500;
  receiver_.SetNackSettings(kMaxNackListSize, kMaxPacketAgeToNack,
                            kMaxNonDecodableDuration);
  timing_.set_min_playout_delay(TimeDelta::Millis(kMinDelayMs));
  int64_t key_frame_inserted = clock_.TimeInMilliseconds();
  EXPECT_GE(InsertFrame(VideoFrameType::kVideoFrameKey, true), kNoError);
  // Insert an incomplete frame.
  EXPECT_GE(InsertFrame(VideoFrameType::kVideoFrameDelta, false), kNoError);
  // Insert all but one frame to not trigger a key frame request due to
  // too long duration of non-decodable frames.
  for (int i = 0; i < kMaxNonDecodableDurationFrames - 1; ++i) {
    EXPECT_GE(InsertFrame(VideoFrameType::kVideoFrameDelta, true), kNoError);
  }
  // Advance time until it's time to decode the key frame.
  clock_.AdvanceTimeMilliseconds(kMinDelayMs - clock_.TimeInMilliseconds() -
                                 key_frame_inserted);
  EXPECT_TRUE(DecodeNextFrame());
  // Make sure we don't get a key frame request since we haven't generated
  // enough frames.
  bool request_key_frame = false;
  std::vector<uint16_t> nack_list = receiver_.NackList(&request_key_frame);
  EXPECT_FALSE(request_key_frame);
}

TEST_F(TestVCMReceiver, NonDecodableDuration_NoTrigger2) {
  const size_t kMaxNackListSize = 1000;
  const int kMaxPacketAgeToNack = 1000;
  const int kMaxNonDecodableDuration = 500;
  const int kMaxNonDecodableDurationFrames =
      (kDefaultFrameRate * kMaxNonDecodableDuration + 500) / 1000;
  const int kMinDelayMs = 500;
  receiver_.SetNackSettings(kMaxNackListSize, kMaxPacketAgeToNack,
                            kMaxNonDecodableDuration);
  timing_.set_min_playout_delay(TimeDelta::Millis(kMinDelayMs));
  int64_t key_frame_inserted = clock_.TimeInMilliseconds();
  EXPECT_GE(InsertFrame(VideoFrameType::kVideoFrameKey, true), kNoError);
  // Insert enough frames to have too long non-decodable sequence, except that
  // we don't have any losses.
  for (int i = 0; i < kMaxNonDecodableDurationFrames; ++i) {
    EXPECT_GE(InsertFrame(VideoFrameType::kVideoFrameDelta, true), kNoError);
  }
  // Insert an incomplete frame.
  EXPECT_GE(InsertFrame(VideoFrameType::kVideoFrameDelta, false), kNoError);
  // Advance time until it's time to decode the key frame.
  clock_.AdvanceTimeMilliseconds(kMinDelayMs - clock_.TimeInMilliseconds() -
                                 key_frame_inserted);
  EXPECT_TRUE(DecodeNextFrame());
  // Make sure we don't get a key frame request since the non-decodable duration
  // is only one frame.
  bool request_key_frame = false;
  std::vector<uint16_t> nack_list = receiver_.NackList(&request_key_frame);
  EXPECT_FALSE(request_key_frame);
}

TEST_F(TestVCMReceiver, NonDecodableDuration_KeyFrameAfterIncompleteFrames) {
  const size_t kMaxNackListSize = 1000;
  const int kMaxPacketAgeToNack = 1000;
  const int kMaxNonDecodableDuration = 500;
  const int kMaxNonDecodableDurationFrames =
      (kDefaultFrameRate * kMaxNonDecodableDuration + 500) / 1000;
  const int kMinDelayMs = 500;
  receiver_.SetNackSettings(kMaxNackListSize, kMaxPacketAgeToNack,
                            kMaxNonDecodableDuration);
  timing_.set_min_playout_delay(TimeDelta::Millis(kMinDelayMs));
  int64_t key_frame_inserted = clock_.TimeInMilliseconds();
  EXPECT_GE(InsertFrame(VideoFrameType::kVideoFrameKey, true), kNoError);
  // Insert an incomplete frame.
  EXPECT_GE(InsertFrame(VideoFrameType::kVideoFrameDelta, false), kNoError);
  // Insert enough frames to have too long non-decodable sequence.
  for (int i = 0; i < kMaxNonDecodableDurationFrames; ++i) {
    EXPECT_GE(InsertFrame(VideoFrameType::kVideoFrameDelta, true), kNoError);
  }
  EXPECT_GE(InsertFrame(VideoFrameType::kVideoFrameKey, true), kNoError);
  // Advance time until it's time to decode the key frame.
  clock_.AdvanceTimeMilliseconds(kMinDelayMs - clock_.TimeInMilliseconds() -
                                 key_frame_inserted);
  EXPECT_TRUE(DecodeNextFrame());
  // Make sure we don't get a key frame request since we have a key frame
  // in the list.
  bool request_key_frame = false;
  std::vector<uint16_t> nack_list = receiver_.NackList(&request_key_frame);
  EXPECT_FALSE(request_key_frame);
}

// A simulated clock, when time elapses, will insert frames into the jitter
// buffer, based on initial settings.
class SimulatedClockWithFrames : public SimulatedClock {
 public:
  SimulatedClockWithFrames(StreamGenerator* stream_generator,
                           VCMReceiver* receiver)
      : SimulatedClock(0),
        stream_generator_(stream_generator),
        receiver_(receiver) {}
  virtual ~SimulatedClockWithFrames() {}

  // If `stop_on_frame` is true and next frame arrives between now and
  // now+`milliseconds`, the clock will be advanced to the arrival time of next
  // frame.
  // Otherwise, the clock will be advanced by `milliseconds`.
  //
  // For both cases, a frame will be inserted into the jitter buffer at the
  // instant when the clock time is timestamps_.front().arrive_time.
  //
  // Return true if some frame arrives between now and now+`milliseconds`.
  bool AdvanceTimeMilliseconds(int64_t milliseconds, bool stop_on_frame) {
    return AdvanceTimeMicroseconds(milliseconds * 1000, stop_on_frame);
  }

  bool AdvanceTimeMicroseconds(int64_t microseconds, bool stop_on_frame) {
    int64_t start_time = TimeInMicroseconds();
    int64_t end_time = start_time + microseconds;
    bool frame_injected = false;
    while (!timestamps_.empty() &&
           timestamps_.front().arrive_time <= end_time) {
      RTC_DCHECK_GE(timestamps_.front().arrive_time, start_time);

      SimulatedClock::AdvanceTimeMicroseconds(timestamps_.front().arrive_time -
                                              TimeInMicroseconds());
      GenerateAndInsertFrame((timestamps_.front().render_time + 500) / 1000);
      timestamps_.pop();
      frame_injected = true;

      if (stop_on_frame)
        return frame_injected;
    }

    if (TimeInMicroseconds() < end_time) {
      SimulatedClock::AdvanceTimeMicroseconds(end_time - TimeInMicroseconds());
    }
    return frame_injected;
  }

  // Input timestamps are in unit Milliseconds.
  // And `arrive_timestamps` must be positive and in increasing order.
  // `arrive_timestamps` determine when we are going to insert frames into the
  // jitter buffer.
  // `render_timestamps` are the timestamps on the frame.
  void SetFrames(const int64_t* arrive_timestamps,
                 const int64_t* render_timestamps,
                 size_t size) {
    int64_t previous_arrive_timestamp = 0;
    for (size_t i = 0; i < size; i++) {
      RTC_CHECK_GE(arrive_timestamps[i], previous_arrive_timestamp);
      timestamps_.push(TimestampPair(arrive_timestamps[i] * 1000,
                                     render_timestamps[i] * 1000));
      previous_arrive_timestamp = arrive_timestamps[i];
    }
  }

 private:
  struct TimestampPair {
    TimestampPair(int64_t arrive_timestamp, int64_t render_timestamp)
        : arrive_time(arrive_timestamp), render_time(render_timestamp) {}

    int64_t arrive_time;
    int64_t render_time;
  };

  void GenerateAndInsertFrame(int64_t render_timestamp_ms) {
    VCMPacket packet;
    stream_generator_->GenerateFrame(VideoFrameType::kVideoFrameKey,
                                     1,  // media packets
                                     0,  // empty packets
                                     render_timestamp_ms);

    bool packet_available = stream_generator_->PopPacket(&packet, 0);
    EXPECT_TRUE(packet_available);
    if (!packet_available)
      return;  // Return here to avoid crashes below.
    receiver_->InsertPacket(packet);
  }

  std::queue<TimestampPair> timestamps_;
  StreamGenerator* stream_generator_;
  VCMReceiver* receiver_;
};

// Use a SimulatedClockWithFrames
// Wait call will do either of these:
// 1. If `stop_on_frame` is true, the clock will be turned to the exact instant
// that the first frame comes and the frame will be inserted into the jitter
// buffer, or the clock will be turned to now + `max_time` if no frame comes in
// the window.
// 2. If `stop_on_frame` is false, the clock will be turn to now + `max_time`,
// and all the frames arriving between now and now + `max_time` will be
// inserted into the jitter buffer.
//
// This is used to simulate the JitterBuffer getting packets from internet as
// time elapses.

class FrameInjectEvent : public EventWrapper {
 public:
  FrameInjectEvent(SimulatedClockWithFrames* clock, bool stop_on_frame)
      : clock_(clock), stop_on_frame_(stop_on_frame) {}

  bool Set() override { return true; }

  EventTypeWrapper Wait(int max_time_ms) override {
    if (clock_->AdvanceTimeMilliseconds(max_time_ms, stop_on_frame_) &&
        stop_on_frame_) {
      return EventTypeWrapper::kEventSignaled;
    } else {
      return EventTypeWrapper::kEventTimeout;
    }
  }

 private:
  SimulatedClockWithFrames* clock_;
  bool stop_on_frame_;
};

class VCMReceiverTimingTest : public ::testing::Test {
 protected:
  VCMReceiverTimingTest()
      : clock_(&stream_generator_, &receiver_),
        stream_generator_(0, clock_.TimeInMilliseconds()),
        timing_(&clock_, field_trials_),
        receiver_(
            &timing_,
            &clock_,
            std::unique_ptr<EventWrapper>(new FrameInjectEvent(&clock_, false)),
            std::unique_ptr<EventWrapper>(new FrameInjectEvent(&clock_, true)),
            field_trials_) {}

  virtual void SetUp() {}

  test::ScopedKeyValueConfig field_trials_;
  SimulatedClockWithFrames clock_;
  StreamGenerator stream_generator_;
  VCMTiming timing_;
  VCMReceiver receiver_;
};

// Test whether VCMReceiver::FrameForDecoding handles parameter
// `max_wait_time_ms` correctly:
// 1. The function execution should never take more than `max_wait_time_ms`.
// 2. If the function exit before now + `max_wait_time_ms`, a frame must be
//    returned.
TEST_F(VCMReceiverTimingTest, FrameForDecoding) {
  const size_t kNumFrames = 100;
  const int kFramePeriod = 40;
  int64_t arrive_timestamps[kNumFrames];
  int64_t render_timestamps[kNumFrames];

  // Construct test samples.
  // render_timestamps are the timestamps stored in the Frame;
  // arrive_timestamps controls when the Frame packet got received.
  for (size_t i = 0; i < kNumFrames; i++) {
    // Preset frame rate to 25Hz.
    // But we add a reasonable deviation to arrive_timestamps to mimic Internet
    // fluctuation.
    arrive_timestamps[i] =
        (i + 1) * kFramePeriod + (i % 10) * ((i % 2) ? 1 : -1);
    render_timestamps[i] = (i + 1) * kFramePeriod;
  }

  clock_.SetFrames(arrive_timestamps, render_timestamps, kNumFrames);

  // Record how many frames we finally get out of the receiver.
  size_t num_frames_return = 0;

  const int64_t kMaxWaitTime = 30;

  // Ideally, we should get all frames that we input in InitializeFrames.
  // In the case that FrameForDecoding kills frames by error, we rely on the
  // build bot to kill the test.
  while (num_frames_return < kNumFrames) {
    int64_t start_time = clock_.TimeInMilliseconds();
    VCMEncodedFrame* frame = receiver_.FrameForDecoding(kMaxWaitTime, false);
    int64_t end_time = clock_.TimeInMilliseconds();

    // In any case the FrameForDecoding should not wait longer than
    // max_wait_time.
    // In the case that we did not get a frame, it should have been waiting for
    // exactly max_wait_time. (By the testing samples we constructed above, we
    // are sure there is no timing error, so the only case it returns with NULL
    // is that it runs out of time.)
    if (frame) {
      receiver_.ReleaseFrame(frame);
      ++num_frames_return;
      EXPECT_GE(kMaxWaitTime, end_time - start_time);
    } else {
      EXPECT_EQ(kMaxWaitTime, end_time - start_time);
    }
  }
}

// Test whether VCMReceiver::FrameForDecoding handles parameter
// `prefer_late_decoding` and `max_wait_time_ms` correctly:
// 1. The function execution should never take more than `max_wait_time_ms`.
// 2. If the function exit before now + `max_wait_time_ms`, a frame must be
//    returned and the end time must be equal to the render timestamp - delay
//    for decoding and rendering.
TEST_F(VCMReceiverTimingTest, FrameForDecodingPreferLateDecoding) {
  const size_t kNumFrames = 100;
  const int kFramePeriod = 40;

  int64_t arrive_timestamps[kNumFrames];
  int64_t render_timestamps[kNumFrames];

  auto timings = timing_.GetTimings();
  TimeDelta render_delay = timings.render_delay;
  TimeDelta max_decode = timings.max_decode_duration;

  // Construct test samples.
  // render_timestamps are the timestamps stored in the Frame;
  // arrive_timestamps controls when the Frame packet got received.
  for (size_t i = 0; i < kNumFrames; i++) {
    // Preset frame rate to 25Hz.
    // But we add a reasonable deviation to arrive_timestamps to mimic Internet
    // fluctuation.
    arrive_timestamps[i] =
        (i + 1) * kFramePeriod + (i % 10) * ((i % 2) ? 1 : -1);
    render_timestamps[i] = (i + 1) * kFramePeriod;
  }

  clock_.SetFrames(arrive_timestamps, render_timestamps, kNumFrames);

  // Record how many frames we finally get out of the receiver.
  size_t num_frames_return = 0;
  const int64_t kMaxWaitTime = 30;
  bool prefer_late_decoding = true;
  while (num_frames_return < kNumFrames) {
    int64_t start_time = clock_.TimeInMilliseconds();

    VCMEncodedFrame* frame =
        receiver_.FrameForDecoding(kMaxWaitTime, prefer_late_decoding);
    int64_t end_time = clock_.TimeInMilliseconds();
    if (frame) {
      EXPECT_EQ(frame->RenderTimeMs() - max_decode.ms() - render_delay.ms(),
                end_time);
      receiver_.ReleaseFrame(frame);
      ++num_frames_return;
    } else {
      EXPECT_EQ(kMaxWaitTime, end_time - start_time);
    }
  }
}

}  // namespace webrtc
