/*  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 <string.h>

#include <list>

#include "testing/gtest/include/gtest/gtest.h"
#include "webrtc/modules/video_coding/main/source/packet.h"
#include "webrtc/modules/video_coding/main/source/receiver.h"
#include "webrtc/modules/video_coding/main/source/test/stream_generator.h"
#include "webrtc/modules/video_coding/main/source/timing.h"
#include "webrtc/modules/video_coding/main/test/test_util.h"
#include "webrtc/system_wrappers/interface/clock.h"
#include "webrtc/system_wrappers/interface/critical_section_wrapper.h"

namespace webrtc {

class TestVCMReceiver : public ::testing::Test {
 protected:
  enum { kDataBufferSize = 10 };
  enum { kWidth = 640 };
  enum { kHeight = 480 };

  TestVCMReceiver()
      : clock_(new SimulatedClock(0)),
        timing_(clock_.get()),
        receiver_(&timing_, clock_.get(), &event_factory_, true) {
    stream_generator_.reset(new
        StreamGenerator(0, 0, clock_->TimeInMilliseconds()));
    memset(data_buffer_, 0, kDataBufferSize);
  }

  virtual void SetUp() {
    receiver_.Reset();
  }

  int32_t InsertPacket(int index) {
    VCMPacket packet;
    packet.dataPtr = data_buffer_;
    bool packet_available = stream_generator_->GetPacket(&packet, index);
    EXPECT_TRUE(packet_available);
    if (!packet_available)
      return kGeneralError;  // Return here to avoid crashes below.
    // Arbitrary width and height.
    return receiver_.InsertPacket(packet, 640, 480);
  }

  int32_t InsertPacketAndPop(int index) {
    VCMPacket packet;
    packet.dataPtr = data_buffer_;
    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, kWidth, kHeight);
  }

  int32_t InsertFrame(FrameType frame_type, bool complete) {
    int num_of_packets = complete ? 1 : 2;
    stream_generator_->GenerateFrame(
        frame_type,
        (frame_type != kFrameEmpty) ? num_of_packets : 0,
        (frame_type == kFrameEmpty) ? 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() {
    int64_t render_time_ms = 0;
    VCMEncodedFrame* frame =
        receiver_.FrameForDecoding(0, render_time_ms, false);
    if (!frame)
      return false;
    receiver_.ReleaseFrame(frame);
    return true;
  }

  rtc::scoped_ptr<SimulatedClock> clock_;
  VCMTiming timing_;
  NullEventFactory event_factory_;
  VCMReceiver receiver_;
  rtc::scoped_ptr<StreamGenerator> stream_generator_;
  uint8_t data_buffer_[kDataBufferSize];
};

TEST_F(TestVCMReceiver, RenderBufferSize_AllComplete) {
  EXPECT_EQ(0, receiver_.RenderBufferSizeMs());
  EXPECT_GE(InsertFrame(kVideoFrameKey, true), kNoError);
  int num_of_frames = 10;
  for (int i = 0; i < num_of_frames; ++i) {
    EXPECT_GE(InsertFrame(kVideoFrameDelta, true), kNoError);
  }
  EXPECT_EQ(num_of_frames * kDefaultFramePeriodMs,
            receiver_.RenderBufferSizeMs());
}

TEST_F(TestVCMReceiver, RenderBufferSize_SkipToKeyFrame) {
  EXPECT_EQ(0, receiver_.RenderBufferSizeMs());
  const int kNumOfNonDecodableFrames = 2;
  for (int i = 0; i < kNumOfNonDecodableFrames; ++i) {
    EXPECT_GE(InsertFrame(kVideoFrameDelta, true), kNoError);
  }
  const int kNumOfFrames = 10;
  EXPECT_GE(InsertFrame(kVideoFrameKey, true), kNoError);
  for (int i = 0; i < kNumOfFrames - 1; ++i) {
    EXPECT_GE(InsertFrame(kVideoFrameDelta, true), kNoError);
  }
  EXPECT_EQ((kNumOfFrames - 1) * kDefaultFramePeriodMs,
      receiver_.RenderBufferSizeMs());
}

TEST_F(TestVCMReceiver, RenderBufferSize_NotAllComplete) {
  EXPECT_EQ(0, receiver_.RenderBufferSizeMs());
  EXPECT_GE(InsertFrame(kVideoFrameKey, true), kNoError);
  int num_of_frames = 10;
  for (int i = 0; i < num_of_frames; ++i) {
    EXPECT_GE(InsertFrame(kVideoFrameDelta, true), kNoError);
  }
  num_of_frames++;
  EXPECT_GE(InsertFrame(kVideoFrameDelta, false), kNoError);
  for (int i = 0; i < num_of_frames; ++i) {
    EXPECT_GE(InsertFrame(kVideoFrameDelta, true), kNoError);
  }
  EXPECT_EQ((num_of_frames - 1) * kDefaultFramePeriodMs,
      receiver_.RenderBufferSizeMs());
}

TEST_F(TestVCMReceiver, RenderBufferSize_NoKeyFrame) {
  EXPECT_EQ(0, receiver_.RenderBufferSizeMs());
  int num_of_frames = 10;
  for (int i = 0; i < num_of_frames; ++i) {
    EXPECT_GE(InsertFrame(kVideoFrameDelta, true), kNoError);
  }
  int64_t next_render_time_ms = 0;
  VCMEncodedFrame* frame = receiver_.FrameForDecoding(10, next_render_time_ms);
  EXPECT_TRUE(frame == NULL);
  receiver_.ReleaseFrame(frame);
  EXPECT_GE(InsertFrame(kVideoFrameDelta, false), kNoError);
  for (int i = 0; i < num_of_frames; ++i) {
    EXPECT_GE(InsertFrame(kVideoFrameDelta, true), kNoError);
  }
  EXPECT_EQ(0, receiver_.RenderBufferSizeMs());
}

TEST_F(TestVCMReceiver, NonDecodableDuration_Empty) {
  // Enable NACK and with no RTT thresholds for disabling retransmission delay.
  receiver_.SetNackMode(kNack, -1, -1);
  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(kVideoFrameKey, true), kNoError);
  // Advance time until it's time to decode the key frame.
  clock_->AdvanceTimeMilliseconds(kMinDelayMs);
  EXPECT_TRUE(DecodeNextFrame());
  uint16_t nack_list[kMaxNackListSize];
  uint16_t nack_list_length = 0;
  VCMNackStatus ret = receiver_.NackList(nack_list, kMaxNackListSize,
                                         &nack_list_length);
  EXPECT_EQ(kNackOk, ret);
}

TEST_F(TestVCMReceiver, NonDecodableDuration_NoKeyFrame) {
  // Enable NACK and with no RTT thresholds for disabling retransmission delay.
  receiver_.SetNackMode(kNack, -1, -1);
  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(kVideoFrameDelta, true), kNoError);
  }
  uint16_t nack_list[kMaxNackListSize];
  uint16_t nack_list_length = 0;
  VCMNackStatus ret = receiver_.NackList(nack_list, kMaxNackListSize,
                                         &nack_list_length);
  EXPECT_EQ(kNackKeyFrameRequest, ret);
}

TEST_F(TestVCMReceiver, NonDecodableDuration_OneIncomplete) {
  // Enable NACK and with no RTT thresholds for disabling retransmission delay.
  receiver_.SetNackMode(kNack, -1, -1);
  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);
  receiver_.SetMinReceiverDelay(kMinDelayMs);
  int64_t key_frame_inserted = clock_->TimeInMilliseconds();
  EXPECT_GE(InsertFrame(kVideoFrameKey, true), kNoError);
  // Insert an incomplete frame.
  EXPECT_GE(InsertFrame(kVideoFrameDelta, false), kNoError);
  // Insert enough frames to have too long non-decodable sequence.
  for (int i = 0; i < kMaxNonDecodableDurationFrames;
       ++i) {
    EXPECT_GE(InsertFrame(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.
  uint16_t nack_list[kMaxNackListSize];
  uint16_t nack_list_length = 0;
  VCMNackStatus ret = receiver_.NackList(nack_list, kMaxNackListSize,
                                         &nack_list_length);
  EXPECT_EQ(kNackKeyFrameRequest, ret);
}

TEST_F(TestVCMReceiver, NonDecodableDuration_NoTrigger) {
  // Enable NACK and with no RTT thresholds for disabling retransmission delay.
  receiver_.SetNackMode(kNack, -1, -1);
  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);
  receiver_.SetMinReceiverDelay(kMinDelayMs);
  int64_t key_frame_inserted = clock_->TimeInMilliseconds();
  EXPECT_GE(InsertFrame(kVideoFrameKey, true), kNoError);
  // Insert an incomplete frame.
  EXPECT_GE(InsertFrame(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(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.
  uint16_t nack_list[kMaxNackListSize];
  uint16_t nack_list_length = 0;
  VCMNackStatus ret = receiver_.NackList(nack_list, kMaxNackListSize,
                                         &nack_list_length);
  EXPECT_EQ(kNackOk, ret);
}

TEST_F(TestVCMReceiver, NonDecodableDuration_NoTrigger2) {
  // Enable NACK and with no RTT thresholds for disabling retransmission delay.
  receiver_.SetNackMode(kNack, -1, -1);
  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);
  receiver_.SetMinReceiverDelay(kMinDelayMs);
  int64_t key_frame_inserted = clock_->TimeInMilliseconds();
  EXPECT_GE(InsertFrame(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(kVideoFrameDelta, true), kNoError);
  }
  // Insert an incomplete frame.
  EXPECT_GE(InsertFrame(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.
  uint16_t nack_list[kMaxNackListSize];
  uint16_t nack_list_length = 0;
  VCMNackStatus ret = receiver_.NackList(nack_list, kMaxNackListSize,
                                         &nack_list_length);
  EXPECT_EQ(kNackOk, ret);
}

TEST_F(TestVCMReceiver, NonDecodableDuration_KeyFrameAfterIncompleteFrames) {
  // Enable NACK and with no RTT thresholds for disabling retransmission delay.
  receiver_.SetNackMode(kNack, -1, -1);
  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);
  receiver_.SetMinReceiverDelay(kMinDelayMs);
  int64_t key_frame_inserted = clock_->TimeInMilliseconds();
  EXPECT_GE(InsertFrame(kVideoFrameKey, true), kNoError);
  // Insert an incomplete frame.
  EXPECT_GE(InsertFrame(kVideoFrameDelta, false), kNoError);
  // Insert enough frames to have too long non-decodable sequence.
  for (int i = 0; i < kMaxNonDecodableDurationFrames;
       ++i) {
    EXPECT_GE(InsertFrame(kVideoFrameDelta, true), kNoError);
  }
  EXPECT_GE(InsertFrame(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.
  uint16_t nack_list[kMaxNackListSize];
  uint16_t nack_list_length = 0;
  VCMNackStatus ret = receiver_.NackList(nack_list, kMaxNackListSize,
                                         &nack_list_length);
  EXPECT_EQ(kNackOk, ret);
}
}  // namespace webrtc
