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

#include <algorithm>
#include <map>
#include <sstream>
#include <string>

#include "testing/gtest/include/gtest/gtest.h"

#include "webrtc/call.h"
#include "webrtc/frame_callback.h"
#include "webrtc/modules/rtp_rtcp/source/rtcp_utility.h"
#include "webrtc/modules/video_coding/codecs/vp8/include/vp8.h"
#include "webrtc/system_wrappers/interface/critical_section_wrapper.h"
#include "webrtc/system_wrappers/interface/event_wrapper.h"
#include "webrtc/system_wrappers/interface/scoped_ptr.h"
#include "webrtc/system_wrappers/interface/sleep.h"
#include "webrtc/test/direct_transport.h"
#include "webrtc/test/encoder_settings.h"
#include "webrtc/test/fake_audio_device.h"
#include "webrtc/test/fake_decoder.h"
#include "webrtc/test/fake_encoder.h"
#include "webrtc/test/frame_generator.h"
#include "webrtc/test/frame_generator_capturer.h"
#include "webrtc/test/null_transport.h"
#include "webrtc/test/rtp_rtcp_observer.h"
#include "webrtc/test/testsupport/fileutils.h"
#include "webrtc/test/testsupport/perf_test.h"
#include "webrtc/video/transport_adapter.h"

namespace webrtc {

static unsigned int kDefaultTimeoutMs = 30 * 1000;
static unsigned int kLongTimeoutMs = 120 * 1000;
static const uint32_t kSendSsrc = 0x654321;
static const uint32_t kSendRtxSsrc = 0x424242;
static const uint32_t kReceiverLocalSsrc = 0x123456;
static const uint8_t kSendPayloadType = 125;
static const uint8_t kSendRtxPayloadType = 126;
static const int kRedPayloadType = 118;
static const int kUlpfecPayloadType = 119;

class CallTest : public ::testing::Test {
 public:
  CallTest()
      : send_stream_(NULL),
        receive_stream_(NULL),
        fake_encoder_(Clock::GetRealTimeClock()) {}

  virtual ~CallTest() {
    EXPECT_EQ(NULL, send_stream_);
    EXPECT_EQ(NULL, receive_stream_);
  }

 protected:
  void CreateCalls(const Call::Config& sender_config,
                   const Call::Config& receiver_config) {
    sender_call_.reset(Call::Create(sender_config));
    receiver_call_.reset(Call::Create(receiver_config));
  }

  void CreateTestConfigs() {
    send_config_ = sender_call_->GetDefaultSendConfig();
    receive_config_ = receiver_call_->GetDefaultReceiveConfig();

    send_config_.rtp.ssrcs.push_back(kSendSsrc);
    send_config_.encoder_settings.encoder = &fake_encoder_;
    send_config_.encoder_settings.payload_name = "FAKE";
    send_config_.encoder_settings.payload_type = kSendPayloadType;
    video_streams_ = test::CreateVideoStreams(1);

    assert(receive_config_.codecs.empty());
    VideoCodec codec =
        test::CreateDecoderVideoCodec(send_config_.encoder_settings);
    receive_config_.codecs.push_back(codec);
    ExternalVideoDecoder decoder;
    decoder.decoder = &fake_decoder_;
    decoder.payload_type = send_config_.encoder_settings.payload_type;
    receive_config_.external_decoders.push_back(decoder);
    receive_config_.rtp.remote_ssrc = send_config_.rtp.ssrcs[0];
    receive_config_.rtp.local_ssrc = kReceiverLocalSsrc;
  }

  void CreateStreams() {
    assert(send_stream_ == NULL);
    assert(receive_stream_ == NULL);

    send_stream_ =
        sender_call_->CreateVideoSendStream(send_config_, video_streams_, NULL);
    receive_stream_ = receiver_call_->CreateVideoReceiveStream(receive_config_);
  }

  void CreateFrameGenerator() {
    frame_generator_capturer_.reset(
        test::FrameGeneratorCapturer::Create(send_stream_->Input(),
                                             video_streams_[0].width,
                                             video_streams_[0].height,
                                             30,
                                             Clock::GetRealTimeClock()));
  }

  void StartSending() {
    receive_stream_->Start();
    send_stream_->Start();
    if (frame_generator_capturer_.get() != NULL)
      frame_generator_capturer_->Start();
  }

  void StopSending() {
    if (frame_generator_capturer_.get() != NULL)
      frame_generator_capturer_->Stop();
    if (send_stream_ != NULL)
      send_stream_->Stop();
    if (receive_stream_ != NULL)
      receive_stream_->Stop();
  }

  void DestroyStreams() {
    if (send_stream_ != NULL)
      sender_call_->DestroyVideoSendStream(send_stream_);
    if (receive_stream_ != NULL)
      receiver_call_->DestroyVideoReceiveStream(receive_stream_);
    send_stream_ = NULL;
    receive_stream_ = NULL;
  }

  void DecodesRetransmittedFrame(bool retransmit_over_rtx);
  void ReceivesPliAndRecovers(int rtp_history_ms);
  void RespectsRtcpMode(newapi::RtcpMode rtcp_mode);
  void TestXrReceiverReferenceTimeReport(bool enable_rrtr);

  scoped_ptr<Call> sender_call_;
  scoped_ptr<Call> receiver_call_;

  VideoSendStream::Config send_config_;
  std::vector<VideoStream> video_streams_;
  VideoReceiveStream::Config receive_config_;

  VideoSendStream* send_stream_;
  VideoReceiveStream* receive_stream_;

  scoped_ptr<test::FrameGeneratorCapturer> frame_generator_capturer_;

  test::FakeEncoder fake_encoder_;
  test::FakeDecoder fake_decoder_;
};

class NackObserver : public test::RtpRtcpObserver {
  static const int kNumberOfNacksToObserve = 2;
  static const int kLossBurstSize = 2;
  static const int kPacketsBetweenLossBursts = 9;

 public:
  NackObserver()
      : test::RtpRtcpObserver(kLongTimeoutMs),
        rtp_parser_(RtpHeaderParser::Create()),
        sent_rtp_packets_(0),
        packets_left_to_drop_(0),
        nacks_left_(kNumberOfNacksToObserve) {}

 private:
  virtual Action OnSendRtp(const uint8_t* packet, size_t length) OVERRIDE {
    RTPHeader header;
    EXPECT_TRUE(rtp_parser_->Parse(packet, static_cast<int>(length), &header));

    // Never drop retransmitted packets.
    if (dropped_packets_.find(header.sequenceNumber) !=
        dropped_packets_.end()) {
      retransmitted_packets_.insert(header.sequenceNumber);
      if (nacks_left_ == 0 &&
          retransmitted_packets_.size() == dropped_packets_.size()) {
        observation_complete_->Set();
      }
      return SEND_PACKET;
    }

    ++sent_rtp_packets_;

    // Enough NACKs received, stop dropping packets.
    if (nacks_left_ == 0)
      return SEND_PACKET;

    // Check if it's time for a new loss burst.
    if (sent_rtp_packets_ % kPacketsBetweenLossBursts == 0)
      packets_left_to_drop_ = kLossBurstSize;

    if (packets_left_to_drop_ > 0) {
      --packets_left_to_drop_;
      dropped_packets_.insert(header.sequenceNumber);
      return DROP_PACKET;
    }

    return SEND_PACKET;
  }

