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
63static const uint32 kTimeout = 5000U;
64static const uint32 kSsrc = 1234u;
65static const uint32 kRtxSsrc = 4321u;
66static const uint32 kSsrcs4[] = {1, 2, 3, 4};
67
68inline 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
72inline 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
78namespace std {
79inline 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
86inline 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.
97template<class T>
98class 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
141template<class E>
142class 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
447template<class E, class C>
448class 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