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