  virtual Action OnReceiveRtcp(const uint8_t* packet, size_t length) OVERRIDE {
    RTCPUtility::RTCPParserV2 parser(packet, length, true);
    EXPECT_TRUE(parser.IsValid());

    RTCPUtility::RTCPPacketTypes packet_type = parser.Begin();
    while (packet_type != RTCPUtility::kRtcpNotValidCode) {
      if (packet_type == RTCPUtility::kRtcpRtpfbNackCode) {
        --nacks_left_;
        break;
      }
      packet_type = parser.Iterate();
    }
    return SEND_PACKET;
  }

 private:
  scoped_ptr<RtpHeaderParser> rtp_parser_;
  std::set<uint16_t> dropped_packets_;
  std::set<uint16_t> retransmitted_packets_;
  uint64_t sent_rtp_packets_;
  int packets_left_to_drop_;
  int nacks_left_;
};

TEST_F(CallTest, ReceiverCanBeStartedTwice) {
  test::NullTransport transport;
  CreateCalls(Call::Config(&transport), Call::Config(&transport));

  CreateTestConfigs();
  CreateStreams();

  receive_stream_->Start();
  receive_stream_->Start();

  DestroyStreams();
}

TEST_F(CallTest, ReceiverCanBeStoppedTwice) {
  test::NullTransport transport;
  CreateCalls(Call::Config(&transport), Call::Config(&transport));

  CreateTestConfigs();
  CreateStreams();

  receive_stream_->Stop();
  receive_stream_->Stop();

  DestroyStreams();
}

TEST_F(CallTest, RendersSingleDelayedFrame) {
  static const int kWidth = 320;
  static const int kHeight = 240;
  // This constant is chosen to be higher than the timeout in the video_render
  // module. This makes sure that frames aren't dropped if there are no other
  // frames in the queue.
  static const int kDelayRenderCallbackMs = 1000;

  class Renderer : public VideoRenderer {
   public:
    Renderer() : event_(EventWrapper::Create()) {}

    virtual void RenderFrame(const I420VideoFrame& video_frame,
                             int /*time_to_render_ms*/) OVERRIDE {
      event_->Set();
    }

    EventTypeWrapper Wait() { return event_->Wait(kDefaultTimeoutMs); }

    scoped_ptr<EventWrapper> event_;
  } renderer;

  class TestFrameCallback : public I420FrameCallback {
   public:
    TestFrameCallback() : event_(EventWrapper::Create()) {}

    EventTypeWrapper Wait() { return event_->Wait(kDefaultTimeoutMs); }

   private:
    virtual void FrameCallback(I420VideoFrame* frame) OVERRIDE {
      SleepMs(kDelayRenderCallbackMs);
      event_->Set();
    }

    scoped_ptr<EventWrapper> event_;
  };

  test::DirectTransport sender_transport, receiver_transport;

  CreateCalls(Call::Config(&sender_transport),
              Call::Config(&receiver_transport));

  sender_transport.SetReceiver(receiver_call_->Receiver());
  receiver_transport.SetReceiver(sender_call_->Receiver());

  CreateTestConfigs();

  TestFrameCallback pre_render_callback;
  receive_config_.pre_render_callback = &pre_render_callback;
  receive_config_.renderer = &renderer;

  CreateStreams();
  StartSending();

  // Create frames that are smaller than the send width/height, this is done to
  // check that the callbacks are done after processing video.
  scoped_ptr<test::FrameGenerator> frame_generator(
      test::FrameGenerator::Create(kWidth, kHeight));
  send_stream_->Input()->SwapFrame(frame_generator->NextFrame());
  EXPECT_EQ(kEventSignaled, pre_render_callback.Wait())
      << "Timed out while waiting for pre-render callback.";
  EXPECT_EQ(kEventSignaled, renderer.Wait())
      << "Timed out while waiting for the frame to render.";

  StopSending();

  sender_transport.StopSending();
  receiver_transport.StopSending();

  DestroyStreams();
}

TEST_F(CallTest, TransmitsFirstFrame) {
  class Renderer : public VideoRenderer {
   public:
    Renderer() : event_(EventWrapper::Create()) {}

    virtual void RenderFrame(const I420VideoFrame& video_frame,
                             int /*time_to_render_ms*/) OVERRIDE {
      event_->Set();
    }

    EventTypeWrapper Wait() { return event_->Wait(kDefaultTimeoutMs); }

    scoped_ptr<EventWrapper> event_;
  } renderer;

  test::DirectTransport sender_transport, receiver_transport;

  CreateCalls(Call::Config(&sender_transport),
              Call::Config(&receiver_transport));

  sender_transport.SetReceiver(receiver_call_->Receiver());
  receiver_transport.SetReceiver(sender_call_->Receiver());

  CreateTestConfigs();
  receive_config_.renderer = &renderer;

  CreateStreams();
  StartSending();

  scoped_ptr<test::FrameGenerator> frame_generator(test::FrameGenerator::Create(
      video_streams_[0].width, video_streams_[0].height));
  send_stream_->Input()->SwapFrame(frame_generator->NextFrame());

  EXPECT_EQ(kEventSignaled, renderer.Wait())
      << "Timed out while waiting for the frame to render.";

  StopSending();

  sender_transport.StopSending();
  receiver_transport.StopSending();

  DestroyStreams();
}

TEST_F(CallTest, ReceiverUsesLocalSsrc) {
  class SyncRtcpObserver : public test::RtpRtcpObserver {
   public:
    SyncRtcpObserver() : test::RtpRtcpObserver(kDefaultTimeoutMs) {}

    virtual Action OnReceiveRtcp(const uint8_t* packet,
                                 size_t length) OVERRIDE {
      RTCPUtility::RTCPParserV2 parser(packet, length, true);
      EXPECT_TRUE(parser.IsValid());
      uint32_t ssrc = 0;
      ssrc |= static_cast<uint32_t>(packet[4]) << 24;
      ssrc |= static_cast<uint32_t>(packet[5]) << 16;
      ssrc |= static_cast<uint32_t>(packet[6]) << 8;
      ssrc |= static_cast<uint32_t>(packet[7]) << 0;
      EXPECT_EQ(kReceiverLocalSsrc, ssrc);
      observation_complete_->Set();

      return SEND_PACKET;
    }
  } observer;

  CreateCalls(Call::Config(observer.SendTransport()),
              Call::Config(observer.ReceiveTransport()));

  observer.SetReceivers(receiver_call_->Receiver(), sender_call_->Receiver());

  CreateTestConfigs();

  CreateStreams();
  CreateFrameGenerator();
  StartSending();

  EXPECT_EQ(kEventSignaled, observer.Wait())
      << "Timed out while waiting for a receiver RTCP packet to be sent.";

  StopSending();

  observer.StopSending();

  DestroyStreams();
}

TEST_F(CallTest, ReceivesAndRetransmitsNack) {
  NackObserver observer;

  CreateCalls(Call::Config(observer.SendTransport()),
              Call::Config(observer.ReceiveTransport()));

  observer.SetReceivers(receiver_call_->Receiver(), sender_call_->Receiver());

  CreateTestConfigs();
  int rtp_history_ms = 1000;
  send_config_.rtp.nack.rtp_history_ms = rtp_history_ms;
  receive_config_.rtp.nack.rtp_history_ms = rtp_history_ms;

  CreateStreams();
  CreateFrameGenerator();
  StartSending();

  // Wait() waits for an event triggered when NACKs have been received, NACKed
  // packets retransmitted and frames rendered again.
  EXPECT_EQ(kEventSignaled, observer.Wait());

  StopSending();

  observer.StopSending();

  DestroyStreams();
}

// TODO(pbos): Flaky, webrtc:3269
TEST_F(CallTest, DISABLED_CanReceiveFec) {
  class FecRenderObserver : public test::RtpRtcpObserver, public VideoRenderer {
   public:
    FecRenderObserver()
        : RtpRtcpObserver(kDefaultTimeoutMs),
          state_(kFirstPacket),
          protected_sequence_number_(0),
          protected_frame_timestamp_(0) {}

   private:
    virtual Action OnSendRtp(const uint8_t* packet, size_t length) OVERRIDE
        EXCLUSIVE_LOCKS_REQUIRED(crit_) {
      RTPHeader header;
      EXPECT_TRUE(parser_->Parse(packet, static_cast<int>(length), &header));

      EXPECT_EQ(kRedPayloadType, header.payloadType);
      int encapsulated_payload_type =
          static_cast<int>(packet[header.headerLength]);
      if (encapsulated_payload_type != kSendPayloadType)
        EXPECT_EQ(kUlpfecPayloadType, encapsulated_payload_type);

      switch(state_) {
        case kFirstPacket:
          state_ = kDropEveryOtherPacketUntilFec;
          break;
        case kDropEveryOtherPacketUntilFec:
          if (encapsulated_payload_type == kUlpfecPayloadType) {
            state_ = kDropNextMediaPacket;
            return SEND_PACKET;
          }
          if (header.sequenceNumber % 2 == 0)
            return DROP_PACKET;
          break;
        case kDropNextMediaPacket:
          if (encapsulated_payload_type == kSendPayloadType) {
            protected_sequence_number_ = header.sequenceNumber;
            protected_frame_timestamp_ = header.timestamp;
            state_ = kProtectedPacketDropped;
            return DROP_PACKET;
          }
          break;
        case kProtectedPacketDropped:
          EXPECT_NE(header.sequenceNumber, protected_sequence_number_)
              << "Protected packet retransmitted. Should not happen with FEC.";
          break;
      }

      return SEND_PACKET;
    }

    virtual void RenderFrame(const I420VideoFrame& video_frame,
                             int time_to_render_ms) OVERRIDE {
      CriticalSectionScoped lock(crit_.get());
      // Rendering frame with timestamp associated with dropped packet -> FEC
      // protection worked.
      if (state_ == kProtectedPacketDropped &&
          video_frame.timestamp() == protected_frame_timestamp_) {
        observation_complete_->Set();
      }
    }

    enum {
      kFirstPacket,
      kDropEveryOtherPacketUntilFec,
      kDropNextMediaPacket,
      kProtectedPacketDropped,
    } state_;

    uint32_t protected_sequence_number_ GUARDED_BY(crit_);
    uint32_t protected_frame_timestamp_ GUARDED_BY(crit_);
  } observer;

  CreateCalls(Call::Config(observer.SendTransport()),
              Call::Config(observer.ReceiveTransport()));

  observer.SetReceivers(receiver_call_->Receiver(), sender_call_->Receiver());

  CreateTestConfigs();
  // TODO(pbos): Run this test with combined NACK/FEC enabled as well.
  // int rtp_history_ms = 1000;
  // receive_config_.rtp.nack.rtp_history_ms = rtp_history_ms;
  // send_config_.rtp.nack.rtp_history_ms = rtp_history_ms;
  send_config_.rtp.fec.red_payload_type = kRedPayloadType;
  send_config_.rtp.fec.ulpfec_payload_type = kUlpfecPayloadType;

  receive_config_.rtp.fec.red_payload_type = kRedPayloadType;
  receive_config_.rtp.fec.ulpfec_payload_type = kUlpfecPayloadType;
  receive_config_.renderer = &observer;

  CreateStreams();
  CreateFrameGenerator();
  StartSending();

  // Wait() waits for an event triggered when NACKs have been received, NACKed
  // packets retransmitted and frames rendered again.
  EXPECT_EQ(kEventSignaled, observer.Wait());

  StopSending();

  observer.StopSending();

  DestroyStreams();
}

// This test drops second RTP packet with a marker bit set, makes sure it's
// retransmitted and renders. Retransmission SSRCs are also checked.
void CallTest::DecodesRetransmittedFrame(bool retransmit_over_rtx) {
  static const int kDroppedFrameNumber = 2;
  class RetransmissionObserver : public test::RtpRtcpObserver,
                                 public I420FrameCallback {
   public:
    RetransmissionObserver(bool expect_rtx)
        : RtpRtcpObserver(kDefaultTimeoutMs),
          retransmission_ssrc_(expect_rtx ? kSendRtxSsrc : kSendSsrc),
          retransmission_payload_type_(expect_rtx ? kSendRtxPayloadType
                                                  : kSendPayloadType),
          marker_bits_observed_(0),
          retransmitted_timestamp_(0),
          frame_retransmitted_(false) {}

   private:
    virtual Action OnSendRtp(const uint8_t* packet, size_t length) OVERRIDE {
      RTPHeader header;
      EXPECT_TRUE(parser_->Parse(packet, static_cast<int>(length), &header));

      if (header.timestamp == retransmitted_timestamp_) {
        EXPECT_EQ(retransmission_ssrc_, header.ssrc);
        EXPECT_EQ(retransmission_payload_type_, header.payloadType);
        frame_retransmitted_ = true;
        return SEND_PACKET;
      }

      EXPECT_EQ(kSendSsrc, header.ssrc);
      EXPECT_EQ(kSendPayloadType, header.payloadType);

      // Found the second frame's final packet, drop this and expect a
      // retransmission.
      if (header.markerBit && ++marker_bits_observed_ == kDroppedFrameNumber) {
        retransmitted_timestamp_ = header.timestamp;
        return DROP_PACKET;
      }

      return SEND_PACKET;
    }

    virtual void FrameCallback(I420VideoFrame* frame) OVERRIDE {
      CriticalSectionScoped lock(crit_.get());
      if (frame->timestamp() == retransmitted_timestamp_) {
        EXPECT_TRUE(frame_retransmitted_);
        observation_complete_->Set();
      }
    }

    const uint32_t retransmission_ssrc_;
    const int retransmission_payload_type_;
    int marker_bits_observed_;
    uint32_t retransmitted_timestamp_;
    bool frame_retransmitted_;
  } observer(retransmit_over_rtx);

  CreateCalls(Call::Config(observer.SendTransport()),
              Call::Config(observer.ReceiveTransport()));

  observer.SetReceivers(receiver_call_->Receiver(), sender_call_->Receiver());

  CreateTestConfigs();
  send_config_.rtp.nack.rtp_history_ms =
      receive_config_.rtp.nack.rtp_history_ms = 1000;
  if (retransmit_over_rtx) {
    send_config_.rtp.rtx.ssrcs.push_back(kSendRtxSsrc);
    send_config_.rtp.rtx.payload_type = kSendRtxPayloadType;
    int payload_type = send_config_.encoder_settings.payload_type;
    receive_config_.rtp.rtx[payload_type].ssrc = kSendRtxSsrc;
    receive_config_.rtp.rtx[payload_type].payload_type = kSendRtxPayloadType;
  }
  receive_config_.pre_render_callback = &observer;

  CreateStreams();
  CreateFrameGenerator();
  StartSending();

  EXPECT_EQ(kEventSignaled, observer.Wait())
      << "Timed out while waiting for retransmission to render.";

  StopSending();
  observer.StopSending();
  DestroyStreams();
}

TEST_F(CallTest, DecodesRetransmittedFrame) {
  DecodesRetransmittedFrame(false);
}

TEST_F(CallTest, DecodesRetransmittedFrameOverRtx) {
  DecodesRetransmittedFrame(true);
}

TEST_F(CallTest, UsesFrameCallbacks) {
  static const int kWidth = 320;
  static const int kHeight = 240;

  class Renderer : public VideoRenderer {
   public:
    Renderer() : event_(EventWrapper::Create()) {}

    virtual void RenderFrame(const I420VideoFrame& video_frame,
                             int /*time_to_render_ms*/) OVERRIDE {
      EXPECT_EQ(0, *video_frame.buffer(kYPlane))
          << "Rendered frame should have zero luma which is applied by the "
             "pre-render callback.";
      event_->Set();
    }

    EventTypeWrapper Wait() { return event_->Wait(kDefaultTimeoutMs); }
    scoped_ptr<EventWrapper> event_;
  } renderer;

  class TestFrameCallback : public I420FrameCallback {
   public:
    TestFrameCallback(int expected_luma_byte, int next_luma_byte)
        : event_(EventWrapper::Create()),
          expected_luma_byte_(expected_luma_byte),
          next_luma_byte_(next_luma_byte) {}

    EventTypeWrapper Wait() { return event_->Wait(kDefaultTimeoutMs); }

   private:
    virtual void FrameCallback(I420VideoFrame* frame) {
      EXPECT_EQ(kWidth, frame->width())
          << "Width not as expected, callback done before resize?";
      EXPECT_EQ(kHeight, frame->height())
          << "Height not as expected, callback done before resize?";

      // Previous luma specified, observed luma should be fairly close.
      if (expected_luma_byte_ != -1) {
        EXPECT_NEAR(expected_luma_byte_, *frame->buffer(kYPlane), 10);
      }

      memset(frame->buffer(kYPlane),
             next_luma_byte_,
             frame->allocated_size(kYPlane));

      event_->Set();
    }

    scoped_ptr<EventWrapper> event_;
    int expected_luma_byte_;
    int next_luma_byte_;
  };

  TestFrameCallback pre_encode_callback(-1, 255);  // Changes luma to 255.
  TestFrameCallback pre_render_callback(255, 0);  // Changes luma from 255 to 0.

  test::DirectTransport sender_transport, receiver_transport;

  CreateCalls(Call::Config(&sender_transport),
              Call::Config(&receiver_transport));

  sender_transport.SetReceiver(receiver_call_->Receiver());
  receiver_transport.SetReceiver(sender_call_->Receiver());

  CreateTestConfigs();
  scoped_ptr<VP8Encoder> encoder(VP8Encoder::Create());
  send_config_.encoder_settings.encoder = encoder.get();
  send_config_.encoder_settings.payload_name = "VP8";
  ASSERT_EQ(1u, video_streams_.size()) << "Test setup error.";
  video_streams_[0].width = kWidth;
  video_streams_[0].height = kHeight;
  send_config_.pre_encode_callback = &pre_encode_callback;
  receive_config_.codecs.clear();
  VideoCodec codec =
      test::CreateDecoderVideoCodec(send_config_.encoder_settings);
  receive_config_.external_decoders.clear();
  receive_config_.codecs.push_back(codec);
  receive_config_.pre_render_callback = &pre_render_callback;
  receive_config_.renderer = &renderer;

  CreateStreams();
  StartSending();

  // Create frames that are smaller than the send width/height, this is done to
  // check that the callbacks are done after processing video.
  scoped_ptr<test::FrameGenerator> frame_generator(
      test::FrameGenerator::Create(kWidth / 2, kHeight / 2));
  send_stream_->Input()->SwapFrame(frame_generator->NextFrame());

  EXPECT_EQ(kEventSignaled, pre_encode_callback.Wait())
      << "Timed out while waiting for pre-encode callback.";
  EXPECT_EQ(kEventSignaled, pre_render_callback.Wait())
      << "Timed out while waiting for pre-render callback.";
  EXPECT_EQ(kEventSignaled, renderer.Wait())
      << "Timed out while waiting for the frame to render.";

  StopSending();

  sender_transport.StopSending();
  receiver_transport.StopSending();

  DestroyStreams();
}

class PliObserver : public test::RtpRtcpObserver, public VideoRenderer {
  static const int kInverseDropProbability = 16;

