Home | History | Annotate | Download | only in base
      1 // libjingle
      2 // Copyright 2004 Google Inc. All rights reserved.
      3 //
      4 // Redistribution and use in source and binary forms, with or without
      5 // modification, are permitted provided that the following conditions are met:
      6 //
      7 //  1. Redistributions of source code must retain the above copyright notice,
      8 //     this list of conditions and the following disclaimer.
      9 //  2. Redistributions in binary form must reproduce the above copyright notice,
     10 //     this list of conditions and the following disclaimer in the documentation
     11 //     and/or other materials provided with the distribution.
     12 //  3. The name of the author may not be used to endorse or promote products
     13 //     derived from this software without specific prior written permission.
     14 //
     15 // THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
     16 // WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
     17 // MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
     18 // EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
     19 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
     20 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
     21 // OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
     22 // WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
     23 // OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
     24 // ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     25 
     26 #ifndef TALK_MEDIA_BASE_VIDEOENGINE_UNITTEST_H_  // NOLINT
     27 #define TALK_MEDIA_BASE_VIDEOENGINE_UNITTEST_H_
     28 
     29 #include <string>
     30 #include <vector>
     31 
     32 #include "talk/base/bytebuffer.h"
     33 #include "talk/base/gunit.h"
     34 #include "talk/base/timeutils.h"
     35 #include "talk/media/base/fakenetworkinterface.h"
     36 #include "talk/media/base/fakevideocapturer.h"
     37 #include "talk/media/base/fakevideorenderer.h"
     38 #include "talk/media/base/mediachannel.h"
     39 #include "talk/media/base/streamparams.h"
     40 
     41 #ifdef WIN32
     42 #include <objbase.h>  // NOLINT
     43 #endif
     44 
     45 #define EXPECT_FRAME_WAIT(c, w, h, t) \
     46   EXPECT_EQ_WAIT((c), renderer_.num_rendered_frames(), (t)); \
     47   EXPECT_EQ((w), renderer_.width()); \
     48   EXPECT_EQ((h), renderer_.height()); \
     49   EXPECT_EQ(0, renderer_.errors()); \
     50 
     51 #define EXPECT_FRAME_ON_RENDERER_WAIT(r, c, w, h, t) \
     52   EXPECT_EQ_WAIT((c), (r).num_rendered_frames(), (t)); \
     53   EXPECT_EQ((w), (r).width()); \
     54   EXPECT_EQ((h), (r).height()); \
     55   EXPECT_EQ(0, (r).errors()); \
     56 
     57 #define EXPECT_GT_FRAME_ON_RENDERER_WAIT(r, c, w, h, t) \
     58   EXPECT_TRUE_WAIT((r).num_rendered_frames() >= (c) && \
     59                    (w) == (r).width() && \
     60                    (h) == (r).height(), (t)); \
     61   EXPECT_EQ(0, (r).errors()); \
     62 
     63 static const uint32 kTimeout = 5000U;
     64 static const uint32 kSsrc = 1234u;
     65 static const uint32 kRtxSsrc = 4321u;
     66 static const uint32 kSsrcs4[] = {1, 2, 3, 4};
     67 
     68 inline bool IsEqualRes(const cricket::VideoCodec& a, int w, int h, int fps) {
     69   return a.width == w && a.height == h && a.framerate == fps;
     70 }
     71 
     72 inline bool IsEqualCodec(const cricket::VideoCodec& a,
     73                          const cricket::VideoCodec& b) {
     74   return a.id == b.id && a.name == b.name &&
     75       IsEqualRes(a, b.width, b.height, b.framerate);
     76 }
     77 
     78 namespace std {
     79 inline std::ostream& operator<<(std::ostream& s, const cricket::VideoCodec& c) {
     80   s << "{" << c.name << "(" << c.id << "), "
     81     << c.width << "x" << c.height << "x" << c.framerate << "}";
     82   return s;
     83 }
     84 }  // namespace std
     85 
     86 inline int TimeBetweenSend(const cricket::VideoCodec& codec) {
     87   return static_cast<int>(
     88       cricket::VideoFormat::FpsToInterval(codec.framerate) /
     89       talk_base::kNumNanosecsPerMillisec);
     90 }
     91 
     92 // Fake video engine that makes it possible to test enabling and disabling
     93 // capturer (checking that the engine state is updated and that the capturer
     94 // is indeed capturing) without having to create a channel. It also makes it
     95 // possible to test that the media processors are indeed being called when
     96 // registered.
     97 template<class T>
     98 class VideoEngineOverride : public T {
     99  public:
    100   VideoEngineOverride() {
    101   }
    102   virtual ~VideoEngineOverride() {
    103   }
    104   bool is_camera_on() const { return T::GetVideoCapturer()->IsRunning(); }
    105   void set_has_senders(bool has_senders) {
    106     cricket::VideoCapturer* video_capturer = T::GetVideoCapturer();
    107     if (has_senders) {
    108       video_capturer->SignalVideoFrame.connect(this,
    109           &VideoEngineOverride<T>::OnLocalFrame);
    110     } else {
    111       video_capturer->SignalVideoFrame.disconnect(this);
    112     }
    113   }
    114   void OnLocalFrame(cricket::VideoCapturer*,
    115                     const cricket::VideoFrame*) {
    116   }
    117   void OnLocalFrameFormat(cricket::VideoCapturer*,
    118                           const cricket::VideoFormat*) {
    119   }
    120 
    121   void TriggerMediaFrame(
    122       uint32 ssrc, cricket::VideoFrame* frame, bool* drop_frame) {
    123     T::SignalMediaFrame(ssrc, frame, drop_frame);
    124   }
    125 };
    126 
    127 // Macroes that declare test functions for a given test class, before and after
    128 // Init().
    129 // To use, define a test function called FooBody and pass Foo to the macro.
    130 #define TEST_PRE_VIDEOENGINE_INIT(TestClass, func) \
    131   TEST_F(TestClass, func##PreInit) { \
    132     func##Body(); \
    133   }
    134 #define TEST_POST_VIDEOENGINE_INIT(TestClass, func) \
    135   TEST_F(TestClass, func##PostInit) { \
    136     EXPECT_TRUE(engine_.Init(talk_base::Thread::Current())); \
    137     func##Body(); \
    138     engine_.Terminate(); \
    139   }
    140 
    141 template<class E>
    142 class VideoEngineTest : public testing::Test {
    143  protected:
    144   // Tests starting and stopping the engine, and creating a channel.
    145   void StartupShutdown() {
    146     EXPECT_TRUE(engine_.Init(talk_base::Thread::Current()));
    147     cricket::VideoMediaChannel* channel = engine_.CreateChannel(NULL);
    148     EXPECT_TRUE(channel != NULL);
    149     delete channel;
    150     engine_.Terminate();
    151   }
    152 
    153 #ifdef WIN32
    154   // Tests that the COM reference count is not munged by the engine.
    155   // Test to make sure LMI does not munge the CoInitialize reference count.
    156   void CheckCoInitialize() {
    157     // Initial refcount should be 0.
    158     EXPECT_EQ(S_OK, CoInitializeEx(NULL, COINIT_MULTITHREADED));
    159 
    160     // Engine should start even with COM already inited.
    161     EXPECT_TRUE(engine_.Init(talk_base::Thread::Current()));
    162     engine_.Terminate();
    163     // Refcount after terminate should be 1; this tests if it is nonzero.
    164     EXPECT_EQ(S_FALSE, CoInitializeEx(NULL, COINIT_MULTITHREADED));
    165     // Decrement refcount to (hopefully) 0.
    166     CoUninitialize();
    167     CoUninitialize();
    168 
    169     // Ensure refcount is 0.
    170     EXPECT_EQ(S_OK, CoInitializeEx(NULL, COINIT_MULTITHREADED));
    171     CoUninitialize();
    172   }
    173 #endif
    174 
    175   void ConstrainNewCodecBody() {
    176     cricket::VideoCodec empty, in, out;
    177     cricket::VideoCodec max_settings(engine_.codecs()[0].id,
    178                                      engine_.codecs()[0].name,
    179                                      1280, 800, 30, 0);
    180 
    181     // set max settings of 1280x960x30
    182     EXPECT_TRUE(engine_.SetDefaultEncoderConfig(
    183         cricket::VideoEncoderConfig(max_settings)));
    184 
    185     // don't constrain the max resolution
    186     in = max_settings;
    187     EXPECT_TRUE(engine_.CanSendCodec(in, empty, &out));
    188     EXPECT_PRED2(IsEqualCodec, out, in);
    189 
    190     // constrain resolution greater than the max and wider aspect,
    191     // picking best aspect (16:10)
    192     in.width = 1380;
    193     in.height = 800;
    194     EXPECT_TRUE(engine_.CanSendCodec(in, empty, &out));
    195     EXPECT_PRED4(IsEqualRes, out, 1280, 720, 30);
    196 
    197     // constrain resolution greater than the max and narrow aspect,
    198     // picking best aspect (16:9)
    199     in.width = 1280;
    200     in.height = 740;
    201     EXPECT_TRUE(engine_.CanSendCodec(in, empty, &out));
    202     EXPECT_PRED4(IsEqualRes, out, 1280, 720, 30);
    203 
    204     // constrain resolution greater than the max, picking equal aspect (4:3)
    205     in.width = 1280;
    206     in.height = 960;
    207     EXPECT_TRUE(engine_.CanSendCodec(in, empty, &out));
    208     EXPECT_PRED4(IsEqualRes, out, 1280, 800, 30);
    209 
    210     // constrain resolution greater than the max, picking equal aspect (16:10)
    211     in.width = 1280;
    212     in.height = 800;
    213     EXPECT_TRUE(engine_.CanSendCodec(in, empty, &out));
    214     EXPECT_PRED4(IsEqualRes, out, 1280, 800, 30);
    215 
    216     // reduce max settings to 640x480x30
    217     max_settings.width = 640;
    218     max_settings.height = 480;
    219     EXPECT_TRUE(engine_.SetDefaultEncoderConfig(
    220         cricket::VideoEncoderConfig(max_settings)));
    221 
    222     // don't constrain the max resolution
    223     in = max_settings;
    224     in.width = 640;
    225     in.height = 480;
    226     EXPECT_TRUE(engine_.CanSendCodec(in, empty, &out));
    227     EXPECT_PRED2(IsEqualCodec, out, in);
    228 
    229     // keep 16:10 if they request it
    230     in.height = 400;
    231     EXPECT_TRUE(engine_.CanSendCodec(in, empty, &out));
    232     EXPECT_PRED2(IsEqualCodec, out, in);
    233 
    234     // don't constrain lesser 4:3 resolutions
    235     in.width = 320;
    236     in.height = 240;
    237     EXPECT_TRUE(engine_.CanSendCodec(in, empty, &out));
    238     EXPECT_PRED2(IsEqualCodec, out, in);
    239 
    240     // don't constrain lesser 16:10 resolutions
    241     in.width = 320;
    242     in.height = 200;
    243     EXPECT_TRUE(engine_.CanSendCodec(in, empty, &out));
    244     EXPECT_PRED2(IsEqualCodec, out, in);
    245 
    246     // requested resolution of 0x0 succeeds
    247     in.width = 0;
    248     in.height = 0;
    249     EXPECT_TRUE(engine_.CanSendCodec(in, empty, &out));
    250     EXPECT_PRED2(IsEqualCodec, out, in);
    251 
    252     // constrain resolution lesser than the max and wider aspect,
    253     // picking best aspect (16:9)
    254     in.width = 350;
    255     in.height = 201;
    256     EXPECT_TRUE(engine_.CanSendCodec(in, empty, &out));
    257     EXPECT_PRED4(IsEqualRes, out, 320, 180, 30);
    258 
    259     // constrain resolution greater than the max and narrow aspect,
    260     // picking best aspect (4:3)
    261     in.width = 350;
    262     in.height = 300;
    263     EXPECT_TRUE(engine_.CanSendCodec(in, empty, &out));
    264     EXPECT_PRED4(IsEqualRes, out, 320, 240, 30);
    265 
    266     // constrain resolution greater than the max and wider aspect,
    267     // picking best aspect (16:9)
    268     in.width = 1380;
    269     in.height = 800;
    270     EXPECT_TRUE(engine_.CanSendCodec(in, empty, &out));
    271     EXPECT_PRED4(IsEqualRes, out, 640, 360, 30);
    272 
    273     // constrain resolution greater than the max and narrow aspect,
    274     // picking best aspect (4:3)
    275     in.width = 1280;
    276     in.height = 900;
    277     EXPECT_TRUE(engine_.CanSendCodec(in, empty, &out));
    278     EXPECT_PRED4(IsEqualRes, out, 640, 480, 30);
    279 
    280     // constrain resolution greater than the max, picking equal aspect (4:3)
    281     in.width = 1280;
    282     in.height = 960;
    283     EXPECT_TRUE(engine_.CanSendCodec(in, empty, &out));
    284     EXPECT_PRED4(IsEqualRes, out, 640, 480, 30);
    285 
    286     // constrain resolution greater than the max, picking equal aspect (16:10)
    287     in.width = 1280;
    288     in.height = 800;
    289     EXPECT_TRUE(engine_.CanSendCodec(in, empty, &out));
    290     EXPECT_PRED4(IsEqualRes, out, 640, 400, 30);
    291 
    292     // constrain res & fps greater than the max
    293     in.framerate = 50;
    294     EXPECT_TRUE(engine_.CanSendCodec(in, empty, &out));
    295     EXPECT_PRED4(IsEqualRes, out, 640, 400, 30);
    296 
    297     // reduce max settings to 160x100x10
    298     max_settings.width = 160;
    299     max_settings.height = 100;
    300     max_settings.framerate = 10;
    301     EXPECT_TRUE(engine_.SetDefaultEncoderConfig(
    302         cricket::VideoEncoderConfig(max_settings)));
    303 
    304     // constrain res & fps to new max
    305     EXPECT_TRUE(engine_.CanSendCodec(in, empty, &out));
    306     EXPECT_PRED4(IsEqualRes, out, 160, 100, 10);
    307 
    308     // allow 4:3 "comparable" resolutions
    309     in.width = 160;
    310     in.height = 120;
    311     in.framerate = 10;
    312     EXPECT_TRUE(engine_.CanSendCodec(in, empty, &out));
    313     EXPECT_PRED4(IsEqualRes, out, 160, 120, 10);
    314   }
    315 
    316   void ConstrainRunningCodecBody() {
    317     cricket::VideoCodec in, out, current;
    318     cricket::VideoCodec max_settings(engine_.codecs()[0].id,
    319                                      engine_.codecs()[0].name,
    320                                      1280, 800, 30, 0);
    321 
    322     // set max settings of 1280x960x30
    323     EXPECT_TRUE(engine_.SetDefaultEncoderConfig(
    324         cricket::VideoEncoderConfig(max_settings)));
    325 
    326     // establish current call at 1280x800x30 (16:10)
    327     current = max_settings;
    328     current.height = 800;
    329 
    330     // Don't constrain current resolution
    331     in = current;
    332     EXPECT_TRUE(engine_.CanSendCodec(in, current, &out));
    333     EXPECT_PRED2(IsEqualCodec, out, in);
    334 
    335     // requested resolution of 0x0 succeeds
    336     in.width = 0;
    337     in.height = 0;
    338     EXPECT_TRUE(engine_.CanSendCodec(in, current, &out));
    339     EXPECT_PRED2(IsEqualCodec, out, in);
    340 
    341     // Reduce an intermediate resolution down to the next lowest one, preserving
    342     // aspect ratio.
    343     in.width = 800;
    344     in.height = 600;
    345     EXPECT_TRUE(engine_.CanSendCodec(in, current, &out));
    346     EXPECT_PRED4(IsEqualRes, out, 640, 400, 30);
    347 
    348     // Clamping by aspect ratio, but still never return a dimension higher than
    349     // requested.
    350     in.width = 1280;
    351     in.height = 720;
    352     EXPECT_TRUE(engine_.CanSendCodec(in, current, &out));
    353     EXPECT_PRED4(IsEqualRes, out, 1280, 720, 30);
    354 
    355     in.width = 1279;
    356     EXPECT_TRUE(engine_.CanSendCodec(in, current, &out));
    357     EXPECT_PRED4(IsEqualRes, out, 960, 600, 30);
    358 
    359     in.width = 1281;
    360     EXPECT_TRUE(engine_.CanSendCodec(in, current, &out));
    361     EXPECT_PRED4(IsEqualRes, out, 1280, 720, 30);
    362 
    363     // Clamp large resolutions down, always preserving aspect
    364     in.width = 1920;
    365     in.height = 1080;
    366     EXPECT_TRUE(engine_.CanSendCodec(in, current, &out));
    367     EXPECT_PRED4(IsEqualRes, out, 1280, 800, 30);
    368 
    369     in.width = 1921;
    370     EXPECT_TRUE(engine_.CanSendCodec(in, current, &out));
    371     EXPECT_PRED4(IsEqualRes, out, 1280, 800, 30);
    372 
    373     in.width = 1919;
    374     EXPECT_TRUE(engine_.CanSendCodec(in, current, &out));
    375     EXPECT_PRED4(IsEqualRes, out, 1280, 800, 30);
    376 
    377     // reduce max settings to 640x480x30
    378     max_settings.width = 640;
    379     max_settings.height = 480;
    380     EXPECT_TRUE(engine_.SetDefaultEncoderConfig(
    381         cricket::VideoEncoderConfig(max_settings)));
    382 
    383     // establish current call at 640x400x30 (16:10)
    384     current = max_settings;
    385     current.height = 400;
    386 
    387     // Don't constrain current resolution
    388     in = current;
    389     EXPECT_TRUE(engine_.CanSendCodec(in, current, &out));
    390     EXPECT_PRED2(IsEqualCodec, out, in);
    391 
    392     // requested resolution of 0x0 succeeds
    393     in.width = 0;
    394     in.height = 0;
    395     EXPECT_TRUE(engine_.CanSendCodec(in, current, &out));
    396     EXPECT_PRED2(IsEqualCodec, out, in);
    397 
    398     // Reduce an intermediate resolution down to the next lowest one, preserving
    399     // aspect ratio.
    400     in.width = 400;
    401     in.height = 300;
    402     EXPECT_TRUE(engine_.CanSendCodec(in, current, &out));
    403     EXPECT_PRED4(IsEqualRes, out, 320, 200, 30);
    404 
    405     // Clamping by aspect ratio, but still never return a dimension higher than
    406     // requested.
    407     in.width = 640;
    408     in.height = 360;
    409     EXPECT_TRUE(engine_.CanSendCodec(in, current, &out));
    410     EXPECT_PRED4(IsEqualRes, out, 640, 360, 30);
    411 
    412     in.width = 639;
    413     EXPECT_TRUE(engine_.CanSendCodec(in, current, &out));
    414     EXPECT_PRED4(IsEqualRes, out, 480, 300, 30);
    415 
    416     in.width = 641;
    417     EXPECT_TRUE(engine_.CanSendCodec(in, current, &out));
    418     EXPECT_PRED4(IsEqualRes, out, 640, 360, 30);
    419 
    420     // Clamp large resolutions down, always preserving aspect
    421     in.width = 1280;
    422     in.height = 800;
    423     EXPECT_TRUE(engine_.CanSendCodec(in, current, &out));
    424     EXPECT_PRED4(IsEqualRes, out, 640, 400, 30);
    425 
    426     in.width = 1281;
    427     EXPECT_TRUE(engine_.CanSendCodec(in, current, &out));
    428     EXPECT_PRED4(IsEqualRes, out, 640, 400, 30);
    429 
    430     in.width = 1279;
    431     EXPECT_TRUE(engine_.CanSendCodec(in, current, &out));
    432     EXPECT_PRED4(IsEqualRes, out, 640, 400, 30);
    433 
    434     // Should fail for any that are smaller than our supported formats
    435     in.width = 80;
    436     in.height = 80;
    437     EXPECT_FALSE(engine_.CanSendCodec(in, current, &out));
    438 
    439     in.height = 50;
    440     EXPECT_FALSE(engine_.CanSendCodec(in, current, &out));
    441   }
    442 
    443   VideoEngineOverride<E> engine_;
    444   talk_base::scoped_ptr<cricket::FakeVideoCapturer> video_capturer_;
    445 };
    446 
    447 template<class E, class C>
    448 class VideoMediaChannelTest : public testing::Test,
    449                               public sigslot::has_slots<> {
    450  protected:
    451   virtual cricket::VideoCodec DefaultCodec() = 0;
    452 
    453   virtual cricket::StreamParams DefaultSendStreamParams() {
    454     return cricket::StreamParams::CreateLegacy(kSsrc);
    455   }
    456 
    457   virtual void SetUp() {
    458     cricket::Device device("test", "device");
    459     EXPECT_TRUE(engine_.Init(talk_base::Thread::Current()));
    460     channel_.reset(engine_.CreateChannel(NULL));
    461     EXPECT_TRUE(channel_.get() != NULL);
    462     ConnectVideoChannelError();
    463     network_interface_.SetDestination(channel_.get());
    464     channel_->SetInterface(&network_interface_);
    465     SetRendererAsDefault();
    466     media_error_ = cricket::VideoMediaChannel::ERROR_NONE;
    467     channel_->SetRecvCodecs(engine_.codecs());
    468     EXPECT_TRUE(channel_->AddSendStream(DefaultSendStreamParams()));
    469 
    470     video_capturer_.reset(new cricket::FakeVideoCapturer);
    471     cricket::VideoFormat format(640, 480,
    472                                 cricket::VideoFormat::FpsToInterval(30),
    473                                 cricket::FOURCC_I420);
    474     EXPECT_EQ(cricket::CS_RUNNING, video_capturer_->Start(format));
    475     EXPECT_TRUE(channel_->SetCapturer(kSsrc, video_capturer_.get()));
    476   }
    477   // Utility method to setup an additional stream to send and receive video.
    478   // Used to test send and recv between two streams.
    479   void SetUpSecondStream() {
    480     SetUpSecondStreamWithNoRecv();
    481     // Setup recv for second stream.
    482     EXPECT_TRUE(channel_->AddRecvStream(
    483         cricket::StreamParams::CreateLegacy(kSsrc + 2)));
    484     // Make the second renderer available for use by a new stream.
    485     EXPECT_TRUE(channel_->SetRenderer(kSsrc + 2, &renderer2_));
    486   }
    487   // Setup an additional stream just to send video. Defer add recv stream.
    488   // This is required if you want to test unsignalled recv of video rtp packets.
    489   void SetUpSecondStreamWithNoRecv() {
    490     // SetUp() already added kSsrc make sure duplicate SSRCs cant be added.
    491     EXPECT_TRUE(channel_->AddRecvStream(
    492         cricket::StreamParams::CreateLegacy(kSsrc)));
    493     EXPECT_FALSE(channel_->AddSendStream(
    494         cricket::StreamParams::CreateLegacy(kSsrc)));
    495     EXPECT_TRUE(channel_->AddSendStream(
    496         cricket::StreamParams::CreateLegacy(kSsrc + 2)));
    497     // We dont add recv for the second stream.
    498 
    499     // Setup the receive and renderer for second stream after send.
    500     video_capturer_2_.reset(new cricket::FakeVideoCapturer());
    501     cricket::VideoFormat format(640, 480,
    502                                 cricket::VideoFormat::FpsToInterval(30),
    503                                 cricket::FOURCC_I420);
    504     EXPECT_EQ(cricket::CS_RUNNING, video_capturer_2_->Start(format));
    505 
    506     EXPECT_TRUE(channel_->SetCapturer(kSsrc + 2, video_capturer_2_.get()));
    507   }
    508   virtual void TearDown() {
    509     channel_.reset();
    510     engine_.Terminate();
    511   }
    512   void ConnectVideoChannelError() {
    513     channel_->SignalMediaError.connect(this,
    514         &VideoMediaChannelTest<E, C>::OnVideoChannelError);
    515   }
    516   bool SetDefaultCodec() {
    517     return SetOneCodec(DefaultCodec());
    518   }
    519   void SetRendererAsDefault() {
    520     EXPECT_TRUE(channel_->SetRenderer(0, &renderer_));
    521   }
    522 
    523   bool SetOneCodec(int pt, const char* name, int w, int h, int fr) {
    524     return SetOneCodec(cricket::VideoCodec(pt, name, w, h, fr, 0));
    525   }
    526   bool SetOneCodec(const cricket::VideoCodec& codec) {
    527     std::vector<cricket::VideoCodec> codecs;
    528     codecs.push_back(codec);
    529 
    530     cricket::VideoFormat capture_format(codec.width, codec.height,
    531         cricket::VideoFormat::FpsToInterval(codec.framerate),
    532         cricket::FOURCC_I420);
    533 
    534     if (video_capturer_) {
    535       EXPECT_EQ(cricket::CS_RUNNING, video_capturer_->Start(capture_format));
    536     }
    537     if (video_capturer_2_) {
    538       EXPECT_EQ(cricket::CS_RUNNING, video_capturer_2_->Start(capture_format));
    539     }
    540 
    541     bool sending = channel_->sending();
    542     bool success = SetSend(false);
    543     if (success)
    544       success = channel_->SetSendCodecs(codecs);
    545     if (success)
    546       success = SetSend(sending);
    547     return success;
    548   }
    549   bool SetSend(bool send) {
    550     return channel_->SetSend(send);
    551   }
    552   bool SetSendStreamFormat(uint32 ssrc, const cricket::VideoCodec& codec) {
    553     return channel_->SetSendStreamFormat(ssrc, cricket::VideoFormat(
    554         codec.width, codec.height,
    555         cricket::VideoFormat::FpsToInterval(codec.framerate),
    556         cricket::FOURCC_ANY));
    557   }
    558   int DrainOutgoingPackets() {
    559     int packets = 0;
    560     do {
    561       packets = NumRtpPackets();
    562       // 100 ms should be long enough.
    563       talk_base::Thread::Current()->ProcessMessages(100);
    564     } while (NumRtpPackets() > packets);
    565     return NumRtpPackets();
    566   }
    567   bool SendFrame() {
    568     if (video_capturer_2_) {
    569       video_capturer_2_->CaptureFrame();
    570     }
    571     return video_capturer_.get() &&
    572         video_capturer_->CaptureFrame();
    573   }
    574   bool WaitAndSendFrame(int wait_ms) {
    575     bool ret = talk_base::Thread::Current()->ProcessMessages(wait_ms);
    576     ret &= SendFrame();
    577     return ret;
    578   }
    579   // Sends frames and waits for the decoder to be fully initialized.
    580   // Returns the number of frames that were sent.
    581   int WaitForDecoder() {
    582 #if defined(HAVE_OPENMAX)
    583     // Send enough frames for the OpenMAX decoder to continue processing, and
    584     // return the number of frames sent.
    585     // Send frames for a full kTimeout's worth of 15fps video.
    586     int frame_count = 0;
    587     while (frame_count < static_cast<int>(kTimeout) / 66) {
    588       EXPECT_TRUE(WaitAndSendFrame(66));
    589       ++frame_count;
    590     }
    591     return frame_count;
    592 #else
    593     return 0;
    594 #endif
    595   }
    596   bool SendCustomVideoFrame(int w, int h) {
    597     if (!video_capturer_.get()) return false;
    598     return video_capturer_->CaptureCustomFrame(w, h, cricket::FOURCC_I420);
    599   }
    600   int NumRtpBytes() {
    601     return network_interface_.NumRtpBytes();
    602   }
    603   int NumRtpBytes(uint32 ssrc) {
    604     return network_interface_.NumRtpBytes(ssrc);
    605   }
    606   int NumRtpPackets() {
    607     return network_interface_.NumRtpPackets();
    608   }
    609   int NumRtpPackets(uint32 ssrc) {
    610     return network_interface_.NumRtpPackets(ssrc);
    611   }
    612   int NumSentSsrcs() {
    613     return network_interface_.NumSentSsrcs();
    614   }
    615   const talk_base::Buffer* GetRtpPacket(int index) {
    616     return network_interface_.GetRtpPacket(index);
    617   }
    618   int NumRtcpPackets() {
    619     return network_interface_.NumRtcpPackets();
    620   }
    621   const talk_base::Buffer* GetRtcpPacket(int index) {
    622     return network_interface_.GetRtcpPacket(index);
    623   }
    624   static int GetPayloadType(const talk_base::Buffer* p) {
    625     int pt = -1;
    626     ParseRtpPacket(p, NULL, &pt, NULL, NULL, NULL, NULL);
    627     return pt;
    628   }
    629   static bool ParseRtpPacket(const talk_base::Buffer* p, bool* x, int* pt,
    630                              int* seqnum, uint32* tstamp, uint32* ssrc,
    631                              std::string* payload) {
    632     talk_base::ByteBuffer buf(p->data(), p->length());
    633     uint8 u08 = 0;
    634     uint16 u16 = 0;
    635     uint32 u32 = 0;
    636 
    637     // Read X and CC fields.
    638     if (!buf.ReadUInt8(&u08)) return false;
    639     bool extension = ((u08 & 0x10) != 0);
    640     uint8 cc = (u08 & 0x0F);
    641     if (x) *x = extension;
    642 
    643     // Read PT field.
    644     if (!buf.ReadUInt8(&u08)) return false;
    645     if (pt) *pt = (u08 & 0x7F);
    646 
    647     // Read Sequence Number field.
    648     if (!buf.ReadUInt16(&u16)) return false;
    649     if (seqnum) *seqnum = u16;
    650 
    651     // Read Timestamp field.
    652     if (!buf.ReadUInt32(&u32)) return false;
    653     if (tstamp) *tstamp = u32;
    654 
    655     // Read SSRC field.
    656     if (!buf.ReadUInt32(&u32)) return false;
    657     if (ssrc) *ssrc = u32;
    658 
    659     // Skip CSRCs.
    660     for (uint8 i = 0; i < cc; ++i) {
    661       if (!buf.ReadUInt32(&u32)) return false;
    662     }
    663 
    664     // Skip extension header.
    665     if (extension) {
    666       // Read Profile-specific extension header ID
    667       if (!buf.ReadUInt16(&u16)) return false;
    668 
    669       // Read Extension header length
    670       if (!buf.ReadUInt16(&u16)) return false;
    671       uint16 ext_header_len = u16;
    672 
    673       // Read Extension header
    674       for (uint16 i = 0; i < ext_header_len; ++i) {
    675         if (!buf.ReadUInt32(&u32)) return false;
    676       }
    677     }
    678 
    679     if (payload) {
    680       return buf.ReadString(payload, buf.Length());
    681     }
    682     return true;
    683   }
    684 
    685   // Parse all RTCP packet, from start_index to stop_index, and count how many
    686   // FIR (PT=206 and FMT=4 according to RFC 5104). If successful, set the count
    687   // and return true.
    688   bool CountRtcpFir(int start_index, int stop_index, int* fir_count) {
    689     int count = 0;
    690     for (int i = start_index; i < stop_index; ++i) {
    691       talk_base::scoped_ptr<const talk_base::Buffer> p(GetRtcpPacket(i));
    692       talk_base::ByteBuffer buf(p->data(), p->length());
    693       size_t total_len = 0;
    694       // The packet may be a compound RTCP packet.
    695       while (total_len < p->length()) {
    696         // Read FMT, type and length.
    697         uint8 fmt = 0;
    698         uint8 type = 0;
    699         uint16 length = 0;
    700         if (!buf.ReadUInt8(&fmt)) return false;
    701         fmt &= 0x1F;
    702         if (!buf.ReadUInt8(&type)) return false;
    703         if (!buf.ReadUInt16(&length)) return false;
    704         buf.Consume(length * 4);  // Skip RTCP data.
    705         total_len += (length + 1) * 4;
    706         if ((192 == type) || ((206 == type) && (4 == fmt))) {
    707           ++count;
    708         }
    709       }
    710     }
    711 
    712     if (fir_count) {
    713       *fir_count = count;
    714     }
    715     return true;
    716   }
    717 
    718   void OnVideoChannelError(uint32 ssrc,
    719                            cricket::VideoMediaChannel::Error error) {
    720     media_error_ = error;
    721   }
    722 
    723   // Test that SetSend works.
    724   void SetSend() {
    725     EXPECT_FALSE(channel_->sending());
    726     EXPECT_TRUE(channel_->SetCapturer(kSsrc, video_capturer_.get()));
    727     EXPECT_TRUE(SetOneCodec(DefaultCodec()));
    728     EXPECT_FALSE(channel_->sending());
    729     EXPECT_TRUE(SetSend(true));
    730     EXPECT_TRUE(channel_->sending());
    731     EXPECT_TRUE(SendFrame());
    732     EXPECT_TRUE_WAIT(NumRtpPackets() > 0, kTimeout);
    733     EXPECT_TRUE(SetSend(false));
    734     EXPECT_FALSE(channel_->sending());
    735   }
    736   // Test that SetSend fails without codecs being set.
    737   void SetSendWithoutCodecs() {
    738     EXPECT_FALSE(channel_->sending());
    739     EXPECT_FALSE(SetSend(true));
    740     EXPECT_FALSE(channel_->sending());
    741   }
    742   // Test that we properly set the send and recv buffer sizes by the time
    743   // SetSend is called.
    744   void SetSendSetsTransportBufferSizes() {
    745     EXPECT_TRUE(SetOneCodec(DefaultCodec()));
    746     EXPECT_TRUE(SetSend(true));
    747     // TODO(sriniv): Remove or re-enable this.
    748     // As part of b/8030474, send-buffer is size now controlled through
    749     // portallocator flags. Its not set by channels.
    750     // EXPECT_EQ(64 * 1024, network_interface_.sendbuf_size());
    751     EXPECT_EQ(64 * 1024, network_interface_.recvbuf_size());
    752   }
    753   // Tests that we can send frames and the right payload type is used.
    754   void Send(const cricket::VideoCodec& codec) {
    755     EXPECT_TRUE(SetOneCodec(codec));
    756     EXPECT_TRUE(SetSend(true));
    757     EXPECT_TRUE(SendFrame());
    758     EXPECT_TRUE_WAIT(NumRtpPackets() > 0, kTimeout);
    759     talk_base::scoped_ptr<const talk_base::Buffer> p(GetRtpPacket(0));
    760     EXPECT_EQ(codec.id, GetPayloadType(p.get()));
    761   }
    762   // Tests that we can send and receive frames.
    763   void SendAndReceive(const cricket::VideoCodec& codec) {
    764     EXPECT_TRUE(SetOneCodec(codec));
    765     EXPECT_TRUE(SetSend(true));
    766     EXPECT_TRUE(channel_->SetRender(true));
    767     EXPECT_EQ(0, renderer_.num_rendered_frames());
    768     EXPECT_TRUE(SendFrame());
    769     EXPECT_FRAME_WAIT(1, codec.width, codec.height, kTimeout);
    770     talk_base::scoped_ptr<const talk_base::Buffer> p(GetRtpPacket(0));
    771     EXPECT_EQ(codec.id, GetPayloadType(p.get()));
    772   }
    773   // Tests that we only get a VideoRenderer::SetSize() callback when needed.
    774   void SendManyResizeOnce() {
    775     cricket::VideoCodec codec(DefaultCodec());
    776     EXPECT_TRUE(SetOneCodec(codec));
    777     EXPECT_TRUE(SetSend(true));
    778     EXPECT_TRUE(channel_->SetRender(true));
    779     EXPECT_EQ(0, renderer_.num_rendered_frames());
    780     EXPECT_TRUE(WaitAndSendFrame(30));
    781     EXPECT_FRAME_WAIT(1, codec.width, codec.height, kTimeout);
    782     EXPECT_TRUE(WaitAndSendFrame(30));
    783     EXPECT_FRAME_WAIT(2, codec.width, codec.height, kTimeout);
    784     talk_base::scoped_ptr<const talk_base::Buffer> p(GetRtpPacket(0));
    785     EXPECT_EQ(codec.id, GetPayloadType(p.get()));
    786     EXPECT_EQ(1, renderer_.num_set_sizes());
    787 
    788     codec.width /= 2;
    789     codec.height /= 2;
    790     EXPECT_TRUE(SetOneCodec(codec));
    791     EXPECT_TRUE(WaitAndSendFrame(30));
    792     EXPECT_FRAME_WAIT(3, codec.width, codec.height, kTimeout);
    793     EXPECT_EQ(2, renderer_.num_set_sizes());
    794   }
    795   void SendReceiveManyAndGetStats(const cricket::VideoCodec& codec,
    796                                   int duration_sec, int fps) {
    797     EXPECT_TRUE(SetOneCodec(codec));
    798     EXPECT_TRUE(SetSend(true));
    799     EXPECT_TRUE(channel_->SetRender(true));
    800     EXPECT_EQ(0, renderer_.num_rendered_frames());
    801     for (int i = 0; i < duration_sec; ++i) {
    802       for (int frame = 1; frame <= fps; ++frame) {
    803         EXPECT_TRUE(WaitAndSendFrame(1000 / fps));
    804         EXPECT_FRAME_WAIT(frame + i * fps, codec.width, codec.height, kTimeout);
    805       }
    806       cricket::VideoMediaInfo info;
    807       EXPECT_TRUE(channel_->GetStats(cricket::StatsOptions(), &info));
    808       // For webrtc, |framerate_sent| and |framerate_rcvd| depend on periodic
    809       // callbacks (1 sec).
    810       // Received |fraction_lost| and |packets_lost| are from sent RTCP packet.
    811       // One sent packet needed (sent about once per second).
    812       // |framerate_input|, |framerate_decoded| and |framerate_output| are using
    813       // RateTracker. RateTracker needs to be called twice (with >1 second in
    814       // b/w calls) before a framerate is calculated.
    815       // Therefore insert frames (and call GetStats each sec) for a few seconds
    816       // before testing stats.
    817     }
    818     talk_base::scoped_ptr<const talk_base::Buffer> p(GetRtpPacket(0));
    819     EXPECT_EQ(codec.id, GetPayloadType(p.get()));
    820   }
    821 
    822   // Test that stats work properly for a 1-1 call.
    823   void GetStats() {
    824     const int kDurationSec = 3;
    825     const int kFps = 10;
    826     SendReceiveManyAndGetStats(DefaultCodec(), kDurationSec, kFps);
    827 
    828     cricket::VideoMediaInfo info;
    829     EXPECT_TRUE(channel_->GetStats(cricket::StatsOptions(), &info));
    830 
    831     ASSERT_EQ(1U, info.senders.size());
    832     // TODO(whyuan): bytes_sent and bytes_rcvd are different. Are both payload?
    833     // For webrtc, bytes_sent does not include the RTP header length.
    834     EXPECT_GT(info.senders[0].bytes_sent, 0);
    835     EXPECT_EQ(NumRtpPackets(), info.senders[0].packets_sent);
    836     EXPECT_EQ(0.0, info.senders[0].fraction_lost);
    837     EXPECT_EQ(0, info.senders[0].firs_rcvd);
    838     EXPECT_EQ(0, info.senders[0].plis_rcvd);
    839     EXPECT_EQ(0, info.senders[0].nacks_rcvd);
    840     EXPECT_EQ(DefaultCodec().width, info.senders[0].send_frame_width);
    841     EXPECT_EQ(DefaultCodec().height, info.senders[0].send_frame_height);
    842     EXPECT_GT(info.senders[0].framerate_input, 0);
    843     EXPECT_GT(info.senders[0].framerate_sent, 0);
    844 
    845     ASSERT_EQ(1U, info.receivers.size());
    846     EXPECT_EQ(1U, info.senders[0].ssrcs().size());
    847     EXPECT_EQ(1U, info.receivers[0].ssrcs().size());
    848     EXPECT_EQ(info.senders[0].ssrcs()[0], info.receivers[0].ssrcs()[0]);
    849     EXPECT_EQ(NumRtpBytes(), info.receivers[0].bytes_rcvd);
    850     EXPECT_EQ(NumRtpPackets(), info.receivers[0].packets_rcvd);
    851     EXPECT_EQ(0.0, info.receivers[0].fraction_lost);
    852     EXPECT_EQ(0, info.receivers[0].packets_lost);
    853     // TODO(asapersson): Not set for webrtc. Handle missing stats.
    854     // EXPECT_EQ(0, info.receivers[0].packets_concealed);
    855     EXPECT_EQ(0, info.receivers[0].firs_sent);
    856     EXPECT_EQ(0, info.receivers[0].plis_sent);
    857     EXPECT_EQ(0, info.receivers[0].nacks_sent);
    858     EXPECT_EQ(DefaultCodec().width, info.receivers[0].frame_width);
    859     EXPECT_EQ(DefaultCodec().height, info.receivers[0].frame_height);
    860     EXPECT_GT(info.receivers[0].framerate_rcvd, 0);
    861     EXPECT_GT(info.receivers[0].framerate_decoded, 0);
    862     EXPECT_GT(info.receivers[0].framerate_output, 0);
    863   }
    864   // Test that stats work properly for a conf call with multiple recv streams.
    865   void GetStatsMultipleRecvStreams() {
    866     cricket::FakeVideoRenderer renderer1, renderer2;
    867     EXPECT_TRUE(SetOneCodec(DefaultCodec()));
    868     cricket::VideoOptions vmo;
    869     vmo.conference_mode.Set(true);
    870     EXPECT_TRUE(channel_->SetOptions(vmo));
    871     EXPECT_TRUE(SetSend(true));
    872     EXPECT_TRUE(channel_->AddRecvStream(
    873         cricket::StreamParams::CreateLegacy(1)));
    874     EXPECT_TRUE(channel_->AddRecvStream(
    875         cricket::StreamParams::CreateLegacy(2)));
    876     EXPECT_TRUE(channel_->SetRenderer(1, &renderer1));
    877     EXPECT_TRUE(channel_->SetRenderer(2, &renderer2));
    878     EXPECT_TRUE(channel_->SetRender(true));
    879     EXPECT_EQ(0, renderer1.num_rendered_frames());
    880     EXPECT_EQ(0, renderer2.num_rendered_frames());
    881     std::vector<uint32> ssrcs;
    882     ssrcs.push_back(1);
    883     ssrcs.push_back(2);
    884     network_interface_.SetConferenceMode(true, ssrcs);
    885     EXPECT_TRUE(SendFrame());
    886     EXPECT_FRAME_ON_RENDERER_WAIT(
    887         renderer1, 1, DefaultCodec().width, DefaultCodec().height, kTimeout);
    888     EXPECT_FRAME_ON_RENDERER_WAIT(
    889         renderer2, 1, DefaultCodec().width, DefaultCodec().height, kTimeout);
    890     cricket::VideoMediaInfo info;
    891     EXPECT_TRUE(channel_->GetStats(cricket::StatsOptions(), &info));
    892 
    893     ASSERT_EQ(1U, info.senders.size());
    894     // TODO(whyuan): bytes_sent and bytes_rcvd are different. Are both payload?
    895     // For webrtc, bytes_sent does not include the RTP header length.
    896     EXPECT_GT(info.senders[0].bytes_sent, 0);
    897     EXPECT_EQ(NumRtpPackets(), info.senders[0].packets_sent);
    898     EXPECT_EQ(DefaultCodec().width, info.senders[0].send_frame_width);
    899     EXPECT_EQ(DefaultCodec().height, info.senders[0].send_frame_height);
    900 
    901     ASSERT_EQ(2U, info.receivers.size());
    902     for (size_t i = 0; i < info.receivers.size(); ++i) {
    903       EXPECT_EQ(1U, info.receivers[i].ssrcs().size());
    904       EXPECT_EQ(i + 1, info.receivers[i].ssrcs()[0]);
    905       EXPECT_EQ(NumRtpBytes(), info.receivers[i].bytes_rcvd);
    906       EXPECT_EQ(NumRtpPackets(), info.receivers[i].packets_rcvd);
    907       EXPECT_EQ(DefaultCodec().width, info.receivers[i].frame_width);
    908       EXPECT_EQ(DefaultCodec().height, info.receivers[i].frame_height);
    909     }
    910   }
    911   // Test that stats work properly for a conf call with multiple send streams.
    912   void GetStatsMultipleSendStreams() {
    913     // Normal setup; note that we set the SSRC explicitly to ensure that
    914     // it will come first in the senders map.
    915     EXPECT_TRUE(SetOneCodec(DefaultCodec()));
    916     cricket::VideoOptions vmo;
    917     vmo.conference_mode.Set(true);
    918     EXPECT_TRUE(channel_->SetOptions(vmo));
    919     EXPECT_TRUE(channel_->AddRecvStream(
    920         cricket::StreamParams::CreateLegacy(1234)));
    921     channel_->UpdateAspectRatio(640, 400);
    922     EXPECT_TRUE(SetSend(true));
    923     EXPECT_TRUE(channel_->SetRender(true));
    924     EXPECT_TRUE(SendFrame());
    925     EXPECT_TRUE_WAIT(NumRtpPackets() > 0, kTimeout);
    926     EXPECT_FRAME_WAIT(1, DefaultCodec().width, DefaultCodec().height, kTimeout);
    927 
    928     // Add an additional capturer, and hook up a renderer to receive it.
    929     cricket::FakeVideoRenderer renderer1;
    930     talk_base::scoped_ptr<cricket::FakeVideoCapturer> capturer(
    931       new cricket::FakeVideoCapturer);
    932     capturer->SetScreencast(true);
    933     const int kTestWidth = 160;
    934     const int kTestHeight = 120;
    935     cricket::VideoFormat format(kTestWidth, kTestHeight,
    936                                 cricket::VideoFormat::FpsToInterval(5),
    937                                 cricket::FOURCC_I420);
    938     EXPECT_EQ(cricket::CS_RUNNING, capturer->Start(format));
    939     EXPECT_TRUE(channel_->AddSendStream(
    940         cricket::StreamParams::CreateLegacy(5678)));
    941     EXPECT_TRUE(channel_->SetCapturer(5678, capturer.get()));
    942     EXPECT_TRUE(channel_->AddRecvStream(
    943         cricket::StreamParams::CreateLegacy(5678)));
    944     EXPECT_TRUE(channel_->SetRenderer(5678, &renderer1));
    945     EXPECT_TRUE(capturer->CaptureCustomFrame(
    946         kTestWidth, kTestHeight, cricket::FOURCC_I420));
    947     EXPECT_FRAME_ON_RENDERER_WAIT(
    948         renderer1, 1, kTestWidth, kTestHeight, kTimeout);
    949 
    950     // Get stats, and make sure they are correct for two senders.
    951     cricket::VideoMediaInfo info;
    952     EXPECT_TRUE(channel_->GetStats(cricket::StatsOptions(), &info));
    953     ASSERT_EQ(2U, info.senders.size());
    954     EXPECT_EQ(NumRtpPackets(),
    955         info.senders[0].packets_sent + info.senders[1].packets_sent);
    956     EXPECT_EQ(1U, info.senders[0].ssrcs().size());
    957     EXPECT_EQ(1234U, info.senders[0].ssrcs()[0]);
    958     EXPECT_EQ(DefaultCodec().width, info.senders[0].send_frame_width);
    959     EXPECT_EQ(DefaultCodec().height, info.senders[0].send_frame_height);
    960     EXPECT_EQ(1U, info.senders[1].ssrcs().size());
    961     EXPECT_EQ(5678U, info.senders[1].ssrcs()[0]);
    962     EXPECT_EQ(kTestWidth, info.senders[1].send_frame_width);
    963     EXPECT_EQ(kTestHeight, info.senders[1].send_frame_height);
    964     // The capturer must be unregistered here as it runs out of it's scope next.
    965     EXPECT_TRUE(channel_->SetCapturer(5678, NULL));
    966   }
    967 
    968   // Test that we can set the bandwidth.
    969   void SetSendBandwidth() {
    970     EXPECT_TRUE(channel_->SetStartSendBandwidth(64 * 1024));
    971     EXPECT_TRUE(channel_->SetMaxSendBandwidth(-1));  // <= 0 means unlimited.
    972     EXPECT_TRUE(channel_->SetMaxSendBandwidth(128 * 1024));
    973   }
    974   // Test that we can set the SSRC for the default send source.
    975   void SetSendSsrc() {
    976     EXPECT_TRUE(SetDefaultCodec());
    977     EXPECT_TRUE(SetSendStreamFormat(kSsrc, DefaultCodec()));
    978     EXPECT_TRUE(SetSend(true));
    979     EXPECT_TRUE(SendFrame());
    980     EXPECT_TRUE_WAIT(NumRtpPackets() > 0, kTimeout);
    981     uint32 ssrc = 0;
    982     talk_base::scoped_ptr<const talk_base::Buffer> p(GetRtpPacket(0));
    983     ParseRtpPacket(p.get(), NULL, NULL, NULL, NULL, &ssrc, NULL);
    984     EXPECT_EQ(kSsrc, ssrc);
    985     EXPECT_EQ(NumRtpPackets(), NumRtpPackets(ssrc));
    986     EXPECT_EQ(NumRtpBytes(), NumRtpBytes(ssrc));
    987     EXPECT_EQ(1, NumSentSsrcs());
    988     EXPECT_EQ(0, NumRtpPackets(kSsrc - 1));
    989     EXPECT_EQ(0, NumRtpBytes(kSsrc - 1));
    990   }
    991   // Test that we can set the SSRC even after codecs are set.
    992   void SetSendSsrcAfterSetCodecs() {
    993     // Remove stream added in Setup.
    994     EXPECT_TRUE(channel_->RemoveSendStream(kSsrc));
    995     EXPECT_TRUE(SetDefaultCodec());
    996     EXPECT_TRUE(channel_->AddSendStream(
    997         cricket::StreamParams::CreateLegacy(999)));
    998     EXPECT_TRUE(channel_->SetCapturer(999u, video_capturer_.get()));
    999     EXPECT_TRUE(SetSendStreamFormat(999u, DefaultCodec()));
   1000     EXPECT_TRUE(SetSend(true));
   1001     EXPECT_TRUE(WaitAndSendFrame(0));
   1002     EXPECT_TRUE_WAIT(NumRtpPackets() > 0, kTimeout);
   1003     uint32 ssrc = 0;
   1004     talk_base::scoped_ptr<const talk_base::Buffer> p(GetRtpPacket(0));
   1005     ParseRtpPacket(p.get(), NULL, NULL, NULL, NULL, &ssrc, NULL);
   1006     EXPECT_EQ(999u, ssrc);
   1007     EXPECT_EQ(NumRtpPackets(), NumRtpPackets(ssrc));
   1008     EXPECT_EQ(NumRtpBytes(), NumRtpBytes(ssrc));
   1009     EXPECT_EQ(1, NumSentSsrcs());
   1010     EXPECT_EQ(0, NumRtpPackets(kSsrc));
   1011     EXPECT_EQ(0, NumRtpBytes(kSsrc));
   1012   }
   1013   // Test that we can set the default video renderer before and after
   1014   // media is received.
   1015   void SetRenderer() {
   1016     uint8 data1[] = {
   1017         0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
   1018     };
   1019 
   1020     talk_base::Buffer packet1(data1, sizeof(data1));
   1021     talk_base::SetBE32(packet1.data() + 8, kSsrc);
   1022     channel_->SetRenderer(0, NULL);
   1023     EXPECT_TRUE(SetDefaultCodec());
   1024     EXPECT_TRUE(SetSend(true));
   1025     EXPECT_TRUE(channel_->SetRender(true));
   1026     EXPECT_EQ(0, renderer_.num_rendered_frames());
   1027     channel_->OnPacketReceived(&packet1, talk_base::PacketTime());
   1028     SetRendererAsDefault();
   1029     EXPECT_TRUE(SendFrame());
   1030     EXPECT_FRAME_WAIT(1, DefaultCodec().width, DefaultCodec().height, kTimeout);
   1031   }
   1032 
   1033   // Tests empty StreamParams is rejected.
   1034   void RejectEmptyStreamParams() {
   1035     // Remove the send stream that was added during Setup.
   1036     EXPECT_TRUE(channel_->RemoveSendStream(kSsrc));
   1037 
   1038     cricket::StreamParams empty;
   1039     EXPECT_FALSE(channel_->AddSendStream(empty));
   1040     EXPECT_TRUE(channel_->AddSendStream(
   1041         cricket::StreamParams::CreateLegacy(789u)));
   1042   }
   1043 
   1044   // Tests setting up and configuring a send stream.
   1045   void AddRemoveSendStreams() {
   1046     EXPECT_TRUE(SetOneCodec(DefaultCodec()));
   1047     EXPECT_TRUE(SetSend(true));
   1048     EXPECT_TRUE(channel_->SetRender(true));
   1049     EXPECT_TRUE(SendFrame());
   1050     EXPECT_FRAME_WAIT(1, DefaultCodec().width, DefaultCodec().height, kTimeout);
   1051     EXPECT_GE(2, NumRtpPackets());
   1052     uint32 ssrc = 0;
   1053     size_t last_packet = NumRtpPackets() - 1;
   1054     talk_base::scoped_ptr<const talk_base::Buffer>
   1055         p(GetRtpPacket(static_cast<int>(last_packet)));
   1056     ParseRtpPacket(p.get(), NULL, NULL, NULL, NULL, &ssrc, NULL);
   1057     EXPECT_EQ(kSsrc, ssrc);
   1058 
   1059     // Remove the send stream that was added during Setup.
   1060     EXPECT_TRUE(channel_->RemoveSendStream(kSsrc));
   1061     int rtp_packets = NumRtpPackets();
   1062 
   1063     EXPECT_TRUE(channel_->AddSendStream(
   1064         cricket::StreamParams::CreateLegacy(789u)));
   1065     EXPECT_TRUE(channel_->SetCapturer(789u, video_capturer_.get()));
   1066     EXPECT_EQ(rtp_packets, NumRtpPackets());
   1067     // Wait 30ms to guarantee the engine does not drop the frame.
   1068     EXPECT_TRUE(WaitAndSendFrame(30));
   1069     EXPECT_TRUE_WAIT(NumRtpPackets() > rtp_packets, kTimeout);
   1070 
   1071     last_packet = NumRtpPackets() - 1;
   1072     p.reset(GetRtpPacket(static_cast<int>(last_packet)));
   1073     ParseRtpPacket(p.get(), NULL, NULL, NULL, NULL, &ssrc, NULL);
   1074     EXPECT_EQ(789u, ssrc);
   1075   }
   1076 
   1077   // Tests adding streams already exists returns false.
   1078   void AddRecvStreamsAlreadyExist() {
   1079     cricket::VideoOptions vmo;
   1080     vmo.conference_mode.Set(true);
   1081     EXPECT_TRUE(channel_->SetOptions(vmo));
   1082 
   1083     EXPECT_FALSE(channel_->AddRecvStream(
   1084         cricket::StreamParams::CreateLegacy(0)));
   1085 
   1086     EXPECT_TRUE(channel_->AddRecvStream(
   1087         cricket::StreamParams::CreateLegacy(1)));
   1088     EXPECT_FALSE(channel_->AddRecvStream(
   1089         cricket::StreamParams::CreateLegacy(1)));
   1090 
   1091     EXPECT_TRUE(channel_->RemoveRecvStream(1));
   1092     EXPECT_FALSE(channel_->AddRecvStream(
   1093         cricket::StreamParams::CreateLegacy(0)));
   1094     EXPECT_TRUE(channel_->AddRecvStream(
   1095         cricket::StreamParams::CreateLegacy(1)));
   1096   }
   1097 
   1098   // Tests setting up and configuring multiple incoming streams.
   1099   void AddRemoveRecvStreams() {
   1100     cricket::FakeVideoRenderer renderer1, renderer2;
   1101     cricket::VideoOptions vmo;
   1102     vmo.conference_mode.Set(true);
   1103     EXPECT_TRUE(channel_->SetOptions(vmo));
   1104     // Ensure we can't set the renderer on a non-existent stream.
   1105     EXPECT_FALSE(channel_->SetRenderer(1, &renderer1));
   1106     EXPECT_FALSE(channel_->SetRenderer(2, &renderer2));
   1107     cricket::VideoRenderer* renderer;
   1108     EXPECT_FALSE(channel_->GetRenderer(1, &renderer));
   1109     EXPECT_FALSE(channel_->GetRenderer(2, &renderer));
   1110 
   1111     // Ensure we can add streams.
   1112     EXPECT_TRUE(channel_->AddRecvStream(
   1113         cricket::StreamParams::CreateLegacy(1)));
   1114     EXPECT_TRUE(channel_->AddRecvStream(
   1115         cricket::StreamParams::CreateLegacy(2)));
   1116     EXPECT_TRUE(channel_->GetRenderer(1, &renderer));
   1117     // Verify the first AddRecvStream hook up to the default renderer.
   1118     EXPECT_EQ(&renderer_, renderer);
   1119     EXPECT_TRUE(channel_->GetRenderer(2, &renderer));
   1120     EXPECT_TRUE(NULL == renderer);
   1121 
   1122     // Ensure we can now set the renderers.
   1123     EXPECT_TRUE(channel_->SetRenderer(1, &renderer1));
   1124     EXPECT_TRUE(channel_->SetRenderer(2, &renderer2));
   1125     EXPECT_TRUE(channel_->GetRenderer(1, &renderer));
   1126     EXPECT_TRUE(&renderer1 == renderer);
   1127     EXPECT_TRUE(channel_->GetRenderer(2, &renderer));
   1128     EXPECT_TRUE(&renderer2 == renderer);
   1129 
   1130     // Ensure we can change the renderers if needed.
   1131     EXPECT_TRUE(channel_->SetRenderer(1, &renderer2));
   1132     EXPECT_TRUE(channel_->SetRenderer(2, &renderer1));
   1133     EXPECT_TRUE(channel_->GetRenderer(1, &renderer));
   1134     EXPECT_TRUE(&renderer2 == renderer);
   1135     EXPECT_TRUE(channel_->GetRenderer(2, &renderer));
   1136     EXPECT_TRUE(&renderer1 == renderer);
   1137 
   1138     EXPECT_TRUE(channel_->RemoveRecvStream(2));
   1139     EXPECT_TRUE(channel_->RemoveRecvStream(1));
   1140     EXPECT_FALSE(channel_->GetRenderer(1, &renderer));
   1141     EXPECT_FALSE(channel_->GetRenderer(2, &renderer));
   1142   }
   1143 
   1144   // Tests setting up and configuring multiple incoming streams in a
   1145   // non-conference call.
   1146   void AddRemoveRecvStreamsNoConference() {
   1147     cricket::FakeVideoRenderer renderer1, renderer2;
   1148     // Ensure we can't set the renderer on a non-existent stream.
   1149     EXPECT_FALSE(channel_->SetRenderer(1, &renderer1));
   1150     EXPECT_FALSE(channel_->SetRenderer(2, &renderer2));
   1151     cricket::VideoRenderer* renderer;
   1152     EXPECT_FALSE(channel_->GetRenderer(1, &renderer));
   1153     EXPECT_FALSE(channel_->GetRenderer(2, &renderer));
   1154 
   1155     // Ensure we can add streams.
   1156     EXPECT_TRUE(channel_->AddRecvStream(
   1157         cricket::StreamParams::CreateLegacy(1)));
   1158     EXPECT_TRUE(channel_->AddRecvStream(
   1159         cricket::StreamParams::CreateLegacy(2)));
   1160     EXPECT_TRUE(channel_->GetRenderer(1, &renderer));
   1161     // Verify the first AddRecvStream hook up to the default renderer.
   1162     EXPECT_EQ(&renderer_, renderer);
   1163     EXPECT_TRUE(channel_->GetRenderer(2, &renderer));
   1164     EXPECT_TRUE(NULL == renderer);
   1165 
   1166     // Ensure we can now set the renderers.
   1167     EXPECT_TRUE(channel_->SetRenderer(1, &renderer1));
   1168     EXPECT_TRUE(channel_->SetRenderer(2, &renderer2));
   1169     EXPECT_TRUE(channel_->GetRenderer(1, &renderer));
   1170     EXPECT_TRUE(&renderer1 == renderer);
   1171     EXPECT_TRUE(channel_->GetRenderer(2, &renderer));
   1172     EXPECT_TRUE(&renderer2 == renderer);
   1173 
   1174     // Ensure we can change the renderers if needed.
   1175     EXPECT_TRUE(channel_->SetRenderer(1, &renderer2));
   1176     EXPECT_TRUE(channel_->SetRenderer(2, &renderer1));
   1177     EXPECT_TRUE(channel_->GetRenderer(1, &renderer));
   1178     EXPECT_TRUE(&renderer2 == renderer);
   1179     EXPECT_TRUE(channel_->GetRenderer(2, &renderer));
   1180     EXPECT_TRUE(&renderer1 == renderer);
   1181 
   1182     EXPECT_TRUE(channel_->RemoveRecvStream(2));
   1183     EXPECT_TRUE(channel_->RemoveRecvStream(1));
   1184     EXPECT_FALSE(channel_->GetRenderer(1, &renderer));
   1185     EXPECT_FALSE(channel_->GetRenderer(2, &renderer));
   1186   }
   1187 
   1188   // Test that no frames are rendered after the receive stream have been
   1189   // removed.
   1190   void AddRemoveRecvStreamAndRender() {
   1191     cricket::FakeVideoRenderer renderer1;
   1192     EXPECT_TRUE(SetDefaultCodec());
   1193     EXPECT_TRUE(SetSend(true));
   1194     EXPECT_TRUE(channel_->SetRender(true));
   1195     EXPECT_TRUE(channel_->AddRecvStream(
   1196         cricket::StreamParams::CreateLegacy(kSsrc)));
   1197     EXPECT_TRUE(channel_->SetRenderer(kSsrc, &renderer1));
   1198 
   1199     EXPECT_TRUE(SendFrame());
   1200     EXPECT_FRAME_ON_RENDERER_WAIT(
   1201         renderer1, 1, DefaultCodec().width, DefaultCodec().height, kTimeout);
   1202     EXPECT_TRUE(channel_->RemoveRecvStream(kSsrc));
   1203     // Send three more frames. This is to avoid that the test might be flaky
   1204     // due to frame dropping.
   1205     for (size_t i = 0; i < 3; ++i)
   1206       EXPECT_TRUE(WaitAndSendFrame(100));
   1207 
   1208     // Test that no more frames have been rendered.
   1209     EXPECT_EQ(1, renderer1.num_rendered_frames());
   1210 
   1211     // Re-add the stream again and make sure it renders.
   1212     EXPECT_TRUE(channel_->AddRecvStream(
   1213         cricket::StreamParams::CreateLegacy(kSsrc)));
   1214     // Force the next frame to be a key frame to make the receiving
   1215     // decoder happy.
   1216     EXPECT_TRUE(channel_->SendIntraFrame());
   1217 
   1218     EXPECT_TRUE(channel_->SetRenderer(kSsrc, &renderer1));
   1219     EXPECT_TRUE(SendFrame());
   1220     // Because the default channel is used, RemoveRecvStream above is not going
   1221     // to delete the channel. As a result the engine will continue to receive
   1222     // and decode the 3 frames sent above. So it is possible we will receive
   1223     // some (e.g. 1) of these 3 frames after the renderer is set again.
   1224     EXPECT_GT_FRAME_ON_RENDERER_WAIT(
   1225         renderer1, 2, DefaultCodec().width, DefaultCodec().height, kTimeout);
   1226     // Detach |renderer1| before exit as there might be frames come late.
   1227     EXPECT_TRUE(channel_->SetRenderer(kSsrc, NULL));
   1228   }
   1229 
   1230   // Tests the behavior of incoming streams in a conference scenario.
   1231   void SimulateConference() {
   1232     cricket::FakeVideoRenderer renderer1, renderer2;
   1233     EXPECT_TRUE(SetDefaultCodec());
   1234     cricket::VideoOptions vmo;
   1235     vmo.conference_mode.Set(true);
   1236     EXPECT_TRUE(channel_->SetOptions(vmo));
   1237     EXPECT_TRUE(SetSend(true));
   1238     EXPECT_TRUE(channel_->SetRender(true));
   1239     EXPECT_TRUE(channel_->AddRecvStream(
   1240         cricket::StreamParams::CreateLegacy(1)));
   1241     EXPECT_TRUE(channel_->AddRecvStream(
   1242         cricket::StreamParams::CreateLegacy(2)));
   1243     EXPECT_TRUE(channel_->SetRenderer(1, &renderer1));
   1244     EXPECT_TRUE(channel_->SetRenderer(2, &renderer2));
   1245     EXPECT_EQ(0, renderer1.num_rendered_frames());
   1246     EXPECT_EQ(0, renderer2.num_rendered_frames());
   1247     std::vector<uint32> ssrcs;
   1248     ssrcs.push_back(1);
   1249     ssrcs.push_back(2);
   1250     network_interface_.SetConferenceMode(true, ssrcs);
   1251     EXPECT_TRUE(SendFrame());
   1252     EXPECT_FRAME_ON_RENDERER_WAIT(
   1253         renderer1, 1, DefaultCodec().width, DefaultCodec().height, kTimeout);
   1254     EXPECT_FRAME_ON_RENDERER_WAIT(
   1255         renderer2, 1, DefaultCodec().width, DefaultCodec().height, kTimeout);
   1256 
   1257     talk_base::scoped_ptr<const talk_base::Buffer> p(GetRtpPacket(0));
   1258     EXPECT_EQ(DefaultCodec().id, GetPayloadType(p.get()));
   1259     EXPECT_EQ(DefaultCodec().width, renderer1.width());
   1260     EXPECT_EQ(DefaultCodec().height, renderer1.height());
   1261     EXPECT_EQ(DefaultCodec().width, renderer2.width());
   1262     EXPECT_EQ(DefaultCodec().height, renderer2.height());
   1263     EXPECT_TRUE(channel_->RemoveRecvStream(2));
   1264     EXPECT_TRUE(channel_->RemoveRecvStream(1));
   1265   }
   1266 
   1267   // Tests that we can add and remove capturers and frames are sent out properly
   1268   void AddRemoveCapturer() {
   1269     cricket::VideoCodec codec = DefaultCodec();
   1270     codec.width = 320;
   1271     codec.height = 240;
   1272     const int time_between_send = TimeBetweenSend(codec);
   1273     EXPECT_TRUE(SetOneCodec(codec));
   1274     EXPECT_TRUE(SetSend(true));
   1275     EXPECT_TRUE(channel_->SetRender(true));
   1276     EXPECT_EQ(0, renderer_.num_rendered_frames());
   1277     EXPECT_TRUE(SendFrame());
   1278     EXPECT_FRAME_WAIT(1, codec.width, codec.height, kTimeout);
   1279     talk_base::scoped_ptr<cricket::FakeVideoCapturer> capturer(
   1280         new cricket::FakeVideoCapturer);
   1281     capturer->SetScreencast(true);
   1282     cricket::VideoFormat format(480, 360,
   1283                                 cricket::VideoFormat::FpsToInterval(30),
   1284                                 cricket::FOURCC_I420);
   1285     EXPECT_EQ(cricket::CS_RUNNING, capturer->Start(format));
   1286     // All capturers start generating frames with the same timestamp. ViE does
   1287     // not allow the same timestamp to be used. Capture one frame before
   1288     // associating the capturer with the channel.
   1289     EXPECT_TRUE(capturer->CaptureCustomFrame(format.width, format.height,
   1290                                              cricket::FOURCC_I420));
   1291 
   1292     int captured_frames = 1;
   1293     for (int iterations = 0; iterations < 2; ++iterations) {
   1294       EXPECT_TRUE(channel_->SetCapturer(kSsrc, capturer.get()));
   1295       talk_base::Thread::Current()->ProcessMessages(time_between_send);
   1296       EXPECT_TRUE(capturer->CaptureCustomFrame(format.width, format.height,
   1297                                                cricket::FOURCC_I420));
   1298       ++captured_frames;
   1299       // Wait until frame of right size is captured.
   1300       EXPECT_TRUE_WAIT(renderer_.num_rendered_frames() >= captured_frames &&
   1301                        format.width == renderer_.width() &&
   1302                        format.height == renderer_.height() &&
   1303                        !renderer_.black_frame(), kTimeout);
   1304       EXPECT_GE(renderer_.num_rendered_frames(), captured_frames);
   1305       EXPECT_EQ(format.width, renderer_.width());
   1306       EXPECT_EQ(format.height, renderer_.height());
   1307       captured_frames = renderer_.num_rendered_frames() + 1;
   1308       EXPECT_FALSE(renderer_.black_frame());
   1309       EXPECT_TRUE(channel_->SetCapturer(kSsrc, NULL));
   1310       // Make sure a black frame is generated within the specified timeout.
   1311       // The black frame should be the resolution of the send codec.
   1312       EXPECT_TRUE_WAIT(renderer_.num_rendered_frames() >= captured_frames &&
   1313                        codec.width == renderer_.width() &&
   1314                        codec.height == renderer_.height() &&
   1315                        renderer_.black_frame(), kTimeout);
   1316       EXPECT_GE(renderer_.num_rendered_frames(), captured_frames);
   1317       EXPECT_EQ(codec.width, renderer_.width());
   1318       EXPECT_EQ(codec.height, renderer_.height());
   1319       EXPECT_TRUE(renderer_.black_frame());
   1320 
   1321       // The black frame has the same timestamp as the next frame since it's
   1322       // timestamp is set to the last frame's timestamp + interval. WebRTC will
   1323       // not render a frame with the same timestamp so capture another frame
   1324       // with the frame capturer to increment the next frame's timestamp.
   1325       EXPECT_TRUE(capturer->CaptureCustomFrame(format.width, format.height,
   1326                                                cricket::FOURCC_I420));
   1327     }
   1328   }
   1329 
   1330   // Tests that if RemoveCapturer is called without a capturer ever being
   1331   // added, the plugin shouldn't crash (and no black frame should be sent).
   1332   void RemoveCapturerWithoutAdd() {
   1333     EXPECT_TRUE(SetOneCodec(DefaultCodec()));
   1334     EXPECT_TRUE(SetSend(true));
   1335     EXPECT_TRUE(channel_->SetRender(true));
   1336     EXPECT_EQ(0, renderer_.num_rendered_frames());
   1337     EXPECT_TRUE(SendFrame());
   1338     EXPECT_FRAME_WAIT(1, 640, 400, kTimeout);
   1339     // Remove the capturer.
   1340     EXPECT_TRUE(channel_->SetCapturer(kSsrc, NULL));
   1341     // Wait for one black frame for removing the capturer.
   1342     EXPECT_FRAME_WAIT(2, 640, 400, kTimeout);
   1343 
   1344     // No capturer was added, so this RemoveCapturer should
   1345     // fail.
   1346     EXPECT_FALSE(channel_->SetCapturer(kSsrc, NULL));
   1347     talk_base::Thread::Current()->ProcessMessages(300);
   1348     // Verify no more frames were sent.
   1349     EXPECT_EQ(2, renderer_.num_rendered_frames());
   1350   }
   1351 
   1352   // Tests that we can add and remove capturer as unique sources.
   1353   void AddRemoveCapturerMultipleSources() {
   1354     // WebRTC implementation will drop frames if pushed to quickly. Wait the
   1355     // interval time to avoid that.
   1356     // WebRTC implementation will drop frames if pushed to quickly. Wait the
   1357     // interval time to avoid that.
   1358     // Set up the stream associated with the engine.
   1359     EXPECT_TRUE(channel_->AddRecvStream(
   1360         cricket::StreamParams::CreateLegacy(kSsrc)));
   1361     EXPECT_TRUE(channel_->SetRenderer(kSsrc, &renderer_));
   1362     cricket::VideoFormat capture_format;  // default format
   1363     capture_format.interval = cricket::VideoFormat::FpsToInterval(30);
   1364     // Set up additional stream 1.
   1365     cricket::FakeVideoRenderer renderer1;
   1366     EXPECT_FALSE(channel_->SetRenderer(1, &renderer1));
   1367     EXPECT_TRUE(channel_->AddRecvStream(
   1368         cricket::StreamParams::CreateLegacy(1)));
   1369     EXPECT_TRUE(channel_->SetRenderer(1, &renderer1));
   1370     EXPECT_TRUE(channel_->AddSendStream(
   1371         cricket::StreamParams::CreateLegacy(1)));
   1372     talk_base::scoped_ptr<cricket::FakeVideoCapturer> capturer1(
   1373         new cricket::FakeVideoCapturer);
   1374     capturer1->SetScreencast(true);
   1375     EXPECT_EQ(cricket::CS_RUNNING, capturer1->Start(capture_format));
   1376     // Set up additional stream 2.
   1377     cricket::FakeVideoRenderer renderer2;
   1378     EXPECT_FALSE(channel_->SetRenderer(2, &renderer2));
   1379     EXPECT_TRUE(channel_->AddRecvStream(
   1380         cricket::StreamParams::CreateLegacy(2)));
   1381     EXPECT_TRUE(channel_->SetRenderer(2, &renderer2));
   1382     EXPECT_TRUE(channel_->AddSendStream(
   1383         cricket::StreamParams::CreateLegacy(2)));
   1384     talk_base::scoped_ptr<cricket::FakeVideoCapturer> capturer2(
   1385         new cricket::FakeVideoCapturer);
   1386     capturer2->SetScreencast(true);
   1387     EXPECT_EQ(cricket::CS_RUNNING, capturer2->Start(capture_format));
   1388     // State for all the streams.
   1389     EXPECT_TRUE(SetOneCodec(DefaultCodec()));
   1390     // A limitation in the lmi implementation requires that SetCapturer() is
   1391     // called after SetOneCodec().
   1392     // TODO(hellner): this seems like an unnecessary constraint, fix it.
   1393     EXPECT_TRUE(channel_->SetCapturer(1, capturer1.get()));
   1394     EXPECT_TRUE(channel_->SetCapturer(2, capturer2.get()));
   1395     EXPECT_TRUE(SetSend(true));
   1396     EXPECT_TRUE(channel_->SetRender(true));
   1397     // Test capturer associated with engine.
   1398     const int kTestWidth = 160;
   1399     const int kTestHeight = 120;
   1400     EXPECT_TRUE(capturer1->CaptureCustomFrame(
   1401         kTestWidth, kTestHeight, cricket::FOURCC_I420));
   1402     EXPECT_FRAME_ON_RENDERER_WAIT(
   1403         renderer1, 1, kTestWidth, kTestHeight, kTimeout);
   1404     // Capture a frame with additional capturer2, frames should be received
   1405     EXPECT_TRUE(capturer2->CaptureCustomFrame(
   1406         kTestWidth, kTestHeight, cricket::FOURCC_I420));
   1407     EXPECT_FRAME_ON_RENDERER_WAIT(
   1408         renderer2, 1, kTestWidth, kTestHeight, kTimeout);
   1409     // Successfully remove the capturer.
   1410     EXPECT_TRUE(channel_->SetCapturer(kSsrc, NULL));
   1411     // Fail to re-remove the capturer.
   1412     EXPECT_FALSE(channel_->SetCapturer(kSsrc, NULL));
   1413     // The capturers must be unregistered here as it runs out of it's scope
   1414     // next.
   1415     EXPECT_TRUE(channel_->SetCapturer(1, NULL));
   1416     EXPECT_TRUE(channel_->SetCapturer(2, NULL));
   1417   }
   1418 
   1419   void HighAspectHighHeightCapturer() {
   1420     const int kWidth  = 80;
   1421     const int kHeight = 10000;
   1422     const int kScaledWidth = 20;
   1423     const int kScaledHeight = 2500;
   1424 
   1425     cricket::VideoCodec codec(DefaultCodec());
   1426     EXPECT_TRUE(SetOneCodec(codec));
   1427     EXPECT_TRUE(SetSend(true));
   1428 
   1429     cricket::FakeVideoRenderer renderer;
   1430     EXPECT_TRUE(channel_->AddRecvStream(
   1431         cricket::StreamParams::CreateLegacy(kSsrc)));
   1432     EXPECT_TRUE(channel_->SetRenderer(kSsrc, &renderer));
   1433     EXPECT_TRUE(channel_->SetRender(true));
   1434     EXPECT_EQ(0, renderer.num_rendered_frames());
   1435 
   1436     EXPECT_TRUE(SendFrame());
   1437     EXPECT_GT_FRAME_ON_RENDERER_WAIT(
   1438         renderer, 1, codec.width, codec.height, kTimeout);
   1439 
   1440     // Registering an external capturer is currently the same as screen casting
   1441     // (update the test when this changes).
   1442     talk_base::scoped_ptr<cricket::FakeVideoCapturer> capturer(
   1443         new cricket::FakeVideoCapturer);
   1444     capturer->SetScreencast(true);
   1445     const std::vector<cricket::VideoFormat>* formats =
   1446         capturer->GetSupportedFormats();
   1447     cricket::VideoFormat capture_format = (*formats)[0];
   1448     EXPECT_EQ(cricket::CS_RUNNING, capturer->Start(capture_format));
   1449     // Capture frame to not get same frame timestamps as previous capturer.
   1450     capturer->CaptureFrame();
   1451     EXPECT_TRUE(channel_->SetCapturer(kSsrc, capturer.get()));
   1452     EXPECT_TRUE(talk_base::Thread::Current()->ProcessMessages(30));
   1453     EXPECT_TRUE(capturer->CaptureCustomFrame(kWidth, kHeight,
   1454                                              cricket::FOURCC_ARGB));
   1455     EXPECT_TRUE(capturer->CaptureFrame());
   1456     EXPECT_GT_FRAME_ON_RENDERER_WAIT(
   1457         renderer, 2, kScaledWidth, kScaledHeight, kTimeout);
   1458     EXPECT_TRUE(channel_->SetCapturer(kSsrc, NULL));
   1459   }
   1460 
   1461   // Tests that we can adapt video resolution with 16:10 aspect ratio properly.
   1462   void AdaptResolution16x10() {
   1463     cricket::VideoCodec codec(DefaultCodec());
   1464     codec.width = 640;
   1465     codec.height = 400;
   1466     SendAndReceive(codec);
   1467     codec.width /= 2;
   1468     codec.height /= 2;
   1469     // Adapt the resolution.
   1470     EXPECT_TRUE(SetOneCodec(codec));
   1471     EXPECT_TRUE(WaitAndSendFrame(30));
   1472     EXPECT_FRAME_WAIT(2, codec.width, codec.height, kTimeout);
   1473   }
   1474   // Tests that we can adapt video resolution with 4:3 aspect ratio properly.
   1475   void AdaptResolution4x3() {
   1476     cricket::VideoCodec codec(DefaultCodec());
   1477     codec.width = 640;
   1478     codec.height = 400;
   1479     SendAndReceive(codec);
   1480     codec.width /= 2;
   1481     codec.height /= 2;
   1482     // Adapt the resolution.
   1483     EXPECT_TRUE(SetOneCodec(codec));
   1484     EXPECT_TRUE(WaitAndSendFrame(30));
   1485     EXPECT_FRAME_WAIT(2, codec.width, codec.height, kTimeout);
   1486   }
   1487   // Tests that we can drop all frames properly.
   1488   void AdaptDropAllFrames() {
   1489     // Set the channel codec's resolution to 0, which will require the adapter
   1490     // to drop all frames.
   1491     cricket::VideoCodec codec(DefaultCodec());
   1492     codec.width = codec.height = codec.framerate = 0;
   1493     EXPECT_TRUE(SetOneCodec(codec));
   1494     EXPECT_TRUE(SetSend(true));
   1495     EXPECT_TRUE(channel_->SetRender(true));
   1496     EXPECT_EQ(0, renderer_.num_rendered_frames());
   1497     EXPECT_TRUE(SendFrame());
   1498     EXPECT_TRUE(SendFrame());
   1499     talk_base::Thread::Current()->ProcessMessages(500);
   1500     EXPECT_EQ(0, renderer_.num_rendered_frames());
   1501   }
   1502   // Tests that we can reduce the frame rate on demand properly.
   1503   // TODO(fbarchard): This test is flakey on pulse.  Fix and re-enable
   1504   void AdaptFramerate() {
   1505     cricket::VideoCodec codec(DefaultCodec());
   1506     int frame_count = 0;
   1507     // The capturer runs at 30 fps. The channel requires 30 fps.
   1508     EXPECT_TRUE(SetOneCodec(codec));
   1509     EXPECT_TRUE(SetSend(true));
   1510     EXPECT_TRUE(channel_->SetRender(true));
   1511     EXPECT_EQ(frame_count, renderer_.num_rendered_frames());
   1512     EXPECT_TRUE(WaitAndSendFrame(0));  // Should be rendered.
   1513     EXPECT_TRUE(WaitAndSendFrame(30));  // Should be rendered.
   1514     frame_count += 2;
   1515     EXPECT_FRAME_WAIT(frame_count, codec.width, codec.height, kTimeout);
   1516     talk_base::scoped_ptr<const talk_base::Buffer> p(GetRtpPacket(0));
   1517     EXPECT_EQ(codec.id, GetPayloadType(p.get()));
   1518 
   1519     // The channel requires 15 fps.
   1520     codec.framerate = 15;
   1521     EXPECT_TRUE(SetOneCodec(codec));
   1522     EXPECT_TRUE(WaitAndSendFrame(0));  // Should be rendered.
   1523     EXPECT_TRUE(WaitAndSendFrame(30));  // Should be dropped.
   1524     EXPECT_TRUE(WaitAndSendFrame(30));  // Should be rendered.
   1525     frame_count += 2;
   1526     EXPECT_EQ_WAIT(frame_count, renderer_.num_rendered_frames(), kTimeout);
   1527 
   1528     // The channel requires 10 fps.
   1529     codec.framerate = 10;
   1530     EXPECT_TRUE(SetOneCodec(codec));
   1531     EXPECT_TRUE(WaitAndSendFrame(0));  // Should be rendered.
   1532     EXPECT_TRUE(WaitAndSendFrame(30));  // Should be dropped.
   1533     EXPECT_TRUE(WaitAndSendFrame(30));  // Should be dropped.
   1534     EXPECT_TRUE(WaitAndSendFrame(30));  // Should be rendered.
   1535     frame_count += 2;
   1536     EXPECT_EQ_WAIT(frame_count, renderer_.num_rendered_frames(), kTimeout);
   1537 
   1538     // The channel requires 8 fps. The adapter adapts to 10 fps, which is the
   1539     // closest factor of 30.
   1540     codec.framerate = 8;
   1541     EXPECT_TRUE(SetOneCodec(codec));
   1542     EXPECT_TRUE(WaitAndSendFrame(0));  // Should be rendered.
   1543     EXPECT_TRUE(WaitAndSendFrame(30));  // Should be dropped.
   1544     EXPECT_TRUE(WaitAndSendFrame(30));  // Should be dropped.
   1545     EXPECT_TRUE(WaitAndSendFrame(30));  // Should be rendered.
   1546     frame_count += 2;
   1547     EXPECT_EQ_WAIT(frame_count, renderer_.num_rendered_frames(), kTimeout);
   1548   }
   1549   // Tests that we can set the send stream format properly.
   1550   void SetSendStreamFormat() {
   1551     cricket::VideoCodec codec(DefaultCodec());
   1552     SendAndReceive(codec);
   1553     int frame_count = 1;
   1554     EXPECT_FRAME_WAIT(frame_count, codec.width, codec.height, kTimeout);
   1555 
   1556     // Adapt the resolution and frame rate to half.
   1557     cricket::VideoFormat format(
   1558         codec.width / 2,
   1559         codec.height / 2,
   1560         cricket::VideoFormat::FpsToInterval(codec.framerate / 2),
   1561         cricket::FOURCC_I420);
   1562     // The SSRC differs from the send SSRC.
   1563     EXPECT_FALSE(channel_->SetSendStreamFormat(kSsrc - 1, format));
   1564     EXPECT_TRUE(channel_->SetSendStreamFormat(kSsrc, format));
   1565 
   1566     EXPECT_TRUE(WaitAndSendFrame(30));  // Should be dropped.
   1567     EXPECT_TRUE(WaitAndSendFrame(30));  // Should be rendered.
   1568     EXPECT_TRUE(WaitAndSendFrame(30));  // Should be dropped.
   1569     frame_count += 1;
   1570     EXPECT_FRAME_WAIT(frame_count, format.width, format.height, kTimeout);
   1571 
   1572     // Adapt the resolution to 0x0, which should drop all frames.
   1573     format.width = 0;
   1574     format.height = 0;
   1575     EXPECT_TRUE(channel_->SetSendStreamFormat(kSsrc, format));
   1576     EXPECT_TRUE(SendFrame());
   1577     EXPECT_TRUE(SendFrame());
   1578     talk_base::Thread::Current()->ProcessMessages(500);
   1579     EXPECT_EQ(frame_count, renderer_.num_rendered_frames());
   1580   }
   1581   // Test that setting send stream format to 0x0 resolution will result in
   1582   // frames being dropped.
   1583   void SetSendStreamFormat0x0() {
   1584     EXPECT_TRUE(SetOneCodec(DefaultCodec()));
   1585     EXPECT_TRUE(SetSendStreamFormat(kSsrc, DefaultCodec()));
   1586     EXPECT_TRUE(SetSend(true));
   1587     EXPECT_TRUE(channel_->SetRender(true));
   1588     EXPECT_EQ(0, renderer_.num_rendered_frames());
   1589     // This frame should be received.
   1590     EXPECT_TRUE(SendFrame());
   1591     EXPECT_FRAME_WAIT(1, DefaultCodec().width, DefaultCodec().height, kTimeout);
   1592     const int64 interval = cricket::VideoFormat::FpsToInterval(
   1593         DefaultCodec().framerate);
   1594     cricket::VideoFormat format(
   1595         0,
   1596         0,
   1597         interval,
   1598         cricket::FOURCC_I420);
   1599     EXPECT_TRUE(channel_->SetSendStreamFormat(kSsrc, format));
   1600     // This frame should not be received.
   1601     EXPECT_TRUE(WaitAndSendFrame(
   1602         static_cast<int>(interval/talk_base::kNumNanosecsPerMillisec)));
   1603     talk_base::Thread::Current()->ProcessMessages(500);
   1604     EXPECT_EQ(1, renderer_.num_rendered_frames());
   1605   }
   1606 
   1607   // Tests that we can mute and unmute the channel properly.
   1608   void MuteStream() {
   1609     int frame_count = 0;
   1610     EXPECT_TRUE(SetDefaultCodec());
   1611     cricket::FakeVideoCapturer video_capturer;
   1612     video_capturer.Start(
   1613         cricket::VideoFormat(
   1614             640, 480,
   1615             cricket::VideoFormat::FpsToInterval(30),
   1616             cricket::FOURCC_I420));
   1617     EXPECT_TRUE(channel_->SetCapturer(kSsrc, &video_capturer));
   1618     EXPECT_TRUE(SetSend(true));
   1619     EXPECT_TRUE(channel_->SetRender(true));
   1620     EXPECT_EQ(frame_count, renderer_.num_rendered_frames());
   1621 
   1622     // Mute the channel and expect black output frame.
   1623     EXPECT_TRUE(channel_->MuteStream(kSsrc, true));
   1624     EXPECT_TRUE(video_capturer.CaptureFrame());
   1625     ++frame_count;
   1626     EXPECT_EQ_WAIT(frame_count, renderer_.num_rendered_frames(), kTimeout);
   1627     EXPECT_TRUE(renderer_.black_frame());
   1628 
   1629     // Unmute the channel and expect non-black output frame.
   1630     EXPECT_TRUE(channel_->MuteStream(kSsrc, false));
   1631     EXPECT_TRUE(talk_base::Thread::Current()->ProcessMessages(30));
   1632     EXPECT_TRUE(video_capturer.CaptureFrame());
   1633     ++frame_count;
   1634     EXPECT_EQ_WAIT(frame_count, renderer_.num_rendered_frames(), kTimeout);
   1635     EXPECT_FALSE(renderer_.black_frame());
   1636 
   1637     // Test that we can also Mute using the correct send stream SSRC.
   1638     EXPECT_TRUE(channel_->MuteStream(kSsrc, true));
   1639     EXPECT_TRUE(talk_base::Thread::Current()->ProcessMessages(30));
   1640     EXPECT_TRUE(video_capturer.CaptureFrame());
   1641     ++frame_count;
   1642     EXPECT_EQ_WAIT(frame_count, renderer_.num_rendered_frames(), kTimeout);
   1643     EXPECT_TRUE(renderer_.black_frame());
   1644 
   1645     EXPECT_TRUE(channel_->MuteStream(kSsrc, false));
   1646     EXPECT_TRUE(talk_base::Thread::Current()->ProcessMessages(30));
   1647     EXPECT_TRUE(video_capturer.CaptureFrame());
   1648     ++frame_count;
   1649     EXPECT_EQ_WAIT(frame_count, renderer_.num_rendered_frames(), kTimeout);
   1650     EXPECT_FALSE(renderer_.black_frame());
   1651 
   1652     // Test that muting an invalid stream fails.
   1653     EXPECT_FALSE(channel_->MuteStream(kSsrc+1, true));
   1654     EXPECT_TRUE(channel_->SetCapturer(kSsrc, NULL));
   1655   }
   1656 
   1657   // Test that multiple send streams can be created and deleted properly.
   1658   void MultipleSendStreams() {
   1659     // Remove stream added in Setup. I.e. remove stream corresponding to default
   1660     // channel.
   1661     EXPECT_TRUE(channel_->RemoveSendStream(kSsrc));
   1662     const unsigned int kSsrcsSize = sizeof(kSsrcs4)/sizeof(kSsrcs4[0]);
   1663     for (unsigned int i = 0; i < kSsrcsSize; ++i) {
   1664       EXPECT_TRUE(channel_->AddSendStream(
   1665           cricket::StreamParams::CreateLegacy(kSsrcs4[i])));
   1666     }
   1667     // Delete one of the non default channel streams, let the destructor delete
   1668     // the remaining ones.
   1669     EXPECT_TRUE(channel_->RemoveSendStream(kSsrcs4[kSsrcsSize - 1]));
   1670     // Stream should already be deleted.
   1671     EXPECT_FALSE(channel_->RemoveSendStream(kSsrcs4[kSsrcsSize - 1]));
   1672   }
   1673 
   1674 
   1675   // Two streams one channel tests.
   1676 
   1677   // Tests that we can send and receive frames.
   1678   void TwoStreamsSendAndReceive(const cricket::VideoCodec& codec) {
   1679     SetUpSecondStream();
   1680     // Test sending and receiving on first stream.
   1681     SendAndReceive(codec);
   1682     // Test sending and receiving on second stream.
   1683     EXPECT_EQ_WAIT(1, renderer2_.num_rendered_frames(), kTimeout);
   1684     EXPECT_EQ(2, NumRtpPackets());
   1685     EXPECT_EQ(1, renderer2_.num_rendered_frames());
   1686   }
   1687 
   1688   // Set up 2 streams where the first stream uses the default channel.
   1689   // Then disconnect the first stream and verify default channel becomes
   1690   // available.
   1691   // Then add a new stream with |new_ssrc|. The new stream should re-use the
   1692   // default channel.
   1693   void TwoStreamsReUseFirstStream(const cricket::VideoCodec& codec) {
   1694     SetUpSecondStream();
   1695     // Default channel used by the first stream.
   1696     EXPECT_EQ(kSsrc, channel_->GetDefaultChannelSsrc());
   1697     EXPECT_TRUE(channel_->RemoveRecvStream(kSsrc));
   1698     EXPECT_FALSE(channel_->RemoveRecvStream(kSsrc));
   1699     EXPECT_TRUE(channel_->RemoveSendStream(kSsrc));
   1700     EXPECT_FALSE(channel_->RemoveSendStream(kSsrc));
   1701     // Default channel is no longer used by a stream.
   1702     EXPECT_EQ(0u, channel_->GetDefaultChannelSsrc());
   1703     SetRendererAsDefault();
   1704     uint32 new_ssrc = kSsrc + 100;
   1705     EXPECT_TRUE(channel_->AddSendStream(
   1706         cricket::StreamParams::CreateLegacy(new_ssrc)));
   1707     // Re-use default channel.
   1708     EXPECT_EQ(new_ssrc, channel_->GetDefaultChannelSsrc());
   1709     EXPECT_FALSE(channel_->AddSendStream(
   1710         cricket::StreamParams::CreateLegacy(new_ssrc)));
   1711     EXPECT_TRUE(channel_->AddRecvStream(
   1712         cricket::StreamParams::CreateLegacy(new_ssrc)));
   1713     EXPECT_FALSE(channel_->AddRecvStream(
   1714         cricket::StreamParams::CreateLegacy(new_ssrc)));
   1715 
   1716     EXPECT_TRUE(channel_->SetCapturer(new_ssrc, video_capturer_.get()));
   1717 
   1718     SendAndReceive(codec);
   1719     EXPECT_TRUE(channel_->RemoveSendStream(new_ssrc));
   1720     EXPECT_EQ(0u, channel_->GetDefaultChannelSsrc());
   1721   }
   1722 
   1723   // Tests that we can send and receive frames with early receive.
   1724   void TwoStreamsSendAndUnsignalledRecv(const cricket::VideoCodec& codec) {
   1725     cricket::VideoOptions vmo;
   1726     vmo.conference_mode.Set(true);
   1727     vmo.unsignalled_recv_stream_limit.Set(1);
   1728     EXPECT_TRUE(channel_->SetOptions(vmo));
   1729     SetUpSecondStreamWithNoRecv();
   1730     // Test sending and receiving on first stream.
   1731     EXPECT_TRUE(channel_->SetRender(true));
   1732     Send(codec);
   1733     EXPECT_EQ_WAIT(2, NumRtpPackets(), kTimeout);
   1734     EXPECT_EQ_WAIT(1, renderer_.num_rendered_frames(), kTimeout);
   1735     // The first send is not expected to yield frames, because the ssrc
   1736     // is not signalled yet. With unsignalled recv enabled, we will drop frames
   1737     // instead of packets.
   1738     EXPECT_EQ(0, renderer2_.num_rendered_frames());
   1739     // Give a chance for the decoder to process before adding the receiver.
   1740     talk_base::Thread::Current()->ProcessMessages(100);
   1741     // Test sending and receiving on second stream.
   1742     EXPECT_TRUE(channel_->AddRecvStream(
   1743         cricket::StreamParams::CreateLegacy(kSsrc + 2)));
   1744     EXPECT_TRUE(channel_->SetRenderer(kSsrc + 2, &renderer2_));
   1745     SendFrame();
   1746     EXPECT_EQ_WAIT(2, renderer_.num_rendered_frames(), kTimeout);
   1747     EXPECT_EQ(4, NumRtpPackets());
   1748     // The second send is expected to yield frame as the ssrc is signalled now.
   1749     // Decode should succeed here, though we received the key frame earlier.
   1750     // Without early recv, we would have dropped it and decoding would have
   1751     // failed.
   1752     EXPECT_EQ_WAIT(1, renderer2_.num_rendered_frames(), kTimeout);
   1753   }
   1754 
   1755   // Tests that we cannot receive key frames with unsignalled recv disabled.
   1756   void TwoStreamsSendAndFailUnsignalledRecv(const cricket::VideoCodec& codec) {
   1757     cricket::VideoOptions vmo;
   1758     vmo.conference_mode.Set(true);
   1759     vmo.unsignalled_recv_stream_limit.Set(0);
   1760     EXPECT_TRUE(channel_->SetOptions(vmo));
   1761     SetUpSecondStreamWithNoRecv();
   1762     // Test sending and receiving on first stream.
   1763     EXPECT_TRUE(channel_->SetRender(true));
   1764     Send(codec);
   1765     EXPECT_EQ_WAIT(2, NumRtpPackets(), kTimeout);
   1766     talk_base::Thread::Current()->ProcessMessages(100);
   1767     EXPECT_EQ_WAIT(1, renderer_.num_rendered_frames(), kTimeout);
   1768     EXPECT_EQ_WAIT(0, renderer2_.num_rendered_frames(), kTimeout);
   1769     // Give a chance for the decoder to process before adding the receiver.
   1770     talk_base::Thread::Current()->ProcessMessages(10);
   1771     // Test sending and receiving on second stream.
   1772     EXPECT_TRUE(channel_->AddRecvStream(
   1773         cricket::StreamParams::CreateLegacy(kSsrc + 2)));
   1774     EXPECT_TRUE(channel_->SetRenderer(kSsrc + 2, &renderer2_));
   1775     SendFrame();
   1776     EXPECT_TRUE_WAIT(renderer_.num_rendered_frames() >= 1, kTimeout);
   1777     EXPECT_EQ_WAIT(4, NumRtpPackets(), kTimeout);
   1778     // We dont expect any frames here, because the key frame would have been
   1779     // lost in the earlier packet. This is the case we want to solve with early
   1780     // receive.
   1781     EXPECT_EQ(0, renderer2_.num_rendered_frames());
   1782   }
   1783 
   1784   // Tests that we drop key frames when conference mode is disabled and we
   1785   // receive rtp packets on unsignalled streams.
   1786   void TwoStreamsSendAndFailUnsignalledRecvInOneToOne(
   1787       const cricket::VideoCodec& codec) {
   1788     cricket::VideoOptions vmo;
   1789     vmo.conference_mode.Set(false);
   1790     vmo.unsignalled_recv_stream_limit.Set(1);
   1791     EXPECT_TRUE(channel_->SetOptions(vmo));
   1792     SetUpSecondStreamWithNoRecv();
   1793     // Test sending and receiving on first stream.
   1794     EXPECT_TRUE(channel_->SetRender(true));
   1795     Send(codec);
   1796     EXPECT_EQ_WAIT(2, NumRtpPackets(), kTimeout);
   1797     // In one-to-one mode, we deliver frames to the default channel if there
   1798     // is no registered recv channel for the ssrc.
   1799     EXPECT_TRUE_WAIT(renderer_.num_rendered_frames() >= 1, kTimeout);
   1800     // Give a chance for the decoder to process before adding the receiver.
   1801     talk_base::Thread::Current()->ProcessMessages(100);
   1802     // Test sending and receiving on second stream.
   1803     EXPECT_TRUE(channel_->AddRecvStream(
   1804         cricket::StreamParams::CreateLegacy(kSsrc + 2)));
   1805     EXPECT_TRUE(channel_->SetRenderer(kSsrc + 2, &renderer2_));
   1806     SendFrame();
   1807     EXPECT_TRUE_WAIT(renderer_.num_rendered_frames() >= 1, kTimeout);
   1808     EXPECT_EQ_WAIT(4, NumRtpPackets(), kTimeout);
   1809     // We dont expect any frames here, because the key frame would have been
   1810     // delivered to default channel.
   1811     EXPECT_EQ(0, renderer2_.num_rendered_frames());
   1812   }
   1813 
   1814   // Tests that we drop key frames when conference mode is enabled and we
   1815   // receive rtp packets on unsignalled streams. Removal of a unsignalled recv
   1816   // stream is successful.
   1817   void TwoStreamsAddAndRemoveUnsignalledRecv(
   1818       const cricket::VideoCodec& codec) {
   1819     cricket::VideoOptions vmo;
   1820     vmo.conference_mode.Set(true);
   1821     vmo.unsignalled_recv_stream_limit.Set(1);
   1822     EXPECT_TRUE(channel_->SetOptions(vmo));
   1823     SetUpSecondStreamWithNoRecv();
   1824     // Sending and receiving on first stream.
   1825     EXPECT_TRUE(channel_->SetRender(true));
   1826     Send(codec);
   1827     EXPECT_EQ_WAIT(2, NumRtpPackets(), kTimeout);
   1828     EXPECT_EQ_WAIT(1, renderer_.num_rendered_frames(), kTimeout);
   1829     // The first send is not expected to yield frames, because the ssrc
   1830     // is no signalled yet. With unsignalled recv enabled, we will drop frames
   1831     // instead of packets.
   1832     EXPECT_EQ(0, renderer2_.num_rendered_frames());
   1833     // Give a chance for the decoder to process before adding the receiver.
   1834     talk_base::Thread::Current()->ProcessMessages(100);
   1835     // Ensure that we can remove the unsignalled recv stream that was created
   1836     // when the first video packet with unsignalled recv ssrc is received.
   1837     EXPECT_TRUE(channel_->RemoveRecvStream(kSsrc + 2));
   1838   }
   1839 
   1840   VideoEngineOverride<E> engine_;
   1841   talk_base::scoped_ptr<cricket::FakeVideoCapturer> video_capturer_;
   1842   talk_base::scoped_ptr<cricket::FakeVideoCapturer> video_capturer_2_;
   1843   talk_base::scoped_ptr<C> channel_;
   1844   cricket::FakeNetworkInterface network_interface_;
   1845   cricket::FakeVideoRenderer renderer_;
   1846   cricket::VideoMediaChannel::Error media_error_;
   1847 
   1848   // Used by test cases where 2 streams are run on the same channel.
   1849   cricket::FakeVideoRenderer renderer2_;
   1850 };
   1851 
   1852 #endif  // TALK_MEDIA_BASE_VIDEOENGINE_UNITTEST_H_  NOLINT
   1853