// libjingle
// Copyright 2004 Google Inc. All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
//  1. Redistributions of source code must retain the above copyright notice,
//     this list of conditions and the following disclaimer.
//  2. Redistributions in binary form must reproduce the above copyright notice,
//     this list of conditions and the following disclaimer in the documentation
//     and/or other materials provided with the distribution.
//  3. The name of the author may not be used to endorse or promote products
//     derived from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
// EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

#ifndef TALK_MEDIA_BASE_VIDEOENGINE_UNITTEST_H_  // NOLINT
#define TALK_MEDIA_BASE_VIDEOENGINE_UNITTEST_H_

#include <string>
#include <vector>

#include "talk/media/base/fakenetworkinterface.h"
#include "talk/media/base/fakevideocapturer.h"
#include "talk/media/base/fakevideorenderer.h"
#include "talk/media/base/mediachannel.h"
#include "talk/media/base/streamparams.h"
#include "webrtc/base/bytebuffer.h"
#include "webrtc/base/gunit.h"
#include "webrtc/base/timeutils.h"

#ifdef WIN32
#include <objbase.h>  // NOLINT
#endif

#define EXPECT_FRAME_WAIT(c, w, h, t) \
  EXPECT_EQ_WAIT((c), renderer_.num_rendered_frames(), (t)); \
  EXPECT_EQ((w), renderer_.width()); \
  EXPECT_EQ((h), renderer_.height()); \
  EXPECT_EQ(0, renderer_.errors()); \

#define EXPECT_FRAME_ON_RENDERER_WAIT(r, c, w, h, t) \
  EXPECT_EQ_WAIT((c), (r).num_rendered_frames(), (t)); \
  EXPECT_EQ((w), (r).width()); \
  EXPECT_EQ((h), (r).height()); \
  EXPECT_EQ(0, (r).errors()); \

#define EXPECT_GT_FRAME_ON_RENDERER_WAIT(r, c, w, h, t) \
  EXPECT_TRUE_WAIT((r).num_rendered_frames() >= (c) && \
                   (w) == (r).width() && \
                   (h) == (r).height(), (t)); \
  EXPECT_EQ(0, (r).errors()); \

static const uint32 kTimeout = 5000U;
static const uint32 kDefaultReceiveSsrc = 0;
static const uint32 kSsrc = 1234u;
static const uint32 kRtxSsrc = 4321u;
static const uint32 kSsrcs4[] = {1, 2, 3, 4};

inline bool IsEqualRes(const cricket::VideoCodec& a, int w, int h, int fps) {
  return a.width == w && a.height == h && a.framerate == fps;
}

inline bool IsEqualCodec(const cricket::VideoCodec& a,
                         const cricket::VideoCodec& b) {
  return a.id == b.id && a.name == b.name &&
      IsEqualRes(a, b.width, b.height, b.framerate);
}

namespace std {
inline std::ostream& operator<<(std::ostream& s, const cricket::VideoCodec& c) {
  s << "{" << c.name << "(" << c.id << "), "
    << c.width << "x" << c.height << "x" << c.framerate << "}";
  return s;
}
}  // namespace std

inline int TimeBetweenSend(const cricket::VideoCodec& codec) {
  return static_cast<int>(
      cricket::VideoFormat::FpsToInterval(codec.framerate) /
      rtc::kNumNanosecsPerMillisec);
}

// Fake video engine that makes it possible to test enabling and disabling
// capturer (checking that the engine state is updated and that the capturer
// is indeed capturing) without having to create a channel. It also makes it
// possible to test that the media processors are indeed being called when
// registered.
template<class T>
class VideoEngineOverride : public T {
 public:
  VideoEngineOverride() {
  }
  virtual ~VideoEngineOverride() {
  }
  bool is_camera_on() const { return T::GetVideoCapturer()->IsRunning(); }
  void set_has_senders(bool has_senders) {
    cricket::VideoCapturer* video_capturer = T::GetVideoCapturer();
    if (has_senders) {
      video_capturer->SignalVideoFrame.connect(this,
          &VideoEngineOverride<T>::OnLocalFrame);
    } else {
      video_capturer->SignalVideoFrame.disconnect(this);
    }
  }
  void OnLocalFrame(cricket::VideoCapturer*,
                    const cricket::VideoFrame*) {
  }
  void OnLocalFrameFormat(cricket::VideoCapturer*,
                          const cricket::VideoFormat*) {
  }

  void TriggerMediaFrame(
      uint32 ssrc, cricket::VideoFrame* frame, bool* drop_frame) {
    T::SignalMediaFrame(ssrc, frame, drop_frame);
  }
};

// Macroes that declare test functions for a given test class, before and after
// Init().
// To use, define a test function called FooBody and pass Foo to the macro.
#define TEST_PRE_VIDEOENGINE_INIT(TestClass, func) \
  TEST_F(TestClass, func##PreInit) { \
    func##Body(); \
  }
#define TEST_POST_VIDEOENGINE_INIT(TestClass, func) \
  TEST_F(TestClass, func##PostInit) { \
    EXPECT_TRUE(engine_.Init(rtc::Thread::Current())); \
    func##Body(); \
    engine_.Terminate(); \
  }

template<class E>
class VideoEngineTest : public testing::Test {
 protected:
  // Tests starting and stopping the engine, and creating a channel.
  void StartupShutdown() {
    EXPECT_TRUE(engine_.Init(rtc::Thread::Current()));
    cricket::VideoMediaChannel* channel = engine_.CreateChannel(NULL);
    EXPECT_TRUE(channel != NULL);
    delete channel;
    engine_.Terminate();
  }

#ifdef WIN32
  // Tests that the COM reference count is not munged by the engine.
  // Test to make sure LMI does not munge the CoInitialize reference count.
  void CheckCoInitialize() {
    // Initial refcount should be 0.
    EXPECT_EQ(S_OK, CoInitializeEx(NULL, COINIT_MULTITHREADED));

    // Engine should start even with COM already inited.
    EXPECT_TRUE(engine_.Init(rtc::Thread::Current()));
    engine_.Terminate();
    // Refcount after terminate should be 1; this tests if it is nonzero.
    EXPECT_EQ(S_FALSE, CoInitializeEx(NULL, COINIT_MULTITHREADED));
    // Decrement refcount to (hopefully) 0.
    CoUninitialize();
    CoUninitialize();

    // Ensure refcount is 0.
    EXPECT_EQ(S_OK, CoInitializeEx(NULL, COINIT_MULTITHREADED));
    CoUninitialize();
  }
#endif

  void ConstrainNewCodecBody() {
    cricket::VideoCodec empty, in, out;
    cricket::VideoCodec max_settings(engine_.codecs()[0].id,
                                     engine_.codecs()[0].name,
                                     1280, 800, 30, 0);

    // set max settings of 1280x800x30
    EXPECT_TRUE(engine_.SetDefaultEncoderConfig(
        cricket::VideoEncoderConfig(max_settings)));

    // don't constrain the max resolution
    in = max_settings;
    EXPECT_TRUE(engine_.CanSendCodec(in, empty, &out));
    EXPECT_PRED2(IsEqualCodec, out, in);

    // constrain resolution greater than the max and wider aspect,
    // picking best aspect (16:10)
    in.width = 1380;
    in.height = 800;
    EXPECT_TRUE(engine_.CanSendCodec(in, empty, &out));
    EXPECT_PRED4(IsEqualRes, out, 1280, 720, 30);

    // constrain resolution greater than the max and narrow aspect,
    // picking best aspect (16:9)
    in.width = 1280;
    in.height = 740;
    EXPECT_TRUE(engine_.CanSendCodec(in, empty, &out));
    EXPECT_PRED4(IsEqualRes, out, 1280, 720, 30);

    // constrain resolution greater than the max, picking equal aspect (4:3)
    in.width = 1280;
    in.height = 960;
    EXPECT_TRUE(engine_.CanSendCodec(in, empty, &out));
    EXPECT_PRED4(IsEqualRes, out, 1280, 800, 30);

    // constrain resolution greater than the max, picking equal aspect (16:10)
    in.width = 1280;
    in.height = 800;
    EXPECT_TRUE(engine_.CanSendCodec(in, empty, &out));
    EXPECT_PRED4(IsEqualRes, out, 1280, 800, 30);

    // reduce max settings to 640x480x30
    max_settings.width = 640;
    max_settings.height = 480;
    EXPECT_TRUE(engine_.SetDefaultEncoderConfig(
        cricket::VideoEncoderConfig(max_settings)));

    // don't constrain the max resolution
    in = max_settings;
    in.width = 640;
    in.height = 480;
    EXPECT_TRUE(engine_.CanSendCodec(in, empty, &out));
    EXPECT_PRED2(IsEqualCodec, out, in);

    // keep 16:10 if they request it
    in.height = 400;
    EXPECT_TRUE(engine_.CanSendCodec(in, empty, &out));
    EXPECT_PRED2(IsEqualCodec, out, in);

    // don't constrain lesser 4:3 resolutions
    in.width = 320;
    in.height = 240;
    EXPECT_TRUE(engine_.CanSendCodec(in, empty, &out));
    EXPECT_PRED2(IsEqualCodec, out, in);

    // don't constrain lesser 16:10 resolutions
    in.width = 320;
    in.height = 200;
    EXPECT_TRUE(engine_.CanSendCodec(in, empty, &out));
    EXPECT_PRED2(IsEqualCodec, out, in);

    // requested resolution of 0x0 succeeds
    in.width = 0;
    in.height = 0;
    EXPECT_TRUE(engine_.CanSendCodec(in, empty, &out));
    EXPECT_PRED2(IsEqualCodec, out, in);

    // constrain resolution lesser than the max and wider aspect,
    // picking best aspect (16:9)
    in.width = 350;
    in.height = 201;
    EXPECT_TRUE(engine_.CanSendCodec(in, empty, &out));
    EXPECT_PRED4(IsEqualRes, out, 320, 180, 30);

    // constrain resolution greater than the max and narrow aspect,
    // picking best aspect (4:3)
    in.width = 350;
    in.height = 300;
    EXPECT_TRUE(engine_.CanSendCodec(in, empty, &out));
    EXPECT_PRED4(IsEqualRes, out, 320, 240, 30);

    // constrain resolution greater than the max and wider aspect,
    // picking best aspect (16:9)
    in.width = 1380;
    in.height = 800;
    EXPECT_TRUE(engine_.CanSendCodec(in, empty, &out));
    EXPECT_PRED4(IsEqualRes, out, 640, 360, 30);

    // constrain resolution greater than the max and narrow aspect,
    // picking best aspect (4:3)
    in.width = 1280;
    in.height = 900;
    EXPECT_TRUE(engine_.CanSendCodec(in, empty, &out));
    EXPECT_PRED4(IsEqualRes, out, 640, 480, 30);

    // constrain resolution greater than the max, picking equal aspect (4:3)
    in.width = 1280;
    in.height = 960;
    EXPECT_TRUE(engine_.CanSendCodec(in, empty, &out));
    EXPECT_PRED4(IsEqualRes, out, 640, 480, 30);

    // constrain resolution greater than the max, picking equal aspect (16:10)
    in.width = 1280;
    in.height = 800;
    EXPECT_TRUE(engine_.CanSendCodec(in, empty, &out));
    EXPECT_PRED4(IsEqualRes, out, 640, 400, 30);

    // constrain res & fps greater than the max
    in.framerate = 50;
    EXPECT_TRUE(engine_.CanSendCodec(in, empty, &out));
    EXPECT_PRED4(IsEqualRes, out, 640, 400, 30);

    // reduce max settings to 160x100x10
    max_settings.width = 160;
    max_settings.height = 100;
    max_settings.framerate = 10;
    EXPECT_TRUE(engine_.SetDefaultEncoderConfig(
        cricket::VideoEncoderConfig(max_settings)));

    // constrain res & fps to new max
    EXPECT_TRUE(engine_.CanSendCodec(in, empty, &out));
    EXPECT_PRED4(IsEqualRes, out, 160, 100, 10);

    // allow 4:3 "comparable" resolutions
    in.width = 160;
    in.height = 120;
    in.framerate = 10;
    EXPECT_TRUE(engine_.CanSendCodec(in, empty, &out));
    EXPECT_PRED4(IsEqualRes, out, 160, 120, 10);
  }