 public:
  explicit PliObserver(bool nack_enabled)
      : test::RtpRtcpObserver(kLongTimeoutMs),
        nack_enabled_(nack_enabled),
        highest_dropped_timestamp_(0),
        frames_to_drop_(0),
        received_pli_(false) {}

  virtual Action OnSendRtp(const uint8_t* packet, size_t length) OVERRIDE {
    RTPHeader header;
    EXPECT_TRUE(parser_->Parse(packet, static_cast<int>(length), &header));

    // Drop all retransmitted packets to force a PLI.
    if (header.timestamp <= highest_dropped_timestamp_)
      return DROP_PACKET;

    if (frames_to_drop_ > 0) {
      highest_dropped_timestamp_ = header.timestamp;
      --frames_to_drop_;
      return DROP_PACKET;
    }

    return SEND_PACKET;
  }

  virtual Action OnReceiveRtcp(const uint8_t* packet, size_t length) OVERRIDE {
    RTCPUtility::RTCPParserV2 parser(packet, length, true);
    EXPECT_TRUE(parser.IsValid());

    for (RTCPUtility::RTCPPacketTypes packet_type = parser.Begin();
         packet_type != RTCPUtility::kRtcpNotValidCode;
         packet_type = parser.Iterate()) {
      if (!nack_enabled_)
        EXPECT_NE(packet_type, RTCPUtility::kRtcpRtpfbNackCode);

      if (packet_type == RTCPUtility::kRtcpPsfbPliCode) {
        received_pli_ = true;
        break;
      }
    }
    return SEND_PACKET;
  }

