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