  // This is the new way of constraining codec size, where we no longer maintain
  // a list of the supported formats. Instead, CanSendCodec will just downscale
  // the resolution by 2 until the width is below clamp.
  void ConstrainNewCodec2Body() {
    cricket::VideoCodec empty, in, out;
    cricket::VideoCodec max_settings(engine_.codecs()[0].id,
                                     engine_.codecs()[0].name,
                                     1280, 800, 30, 0);

    // Set max settings of 1280x800x30
    EXPECT_TRUE(engine_.SetDefaultEncoderConfig(
        cricket::VideoEncoderConfig(max_settings)));

    // Don't constrain the max resolution
    in = max_settings;
    EXPECT_TRUE(engine_.CanSendCodec(in, empty, &out));
    EXPECT_PRED2(IsEqualCodec, out, in);

    // Constrain resolution greater than the max width.
    in.width = 1380;
    in.height = 800;
    EXPECT_TRUE(engine_.CanSendCodec(in, empty, &out));
    EXPECT_PRED4(IsEqualRes, out, 690, 400, 30);

    // Don't constrain resolution when only the height is greater than max.
    in.width = 960;
    in.height = 1280;
    EXPECT_TRUE(engine_.CanSendCodec(in, empty, &out));
    EXPECT_PRED4(IsEqualRes, out, 960, 1280, 30);

    // Don't constrain smaller format.
    in.width = 640;
    in.height = 480;
    EXPECT_TRUE(engine_.CanSendCodec(in, empty, &out));
    EXPECT_PRED4(IsEqualRes, out, 640, 480, 30);
  }

  void ConstrainRunningCodecBody() {
    cricket::VideoCodec in, out, current;
    cricket::VideoCodec max_settings(engine_.codecs()[0].id,
                                     engine_.codecs()[0].name,
                                     1280, 800, 30, 0);

    // set max settings of 1280x960x30
    EXPECT_TRUE(engine_.SetDefaultEncoderConfig(
        cricket::VideoEncoderConfig(max_settings)));

    // establish current call at 1280x800x30 (16:10)
    current = max_settings;
    current.height = 800;

    // Don't constrain current resolution
    in = current;
    EXPECT_TRUE(engine_.CanSendCodec(in, current, &out));
    EXPECT_PRED2(IsEqualCodec, out, in);

    // requested resolution of 0x0 succeeds
    in.width = 0;
    in.height = 0;
    EXPECT_TRUE(engine_.CanSendCodec(in, current, &out));
    EXPECT_PRED2(IsEqualCodec, out, in);

    // Reduce an intermediate resolution down to the next lowest one, preserving
    // aspect ratio.
    in.width = 800;
    in.height = 600;
    EXPECT_TRUE(engine_.CanSendCodec(in, current, &out));
    EXPECT_PRED4(IsEqualRes, out, 640, 400, 30);

    // Clamping by aspect ratio, but still never return a dimension higher than
    // requested.
    in.width = 1280;
    in.height = 720;
    EXPECT_TRUE(engine_.CanSendCodec(in, current, &out));
    EXPECT_PRED4(IsEqualRes, out, 1280, 720, 30);

    in.width = 1279;
    EXPECT_TRUE(engine_.CanSendCodec(in, current, &out));
    EXPECT_PRED4(IsEqualRes, out, 960, 600, 30);

    in.width = 1281;
    EXPECT_TRUE(engine_.CanSendCodec(in, current, &out));
    EXPECT_PRED4(IsEqualRes, out, 1280, 720, 30);

    // Clamp large resolutions down, always preserving aspect
    in.width = 1920;
    in.height = 1080;
    EXPECT_TRUE(engine_.CanSendCodec(in, current, &out));
    EXPECT_PRED4(IsEqualRes, out, 1280, 800, 30);

    in.width = 1921;
    EXPECT_TRUE(engine_.CanSendCodec(in, current, &out));
    EXPECT_PRED4(IsEqualRes, out, 1280, 800, 30);

    in.width = 1919;
    EXPECT_TRUE(engine_.CanSendCodec(in, current, &out));
    EXPECT_PRED4(IsEqualRes, out, 1280, 800, 30);

    // reduce max settings to 640x480x30
    max_settings.width = 640;
    max_settings.height = 480;
    EXPECT_TRUE(engine_.SetDefaultEncoderConfig(
        cricket::VideoEncoderConfig(max_settings)));

    // establish current call at 640x400x30 (16:10)
    current = max_settings;
    current.height = 400;

    // Don't constrain current resolution
    in = current;
    EXPECT_TRUE(engine_.CanSendCodec(in, current, &out));
    EXPECT_PRED2(IsEqualCodec, out, in);

    // requested resolution of 0x0 succeeds
    in.width = 0;
    in.height = 0;
    EXPECT_TRUE(engine_.CanSendCodec(in, current, &out));
    EXPECT_PRED2(IsEqualCodec, out, in);

    // Reduce an intermediate resolution down to the next lowest one, preserving
    // aspect ratio.
    in.width = 400;
    in.height = 300;
    EXPECT_TRUE(engine_.CanSendCodec(in, current, &out));
    EXPECT_PRED4(IsEqualRes, out, 320, 200, 30);

    // Clamping by aspect ratio, but still never return a dimension higher than
    // requested.
    in.width = 640;
    in.height = 360;
    EXPECT_TRUE(engine_.CanSendCodec(in, current, &out));
    EXPECT_PRED4(IsEqualRes, out, 640, 360, 30);

    in.width = 639;
    EXPECT_TRUE(engine_.CanSendCodec(in, current, &out));
    EXPECT_PRED4(IsEqualRes, out, 480, 300, 30);

    in.width = 641;
    EXPECT_TRUE(engine_.CanSendCodec(in, current, &out));
    EXPECT_PRED4(IsEqualRes, out, 640, 360, 30);

    // Clamp large resolutions down, always preserving aspect
    in.width = 1280;
    in.height = 800;
    EXPECT_TRUE(engine_.CanSendCodec(in, current, &out));
    EXPECT_PRED4(IsEqualRes, out, 640, 400, 30);

    in.width = 1281;
    EXPECT_TRUE(engine_.CanSendCodec(in, current, &out));
    EXPECT_PRED4(IsEqualRes, out, 640, 400, 30);

    in.width = 1279;
    EXPECT_TRUE(engine_.CanSendCodec(in, current, &out));
    EXPECT_PRED4(IsEqualRes, out, 640, 400, 30);

    // Should fail for any that are smaller than our supported formats
    in.width = 80;
    in.height = 80;
    EXPECT_FALSE(engine_.CanSendCodec(in, current, &out));

    in.height = 50;
    EXPECT_FALSE(engine_.CanSendCodec(in, current, &out));
  }

  VideoEngineOverride<E> engine_;
  rtc::scoped_ptr<cricket::FakeVideoCapturer> video_capturer_;
};