  virtual void RenderFrame(const I420VideoFrame& video_frame,
                           int time_to_render_ms) OVERRIDE {
    CriticalSectionScoped lock(crit_.get());
    if (received_pli_ && video_frame.timestamp() > highest_dropped_timestamp_) {
      observation_complete_->Set();
    }
    if (!received_pli_)
      frames_to_drop_ = kPacketsToDrop;
  }

 private:
  static const int kPacketsToDrop = 1;

  bool nack_enabled_;
  uint32_t highest_dropped_timestamp_;
  int frames_to_drop_;
  bool received_pli_;
};

void CallTest::ReceivesPliAndRecovers(int rtp_history_ms) {
  PliObserver observer(rtp_history_ms > 0);

  CreateCalls(Call::Config(observer.SendTransport()),
              Call::Config(observer.ReceiveTransport()));

  observer.SetReceivers(receiver_call_->Receiver(), sender_call_->Receiver());

  CreateTestConfigs();
  send_config_.rtp.nack.rtp_history_ms = rtp_history_ms;
  receive_config_.rtp.nack.rtp_history_ms = rtp_history_ms;
  receive_config_.renderer = &observer;

  CreateStreams();
  CreateFrameGenerator();
  StartSending();

  // Wait() waits for an event triggered when Pli has been received and frames
  // have been rendered afterwards.
  EXPECT_EQ(kEventSignaled, observer.Wait());

  StopSending();

  observer.StopSending();

  DestroyStreams();
}

TEST_F(CallTest, ReceivesPliAndRecoversWithNack) {
  ReceivesPliAndRecovers(1000);
}

// TODO(pbos): Enable this when 2250 is resolved.
TEST_F(CallTest, DISABLED_ReceivesPliAndRecoversWithoutNack) {
  ReceivesPliAndRecovers(0);
}

TEST_F(CallTest, UnknownRtpPacketGivesUnknownSsrcReturnCode) {
  class PacketInputObserver : public PacketReceiver {
   public:
    explicit PacketInputObserver(PacketReceiver* receiver)
        : receiver_(receiver), delivered_packet_(EventWrapper::Create()) {}

    EventTypeWrapper Wait() {
      return delivered_packet_->Wait(kDefaultTimeoutMs);
    }

   private:
    virtual DeliveryStatus DeliverPacket(const uint8_t* packet,
                                         size_t length) OVERRIDE {
      if (RtpHeaderParser::IsRtcp(packet, static_cast<int>(length))) {
        return receiver_->DeliverPacket(packet, length);
      } else {
        DeliveryStatus delivery_status =
            receiver_->DeliverPacket(packet, length);
        EXPECT_EQ(DELIVERY_UNKNOWN_SSRC, delivery_status);
        delivered_packet_->Set();
        return delivery_status;
      }
    }

    PacketReceiver* receiver_;
    scoped_ptr<EventWrapper> delivered_packet_;
  };

  test::DirectTransport send_transport, receive_transport;

  CreateCalls(Call::Config(&send_transport), Call::Config(&receive_transport));
  PacketInputObserver input_observer(receiver_call_->Receiver());

  send_transport.SetReceiver(&input_observer);
  receive_transport.SetReceiver(sender_call_->Receiver());

  CreateTestConfigs();

  CreateStreams();
  CreateFrameGenerator();
  StartSending();

  receiver_call_->DestroyVideoReceiveStream(receive_stream_);
  receive_stream_ = NULL;

  // Wait() waits for a received packet.
  EXPECT_EQ(kEventSignaled, input_observer.Wait());

  StopSending();

  DestroyStreams();

  send_transport.StopSending();
  receive_transport.StopSending();
}

void CallTest::RespectsRtcpMode(newapi::RtcpMode rtcp_mode) {
  static const int kRtpHistoryMs = 1000;
  static const int kNumCompoundRtcpPacketsToObserve = 10;
  class RtcpModeObserver : public test::RtpRtcpObserver {
   public:
    explicit RtcpModeObserver(newapi::RtcpMode rtcp_mode)
        : test::RtpRtcpObserver(kDefaultTimeoutMs),
          rtcp_mode_(rtcp_mode),
          sent_rtp_(0),
          sent_rtcp_(0) {}

   private:
    virtual Action OnSendRtp(const uint8_t* packet, size_t length) OVERRIDE {
      if (++sent_rtp_ % 3 == 0)
        return DROP_PACKET;

      return SEND_PACKET;
    }

    virtual Action OnReceiveRtcp(const uint8_t* packet,
                                 size_t length) OVERRIDE {
      ++sent_rtcp_;
      RTCPUtility::RTCPParserV2 parser(packet, length, true);
      EXPECT_TRUE(parser.IsValid());

      RTCPUtility::RTCPPacketTypes packet_type = parser.Begin();
      bool has_report_block = false;
      while (packet_type != RTCPUtility::kRtcpNotValidCode) {
        EXPECT_NE(RTCPUtility::kRtcpSrCode, packet_type);
        if (packet_type == RTCPUtility::kRtcpRrCode) {
          has_report_block = true;
          break;
        }
        packet_type = parser.Iterate();
      }

      switch (rtcp_mode_) {
        case newapi::kRtcpCompound:
          if (!has_report_block) {
            ADD_FAILURE() << "Received RTCP packet without receiver report for "
                             "kRtcpCompound.";
            observation_complete_->Set();
          }

          if (sent_rtcp_ >= kNumCompoundRtcpPacketsToObserve)
            observation_complete_->Set();

          break;
        case newapi::kRtcpReducedSize:
          if (!has_report_block)
            observation_complete_->Set();
          break;
      }

      return SEND_PACKET;
    }

    newapi::RtcpMode rtcp_mode_;
    int sent_rtp_;
    int sent_rtcp_;
  } observer(rtcp_mode);

  CreateCalls(Call::Config(observer.SendTransport()),
              Call::Config(observer.ReceiveTransport()));

  observer.SetReceivers(receiver_call_->Receiver(), sender_call_->Receiver());

  CreateTestConfigs();
  send_config_.rtp.nack.rtp_history_ms = kRtpHistoryMs;
  receive_config_.rtp.nack.rtp_history_ms = kRtpHistoryMs;
  receive_config_.rtp.rtcp_mode = rtcp_mode;

  CreateStreams();
  CreateFrameGenerator();
  StartSending();

  EXPECT_EQ(kEventSignaled, observer.Wait())
      << (rtcp_mode == newapi::kRtcpCompound
              ? "Timed out before observing enough compound packets."
              : "Timed out before receiving a non-compound RTCP packet.");

  StopSending();
  observer.StopSending();
  DestroyStreams();
}

TEST_F(CallTest, UsesRtcpCompoundMode) {
  RespectsRtcpMode(newapi::kRtcpCompound);
}

TEST_F(CallTest, UsesRtcpReducedSizeMode) {
  RespectsRtcpMode(newapi::kRtcpReducedSize);
}

// Test sets up a Call multiple senders with different resolutions and SSRCs.
// Another is set up to receive all three of these with different renderers.
// Each renderer verifies that it receives the expected resolution, and as soon
// as every renderer has received a frame, the test finishes.
TEST_F(CallTest, SendsAndReceivesMultipleStreams) {
  static const size_t kNumStreams = 3;

  class VideoOutputObserver : public VideoRenderer {
   public:
    VideoOutputObserver(test::FrameGeneratorCapturer** capturer,
                        int width,
                        int height)
        : capturer_(capturer),
          width_(width),
          height_(height),
          done_(EventWrapper::Create()) {}

    virtual void RenderFrame(const I420VideoFrame& video_frame,
                             int time_to_render_ms) OVERRIDE {
      EXPECT_EQ(width_, video_frame.width());
      EXPECT_EQ(height_, video_frame.height());
      (*capturer_)->Stop();
      done_->Set();
    }

    EventTypeWrapper Wait() { return done_->Wait(kDefaultTimeoutMs); }

   private:
    test::FrameGeneratorCapturer** capturer_;
    int width_;
    int height_;
    scoped_ptr<EventWrapper> done_;
  };

  struct {
    uint32_t ssrc;
    int width;
    int height;
  } codec_settings[kNumStreams] = {{1, 640, 480}, {2, 320, 240}, {3, 240, 160}};

  test::DirectTransport sender_transport, receiver_transport;
  scoped_ptr<Call> sender_call(Call::Create(Call::Config(&sender_transport)));
  scoped_ptr<Call> receiver_call(
      Call::Create(Call::Config(&receiver_transport)));
  sender_transport.SetReceiver(receiver_call->Receiver());
  receiver_transport.SetReceiver(sender_call->Receiver());

  VideoSendStream* send_streams[kNumStreams];
  VideoReceiveStream* receive_streams[kNumStreams];

  VideoOutputObserver* observers[kNumStreams];
  test::FrameGeneratorCapturer* frame_generators[kNumStreams];

  scoped_ptr<VP8Encoder> encoders[kNumStreams];
  for (size_t i = 0; i < kNumStreams; ++i)
    encoders[i].reset(VP8Encoder::Create());

  for (size_t i = 0; i < kNumStreams; ++i) {
    uint32_t ssrc = codec_settings[i].ssrc;
    int width = codec_settings[i].width;
    int height = codec_settings[i].height;
    observers[i] = new VideoOutputObserver(&frame_generators[i], width, height);

    VideoSendStream::Config send_config = sender_call->GetDefaultSendConfig();
    send_config.rtp.ssrcs.push_back(ssrc);
    send_config.encoder_settings.encoder = encoders[i].get();
    send_config.encoder_settings.payload_name = "VP8";
    send_config.encoder_settings.payload_type = 124;
    std::vector<VideoStream> video_streams = test::CreateVideoStreams(1);
    VideoStream* stream = &video_streams[0];
    stream->width = width;
    stream->height = height;
    stream->max_framerate = 5;
    stream->min_bitrate_bps = stream->target_bitrate_bps =
        stream->max_bitrate_bps = 100000;
    send_streams[i] =
        sender_call->CreateVideoSendStream(send_config, video_streams, NULL);
    send_streams[i]->Start();

    VideoReceiveStream::Config receive_config =
        receiver_call->GetDefaultReceiveConfig();
    receive_config.renderer = observers[i];
    receive_config.rtp.remote_ssrc = ssrc;
    receive_config.rtp.local_ssrc = kReceiverLocalSsrc;
    VideoCodec codec =
        test::CreateDecoderVideoCodec(send_config.encoder_settings);
    receive_config.codecs.push_back(codec);
    receive_streams[i] =
        receiver_call->CreateVideoReceiveStream(receive_config);
    receive_streams[i]->Start();

    frame_generators[i] = test::FrameGeneratorCapturer::Create(
        send_streams[i]->Input(), width, height, 30, Clock::GetRealTimeClock());
    frame_generators[i]->Start();
  }

  for (size_t i = 0; i < kNumStreams; ++i) {
    EXPECT_EQ(kEventSignaled, observers[i]->Wait())
        << "Timed out while waiting for observer " << i << " to render.";
  }

  for (size_t i = 0; i < kNumStreams; ++i) {
    frame_generators[i]->Stop();
    sender_call->DestroyVideoSendStream(send_streams[i]);
    receiver_call->DestroyVideoReceiveStream(receive_streams[i]);
    delete frame_generators[i];
    delete observers[i];
  }

  sender_transport.StopSending();
  receiver_transport.StopSending();
};

TEST_F(CallTest, ObserversEncodedFrames) {
  class EncodedFrameTestObserver : public EncodedFrameObserver {
   public:
    EncodedFrameTestObserver()
        : length_(0),
          frame_type_(kFrameEmpty),
          called_(EventWrapper::Create()) {}
    virtual ~EncodedFrameTestObserver() {}

    virtual void EncodedFrameCallback(const EncodedFrame& encoded_frame) {
      frame_type_ = encoded_frame.frame_type_;
      length_ = encoded_frame.length_;
      buffer_.reset(new uint8_t[length_]);
      memcpy(buffer_.get(), encoded_frame.data_, length_);
      called_->Set();
    }

    EventTypeWrapper Wait() { return called_->Wait(kDefaultTimeoutMs); }

    void ExpectEqualFrames(const EncodedFrameTestObserver& observer) {
      ASSERT_EQ(length_, observer.length_)
          << "Observed frames are of different lengths.";
      EXPECT_EQ(frame_type_, observer.frame_type_)
          << "Observed frames have different frame types.";
      EXPECT_EQ(0, memcmp(buffer_.get(), observer.buffer_.get(), length_))
          << "Observed encoded frames have different content.";
    }

   private:
    scoped_ptr<uint8_t[]> buffer_;
    size_t length_;
    FrameType frame_type_;
    scoped_ptr<EventWrapper> called_;
  };

  EncodedFrameTestObserver post_encode_observer;
  EncodedFrameTestObserver pre_decode_observer;

  test::DirectTransport sender_transport, receiver_transport;

  CreateCalls(Call::Config(&sender_transport),
              Call::Config(&receiver_transport));

  sender_transport.SetReceiver(receiver_call_->Receiver());
  receiver_transport.SetReceiver(sender_call_->Receiver());

  CreateTestConfigs();
  send_config_.post_encode_callback = &post_encode_observer;
  receive_config_.pre_decode_callback = &pre_decode_observer;

  CreateStreams();
  StartSending();

  scoped_ptr<test::FrameGenerator> frame_generator(test::FrameGenerator::Create(
      video_streams_[0].width, video_streams_[0].height));
  send_stream_->Input()->SwapFrame(frame_generator->NextFrame());

  EXPECT_EQ(kEventSignaled, post_encode_observer.Wait())
      << "Timed out while waiting for send-side encoded-frame callback.";

  EXPECT_EQ(kEventSignaled, pre_decode_observer.Wait())
      << "Timed out while waiting for pre-decode encoded-frame callback.";

  post_encode_observer.ExpectEqualFrames(pre_decode_observer);

  StopSending();

  sender_transport.StopSending();
  receiver_transport.StopSending();

  DestroyStreams();
}

TEST_F(CallTest, ReceiveStreamSendsRemb) {
  class RembObserver : public test::RtpRtcpObserver {
   public:
    RembObserver() : test::RtpRtcpObserver(kDefaultTimeoutMs) {}

    virtual Action OnReceiveRtcp(const uint8_t* packet,
                                 size_t length) OVERRIDE {
      RTCPUtility::RTCPParserV2 parser(packet, length, true);
      EXPECT_TRUE(parser.IsValid());

      bool received_psfb = false;
      bool received_remb = false;
      RTCPUtility::RTCPPacketTypes packet_type = parser.Begin();
      while (packet_type != RTCPUtility::kRtcpNotValidCode) {
        if (packet_type == RTCPUtility::kRtcpPsfbRembCode) {
          const RTCPUtility::RTCPPacket& packet = parser.Packet();
          EXPECT_EQ(packet.PSFBAPP.SenderSSRC, kReceiverLocalSsrc);
          received_psfb = true;
        } else if (packet_type == RTCPUtility::kRtcpPsfbRembItemCode) {
          const RTCPUtility::RTCPPacket& packet = parser.Packet();
          EXPECT_GT(packet.REMBItem.BitRate, 0u);
          EXPECT_EQ(packet.REMBItem.NumberOfSSRCs, 1u);
          EXPECT_EQ(packet.REMBItem.SSRCs[0], kSendSsrc);
          received_remb = true;
        }
        packet_type = parser.Iterate();
      }
      if (received_psfb && received_remb)
        observation_complete_->Set();
      return SEND_PACKET;
    }
  } observer;

  CreateCalls(Call::Config(observer.SendTransport()),
              Call::Config(observer.ReceiveTransport()));
  observer.SetReceivers(receiver_call_->Receiver(), sender_call_->Receiver());
  CreateTestConfigs();
  CreateStreams();
  CreateFrameGenerator();
  StartSending();

  EXPECT_EQ(kEventSignaled, observer.Wait())
      << "Timed out while waiting for a receiver RTCP REMB packet to be sent.";

  StopSending();
  observer.StopSending();
  DestroyStreams();
}

void CallTest::TestXrReceiverReferenceTimeReport(bool enable_rrtr) {
  static const int kNumRtcpReportPacketsToObserve = 5;
  class RtcpXrObserver : public test::RtpRtcpObserver {
   public:
    explicit RtcpXrObserver(bool enable_rrtr)
        : test::RtpRtcpObserver(kDefaultTimeoutMs),
          enable_rrtr_(enable_rrtr),
          sent_rtcp_sr_(0),
          sent_rtcp_rr_(0),
          sent_rtcp_rrtr_(0),
          sent_rtcp_dlrr_(0) {}

   private:
    // Receive stream should send RR packets (and RRTR packets if enabled).
    virtual Action OnReceiveRtcp(const uint8_t* packet,
                                 size_t length) OVERRIDE {
      RTCPUtility::RTCPParserV2 parser(packet, length, true);
      EXPECT_TRUE(parser.IsValid());

      RTCPUtility::RTCPPacketTypes packet_type = parser.Begin();
      while (packet_type != RTCPUtility::kRtcpNotValidCode) {
        if (packet_type == RTCPUtility::kRtcpRrCode) {
          ++sent_rtcp_rr_;
        } else if (packet_type ==
                   RTCPUtility::kRtcpXrReceiverReferenceTimeCode) {
          ++sent_rtcp_rrtr_;
        }
        EXPECT_NE(packet_type, RTCPUtility::kRtcpSrCode);
        EXPECT_NE(packet_type, RTCPUtility::kRtcpXrDlrrReportBlockItemCode);
        packet_type = parser.Iterate();
      }
      return SEND_PACKET;
    }
    // Send stream should send SR packets (and DLRR packets if enabled).
    virtual Action OnSendRtcp(const uint8_t* packet, size_t length) {
      RTCPUtility::RTCPParserV2 parser(packet, length, true);
      EXPECT_TRUE(parser.IsValid());

      RTCPUtility::RTCPPacketTypes packet_type = parser.Begin();
      while (packet_type != RTCPUtility::kRtcpNotValidCode) {
        if (packet_type == RTCPUtility::kRtcpSrCode) {
          ++sent_rtcp_sr_;
        } else if (packet_type == RTCPUtility::kRtcpXrDlrrReportBlockItemCode) {
          ++sent_rtcp_dlrr_;
        }
        EXPECT_NE(packet_type, RTCPUtility::kRtcpXrReceiverReferenceTimeCode);
        packet_type = parser.Iterate();
      }
      if (sent_rtcp_sr_ > kNumRtcpReportPacketsToObserve &&
          sent_rtcp_rr_ > kNumRtcpReportPacketsToObserve) {
        if (enable_rrtr_) {
          EXPECT_GT(sent_rtcp_rrtr_, 0);
          EXPECT_GT(sent_rtcp_dlrr_, 0);
        } else {
          EXPECT_EQ(0, sent_rtcp_rrtr_);
          EXPECT_EQ(0, sent_rtcp_dlrr_);
        }
        observation_complete_->Set();
      }
      return SEND_PACKET;
    }
    bool enable_rrtr_;
    int sent_rtcp_sr_;
    int sent_rtcp_rr_;
    int sent_rtcp_rrtr_;
    int sent_rtcp_dlrr_;
  } observer(enable_rrtr);

  CreateCalls(Call::Config(observer.SendTransport()),
              Call::Config(observer.ReceiveTransport()));
  observer.SetReceivers(receiver_call_->Receiver(), sender_call_->Receiver());

  CreateTestConfigs();
  receive_config_.rtp.rtcp_mode = newapi::kRtcpReducedSize;
  receive_config_.rtp.rtcp_xr.receiver_reference_time_report = enable_rrtr;

  CreateStreams();
  CreateFrameGenerator();
  StartSending();

  EXPECT_EQ(kEventSignaled, observer.Wait())
      << "Timed out while waiting for RTCP SR/RR packets to be sent.";

  StopSending();
  observer.StopSending();
  DestroyStreams();
}

class StatsObserver : public test::RtpRtcpObserver, public I420FrameCallback {
 public:
  StatsObserver()
      : test::RtpRtcpObserver(kLongTimeoutMs),
        receive_stream_(NULL),
        send_stream_(NULL),
        expected_receive_ssrc_(),
        expected_send_ssrcs_(),
        check_stats_event_(EventWrapper::Create()) {}

  void SetExpectedReceiveSsrc(uint32_t ssrc) { expected_receive_ssrc_ = ssrc; }

  void SetExpectedSendSsrcs(const std::vector<uint32_t>& ssrcs) {
    for (std::vector<uint32_t>::const_iterator it = ssrcs.begin();
         it != ssrcs.end();
         ++it) {
      expected_send_ssrcs_.insert(*it);
    }
  }

  void SetExpectedCName(std::string cname) { expected_cname_ = cname; }

  void SetReceiveStream(VideoReceiveStream* stream) {
    receive_stream_ = stream;
  }

  void SetSendStream(VideoSendStream* stream) { send_stream_ = stream; }

  void WaitForFilledStats() {
    Clock* clock = Clock::GetRealTimeClock();
    int64_t now = clock->TimeInMilliseconds();
    int64_t stop_time = now + kLongTimeoutMs;
    bool receive_ok = false;
    bool send_ok = false;

    while (now < stop_time) {
      if (!receive_ok)
        receive_ok = CheckReceiveStats();
      if (!send_ok)
        send_ok = CheckSendStats();

      if (receive_ok && send_ok)
        return;

      int64_t time_until_timout_ = stop_time - now;
      if (time_until_timout_ > 0)
        check_stats_event_->Wait(time_until_timout_);
      now = clock->TimeInMilliseconds();
    }

    ADD_FAILURE() << "Timed out waiting for filled stats.";
    for (std::map<std::string, bool>::const_iterator it =
             receive_stats_filled_.begin();
         it != receive_stats_filled_.end();
         ++it) {
      if (!it->second) {
        ADD_FAILURE() << "Missing receive stats: " << it->first;
      }
    }

    for (std::map<std::string, bool>::const_iterator it =
             send_stats_filled_.begin();
         it != send_stats_filled_.end();
         ++it) {
      if (!it->second) {
        ADD_FAILURE() << "Missing send stats: " << it->first;
      }
    }
  }