template<class E, class C>
class VideoMediaChannelTest : public testing::Test,
                              public sigslot::has_slots<> {
 protected:
  virtual cricket::VideoCodec DefaultCodec() = 0;

  virtual cricket::StreamParams DefaultSendStreamParams() {
    return cricket::StreamParams::CreateLegacy(kSsrc);
  }

  virtual void SetUp() {
    cricket::Device device("test", "device");
    EXPECT_TRUE(engine_.Init(rtc::Thread::Current()));
    channel_.reset(engine_.CreateChannel(NULL));
    EXPECT_TRUE(channel_.get() != NULL);
    ConnectVideoChannelError();
    network_interface_.SetDestination(channel_.get());
    channel_->SetInterface(&network_interface_);
    media_error_ = cricket::VideoMediaChannel::ERROR_NONE;
    channel_->SetRecvCodecs(engine_.codecs());
    EXPECT_TRUE(channel_->AddSendStream(DefaultSendStreamParams()));
    video_capturer_.reset(CreateFakeVideoCapturer());
    cricket::VideoFormat format(640, 480,
                                cricket::VideoFormat::FpsToInterval(30),
                                cricket::FOURCC_I420);
    EXPECT_EQ(cricket::CS_RUNNING, video_capturer_->Start(format));
    EXPECT_TRUE(channel_->SetCapturer(kSsrc, video_capturer_.get()));
  }

  virtual cricket::FakeVideoCapturer* CreateFakeVideoCapturer() {
    return new cricket::FakeVideoCapturer();
  }

  // Utility method to setup an additional stream to send and receive video.
  // Used to test send and recv between two streams.
  void SetUpSecondStream() {
    SetUpSecondStreamWithNoRecv();
    // Setup recv for second stream.
    EXPECT_TRUE(channel_->AddRecvStream(
        cricket::StreamParams::CreateLegacy(kSsrc + 2)));
    // Make the second renderer available for use by a new stream.
    EXPECT_TRUE(channel_->SetRenderer(kSsrc + 2, &renderer2_));
  }
  // Setup an additional stream just to send video. Defer add recv stream.
  // This is required if you want to test unsignalled recv of video rtp packets.
  void SetUpSecondStreamWithNoRecv() {
    // SetUp() already added kSsrc make sure duplicate SSRCs cant be added.
    EXPECT_TRUE(channel_->AddRecvStream(
        cricket::StreamParams::CreateLegacy(kSsrc)));
    EXPECT_TRUE(channel_->SetRenderer(kSsrc, &renderer_));
    EXPECT_FALSE(channel_->AddSendStream(
        cricket::StreamParams::CreateLegacy(kSsrc)));
    EXPECT_TRUE(channel_->AddSendStream(
        cricket::StreamParams::CreateLegacy(kSsrc + 2)));
    // We dont add recv for the second stream.

    // Setup the receive and renderer for second stream after send.
    video_capturer_2_.reset(CreateFakeVideoCapturer());
    cricket::VideoFormat format(640, 480,
                                cricket::VideoFormat::FpsToInterval(30),
                                cricket::FOURCC_I420);
    EXPECT_EQ(cricket::CS_RUNNING, video_capturer_2_->Start(format));

    EXPECT_TRUE(channel_->SetCapturer(kSsrc + 2, video_capturer_2_.get()));
  }
  virtual void TearDown() {
    channel_.reset();
    engine_.Terminate();
  }
  void ConnectVideoChannelError() {
    channel_->SignalMediaError.connect(this,
        &VideoMediaChannelTest<E, C>::OnVideoChannelError);
  }
  bool SetDefaultCodec() {
    return SetOneCodec(DefaultCodec());
  }

  bool SetOneCodec(int pt, const char* name, int w, int h, int fr) {
    return SetOneCodec(cricket::VideoCodec(pt, name, w, h, fr, 0));
  }
  bool SetOneCodec(const cricket::VideoCodec& codec) {
    std::vector<cricket::VideoCodec> codecs;
    codecs.push_back(codec);

    cricket::VideoFormat capture_format(codec.width, codec.height,
        cricket::VideoFormat::FpsToInterval(codec.framerate),
        cricket::FOURCC_I420);

    if (video_capturer_) {
      EXPECT_EQ(cricket::CS_RUNNING, video_capturer_->Start(capture_format));
    }
    if (video_capturer_2_) {
      EXPECT_EQ(cricket::CS_RUNNING, video_capturer_2_->Start(capture_format));
    }

    bool sending = channel_->sending();
    bool success = SetSend(false);
    if (success)
      success = channel_->SetSendCodecs(codecs);
    if (success)
      success = SetSend(sending);
    return success;
  }
  bool SetSend(bool send) {
    return channel_->SetSend(send);
  }
  bool SetSendStreamFormat(uint32 ssrc, const cricket::VideoCodec& codec) {
    return channel_->SetSendStreamFormat(ssrc, cricket::VideoFormat(
        codec.width, codec.height,
        cricket::VideoFormat::FpsToInterval(codec.framerate),
        cricket::FOURCC_ANY));
  }
  int DrainOutgoingPackets() {
    int packets = 0;
    do {
      packets = NumRtpPackets();
      // 100 ms should be long enough.
      rtc::Thread::Current()->ProcessMessages(100);
    } while (NumRtpPackets() > packets);
    return NumRtpPackets();
  }
  bool SendFrame() {
    if (video_capturer_2_) {
      video_capturer_2_->CaptureFrame();
    }
    return video_capturer_.get() &&
        video_capturer_->CaptureFrame();
  }
  bool WaitAndSendFrame(int wait_ms) {
    bool ret = rtc::Thread::Current()->ProcessMessages(wait_ms);
    ret &= SendFrame();
    return ret;
  }
  // Sends frames and waits for the decoder to be fully initialized.
  // Returns the number of frames that were sent.
  int WaitForDecoder() {
#if defined(HAVE_OPENMAX)
    // Send enough frames for the OpenMAX decoder to continue processing, and
    // return the number of frames sent.
    // Send frames for a full kTimeout's worth of 15fps video.
    int frame_count = 0;
    while (frame_count < static_cast<int>(kTimeout) / 66) {
      EXPECT_TRUE(WaitAndSendFrame(66));
      ++frame_count;
    }
    return frame_count;
#else
    return 0;
#endif
  }
  bool SendCustomVideoFrame(int w, int h) {
    if (!video_capturer_.get()) return false;
    return video_capturer_->CaptureCustomFrame(w, h, cricket::FOURCC_I420);
  }
  int NumRtpBytes() {
    return network_interface_.NumRtpBytes();
  }
  int NumRtpBytes(uint32 ssrc) {
    return network_interface_.NumRtpBytes(ssrc);
  }
  int NumRtpPackets() {
    return network_interface_.NumRtpPackets();
  }
  int NumRtpPackets(uint32 ssrc) {
    return network_interface_.NumRtpPackets(ssrc);
  }
  int NumSentSsrcs() {
    return network_interface_.NumSentSsrcs();
  }
  const rtc::Buffer* GetRtpPacket(int index) {
    return network_interface_.GetRtpPacket(index);
  }
  int NumRtcpPackets() {
    return network_interface_.NumRtcpPackets();
  }
  const rtc::Buffer* GetRtcpPacket(int index) {
    return network_interface_.GetRtcpPacket(index);
  }
  static int GetPayloadType(const rtc::Buffer* p) {
    int pt = -1;
    ParseRtpPacket(p, NULL, &pt, NULL, NULL, NULL, NULL);
    return pt;
  }
  static bool ParseRtpPacket(const rtc::Buffer* p, bool* x, int* pt,
                             int* seqnum, uint32* tstamp, uint32* ssrc,
                             std::string* payload) {
    rtc::ByteBuffer buf(p->data(), p->length());
    uint8 u08 = 0;
    uint16 u16 = 0;
    uint32 u32 = 0;

    // Read X and CC fields.
    if (!buf.ReadUInt8(&u08)) return false;
    bool extension = ((u08 & 0x10) != 0);
    uint8 cc = (u08 & 0x0F);
    if (x) *x = extension;

    // Read PT field.
    if (!buf.ReadUInt8(&u08)) return false;
    if (pt) *pt = (u08 & 0x7F);

    // Read Sequence Number field.
    if (!buf.ReadUInt16(&u16)) return false;
    if (seqnum) *seqnum = u16;

    // Read Timestamp field.
    if (!buf.ReadUInt32(&u32)) return false;
    if (tstamp) *tstamp = u32;

    // Read SSRC field.
    if (!buf.ReadUInt32(&u32)) return false;
    if (ssrc) *ssrc = u32;

    // Skip CSRCs.
    for (uint8 i = 0; i < cc; ++i) {
      if (!buf.ReadUInt32(&u32)) return false;
    }

    // Skip extension header.
    if (extension) {
      // Read Profile-specific extension header ID
      if (!buf.ReadUInt16(&u16)) return false;

      // Read Extension header length
      if (!buf.ReadUInt16(&u16)) return false;
      uint16 ext_header_len = u16;

      // Read Extension header
      for (uint16 i = 0; i < ext_header_len; ++i) {
        if (!buf.ReadUInt32(&u32)) return false;
      }
    }

    if (payload) {
      return buf.ReadString(payload, buf.Length());
    }
    return true;
  }

  // Parse all RTCP packet, from start_index to stop_index, and count how many
  // FIR (PT=206 and FMT=4 according to RFC 5104). If successful, set the count
  // and return true.
  bool CountRtcpFir(int start_index, int stop_index, int* fir_count) {
    int count = 0;
    for (int i = start_index; i < stop_index; ++i) {
      rtc::scoped_ptr<const rtc::Buffer> p(GetRtcpPacket(i));
      rtc::ByteBuffer buf(p->data(), p->length());
      size_t total_len = 0;
      // The packet may be a compound RTCP packet.
      while (total_len < p->length()) {
        // Read FMT, type and length.
        uint8 fmt = 0;
        uint8 type = 0;
        uint16 length = 0;
        if (!buf.ReadUInt8(&fmt)) return false;
        fmt &= 0x1F;
        if (!buf.ReadUInt8(&type)) return false;
        if (!buf.ReadUInt16(&length)) return false;
        buf.Consume(length * 4);  // Skip RTCP data.
        total_len += (length + 1) * 4;
        if ((192 == type) || ((206 == type) && (4 == fmt))) {
          ++count;
        }
      }
    }

    if (fir_count) {
      *fir_count = count;
    }
    return true;
  }

  void OnVideoChannelError(uint32 ssrc,
                           cricket::VideoMediaChannel::Error error) {
    media_error_ = error;
  }

  // Test that SetSend works.
  void SetSend() {
    EXPECT_FALSE(channel_->sending());
    EXPECT_TRUE(channel_->SetCapturer(kSsrc, video_capturer_.get()));
    EXPECT_TRUE(SetOneCodec(DefaultCodec()));
    EXPECT_FALSE(channel_->sending());
    EXPECT_TRUE(SetSend(true));
    EXPECT_TRUE(channel_->sending());
    EXPECT_TRUE(SendFrame());
    EXPECT_TRUE_WAIT(NumRtpPackets() > 0, kTimeout);
    EXPECT_TRUE(SetSend(false));
    EXPECT_FALSE(channel_->sending());
  }
  // Test that SetSend fails without codecs being set.
  void SetSendWithoutCodecs() {
    EXPECT_FALSE(channel_->sending());
    EXPECT_FALSE(SetSend(true));
    EXPECT_FALSE(channel_->sending());
  }
  // Test that we properly set the send and recv buffer sizes by the time
  // SetSend is called.
  void SetSendSetsTransportBufferSizes() {
    EXPECT_TRUE(SetOneCodec(DefaultCodec()));
    EXPECT_TRUE(SetSend(true));
    // TODO(sriniv): Remove or re-enable this.
    // As part of b/8030474, send-buffer is size now controlled through
    // portallocator flags. Its not set by channels.
    // EXPECT_EQ(64 * 1024, network_interface_.sendbuf_size());
    EXPECT_EQ(64 * 1024, network_interface_.recvbuf_size());
  }
  // Tests that we can send frames and the right payload type is used.
  void Send(const cricket::VideoCodec& codec) {
    EXPECT_TRUE(SetOneCodec(codec));
    EXPECT_TRUE(SetSend(true));
    EXPECT_TRUE(SendFrame());
    EXPECT_TRUE_WAIT(NumRtpPackets() > 0, kTimeout);
    rtc::scoped_ptr<const rtc::Buffer> p(GetRtpPacket(0));
    EXPECT_EQ(codec.id, GetPayloadType(p.get()));
  }
  // Tests that we can send and receive frames.
  void SendAndReceive(const cricket::VideoCodec& codec) {
    EXPECT_TRUE(SetOneCodec(codec));
    EXPECT_TRUE(SetSend(true));
    EXPECT_TRUE(channel_->SetRender(true));
    EXPECT_TRUE(channel_->SetRenderer(kDefaultReceiveSsrc, &renderer_));
    EXPECT_EQ(0, renderer_.num_rendered_frames());
    EXPECT_TRUE(SendFrame());
    EXPECT_FRAME_WAIT(1, codec.width, codec.height, kTimeout);
    rtc::scoped_ptr<const rtc::Buffer> p(GetRtpPacket(0));
    EXPECT_EQ(codec.id, GetPayloadType(p.get()));
  }
  // Tests that we only get a VideoRenderer::SetSize() callback when needed.
  void SendManyResizeOnce() {
    cricket::VideoCodec codec(DefaultCodec());
    EXPECT_TRUE(SetOneCodec(codec));
    EXPECT_TRUE(SetSend(true));
    EXPECT_TRUE(channel_->SetRender(true));
    EXPECT_TRUE(channel_->SetRenderer(kDefaultReceiveSsrc, &renderer_));
    EXPECT_EQ(0, renderer_.num_rendered_frames());
    EXPECT_TRUE(WaitAndSendFrame(30));
    EXPECT_FRAME_WAIT(1, codec.width, codec.height, kTimeout);
    EXPECT_TRUE(WaitAndSendFrame(30));
    EXPECT_FRAME_WAIT(2, codec.width, codec.height, kTimeout);
    rtc::scoped_ptr<const rtc::Buffer> p(GetRtpPacket(0));
    EXPECT_EQ(codec.id, GetPayloadType(p.get()));
    EXPECT_EQ(1, renderer_.num_set_sizes());

    codec.width /= 2;
    codec.height /= 2;
    EXPECT_TRUE(SetOneCodec(codec));
    EXPECT_TRUE(WaitAndSendFrame(30));
    EXPECT_FRAME_WAIT(3, codec.width, codec.height, kTimeout);
    EXPECT_EQ(2, renderer_.num_set_sizes());
  }
  void SendReceiveManyAndGetStats(const cricket::VideoCodec& codec,
                                  int duration_sec, int fps) {
    EXPECT_TRUE(SetOneCodec(codec));
    EXPECT_TRUE(SetSend(true));
    EXPECT_TRUE(channel_->SetRender(true));
    EXPECT_TRUE(channel_->SetRenderer(kDefaultReceiveSsrc, &renderer_));
    EXPECT_EQ(0, renderer_.num_rendered_frames());
    for (int i = 0; i < duration_sec; ++i) {
      for (int frame = 1; frame <= fps; ++frame) {
        EXPECT_TRUE(WaitAndSendFrame(1000 / fps));
        EXPECT_FRAME_WAIT(frame + i * fps, codec.width, codec.height, kTimeout);
      }
      cricket::VideoMediaInfo info;
      EXPECT_TRUE(channel_->GetStats(cricket::StatsOptions(), &info));
      // For webrtc, |framerate_sent| and |framerate_rcvd| depend on periodic
      // callbacks (1 sec).
      // Received |fraction_lost| and |packets_lost| are from sent RTCP packet.
      // One sent packet needed (sent about once per second).
      // |framerate_input|, |framerate_decoded| and |framerate_output| are using
      // RateTracker. RateTracker needs to be called twice (with >1 second in
      // b/w calls) before a framerate is calculated.
      // Therefore insert frames (and call GetStats each sec) for a few seconds
      // before testing stats.
    }
    rtc::scoped_ptr<const rtc::Buffer> p(GetRtpPacket(0));
    EXPECT_EQ(codec.id, GetPayloadType(p.get()));
  }

  // Test that stats work properly for a 1-1 call.
  void GetStats() {
    const int kDurationSec = 3;
    const int kFps = 10;
    SendReceiveManyAndGetStats(DefaultCodec(), kDurationSec, kFps);

    cricket::VideoMediaInfo info;
    EXPECT_TRUE(channel_->GetStats(cricket::StatsOptions(), &info));

    ASSERT_EQ(1U, info.senders.size());
    // TODO(whyuan): bytes_sent and bytes_rcvd are different. Are both payload?
    // For webrtc, bytes_sent does not include the RTP header length.
    EXPECT_GT(info.senders[0].bytes_sent, 0);
    EXPECT_EQ(NumRtpPackets(), info.senders[0].packets_sent);
    EXPECT_EQ(0.0, info.senders[0].fraction_lost);
    EXPECT_EQ(0, info.senders[0].firs_rcvd);
    EXPECT_EQ(0, info.senders[0].plis_rcvd);
    EXPECT_EQ(0, info.senders[0].nacks_rcvd);
    EXPECT_EQ(DefaultCodec().width, info.senders[0].send_frame_width);
    EXPECT_EQ(DefaultCodec().height, info.senders[0].send_frame_height);
    EXPECT_GT(info.senders[0].framerate_input, 0);
    EXPECT_GT(info.senders[0].framerate_sent, 0);

    ASSERT_EQ(1U, info.receivers.size());
    EXPECT_EQ(1U, info.senders[0].ssrcs().size());
    EXPECT_EQ(1U, info.receivers[0].ssrcs().size());
    EXPECT_EQ(info.senders[0].ssrcs()[0], info.receivers[0].ssrcs()[0]);
    EXPECT_EQ(NumRtpBytes(), info.receivers[0].bytes_rcvd);
    EXPECT_EQ(NumRtpPackets(), info.receivers[0].packets_rcvd);
    EXPECT_EQ(0.0, info.receivers[0].fraction_lost);
    EXPECT_EQ(0, info.receivers[0].packets_lost);
    // TODO(asapersson): Not set for webrtc. Handle missing stats.
    // EXPECT_EQ(0, info.receivers[0].packets_concealed);
    EXPECT_EQ(0, info.receivers[0].firs_sent);
    EXPECT_EQ(0, info.receivers[0].plis_sent);
    EXPECT_EQ(0, info.receivers[0].nacks_sent);
    EXPECT_EQ(DefaultCodec().width, info.receivers[0].frame_width);
    EXPECT_EQ(DefaultCodec().height, info.receivers[0].frame_height);
    EXPECT_GT(info.receivers[0].framerate_rcvd, 0);
    EXPECT_GT(info.receivers[0].framerate_decoded, 0);
    EXPECT_GT(info.receivers[0].framerate_output, 0);
  }
  // Test that stats work properly for a conf call with multiple recv streams.
  void GetStatsMultipleRecvStreams() {
    cricket::FakeVideoRenderer renderer1, renderer2;
    EXPECT_TRUE(SetOneCodec(DefaultCodec()));
    cricket::VideoOptions vmo;
    vmo.conference_mode.Set(true);
    EXPECT_TRUE(channel_->SetOptions(vmo));
    EXPECT_TRUE(SetSend(true));
    EXPECT_TRUE(channel_->AddRecvStream(
        cricket::StreamParams::CreateLegacy(1)));
    EXPECT_TRUE(channel_->AddRecvStream(
        cricket::StreamParams::CreateLegacy(2)));
    EXPECT_TRUE(channel_->SetRenderer(1, &renderer1));
    EXPECT_TRUE(channel_->SetRenderer(2, &renderer2));
    EXPECT_TRUE(channel_->SetRender(true));
    EXPECT_EQ(0, renderer1.num_rendered_frames());
    EXPECT_EQ(0, renderer2.num_rendered_frames());
    std::vector<uint32> ssrcs;
    ssrcs.push_back(1);
    ssrcs.push_back(2);
    network_interface_.SetConferenceMode(true, ssrcs);
    EXPECT_TRUE(SendFrame());
    EXPECT_FRAME_ON_RENDERER_WAIT(
        renderer1, 1, DefaultCodec().width, DefaultCodec().height, kTimeout);
    EXPECT_FRAME_ON_RENDERER_WAIT(
        renderer2, 1, DefaultCodec().width, DefaultCodec().height, kTimeout);
    cricket::VideoMediaInfo info;
    EXPECT_TRUE(channel_->GetStats(cricket::StatsOptions(), &info));

    ASSERT_EQ(1U, info.senders.size());
    // TODO(whyuan): bytes_sent and bytes_rcvd are different. Are both payload?
    // For webrtc, bytes_sent does not include the RTP header length.
    EXPECT_GT(info.senders[0].bytes_sent, 0);
    EXPECT_EQ(NumRtpPackets(), info.senders[0].packets_sent);
    EXPECT_EQ(DefaultCodec().width, info.senders[0].send_frame_width);
    EXPECT_EQ(DefaultCodec().height, info.senders[0].send_frame_height);

    ASSERT_EQ(2U, info.receivers.size());
    for (size_t i = 0; i < info.receivers.size(); ++i) {
      EXPECT_EQ(1U, info.receivers[i].ssrcs().size());
      EXPECT_EQ(i + 1, info.receivers[i].ssrcs()[0]);
      EXPECT_EQ(NumRtpBytes(), info.receivers[i].bytes_rcvd);
      EXPECT_EQ(NumRtpPackets(), info.receivers[i].packets_rcvd);
      EXPECT_EQ(DefaultCodec().width, info.receivers[i].frame_width);
      EXPECT_EQ(DefaultCodec().height, info.receivers[i].frame_height);
    }
  }
  // Test that stats work properly for a conf call with multiple send streams.
  void GetStatsMultipleSendStreams() {
    // Normal setup; note that we set the SSRC explicitly to ensure that
    // it will come first in the senders map.
    EXPECT_TRUE(SetOneCodec(DefaultCodec()));
    cricket::VideoOptions vmo;
    vmo.conference_mode.Set(true);
    EXPECT_TRUE(channel_->SetOptions(vmo));
    EXPECT_TRUE(channel_->AddRecvStream(
        cricket::StreamParams::CreateLegacy(kSsrc)));
    EXPECT_TRUE(channel_->SetRenderer(kSsrc, &renderer_));
    channel_->UpdateAspectRatio(640, 400);
    EXPECT_TRUE(SetSend(true));
    EXPECT_TRUE(channel_->SetRender(true));
    EXPECT_TRUE(SendFrame());
    EXPECT_TRUE_WAIT(NumRtpPackets() > 0, kTimeout);
    EXPECT_FRAME_WAIT(1, DefaultCodec().width, DefaultCodec().height, kTimeout);

    // Add an additional capturer, and hook up a renderer to receive it.
    cricket::FakeVideoRenderer renderer1;
    rtc::scoped_ptr<cricket::FakeVideoCapturer> capturer(
        CreateFakeVideoCapturer());
    capturer->SetScreencast(true);
    const int kTestWidth = 160;
    const int kTestHeight = 120;
    cricket::VideoFormat format(kTestWidth, kTestHeight,
                                cricket::VideoFormat::FpsToInterval(5),
                                cricket::FOURCC_I420);
    EXPECT_EQ(cricket::CS_RUNNING, capturer->Start(format));
    EXPECT_TRUE(channel_->AddSendStream(
        cricket::StreamParams::CreateLegacy(5678)));
    EXPECT_TRUE(channel_->SetCapturer(5678, capturer.get()));
    EXPECT_TRUE(channel_->AddRecvStream(
        cricket::StreamParams::CreateLegacy(5678)));
    EXPECT_TRUE(channel_->SetRenderer(5678, &renderer1));
    EXPECT_TRUE(capturer->CaptureCustomFrame(
        kTestWidth, kTestHeight, cricket::FOURCC_I420));
    EXPECT_FRAME_ON_RENDERER_WAIT(
        renderer1, 1, kTestWidth, kTestHeight, kTimeout);

    // Get stats, and make sure they are correct for two senders.
    cricket::VideoMediaInfo info;
    EXPECT_TRUE(channel_->GetStats(cricket::StatsOptions(), &info));
    ASSERT_EQ(2U, info.senders.size());
    EXPECT_EQ(NumRtpPackets(),
        info.senders[0].packets_sent + info.senders[1].packets_sent);
    EXPECT_EQ(1U, info.senders[0].ssrcs().size());
    EXPECT_EQ(1234U, info.senders[0].ssrcs()[0]);
    EXPECT_EQ(DefaultCodec().width, info.senders[0].send_frame_width);
    EXPECT_EQ(DefaultCodec().height, info.senders[0].send_frame_height);
    EXPECT_EQ(1U, info.senders[1].ssrcs().size());
    EXPECT_EQ(5678U, info.senders[1].ssrcs()[0]);
    EXPECT_EQ(kTestWidth, info.senders[1].send_frame_width);
    EXPECT_EQ(kTestHeight, info.senders[1].send_frame_height);
    // The capturer must be unregistered here as it runs out of it's scope next.
    EXPECT_TRUE(channel_->SetCapturer(5678, NULL));
  }

  // Test that we can set the bandwidth.
  void SetSendBandwidth() {
    EXPECT_TRUE(channel_->SetStartSendBandwidth(64 * 1024));
    EXPECT_TRUE(channel_->SetMaxSendBandwidth(-1));  // <= 0 means unlimited.
    EXPECT_TRUE(channel_->SetMaxSendBandwidth(128 * 1024));
  }
  // Test that we can set the SSRC for the default send source.
  void SetSendSsrc() {
    EXPECT_TRUE(SetDefaultCodec());
    EXPECT_TRUE(SetSendStreamFormat(kSsrc, DefaultCodec()));
    EXPECT_TRUE(SetSend(true));
    EXPECT_TRUE(SendFrame());
    EXPECT_TRUE_WAIT(NumRtpPackets() > 0, kTimeout);
    uint32 ssrc = 0;
    rtc::scoped_ptr<const rtc::Buffer> p(GetRtpPacket(0));
    ParseRtpPacket(p.get(), NULL, NULL, NULL, NULL, &ssrc, NULL);
    EXPECT_EQ(kSsrc, ssrc);
    EXPECT_EQ(NumRtpPackets(), NumRtpPackets(ssrc));
    EXPECT_EQ(NumRtpBytes(), NumRtpBytes(ssrc));
    EXPECT_EQ(1, NumSentSsrcs());
    EXPECT_EQ(0, NumRtpPackets(kSsrc - 1));
    EXPECT_EQ(0, NumRtpBytes(kSsrc - 1));
  }
  // Test that we can set the SSRC even after codecs are set.
  void SetSendSsrcAfterSetCodecs() {
    // Remove stream added in Setup.
    EXPECT_TRUE(channel_->RemoveSendStream(kSsrc));
    EXPECT_TRUE(SetDefaultCodec());
    EXPECT_TRUE(channel_->AddSendStream(
        cricket::StreamParams::CreateLegacy(999)));
    EXPECT_TRUE(channel_->SetCapturer(999u, video_capturer_.get()));
    EXPECT_TRUE(SetSendStreamFormat(999u, DefaultCodec()));
    EXPECT_TRUE(SetSend(true));
    EXPECT_TRUE(WaitAndSendFrame(0));
    EXPECT_TRUE_WAIT(NumRtpPackets() > 0, kTimeout);
    uint32 ssrc = 0;
    rtc::scoped_ptr<const rtc::Buffer> p(GetRtpPacket(0));
    ParseRtpPacket(p.get(), NULL, NULL, NULL, NULL, &ssrc, NULL);
    EXPECT_EQ(999u, ssrc);
    EXPECT_EQ(NumRtpPackets(), NumRtpPackets(ssrc));
    EXPECT_EQ(NumRtpBytes(), NumRtpBytes(ssrc));
    EXPECT_EQ(1, NumSentSsrcs());
    EXPECT_EQ(0, NumRtpPackets(kSsrc));
    EXPECT_EQ(0, NumRtpBytes(kSsrc));
  }
  // Test that we can set the default video renderer before and after
  // media is received.
  void SetRenderer() {
    uint8 data1[] = {
        0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
    };

    rtc::Buffer packet1(data1, sizeof(data1));
    rtc::SetBE32(packet1.data() + 8, kSsrc);
    channel_->SetRenderer(kDefaultReceiveSsrc, NULL);
    EXPECT_TRUE(SetDefaultCodec());
    EXPECT_TRUE(SetSend(true));
    EXPECT_TRUE(channel_->SetRender(true));
    EXPECT_EQ(0, renderer_.num_rendered_frames());
    channel_->OnPacketReceived(&packet1, rtc::PacketTime());
    EXPECT_TRUE(channel_->SetRenderer(kDefaultReceiveSsrc, &renderer_));
    EXPECT_TRUE(SendFrame());
    EXPECT_FRAME_WAIT(1, DefaultCodec().width, DefaultCodec().height, kTimeout);
  }

  // Tests empty StreamParams is rejected.
  void RejectEmptyStreamParams() {
    // Remove the send stream that was added during Setup.
    EXPECT_TRUE(channel_->RemoveSendStream(kSsrc));

    cricket::StreamParams empty;
    EXPECT_FALSE(channel_->AddSendStream(empty));
    EXPECT_TRUE(channel_->AddSendStream(
        cricket::StreamParams::CreateLegacy(789u)));
  }

  // Tests setting up and configuring a send stream.
  void AddRemoveSendStreams() {
    EXPECT_TRUE(SetOneCodec(DefaultCodec()));
    EXPECT_TRUE(SetSend(true));
    EXPECT_TRUE(channel_->SetRender(true));
    EXPECT_TRUE(channel_->SetRenderer(kDefaultReceiveSsrc, &renderer_));
    EXPECT_TRUE(SendFrame());
    EXPECT_FRAME_WAIT(1, DefaultCodec().width, DefaultCodec().height, kTimeout);
    EXPECT_GE(2, NumRtpPackets());
    uint32 ssrc = 0;
    size_t last_packet = NumRtpPackets() - 1;
    rtc::scoped_ptr<const rtc::Buffer>
        p(GetRtpPacket(static_cast<int>(last_packet)));
    ParseRtpPacket(p.get(), NULL, NULL, NULL, NULL, &ssrc, NULL);
    EXPECT_EQ(kSsrc, ssrc);

    // Remove the send stream that was added during Setup.
    EXPECT_TRUE(channel_->RemoveSendStream(kSsrc));
    int rtp_packets = NumRtpPackets();

    EXPECT_TRUE(channel_->AddSendStream(
        cricket::StreamParams::CreateLegacy(789u)));
    EXPECT_TRUE(channel_->SetCapturer(789u, video_capturer_.get()));
    EXPECT_EQ(rtp_packets, NumRtpPackets());
    // Wait 30ms to guarantee the engine does not drop the frame.
    EXPECT_TRUE(WaitAndSendFrame(30));
    EXPECT_TRUE_WAIT(NumRtpPackets() > rtp_packets, kTimeout);

    last_packet = NumRtpPackets() - 1;
    p.reset(GetRtpPacket(static_cast<int>(last_packet)));
    ParseRtpPacket(p.get(), NULL, NULL, NULL, NULL, &ssrc, NULL);
    EXPECT_EQ(789u, ssrc);
  }

  // Tests adding streams already exists returns false.
  void AddRecvStreamsAlreadyExist() {
    cricket::VideoOptions vmo;
    vmo.conference_mode.Set(true);
    EXPECT_TRUE(channel_->SetOptions(vmo));

    EXPECT_FALSE(channel_->AddRecvStream(
        cricket::StreamParams::CreateLegacy(0)));

    EXPECT_TRUE(channel_->AddRecvStream(
        cricket::StreamParams::CreateLegacy(1)));
    EXPECT_FALSE(channel_->AddRecvStream(
        cricket::StreamParams::CreateLegacy(1)));

    EXPECT_TRUE(channel_->RemoveRecvStream(1));
    EXPECT_FALSE(channel_->AddRecvStream(
        cricket::StreamParams::CreateLegacy(0)));
    EXPECT_TRUE(channel_->AddRecvStream(
        cricket::StreamParams::CreateLegacy(1)));
  }

  // Tests setting up and configuring multiple incoming streams.
  void AddRemoveRecvStreams() {
    cricket::FakeVideoRenderer renderer1, renderer2;
    cricket::VideoOptions vmo;
    vmo.conference_mode.Set(true);
    EXPECT_TRUE(channel_->SetOptions(vmo));
    // Ensure we can't set the renderer on a non-existent stream.
    EXPECT_FALSE(channel_->SetRenderer(1, &renderer1));
    EXPECT_FALSE(channel_->SetRenderer(2, &renderer2));
    cricket::VideoRenderer* renderer;
    EXPECT_FALSE(channel_->GetRenderer(1, &renderer));
    EXPECT_FALSE(channel_->GetRenderer(2, &renderer));

    // Ensure we can add streams.
    EXPECT_TRUE(channel_->AddRecvStream(
        cricket::StreamParams::CreateLegacy(1)));
    EXPECT_TRUE(channel_->AddRecvStream(
        cricket::StreamParams::CreateLegacy(2)));
    EXPECT_TRUE(channel_->GetRenderer(1, &renderer));
    EXPECT_TRUE(renderer == NULL);
    EXPECT_TRUE(channel_->GetRenderer(2, &renderer));
    EXPECT_TRUE(NULL == renderer);

    // Ensure we can now set the renderers.
    EXPECT_TRUE(channel_->SetRenderer(1, &renderer1));
    EXPECT_TRUE(channel_->SetRenderer(2, &renderer2));
    EXPECT_TRUE(channel_->GetRenderer(1, &renderer));
    EXPECT_TRUE(&renderer1 == renderer);
    EXPECT_TRUE(channel_->GetRenderer(2, &renderer));
    EXPECT_TRUE(&renderer2 == renderer);

    // Ensure we can change the renderers if needed.
    EXPECT_TRUE(channel_->SetRenderer(1, &renderer2));
    EXPECT_TRUE(channel_->SetRenderer(2, &renderer1));
    EXPECT_TRUE(channel_->GetRenderer(1, &renderer));
    EXPECT_TRUE(&renderer2 == renderer);
    EXPECT_TRUE(channel_->GetRenderer(2, &renderer));
    EXPECT_TRUE(&renderer1 == renderer);

    EXPECT_TRUE(channel_->RemoveRecvStream(2));
    EXPECT_TRUE(channel_->RemoveRecvStream(1));
    EXPECT_FALSE(channel_->GetRenderer(1, &renderer));
    EXPECT_FALSE(channel_->GetRenderer(2, &renderer));
  }

  // Tests setting up and configuring multiple incoming streams in a
  // non-conference call.
  void AddRemoveRecvStreamsNoConference() {
    cricket::FakeVideoRenderer renderer1, renderer2;
    // Ensure we can't set the renderer on a non-existent stream.
    EXPECT_FALSE(channel_->SetRenderer(1, &renderer1));
    EXPECT_FALSE(channel_->SetRenderer(2, &renderer2));
    cricket::VideoRenderer* renderer;
    EXPECT_FALSE(channel_->GetRenderer(1, &renderer));
    EXPECT_FALSE(channel_->GetRenderer(2, &renderer));

    // Ensure we can add streams.
    EXPECT_TRUE(channel_->AddRecvStream(
        cricket::StreamParams::CreateLegacy(1)));
    EXPECT_TRUE(channel_->AddRecvStream(
        cricket::StreamParams::CreateLegacy(2)));
    EXPECT_TRUE(channel_->GetRenderer(1, &renderer));
    // Verify the first AddRecvStream hook up to the default renderer.
    EXPECT_TRUE(renderer == NULL);
    EXPECT_TRUE(channel_->GetRenderer(2, &renderer));
    EXPECT_TRUE(NULL == renderer);

    // Ensure we can now set the renderers.
    EXPECT_TRUE(channel_->SetRenderer(1, &renderer1));
    EXPECT_TRUE(channel_->SetRenderer(2, &renderer2));
    EXPECT_TRUE(channel_->GetRenderer(1, &renderer));
    EXPECT_TRUE(&renderer1 == renderer);
    EXPECT_TRUE(channel_->GetRenderer(2, &renderer));
    EXPECT_TRUE(&renderer2 == renderer);

    // Ensure we can change the renderers if needed.
    EXPECT_TRUE(channel_->SetRenderer(1, &renderer2));
    EXPECT_TRUE(channel_->SetRenderer(2, &renderer1));
    EXPECT_TRUE(channel_->GetRenderer(1, &renderer));
    EXPECT_TRUE(&renderer2 == renderer);
    EXPECT_TRUE(channel_->GetRenderer(2, &renderer));
    EXPECT_TRUE(&renderer1 == renderer);

    EXPECT_TRUE(channel_->RemoveRecvStream(2));
    EXPECT_TRUE(channel_->RemoveRecvStream(1));
    EXPECT_FALSE(channel_->GetRenderer(1, &renderer));
    EXPECT_FALSE(channel_->GetRenderer(2, &renderer));
  }

  // Test that no frames are rendered after the receive stream have been
  // removed.
  void AddRemoveRecvStreamAndRender() {
    cricket::FakeVideoRenderer renderer1;
    EXPECT_TRUE(SetDefaultCodec());
    EXPECT_TRUE(SetSend(true));
    EXPECT_TRUE(channel_->SetRender(true));
    EXPECT_TRUE(channel_->AddRecvStream(
        cricket::StreamParams::CreateLegacy(kSsrc)));
    EXPECT_TRUE(channel_->SetRenderer(kSsrc, &renderer1));

    EXPECT_TRUE(SendFrame());
    EXPECT_FRAME_ON_RENDERER_WAIT(
        renderer1, 1, DefaultCodec().width, DefaultCodec().height, kTimeout);
    EXPECT_TRUE(channel_->RemoveRecvStream(kSsrc));
    // Send three more frames. This is to avoid that the test might be flaky
    // due to frame dropping.
    for (size_t i = 0; i < 3; ++i)
      EXPECT_TRUE(WaitAndSendFrame(100));

    // Test that no more frames have been rendered.
    EXPECT_EQ(1, renderer1.num_rendered_frames());

    // Re-add the stream again and make sure it renders.
    EXPECT_TRUE(channel_->AddRecvStream(
        cricket::StreamParams::CreateLegacy(kSsrc)));
    // Force the next frame to be a key frame to make the receiving
    // decoder happy.
    EXPECT_TRUE(channel_->SendIntraFrame());

    EXPECT_TRUE(channel_->SetRenderer(kSsrc, &renderer1));
    EXPECT_TRUE(SendFrame());
    // Because the default channel is used, RemoveRecvStream above is not going
    // to delete the channel. As a result the engine will continue to receive
    // and decode the 3 frames sent above. So it is possible we will receive
    // some (e.g. 1) of these 3 frames after the renderer is set again.
    EXPECT_GT_FRAME_ON_RENDERER_WAIT(
        renderer1, 2, DefaultCodec().width, DefaultCodec().height, kTimeout);
    // Detach |renderer1| before exit as there might be frames come late.
    EXPECT_TRUE(channel_->SetRenderer(kSsrc, NULL));
  }

  // Tests the behavior of incoming streams in a conference scenario.
  void SimulateConference() {
    cricket::FakeVideoRenderer renderer1, renderer2;
    EXPECT_TRUE(SetDefaultCodec());
    cricket::VideoOptions vmo;
    vmo.conference_mode.Set(true);
    EXPECT_TRUE(channel_->SetOptions(vmo));
    EXPECT_TRUE(SetSend(true));
    EXPECT_TRUE(channel_->SetRender(true));
    EXPECT_TRUE(channel_->AddRecvStream(
        cricket::StreamParams::CreateLegacy(1)));
    EXPECT_TRUE(channel_->AddRecvStream(
        cricket::StreamParams::CreateLegacy(2)));
    EXPECT_TRUE(channel_->SetRenderer(1, &renderer1));
    EXPECT_TRUE(channel_->SetRenderer(2, &renderer2));
    EXPECT_EQ(0, renderer1.num_rendered_frames());
    EXPECT_EQ(0, renderer2.num_rendered_frames());
    std::vector<uint32> ssrcs;
    ssrcs.push_back(1);
    ssrcs.push_back(2);
    network_interface_.SetConferenceMode(true, ssrcs);
    EXPECT_TRUE(SendFrame());
    EXPECT_FRAME_ON_RENDERER_WAIT(
        renderer1, 1, DefaultCodec().width, DefaultCodec().height, kTimeout);
    EXPECT_FRAME_ON_RENDERER_WAIT(
        renderer2, 1, DefaultCodec().width, DefaultCodec().height, kTimeout);

    rtc::scoped_ptr<const rtc::Buffer> p(GetRtpPacket(0));
    EXPECT_EQ(DefaultCodec().id, GetPayloadType(p.get()));
    EXPECT_EQ(DefaultCodec().width, renderer1.width());
    EXPECT_EQ(DefaultCodec().height, renderer1.height());
    EXPECT_EQ(DefaultCodec().width, renderer2.width());
    EXPECT_EQ(DefaultCodec().height, renderer2.height());
    EXPECT_TRUE(channel_->RemoveRecvStream(2));
    EXPECT_TRUE(channel_->RemoveRecvStream(1));
  }

  // Tests that we can add and remove capturers and frames are sent out properly
  void AddRemoveCapturer() {
    cricket::VideoCodec codec = DefaultCodec();
    codec.width = 320;
    codec.height = 240;
    const int time_between_send = TimeBetweenSend(codec);
    EXPECT_TRUE(SetOneCodec(codec));
    EXPECT_TRUE(SetSend(true));
    EXPECT_TRUE(channel_->SetRender(true));
    EXPECT_TRUE(channel_->SetRenderer(kDefaultReceiveSsrc, &renderer_));
    EXPECT_EQ(0, renderer_.num_rendered_frames());
    EXPECT_TRUE(SendFrame());
    EXPECT_FRAME_WAIT(1, codec.width, codec.height, kTimeout);
    rtc::scoped_ptr<cricket::FakeVideoCapturer> capturer(
        CreateFakeVideoCapturer());
    capturer->SetScreencast(true);
    cricket::VideoFormat format(480, 360,
                                cricket::VideoFormat::FpsToInterval(30),
                                cricket::FOURCC_I420);
    EXPECT_EQ(cricket::CS_RUNNING, capturer->Start(format));
    // All capturers start generating frames with the same timestamp. ViE does
    // not allow the same timestamp to be used. Capture one frame before
    // associating the capturer with the channel.
    EXPECT_TRUE(capturer->CaptureCustomFrame(format.width, format.height,
                                             cricket::FOURCC_I420));

    int captured_frames = 1;
    for (int iterations = 0; iterations < 2; ++iterations) {
      EXPECT_TRUE(channel_->SetCapturer(kSsrc, capturer.get()));
      rtc::Thread::Current()->ProcessMessages(time_between_send);
      EXPECT_TRUE(capturer->CaptureCustomFrame(format.width, format.height,
                                               cricket::FOURCC_I420));
      ++captured_frames;
      // Wait until frame of right size is captured.
      EXPECT_TRUE_WAIT(renderer_.num_rendered_frames() >= captured_frames &&
                       format.width == renderer_.width() &&
                       format.height == renderer_.height() &&
                       !renderer_.black_frame(), kTimeout);
      EXPECT_GE(renderer_.num_rendered_frames(), captured_frames);
      EXPECT_EQ(format.width, renderer_.width());
      EXPECT_EQ(format.height, renderer_.height());
      captured_frames = renderer_.num_rendered_frames() + 1;
      EXPECT_FALSE(renderer_.black_frame());
      EXPECT_TRUE(channel_->SetCapturer(kSsrc, NULL));
      // Make sure a black frame is generated within the specified timeout.
      // The black frame should be the resolution of the send codec.
      EXPECT_TRUE_WAIT(renderer_.num_rendered_frames() >= captured_frames &&
                       codec.width == renderer_.width() &&
                       codec.height == renderer_.height() &&
                       renderer_.black_frame(), kTimeout);
      EXPECT_GE(renderer_.num_rendered_frames(), captured_frames);
      EXPECT_EQ(codec.width, renderer_.width());
      EXPECT_EQ(codec.height, renderer_.height());
      EXPECT_TRUE(renderer_.black_frame());

      // The black frame has the same timestamp as the next frame since it's
      // timestamp is set to the last frame's timestamp + interval. WebRTC will
      // not render a frame with the same timestamp so capture another frame
      // with the frame capturer to increment the next frame's timestamp.
      EXPECT_TRUE(capturer->CaptureCustomFrame(format.width, format.height,
                                               cricket::FOURCC_I420));
    }
  }

  // Tests that if RemoveCapturer is called without a capturer ever being
  // added, the plugin shouldn't crash (and no black frame should be sent).
  void RemoveCapturerWithoutAdd() {
    EXPECT_TRUE(SetOneCodec(DefaultCodec()));
    EXPECT_TRUE(SetSend(true));
    EXPECT_TRUE(channel_->SetRender(true));
    EXPECT_TRUE(channel_->SetRenderer(kDefaultReceiveSsrc, &renderer_));
    EXPECT_EQ(0, renderer_.num_rendered_frames());
    EXPECT_TRUE(SendFrame());
    EXPECT_FRAME_WAIT(1, 640, 400, kTimeout);
    // Remove the capturer.
    EXPECT_TRUE(channel_->SetCapturer(kSsrc, NULL));
    // Wait for one black frame for removing the capturer.
    EXPECT_FRAME_WAIT(2, 640, 400, kTimeout);

    // No capturer was added, so this RemoveCapturer should
    // fail.
    EXPECT_FALSE(channel_->SetCapturer(kSsrc, NULL));
    rtc::Thread::Current()->ProcessMessages(300);
    // Verify no more frames were sent.
    EXPECT_EQ(2, renderer_.num_rendered_frames());
  }

  // Tests that we can add and remove capturer as unique sources.
  void AddRemoveCapturerMultipleSources() {
    // WebRTC implementation will drop frames if pushed to quickly. Wait the
    // interval time to avoid that.
    // WebRTC implementation will drop frames if pushed to quickly. Wait the
    // interval time to avoid that.
    // Set up the stream associated with the engine.
    EXPECT_TRUE(channel_->AddRecvStream(
        cricket::StreamParams::CreateLegacy(kSsrc)));
    EXPECT_TRUE(channel_->SetRenderer(kSsrc, &renderer_));
    cricket::VideoFormat capture_format;  // default format
    capture_format.interval = cricket::VideoFormat::FpsToInterval(30);
    // Set up additional stream 1.
    cricket::FakeVideoRenderer renderer1;
    EXPECT_FALSE(channel_->SetRenderer(1, &renderer1));
    EXPECT_TRUE(channel_->AddRecvStream(
        cricket::StreamParams::CreateLegacy(1)));
    EXPECT_TRUE(channel_->SetRenderer(1, &renderer1));
    EXPECT_TRUE(channel_->AddSendStream(
        cricket::StreamParams::CreateLegacy(1)));
    rtc::scoped_ptr<cricket::FakeVideoCapturer> capturer1(
        CreateFakeVideoCapturer());
    capturer1->SetScreencast(true);
    EXPECT_EQ(cricket::CS_RUNNING, capturer1->Start(capture_format));
    // Set up additional stream 2.
    cricket::FakeVideoRenderer renderer2;
    EXPECT_FALSE(channel_->SetRenderer(2, &renderer2));
    EXPECT_TRUE(channel_->AddRecvStream(
        cricket::StreamParams::CreateLegacy(2)));
    EXPECT_TRUE(channel_->SetRenderer(2, &renderer2));
    EXPECT_TRUE(channel_->AddSendStream(
        cricket::StreamParams::CreateLegacy(2)));
    rtc::scoped_ptr<cricket::FakeVideoCapturer> capturer2(
        CreateFakeVideoCapturer());
    capturer2->SetScreencast(true);
    EXPECT_EQ(cricket::CS_RUNNING, capturer2->Start(capture_format));
    // State for all the streams.
    EXPECT_TRUE(SetOneCodec(DefaultCodec()));
    // A limitation in the lmi implementation requires that SetCapturer() is
    // called after SetOneCodec().
    // TODO(hellner): this seems like an unnecessary constraint, fix it.
    EXPECT_TRUE(channel_->SetCapturer(1, capturer1.get()));
    EXPECT_TRUE(channel_->SetCapturer(2, capturer2.get()));
    EXPECT_TRUE(SetSend(true));
    EXPECT_TRUE(channel_->SetRender(true));
    // Test capturer associated with engine.
    const int kTestWidth = 160;
    const int kTestHeight = 120;
    EXPECT_TRUE(capturer1->CaptureCustomFrame(
        kTestWidth, kTestHeight, cricket::FOURCC_I420));
    EXPECT_FRAME_ON_RENDERER_WAIT(
        renderer1, 1, kTestWidth, kTestHeight, kTimeout);
    // Capture a frame with additional capturer2, frames should be received
    EXPECT_TRUE(capturer2->CaptureCustomFrame(
        kTestWidth, kTestHeight, cricket::FOURCC_I420));
    EXPECT_FRAME_ON_RENDERER_WAIT(
        renderer2, 1, kTestWidth, kTestHeight, kTimeout);
    // Successfully remove the capturer.
    EXPECT_TRUE(channel_->SetCapturer(kSsrc, NULL));
    // Fail to re-remove the capturer.
    EXPECT_FALSE(channel_->SetCapturer(kSsrc, NULL));
    // The capturers must be unregistered here as it runs out of it's scope
    // next.
    EXPECT_TRUE(channel_->SetCapturer(1, NULL));
    EXPECT_TRUE(channel_->SetCapturer(2, NULL));
  }

  void HighAspectHighHeightCapturer() {
    const int kWidth  = 80;
    const int kHeight = 10000;
    const int kScaledWidth = 20;
    const int kScaledHeight = 2500;

    cricket::VideoCodec codec(DefaultCodec());
    EXPECT_TRUE(SetOneCodec(codec));
    EXPECT_TRUE(SetSend(true));

    cricket::FakeVideoRenderer renderer;
    EXPECT_TRUE(channel_->AddRecvStream(
        cricket::StreamParams::CreateLegacy(kSsrc)));
    EXPECT_TRUE(channel_->SetRenderer(kSsrc, &renderer));
    EXPECT_TRUE(channel_->SetRender(true));
    EXPECT_EQ(0, renderer.num_rendered_frames());

    EXPECT_TRUE(SendFrame());
    EXPECT_GT_FRAME_ON_RENDERER_WAIT(
        renderer, 1, codec.width, codec.height, kTimeout);

    // Registering an external capturer is currently the same as screen casting
    // (update the test when this changes).
    rtc::scoped_ptr<cricket::FakeVideoCapturer> capturer(
        CreateFakeVideoCapturer());
    capturer->SetScreencast(true);
    const std::vector<cricket::VideoFormat>* formats =
        capturer->GetSupportedFormats();
    cricket::VideoFormat capture_format = (*formats)[0];
    EXPECT_EQ(cricket::CS_RUNNING, capturer->Start(capture_format));
    // Capture frame to not get same frame timestamps as previous capturer.
    capturer->CaptureFrame();
    EXPECT_TRUE(channel_->SetCapturer(kSsrc, capturer.get()));
    EXPECT_TRUE(rtc::Thread::Current()->ProcessMessages(30));
    EXPECT_TRUE(capturer->CaptureCustomFrame(kWidth, kHeight,
                                             cricket::FOURCC_ARGB));
    EXPECT_GT_FRAME_ON_RENDERER_WAIT(
        renderer, 2, kScaledWidth, kScaledHeight, kTimeout);
    EXPECT_TRUE(channel_->SetCapturer(kSsrc, NULL));
  }

  // Tests that we can adapt video resolution with 16:10 aspect ratio properly.
  void AdaptResolution16x10() {
    EXPECT_TRUE(channel_->SetRenderer(kDefaultReceiveSsrc, &renderer_));
    cricket::VideoCodec codec(DefaultCodec());
    codec.width = 640;
    codec.height = 400;
    SendAndReceive(codec);
    codec.width /= 2;
    codec.height /= 2;
    // Adapt the resolution.
    EXPECT_TRUE(SetOneCodec(codec));
    EXPECT_TRUE(WaitAndSendFrame(30));
    EXPECT_FRAME_WAIT(2, codec.width, codec.height, kTimeout);
  }
  // Tests that we can adapt video resolution with 4:3 aspect ratio properly.
  void AdaptResolution4x3() {
    EXPECT_TRUE(channel_->SetRenderer(kDefaultReceiveSsrc, &renderer_));
    cricket::VideoCodec codec(DefaultCodec());
    codec.width = 640;
    codec.height = 400;
    SendAndReceive(codec);
    codec.width /= 2;
    codec.height /= 2;
    // Adapt the resolution.
    EXPECT_TRUE(SetOneCodec(codec));
    EXPECT_TRUE(WaitAndSendFrame(30));
    EXPECT_FRAME_WAIT(2, codec.width, codec.height, kTimeout);
  }
  // Tests that we can drop all frames properly.
  void AdaptDropAllFrames() {
    // Set the channel codec's resolution to 0, which will require the adapter
    // to drop all frames.
    cricket::VideoCodec codec(DefaultCodec());
    codec.width = codec.height = codec.framerate = 0;
    EXPECT_TRUE(SetOneCodec(codec));
    EXPECT_TRUE(SetSend(true));
    EXPECT_TRUE(channel_->SetRender(true));
    EXPECT_TRUE(channel_->SetRenderer(kDefaultReceiveSsrc, &renderer_));
    EXPECT_EQ(0, renderer_.num_rendered_frames());
    EXPECT_TRUE(SendFrame());
    EXPECT_TRUE(SendFrame());
    rtc::Thread::Current()->ProcessMessages(500);
    EXPECT_EQ(0, renderer_.num_rendered_frames());
  }
  // Tests that we can reduce the frame rate on demand properly.
  // TODO(fbarchard): This test is flakey on pulse.  Fix and re-enable
  void AdaptFramerate() {
    cricket::VideoCodec codec(DefaultCodec());
    int frame_count = 0;
    // The capturer runs at 30 fps. The channel requires 30 fps.
    EXPECT_TRUE(SetOneCodec(codec));
    EXPECT_TRUE(SetSend(true));
    EXPECT_TRUE(channel_->SetRender(true));
    EXPECT_EQ(frame_count, renderer_.num_rendered_frames());
    EXPECT_TRUE(WaitAndSendFrame(0));  // Should be rendered.
    EXPECT_TRUE(WaitAndSendFrame(30));  // Should be rendered.
    frame_count += 2;
    EXPECT_FRAME_WAIT(frame_count, codec.width, codec.height, kTimeout);
    rtc::scoped_ptr<const rtc::Buffer> p(GetRtpPacket(0));
    EXPECT_EQ(codec.id, GetPayloadType(p.get()));

    // The channel requires 15 fps.
    codec.framerate = 15;
    EXPECT_TRUE(SetOneCodec(codec));
    EXPECT_TRUE(WaitAndSendFrame(0));  // Should be rendered.
    EXPECT_TRUE(WaitAndSendFrame(30));  // Should be dropped.
    EXPECT_TRUE(WaitAndSendFrame(30));  // Should be rendered.
    frame_count += 2;
    EXPECT_EQ_WAIT(frame_count, renderer_.num_rendered_frames(), kTimeout);

    // The channel requires 10 fps.
    codec.framerate = 10;
    EXPECT_TRUE(SetOneCodec(codec));
    EXPECT_TRUE(WaitAndSendFrame(0));  // Should be rendered.
    EXPECT_TRUE(WaitAndSendFrame(30));  // Should be dropped.
    EXPECT_TRUE(WaitAndSendFrame(30));  // Should be dropped.
    EXPECT_TRUE(WaitAndSendFrame(30));  // Should be rendered.
    frame_count += 2;
    EXPECT_EQ_WAIT(frame_count, renderer_.num_rendered_frames(), kTimeout);

    // The channel requires 8 fps. The adapter adapts to 10 fps, which is the
    // closest factor of 30.
    codec.framerate = 8;
    EXPECT_TRUE(SetOneCodec(codec));
    EXPECT_TRUE(WaitAndSendFrame(0));  // Should be rendered.
    EXPECT_TRUE(WaitAndSendFrame(30));  // Should be dropped.
    EXPECT_TRUE(WaitAndSendFrame(30));  // Should be dropped.
    EXPECT_TRUE(WaitAndSendFrame(30));  // Should be rendered.
    frame_count += 2;
    EXPECT_EQ_WAIT(frame_count, renderer_.num_rendered_frames(), kTimeout);
  }
  // Tests that we can set the send stream format properly.
  void SetSendStreamFormat() {
    cricket::VideoCodec codec(DefaultCodec());
    SendAndReceive(codec);
    int frame_count = 1;
    EXPECT_FRAME_WAIT(frame_count, codec.width, codec.height, kTimeout);

    // Adapt the resolution and frame rate to half.
    cricket::VideoFormat format(
        codec.width / 2,
        codec.height / 2,
        cricket::VideoFormat::FpsToInterval(codec.framerate / 2),
        cricket::FOURCC_I420);
    // The SSRC differs from the send SSRC.
    EXPECT_FALSE(channel_->SetSendStreamFormat(kSsrc - 1, format));
    EXPECT_TRUE(channel_->SetSendStreamFormat(kSsrc, format));

    EXPECT_TRUE(WaitAndSendFrame(30));  // Should be dropped.
    EXPECT_TRUE(WaitAndSendFrame(30));  // Should be rendered.
    EXPECT_TRUE(WaitAndSendFrame(30));  // Should be dropped.
    frame_count += 1;
    EXPECT_FRAME_WAIT(frame_count, format.width, format.height, kTimeout);

    // Adapt the resolution to 0x0, which should drop all frames.
    format.width = 0;
    format.height = 0;
    EXPECT_TRUE(channel_->SetSendStreamFormat(kSsrc, format));
    EXPECT_TRUE(SendFrame());
    EXPECT_TRUE(SendFrame());
    rtc::Thread::Current()->ProcessMessages(500);
    EXPECT_EQ(frame_count, renderer_.num_rendered_frames());
  }
  // Test that setting send stream format to 0x0 resolution will result in
  // frames being dropped.
  void SetSendStreamFormat0x0() {
    EXPECT_TRUE(SetOneCodec(DefaultCodec()));
    EXPECT_TRUE(SetSendStreamFormat(kSsrc, DefaultCodec()));
    EXPECT_TRUE(SetSend(true));
    EXPECT_TRUE(channel_->SetRender(true));
    EXPECT_TRUE(channel_->SetRenderer(kDefaultReceiveSsrc, &renderer_));
    EXPECT_EQ(0, renderer_.num_rendered_frames());
    // This frame should be received.
    EXPECT_TRUE(SendFrame());
    EXPECT_FRAME_WAIT(1, DefaultCodec().width, DefaultCodec().height, kTimeout);
    const int64 interval = cricket::VideoFormat::FpsToInterval(
        DefaultCodec().framerate);
    cricket::VideoFormat format(
        0,
        0,
        interval,
        cricket::FOURCC_I420);
    EXPECT_TRUE(channel_->SetSendStreamFormat(kSsrc, format));
    // This frame should not be received.
    EXPECT_TRUE(WaitAndSendFrame(
        static_cast<int>(interval/rtc::kNumNanosecsPerMillisec)));
    rtc::Thread::Current()->ProcessMessages(500);
    EXPECT_EQ(1, renderer_.num_rendered_frames());
  }

  // Tests that we can mute and unmute the channel properly.
  void MuteStream() {
    EXPECT_TRUE(SetDefaultCodec());
    cricket::FakeVideoCapturer video_capturer;
    video_capturer.Start(
        cricket::VideoFormat(
            640, 480,
            cricket::VideoFormat::FpsToInterval(30),
            cricket::FOURCC_I420));
    EXPECT_TRUE(channel_->SetCapturer(kSsrc, &video_capturer));
    EXPECT_TRUE(SetSend(true));
    EXPECT_TRUE(channel_->SetRender(true));
    EXPECT_TRUE(channel_->SetRenderer(kDefaultReceiveSsrc, &renderer_));
    EXPECT_EQ(0, renderer_.num_rendered_frames());

    // Mute the channel and expect black output frame.
    int frame_count = 0;
    EXPECT_TRUE(channel_->MuteStream(kSsrc, true));
    EXPECT_TRUE(video_capturer.CaptureFrame());
    ++frame_count;
    EXPECT_EQ_WAIT(frame_count, renderer_.num_rendered_frames(), kTimeout);
    EXPECT_TRUE(renderer_.black_frame());

    // Unmute the channel and expect non-black output frame.
    EXPECT_TRUE(channel_->MuteStream(kSsrc, false));
    EXPECT_TRUE(rtc::Thread::Current()->ProcessMessages(30));
    EXPECT_TRUE(video_capturer.CaptureFrame());
    ++frame_count;
    EXPECT_EQ_WAIT(frame_count, renderer_.num_rendered_frames(), kTimeout);
    EXPECT_FALSE(renderer_.black_frame());

    // Test that we can also Mute using the correct send stream SSRC.
    EXPECT_TRUE(channel_->MuteStream(kSsrc, true));
    EXPECT_TRUE(rtc::Thread::Current()->ProcessMessages(30));
    EXPECT_TRUE(video_capturer.CaptureFrame());
    ++frame_count;
    EXPECT_EQ_WAIT(frame_count, renderer_.num_rendered_frames(), kTimeout);
    EXPECT_TRUE(renderer_.black_frame());

    EXPECT_TRUE(channel_->MuteStream(kSsrc, false));
    EXPECT_TRUE(rtc::Thread::Current()->ProcessMessages(30));
    EXPECT_TRUE(video_capturer.CaptureFrame());
    ++frame_count;
    EXPECT_EQ_WAIT(frame_count, renderer_.num_rendered_frames(), kTimeout);
    EXPECT_FALSE(renderer_.black_frame());

    // Test that muting an existing stream succeeds even if it's muted.
    EXPECT_TRUE(channel_->MuteStream(kSsrc, true));
    EXPECT_TRUE(channel_->MuteStream(kSsrc, true));

    // Test that unmuting an existing stream succeeds even if it's not muted.
    EXPECT_TRUE(channel_->MuteStream(kSsrc, false));
    EXPECT_TRUE(channel_->MuteStream(kSsrc, false));

    // Test that muting an invalid stream fails.
    EXPECT_FALSE(channel_->MuteStream(kSsrc+1, true));
    EXPECT_TRUE(channel_->SetCapturer(kSsrc, NULL));
  }

  // Test that multiple send streams can be created and deleted properly.
  void MultipleSendStreams() {
    // Remove stream added in Setup. I.e. remove stream corresponding to default
    // channel.
    EXPECT_TRUE(channel_->RemoveSendStream(kSsrc));
    const unsigned int kSsrcsSize = sizeof(kSsrcs4)/sizeof(kSsrcs4[0]);
    for (unsigned int i = 0; i < kSsrcsSize; ++i) {
      EXPECT_TRUE(channel_->AddSendStream(
          cricket::StreamParams::CreateLegacy(kSsrcs4[i])));
    }
    // Delete one of the non default channel streams, let the destructor delete
    // the remaining ones.
    EXPECT_TRUE(channel_->RemoveSendStream(kSsrcs4[kSsrcsSize - 1]));
    // Stream should already be deleted.
    EXPECT_FALSE(channel_->RemoveSendStream(kSsrcs4[kSsrcsSize - 1]));
  }

  // Two streams one channel tests.

  // Tests that we can send and receive frames.
  void TwoStreamsSendAndReceive(const cricket::VideoCodec& codec) {
    SetUpSecondStream();
    // Test sending and receiving on first stream.
    SendAndReceive(codec);
    // Test sending and receiving on second stream.
    EXPECT_EQ_WAIT(1, renderer2_.num_rendered_frames(), kTimeout);
    EXPECT_EQ(2, NumRtpPackets());
    EXPECT_EQ(1, renderer2_.num_rendered_frames());
  }

  // Set up 2 streams where the first stream uses the default channel.
  // Then disconnect the first stream and verify default channel becomes
  // available.
  // Then add a new stream with |new_ssrc|. The new stream should re-use the
  // default channel.
  void TwoStreamsReUseFirstStream(const cricket::VideoCodec& codec) {
    SetUpSecondStream();
    // Default channel used by the first stream.
    EXPECT_EQ(kSsrc, channel_->GetDefaultSendChannelSsrc());
    EXPECT_TRUE(channel_->RemoveRecvStream(kSsrc));
    EXPECT_FALSE(channel_->RemoveRecvStream(kSsrc));
    EXPECT_TRUE(channel_->RemoveSendStream(kSsrc));
    EXPECT_FALSE(channel_->RemoveSendStream(kSsrc));
    // Default channel is no longer used by a stream.
    EXPECT_EQ(0u, channel_->GetDefaultSendChannelSsrc());
    uint32 new_ssrc = kSsrc + 100;
    EXPECT_TRUE(channel_->AddSendStream(
        cricket::StreamParams::CreateLegacy(new_ssrc)));
    // Re-use default channel.
    EXPECT_EQ(new_ssrc, channel_->GetDefaultSendChannelSsrc());
    EXPECT_FALSE(channel_->AddSendStream(
        cricket::StreamParams::CreateLegacy(new_ssrc)));
    EXPECT_TRUE(channel_->AddRecvStream(
        cricket::StreamParams::CreateLegacy(new_ssrc)));
    EXPECT_TRUE(channel_->SetRenderer(new_ssrc, &renderer_));
    EXPECT_FALSE(channel_->AddRecvStream(
        cricket::StreamParams::CreateLegacy(new_ssrc)));

    EXPECT_TRUE(channel_->SetCapturer(new_ssrc, video_capturer_.get()));

    SendAndReceive(codec);
    EXPECT_TRUE(channel_->RemoveSendStream(new_ssrc));
    EXPECT_EQ(0u, channel_->GetDefaultSendChannelSsrc());
  }

  // Tests that we can send and receive frames with early receive.
  void TwoStreamsSendAndUnsignalledRecv(const cricket::VideoCodec& codec) {
    cricket::VideoOptions vmo;
    vmo.conference_mode.Set(true);
    vmo.unsignalled_recv_stream_limit.Set(1);
    EXPECT_TRUE(channel_->SetOptions(vmo));
    SetUpSecondStreamWithNoRecv();
    // Test sending and receiving on first stream.
    EXPECT_TRUE(channel_->SetRender(true));
    Send(codec);
    EXPECT_EQ_WAIT(2, NumRtpPackets(), kTimeout);
    EXPECT_EQ_WAIT(1, renderer_.num_rendered_frames(), kTimeout);
    // The first send is not expected to yield frames, because the ssrc
    // is not signalled yet. With unsignalled recv enabled, we will drop frames
    // instead of packets.
    EXPECT_EQ(0, renderer2_.num_rendered_frames());
    // Give a chance for the decoder to process before adding the receiver.
    rtc::Thread::Current()->ProcessMessages(100);
    // Test sending and receiving on second stream.
    EXPECT_TRUE(channel_->AddRecvStream(
        cricket::StreamParams::CreateLegacy(kSsrc + 2)));
    EXPECT_TRUE(channel_->SetRenderer(kSsrc + 2, &renderer2_));
    SendFrame();
    EXPECT_EQ_WAIT(2, renderer_.num_rendered_frames(), kTimeout);
    EXPECT_EQ(4, NumRtpPackets());
    // The second send is expected to yield frame as the ssrc is signalled now.
    // Decode should succeed here, though we received the key frame earlier.
    // Without early recv, we would have dropped it and decoding would have
    // failed.
    EXPECT_EQ_WAIT(1, renderer2_.num_rendered_frames(), kTimeout);
  }

  // Tests that we cannot receive key frames with unsignalled recv disabled.
  void TwoStreamsSendAndFailUnsignalledRecv(const cricket::VideoCodec& codec) {
    cricket::VideoOptions vmo;
    vmo.conference_mode.Set(true);
    vmo.unsignalled_recv_stream_limit.Set(0);
    EXPECT_TRUE(channel_->SetOptions(vmo));
    SetUpSecondStreamWithNoRecv();
    // Test sending and receiving on first stream.
    EXPECT_TRUE(channel_->SetRender(true));
    Send(codec);
    EXPECT_EQ_WAIT(2, NumRtpPackets(), kTimeout);
    rtc::Thread::Current()->ProcessMessages(100);
    EXPECT_EQ_WAIT(1, renderer_.num_rendered_frames(), kTimeout);
    EXPECT_EQ_WAIT(0, renderer2_.num_rendered_frames(), kTimeout);
    // Give a chance for the decoder to process before adding the receiver.
    rtc::Thread::Current()->ProcessMessages(10);
    // Test sending and receiving on second stream.
    EXPECT_TRUE(channel_->AddRecvStream(
        cricket::StreamParams::CreateLegacy(kSsrc + 2)));
    EXPECT_TRUE(channel_->SetRenderer(kSsrc + 2, &renderer2_));
    SendFrame();
    EXPECT_TRUE_WAIT(renderer_.num_rendered_frames() >= 1, kTimeout);
    EXPECT_EQ_WAIT(4, NumRtpPackets(), kTimeout);
    // We dont expect any frames here, because the key frame would have been
    // lost in the earlier packet. This is the case we want to solve with early
    // receive.
    EXPECT_EQ(0, renderer2_.num_rendered_frames());
  }

  // Tests that we drop key frames when conference mode is disabled and we
  // receive rtp packets on unsignalled streams.
  void TwoStreamsSendAndFailUnsignalledRecvInOneToOne(
      const cricket::VideoCodec& codec) {
    cricket::VideoOptions vmo;
    vmo.conference_mode.Set(false);
    vmo.unsignalled_recv_stream_limit.Set(1);
    EXPECT_TRUE(channel_->SetOptions(vmo));
    SetUpSecondStreamWithNoRecv();
    // Test sending and receiving on first stream.
    EXPECT_TRUE(channel_->SetRender(true));
    Send(codec);
    EXPECT_EQ_WAIT(2, NumRtpPackets(), kTimeout);
    // In one-to-one mode, we deliver frames to the default channel if there
    // is no registered recv channel for the ssrc.
    EXPECT_TRUE_WAIT(renderer_.num_rendered_frames() >= 1, kTimeout);
    // Give a chance for the decoder to process before adding the receiver.
    rtc::Thread::Current()->ProcessMessages(100);
    // Test sending and receiving on second stream.
    EXPECT_TRUE(channel_->AddRecvStream(
        cricket::StreamParams::CreateLegacy(kSsrc + 2)));
    EXPECT_TRUE(channel_->SetRenderer(kSsrc + 2, &renderer2_));
    SendFrame();
    EXPECT_TRUE_WAIT(renderer_.num_rendered_frames() >= 1, kTimeout);
    EXPECT_EQ_WAIT(4, NumRtpPackets(), kTimeout);
    // We dont expect any frames here, because the key frame would have been
    // delivered to default channel.
    EXPECT_EQ(0, renderer2_.num_rendered_frames());
  }

  // Tests that we drop key frames when conference mode is enabled and we
  // receive rtp packets on unsignalled streams. Removal of a unsignalled recv
  // stream is successful.
  void TwoStreamsAddAndRemoveUnsignalledRecv(
      const cricket::VideoCodec& codec) {
    cricket::VideoOptions vmo;
    vmo.conference_mode.Set(true);
    vmo.unsignalled_recv_stream_limit.Set(1);
    EXPECT_TRUE(channel_->SetOptions(vmo));
    SetUpSecondStreamWithNoRecv();
    // Sending and receiving on first stream.
    EXPECT_TRUE(channel_->SetRender(true));
    Send(codec);
    EXPECT_EQ_WAIT(2, NumRtpPackets(), kTimeout);
    EXPECT_EQ_WAIT(1, renderer_.num_rendered_frames(), kTimeout);
    // The first send is not expected to yield frames, because the ssrc
    // is no signalled yet. With unsignalled recv enabled, we will drop frames
    // instead of packets.
    EXPECT_EQ(0, renderer2_.num_rendered_frames());
    // Give a chance for the decoder to process before adding the receiver.
    rtc::Thread::Current()->ProcessMessages(100);
    // Ensure that we can remove the unsignalled recv stream that was created
    // when the first video packet with unsignalled recv ssrc is received.
    EXPECT_TRUE(channel_->RemoveRecvStream(kSsrc + 2));
  }

  VideoEngineOverride<E> engine_;
  rtc::scoped_ptr<cricket::FakeVideoCapturer> video_capturer_;
  rtc::scoped_ptr<cricket::FakeVideoCapturer> video_capturer_2_;
  rtc::scoped_ptr<C> channel_;
  cricket::FakeNetworkInterface network_interface_;
  cricket::FakeVideoRenderer renderer_;
  cricket::VideoMediaChannel::Error media_error_;

  // Used by test cases where 2 streams are run on the same channel.
  cricket::FakeVideoRenderer renderer2_;
};

#endif  // TALK_MEDIA_BASE_VIDEOENGINE_UNITTEST_H_  NOLINT