 private:
  virtual Action OnSendRtp(const uint8_t* packet, size_t length) OVERRIDE {
    check_stats_event_->Set();
    return SEND_PACKET;
  }

  virtual Action OnSendRtcp(const uint8_t* packet, size_t length) OVERRIDE {
    check_stats_event_->Set();
    return SEND_PACKET;
  }

  virtual Action OnReceiveRtp(const uint8_t* packet, size_t length) OVERRIDE {
    check_stats_event_->Set();
    return SEND_PACKET;
  }

  virtual Action OnReceiveRtcp(const uint8_t* packet, size_t length) OVERRIDE {
    check_stats_event_->Set();
    return SEND_PACKET;
  }

  virtual void FrameCallback(I420VideoFrame* video_frame) OVERRIDE {
    // Ensure that we have at least 5ms send side delay.
    int64_t render_time = video_frame->render_time_ms();
    if (render_time > 0)
      video_frame->set_render_time_ms(render_time - 5);
  }

  bool CheckReceiveStats() {
    assert(receive_stream_ != NULL);
    VideoReceiveStream::Stats stats = receive_stream_->GetStats();
    EXPECT_EQ(expected_receive_ssrc_, stats.ssrc);

    // Make sure all fields have been populated.

    receive_stats_filled_["IncomingRate"] |=
        stats.network_frame_rate != 0 || stats.bitrate_bps != 0;

    receive_stats_filled_["FrameCallback"] |= stats.decode_frame_rate != 0;

    receive_stats_filled_["FrameRendered"] |= stats.render_frame_rate != 0;

    receive_stats_filled_["StatisticsUpdated"] |=
        stats.rtcp_stats.cumulative_lost != 0 ||
        stats.rtcp_stats.extended_max_sequence_number != 0 ||
        stats.rtcp_stats.fraction_lost != 0 || stats.rtcp_stats.jitter != 0;

    receive_stats_filled_["DataCountersUpdated"] |=
        stats.rtp_stats.bytes != 0 || stats.rtp_stats.fec_packets != 0 ||
        stats.rtp_stats.header_bytes != 0 || stats.rtp_stats.packets != 0 ||
        stats.rtp_stats.padding_bytes != 0 ||
        stats.rtp_stats.retransmitted_packets != 0;

    receive_stats_filled_["CodecStats"] |=
        stats.avg_delay_ms != 0 || stats.discarded_packets != 0 ||
        stats.key_frames != 0 || stats.delta_frames != 0;

    receive_stats_filled_["CName"] |= stats.c_name == expected_cname_;

    return AllStatsFilled(receive_stats_filled_);
  }

  bool CheckSendStats() {
    assert(send_stream_ != NULL);
    VideoSendStream::Stats stats = send_stream_->GetStats();

    send_stats_filled_["NumStreams"] |=
        stats.substreams.size() == expected_send_ssrcs_.size();

    send_stats_filled_["Delay"] |=
        stats.avg_delay_ms != 0 || stats.max_delay_ms != 0;

    receive_stats_filled_["CName"] |= stats.c_name == expected_cname_;

    for (std::map<uint32_t, StreamStats>::const_iterator it =
             stats.substreams.begin();
         it != stats.substreams.end();
         ++it) {
      EXPECT_TRUE(expected_send_ssrcs_.find(it->first) !=
                  expected_send_ssrcs_.end());

      send_stats_filled_[CompoundKey("IncomingRate", it->first)] |=
          stats.input_frame_rate != 0;

      const StreamStats& stream_stats = it->second;

      send_stats_filled_[CompoundKey("StatisticsUpdated", it->first)] |=
          stream_stats.rtcp_stats.cumulative_lost != 0 ||
          stream_stats.rtcp_stats.extended_max_sequence_number != 0 ||
          stream_stats.rtcp_stats.fraction_lost != 0;

      send_stats_filled_[CompoundKey("DataCountersUpdated", it->first)] |=
          stream_stats.rtp_stats.fec_packets != 0 ||
          stream_stats.rtp_stats.padding_bytes != 0 ||
          stream_stats.rtp_stats.retransmitted_packets != 0 ||
          stream_stats.rtp_stats.packets != 0;

      send_stats_filled_[CompoundKey("BitrateStatisticsObserver", it->first)] |=
          stream_stats.bitrate_bps != 0;

      send_stats_filled_[CompoundKey("FrameCountObserver", it->first)] |=
          stream_stats.delta_frames != 0 || stream_stats.key_frames != 0;

      send_stats_filled_[CompoundKey("OutgoingRate", it->first)] |=
          stats.encode_frame_rate != 0;
    }

    return AllStatsFilled(send_stats_filled_);
  }

  std::string CompoundKey(const char* name, uint32_t ssrc) {
    std::ostringstream oss;
    oss << name << "_" << ssrc;
    return oss.str();
  }

  bool AllStatsFilled(const std::map<std::string, bool>& stats_map) {
    for (std::map<std::string, bool>::const_iterator it = stats_map.begin();
         it != stats_map.end();
         ++it) {
      if (!it->second)
        return false;
    }
    return true;
  }

  VideoReceiveStream* receive_stream_;
  std::map<std::string, bool> receive_stats_filled_;

  VideoSendStream* send_stream_;
  std::map<std::string, bool> send_stats_filled_;

  uint32_t expected_receive_ssrc_;
  std::set<uint32_t> expected_send_ssrcs_;
  std::string expected_cname_;

  scoped_ptr<EventWrapper> check_stats_event_;
};

TEST_F(CallTest, GetStats) {
  StatsObserver observer;

  CreateCalls(Call::Config(observer.SendTransport()),
              Call::Config(observer.ReceiveTransport()));

  observer.SetReceivers(receiver_call_->Receiver(), sender_call_->Receiver());

  CreateTestConfigs();
  send_config_.pre_encode_callback = &observer;  // Used to inject delay.
  send_config_.rtp.c_name = "SomeCName";

  observer.SetExpectedReceiveSsrc(receive_config_.rtp.local_ssrc);
  observer.SetExpectedSendSsrcs(send_config_.rtp.ssrcs);
  observer.SetExpectedCName(send_config_.rtp.c_name);

  CreateStreams();
  observer.SetReceiveStream(receive_stream_);
  observer.SetSendStream(send_stream_);
  CreateFrameGenerator();
  StartSending();

  observer.WaitForFilledStats();

  StopSending();
  observer.StopSending();
  DestroyStreams();
}

TEST_F(CallTest, ReceiverReferenceTimeReportEnabled) {
  TestXrReceiverReferenceTimeReport(true);
}

TEST_F(CallTest, ReceiverReferenceTimeReportDisabled) {
  TestXrReceiverReferenceTimeReport(false);
}

TEST_F(CallTest, TestReceivedRtpPacketStats) {
  static const size_t kNumRtpPacketsToSend = 5;
  class ReceivedRtpStatsObserver : public test::RtpRtcpObserver {
   public:
    ReceivedRtpStatsObserver()
        : test::RtpRtcpObserver(kDefaultTimeoutMs),
          receive_stream_(NULL),
          sent_rtp_(0) {}

    void SetReceiveStream(VideoReceiveStream* stream) {
      receive_stream_ = stream;
    }

   private:
    virtual Action OnSendRtp(const uint8_t* packet, size_t length) OVERRIDE {
      if (sent_rtp_ >= kNumRtpPacketsToSend) {
        VideoReceiveStream::Stats stats = receive_stream_->GetStats();
        if (kNumRtpPacketsToSend == stats.rtp_stats.packets) {
          observation_complete_->Set();
        }
        return DROP_PACKET;
      }
      ++sent_rtp_;
      return SEND_PACKET;
    }

    VideoReceiveStream* receive_stream_;
    uint32_t sent_rtp_;
  } observer;

  CreateCalls(Call::Config(observer.SendTransport()),
              Call::Config(observer.ReceiveTransport()));
  observer.SetReceivers(receiver_call_->Receiver(), sender_call_->Receiver());

  CreateTestConfigs();
  CreateStreams();
  observer.SetReceiveStream(receive_stream_);
  CreateFrameGenerator();
  StartSending();

  EXPECT_EQ(kEventSignaled, observer.Wait())
      << "Timed out while verifying number of received RTP packets.";

  StopSending();
  observer.StopSending();
  DestroyStreams();
}

}  // namespace webrtc
