1/*
2 * libjingle
3 * Copyright 2004 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#include "talk/media/base/constants.h"
29#include "talk/media/base/fakenetworkinterface.h"
30#include "talk/media/base/mediachannel.h"
31#include "talk/media/base/testutils.h"
32#include "talk/media/base/videoengine_unittest.h"
33#include "talk/media/webrtc/fakewebrtcvideoengine.h"
34#include "webrtc/base/fakecpumonitor.h"
35#include "webrtc/base/gunit.h"
36#include "webrtc/base/logging.h"
37#include "webrtc/base/scoped_ptr.h"
38#include "webrtc/base/stream.h"
39#include "talk/media/webrtc/webrtcvideoengine.h"
40#include "talk/media/webrtc/webrtcvideoframe.h"
41#include "talk/media/webrtc/webrtcvoiceengine.h"
42#include "talk/session/media/mediasession.h"
43#include "webrtc/system_wrappers/interface/trace.h"
44
45// Tests for the WebRtcVideoEngine/VideoChannel code.
46
47using cricket::kRtpTimestampOffsetHeaderExtension;
48using cricket::kRtpAbsoluteSenderTimeHeaderExtension;
49
50static const cricket::VideoCodec kVP8Codec720p(100, "VP8", 1280, 720, 30, 0);
51
52static const cricket::VideoCodec kVP8Codec(100, "VP8", 640, 400, 30, 0);
53static const cricket::VideoCodec kH264Codec(127, "H264", 640, 400, 30, 0);
54static const cricket::VideoCodec kRedCodec(101, "red", 0, 0, 0, 0);
55static const cricket::VideoCodec kUlpFecCodec(102, "ulpfec", 0, 0, 0, 0);
56static const cricket::VideoCodec* const kVideoCodecs[] = {
57    &kVP8Codec,
58    &kRedCodec,
59    &kUlpFecCodec
60};
61
62static const unsigned int kStartBandwidthKbps = 300;
63static const unsigned int kMinBandwidthKbps = 30;
64static const unsigned int kMaxBandwidthKbps = 2000;
65
66static const uint32 kSsrcs1[] = {1};
67static const uint32 kSsrcs2[] = {1, 2};
68static const uint32 kSsrcs3[] = {1, 2, 3};
69static const uint32 kRtxSsrcs1[] = {4};
70static const uint32 kRtxSsrcs3[] = {4, 5, 6};
71
72class FakeViEWrapper : public cricket::ViEWrapper {
73 public:
74  explicit FakeViEWrapper(cricket::FakeWebRtcVideoEngine* engine)
75      : cricket::ViEWrapper(engine,  // base
76                            engine,  // codec
77                            engine,  // capture
78                            engine,  // network
79                            engine,  // render
80                            engine,  // rtp
81                            engine,  // image
82                            engine) {  // external decoder
83  }
84};
85
86// Test fixture to test WebRtcVideoEngine with a fake webrtc::VideoEngine.
87// Useful for testing failure paths.
88class WebRtcVideoEngineTestFake : public testing::Test,
89  public sigslot::has_slots<> {
90 public:
91  WebRtcVideoEngineTestFake()
92      : vie_(kVideoCodecs, ARRAY_SIZE(kVideoCodecs)),
93        cpu_monitor_(new rtc::FakeCpuMonitor(
94            rtc::Thread::Current())),
95        engine_(NULL,  // cricket::WebRtcVoiceEngine
96                new FakeViEWrapper(&vie_), cpu_monitor_),
97        channel_(NULL),
98        voice_channel_(NULL),
99        last_error_(cricket::VideoMediaChannel::ERROR_NONE) {
100  }
101  bool SetupEngine() {
102    bool result = engine_.Init(rtc::Thread::Current());
103    if (result) {
104      channel_ = engine_.CreateChannel(voice_channel_);
105      channel_->SignalMediaError.connect(this,
106          &WebRtcVideoEngineTestFake::OnMediaError);
107      result = (channel_ != NULL);
108    }
109    return result;
110  }
111  void OnMediaError(uint32 ssrc, cricket::VideoMediaChannel::Error error) {
112    last_error_ = error;
113  }
114  bool SendI420Frame(int width, int height) {
115    if (NULL == channel_) {
116      return false;
117    }
118    cricket::WebRtcVideoFrame frame;
119    if (!frame.InitToBlack(width, height, 1, 1, 0, 0)) {
120      return false;
121    }
122    cricket::FakeVideoCapturer capturer;
123    channel_->SendFrame(&capturer, &frame);
124    return true;
125  }
126  bool SendI420ScreencastFrame(int width, int height) {
127    return SendI420ScreencastFrameWithTimestamp(width, height, 0);
128  }
129  bool SendI420ScreencastFrameWithTimestamp(
130      int width, int height, int64 timestamp) {
131    if (NULL == channel_) {
132      return false;
133    }
134    cricket::WebRtcVideoFrame frame;
135    if (!frame.InitToBlack(width, height, 1, 1, 0, 0)) {
136      return false;
137    }
138    cricket::FakeVideoCapturer capturer;
139    capturer.SetScreencast(true);
140    channel_->SendFrame(&capturer, &frame);
141    return true;
142  }
143  void TestSetSendRtpHeaderExtensions(const std::string& ext) {
144    EXPECT_TRUE(SetupEngine());
145    int channel_num = vie_.GetLastChannel();
146
147    // Verify extensions are off by default.
148    EXPECT_EQ(-1, vie_.GetSendRtpExtensionId(channel_num, ext));
149
150    // Enable extension.
151    const int id = 1;
152    std::vector<cricket::RtpHeaderExtension> extensions;
153    extensions.push_back(cricket::RtpHeaderExtension(ext, id));
154
155    // Verify the send extension id.
156    EXPECT_TRUE(channel_->SetSendRtpHeaderExtensions(extensions));
157    EXPECT_EQ(id, vie_.GetSendRtpExtensionId(channel_num, ext));
158    // Verify call with same set of extensions returns true.
159    EXPECT_TRUE(channel_->SetSendRtpHeaderExtensions(extensions));
160    EXPECT_EQ(id, vie_.GetSendRtpExtensionId(channel_num, ext));
161
162    // Add a new send stream and verify the extension is set.
163    // The first send stream to occupy the default channel.
164    EXPECT_TRUE(
165        channel_->AddSendStream(cricket::StreamParams::CreateLegacy(123)));
166    EXPECT_TRUE(
167        channel_->AddSendStream(cricket::StreamParams::CreateLegacy(234)));
168    int new_send_channel_num = vie_.GetLastChannel();
169    EXPECT_NE(channel_num, new_send_channel_num);
170    EXPECT_EQ(id, vie_.GetSendRtpExtensionId(new_send_channel_num, ext));
171
172    // Remove the extension id.
173    std::vector<cricket::RtpHeaderExtension> empty_extensions;
174    EXPECT_TRUE(channel_->SetSendRtpHeaderExtensions(empty_extensions));
175    EXPECT_EQ(-1, vie_.GetSendRtpExtensionId(channel_num, ext));
176    EXPECT_EQ(-1, vie_.GetSendRtpExtensionId(new_send_channel_num, ext));
177  }
178  void TestSetRecvRtpHeaderExtensions(const std::string& ext) {
179    EXPECT_TRUE(SetupEngine());
180    int channel_num = vie_.GetLastChannel();
181
182    // Verify extensions are off by default.
183    EXPECT_EQ(-1, vie_.GetReceiveRtpExtensionId(channel_num, ext));
184
185    // Enable extension.
186    const int id = 2;
187    std::vector<cricket::RtpHeaderExtension> extensions;
188    extensions.push_back(cricket::RtpHeaderExtension(ext, id));
189
190    // Verify receive extension id.
191    EXPECT_TRUE(channel_->SetRecvRtpHeaderExtensions(extensions));
192    EXPECT_EQ(id, vie_.GetReceiveRtpExtensionId(channel_num, ext));
193    // Verify call with same set of extensions returns true.
194    EXPECT_TRUE(channel_->SetRecvRtpHeaderExtensions(extensions));
195    EXPECT_EQ(id, vie_.GetReceiveRtpExtensionId(channel_num, ext));
196
197    // Add a new receive stream and verify the extension is set.
198    // The first send stream to occupy the default channel.
199    EXPECT_TRUE(
200        channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(345)));
201    EXPECT_TRUE(
202        channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(456)));
203    int new_recv_channel_num = vie_.GetLastChannel();
204    EXPECT_NE(channel_num, new_recv_channel_num);
205    EXPECT_EQ(id, vie_.GetReceiveRtpExtensionId(new_recv_channel_num, ext));
206
207    // Remove the extension id.
208    std::vector<cricket::RtpHeaderExtension> empty_extensions;
209    EXPECT_TRUE(channel_->SetRecvRtpHeaderExtensions(empty_extensions));
210    EXPECT_EQ(-1, vie_.GetReceiveRtpExtensionId(channel_num, ext));
211    EXPECT_EQ(-1, vie_.GetReceiveRtpExtensionId(new_recv_channel_num, ext));
212  }
213  void VerifyCodecFeedbackParams(const cricket::VideoCodec& codec) {
214    EXPECT_TRUE(codec.HasFeedbackParam(
215        cricket::FeedbackParam(cricket::kRtcpFbParamNack,
216                               cricket::kParamValueEmpty)));
217    EXPECT_TRUE(codec.HasFeedbackParam(
218        cricket::FeedbackParam(cricket::kRtcpFbParamNack,
219                               cricket::kRtcpFbNackParamPli)));
220    EXPECT_TRUE(codec.HasFeedbackParam(
221        cricket::FeedbackParam(cricket::kRtcpFbParamRemb,
222                               cricket::kParamValueEmpty)));
223    EXPECT_TRUE(codec.HasFeedbackParam(
224        cricket::FeedbackParam(cricket::kRtcpFbParamCcm,
225                               cricket::kRtcpFbCcmParamFir)));
226  }
227  void VerifyVP8SendCodec(int channel_num,
228                          unsigned int width,
229                          unsigned int height,
230                          unsigned int layers = 0,
231                          unsigned int max_bitrate = kMaxBandwidthKbps,
232                          unsigned int min_bitrate = kMinBandwidthKbps,
233                          unsigned int start_bitrate = kStartBandwidthKbps,
234                          unsigned int fps = 30,
235                          unsigned int max_quantization = 0
236                          ) {
237    webrtc::VideoCodec gcodec;
238    EXPECT_EQ(0, vie_.GetSendCodec(channel_num, gcodec));
239
240    // Video codec properties.
241    EXPECT_EQ(webrtc::kVideoCodecVP8, gcodec.codecType);
242    EXPECT_STREQ("VP8", gcodec.plName);
243    EXPECT_EQ(100, gcodec.plType);
244    EXPECT_EQ(width, gcodec.width);
245    EXPECT_EQ(height, gcodec.height);
246    EXPECT_EQ(rtc::_min(start_bitrate, max_bitrate), gcodec.startBitrate);
247    EXPECT_EQ(max_bitrate, gcodec.maxBitrate);
248    EXPECT_EQ(min_bitrate, gcodec.minBitrate);
249    EXPECT_EQ(fps, gcodec.maxFramerate);
250    // VP8 specific.
251    EXPECT_FALSE(gcodec.codecSpecific.VP8.pictureLossIndicationOn);
252    EXPECT_FALSE(gcodec.codecSpecific.VP8.feedbackModeOn);
253    EXPECT_EQ(webrtc::kComplexityNormal, gcodec.codecSpecific.VP8.complexity);
254    EXPECT_EQ(webrtc::kResilienceOff, gcodec.codecSpecific.VP8.resilience);
255    EXPECT_EQ(max_quantization, gcodec.qpMax);
256  }
257  virtual void TearDown() {
258    delete channel_;
259    engine_.Terminate();
260  }
261
262 protected:
263  cricket::FakeWebRtcVideoEngine vie_;
264  cricket::FakeWebRtcVideoDecoderFactory decoder_factory_;
265  cricket::FakeWebRtcVideoEncoderFactory encoder_factory_;
266  rtc::FakeCpuMonitor* cpu_monitor_;
267  cricket::WebRtcVideoEngine engine_;
268  cricket::WebRtcVideoMediaChannel* channel_;
269  cricket::WebRtcVoiceMediaChannel* voice_channel_;
270  cricket::VideoMediaChannel::Error last_error_;
271};
272
273// Test fixtures to test WebRtcVideoEngine with a real webrtc::VideoEngine.
274class WebRtcVideoEngineTest
275    : public VideoEngineTest<cricket::WebRtcVideoEngine> {
276 protected:
277  typedef VideoEngineTest<cricket::WebRtcVideoEngine> Base;
278};
279class WebRtcVideoMediaChannelTest
280    : public VideoMediaChannelTest<
281        cricket::WebRtcVideoEngine, cricket::WebRtcVideoMediaChannel> {
282 protected:
283  typedef VideoMediaChannelTest<cricket::WebRtcVideoEngine,
284       cricket::WebRtcVideoMediaChannel> Base;
285  virtual cricket::VideoCodec DefaultCodec() { return kVP8Codec; }
286  virtual void SetUp() {
287    Base::SetUp();
288  }
289  virtual void TearDown() {
290    Base::TearDown();
291  }
292};
293
294/////////////////////////
295// Tests with fake ViE //
296/////////////////////////
297
298// Tests that our stub library "works".
299TEST_F(WebRtcVideoEngineTestFake, StartupShutdown) {
300  EXPECT_FALSE(vie_.IsInited());
301  EXPECT_TRUE(engine_.Init(rtc::Thread::Current()));
302  EXPECT_TRUE(vie_.IsInited());
303  engine_.Terminate();
304}
305
306// Tests that webrtc logs are logged when they should be.
307TEST_F(WebRtcVideoEngineTest, WebRtcShouldLog) {
308  const char webrtc_log[] = "WebRtcVideoEngineTest.WebRtcShouldLog";
309  EXPECT_TRUE(engine_.Init(rtc::Thread::Current()));
310  engine_.SetLogging(rtc::LS_INFO, "");
311  std::string str;
312  rtc::StringStream stream(str);
313  rtc::LogMessage::AddLogToStream(&stream, rtc::LS_INFO);
314  EXPECT_EQ(rtc::LS_INFO, rtc::LogMessage::GetLogToStream(&stream));
315  webrtc::Trace::Add(webrtc::kTraceStateInfo, webrtc::kTraceUndefined, 0,
316                     webrtc_log);
317  rtc::Thread::Current()->ProcessMessages(100);
318  rtc::LogMessage::RemoveLogToStream(&stream);
319  // Access |str| after LogMessage is done with it to avoid data racing.
320  EXPECT_NE(std::string::npos, str.find(webrtc_log));
321}
322
323// Tests that webrtc logs are not logged when they should't be.
324TEST_F(WebRtcVideoEngineTest, WebRtcShouldNotLog) {
325  const char webrtc_log[] = "WebRtcVideoEngineTest.WebRtcShouldNotLog";
326  EXPECT_TRUE(engine_.Init(rtc::Thread::Current()));
327  // WebRTC should never be logged lower than LS_INFO.
328  engine_.SetLogging(rtc::LS_WARNING, "");
329  std::string str;
330  rtc::StringStream stream(str);
331  // Make sure that WebRTC is not logged, even at lowest severity
332  rtc::LogMessage::AddLogToStream(&stream, rtc::LS_SENSITIVE);
333  EXPECT_EQ(rtc::LS_SENSITIVE,
334            rtc::LogMessage::GetLogToStream(&stream));
335  webrtc::Trace::Add(webrtc::kTraceStateInfo, webrtc::kTraceUndefined, 0,
336                     webrtc_log);
337  rtc::Thread::Current()->ProcessMessages(10);
338  EXPECT_EQ(std::string::npos, str.find(webrtc_log));
339  rtc::LogMessage::RemoveLogToStream(&stream);
340}
341
342// Tests that we can create and destroy a channel.
343TEST_F(WebRtcVideoEngineTestFake, CreateChannel) {
344  EXPECT_TRUE(engine_.Init(rtc::Thread::Current()));
345  channel_ = engine_.CreateChannel(voice_channel_);
346  EXPECT_TRUE(channel_ != NULL);
347  EXPECT_EQ(1, engine_.GetNumOfChannels());
348  delete channel_;
349  channel_ = NULL;
350  EXPECT_EQ(0, engine_.GetNumOfChannels());
351}
352
353// Tests that we properly handle failures in CreateChannel.
354TEST_F(WebRtcVideoEngineTestFake, CreateChannelFail) {
355  vie_.set_fail_create_channel(true);
356  EXPECT_TRUE(engine_.Init(rtc::Thread::Current()));
357  channel_ = engine_.CreateChannel(voice_channel_);
358  EXPECT_TRUE(channel_ == NULL);
359}
360
361// Tests that we properly handle failures in AllocateExternalCaptureDevice.
362TEST_F(WebRtcVideoEngineTestFake, AllocateExternalCaptureDeviceFail) {
363  vie_.set_fail_alloc_capturer(true);
364  EXPECT_TRUE(engine_.Init(rtc::Thread::Current()));
365  channel_ = engine_.CreateChannel(voice_channel_);
366  EXPECT_TRUE(channel_ == NULL);
367}
368
369// Test that we apply our default codecs properly.
370TEST_F(WebRtcVideoEngineTestFake, SetSendCodecs) {
371  EXPECT_TRUE(SetupEngine());
372  int channel_num = vie_.GetLastChannel();
373  std::vector<cricket::VideoCodec> codecs(engine_.codecs());
374  EXPECT_TRUE(channel_->SetSendCodecs(codecs));
375  VerifyVP8SendCodec(channel_num, kVP8Codec.width, kVP8Codec.height);
376  EXPECT_TRUE(vie_.GetHybridNackFecStatus(channel_num));
377  EXPECT_FALSE(vie_.GetNackStatus(channel_num));
378  EXPECT_EQ(1, vie_.GetNumSetSendCodecs());
379  // TODO(juberti): Check RTCP, PLI, TMMBR.
380}
381
382// Test that ViE Channel doesn't call SetSendCodec again if same codec is tried
383// to apply.
384TEST_F(WebRtcVideoEngineTestFake, DontResetSetSendCodec) {
385  EXPECT_TRUE(SetupEngine());
386  int channel_num = vie_.GetLastChannel();
387  std::vector<cricket::VideoCodec> codecs(engine_.codecs());
388  EXPECT_TRUE(channel_->SetSendCodecs(codecs));
389  VerifyVP8SendCodec(channel_num, kVP8Codec.width, kVP8Codec.height);
390  EXPECT_TRUE(vie_.GetHybridNackFecStatus(channel_num));
391  EXPECT_FALSE(vie_.GetNackStatus(channel_num));
392  EXPECT_EQ(1, vie_.GetNumSetSendCodecs());
393  // Try setting same code again.
394  EXPECT_TRUE(channel_->SetSendCodecs(codecs));
395  // Since it's exact same codec which is already set, media channel shouldn't
396  // send the codec to ViE.
397  EXPECT_EQ(1, vie_.GetNumSetSendCodecs());
398}
399
400TEST_F(WebRtcVideoEngineTestFake, SetSendCodecsWithMinMaxBitrate) {
401  EXPECT_TRUE(SetupEngine());
402  int channel_num = vie_.GetLastChannel();
403  std::vector<cricket::VideoCodec> codecs(engine_.codecs());
404  codecs[0].params[cricket::kCodecParamMinBitrate] = "10";
405  codecs[0].params[cricket::kCodecParamMaxBitrate] = "20";
406  EXPECT_TRUE(channel_->SetSendCodecs(codecs));
407
408  VerifyVP8SendCodec(
409      channel_num, kVP8Codec.width, kVP8Codec.height, 0, 20, 10, 20);
410
411  cricket::VideoCodec codec;
412  EXPECT_TRUE(channel_->GetSendCodec(&codec));
413  EXPECT_EQ("10", codec.params[cricket::kCodecParamMinBitrate]);
414  EXPECT_EQ("20", codec.params[cricket::kCodecParamMaxBitrate]);
415}
416
417TEST_F(WebRtcVideoEngineTestFake, SetSendCodecsWithStartBitrate) {
418  EXPECT_TRUE(SetupEngine());
419  int channel_num = vie_.GetLastChannel();
420  std::vector<cricket::VideoCodec> codecs(engine_.codecs());
421  codecs[0].params[cricket::kCodecParamStartBitrate] = "450";
422  EXPECT_TRUE(channel_->SetSendCodecs(codecs));
423
424  VerifyVP8SendCodec(channel_num,
425                     kVP8Codec.width,
426                     kVP8Codec.height,
427                     0,
428                     kMaxBandwidthKbps,
429                     kMinBandwidthKbps,
430                     450);
431
432  cricket::VideoCodec codec;
433  EXPECT_TRUE(channel_->GetSendCodec(&codec));
434  EXPECT_EQ("450", codec.params[cricket::kCodecParamStartBitrate]);
435}
436
437TEST_F(WebRtcVideoEngineTestFake, SetSendCodecsWithMinMaxStartBitrate) {
438  EXPECT_TRUE(SetupEngine());
439  int channel_num = vie_.GetLastChannel();
440  std::vector<cricket::VideoCodec> codecs(engine_.codecs());
441  codecs[0].params[cricket::kCodecParamMinBitrate] = "10";
442  codecs[0].params[cricket::kCodecParamMaxBitrate] = "20";
443  codecs[0].params[cricket::kCodecParamStartBitrate] = "14";
444  EXPECT_TRUE(channel_->SetSendCodecs(codecs));
445
446  VerifyVP8SendCodec(
447      channel_num, kVP8Codec.width, kVP8Codec.height, 0, 20, 10, 14);
448
449  cricket::VideoCodec codec;
450  EXPECT_TRUE(channel_->GetSendCodec(&codec));
451  EXPECT_EQ("10", codec.params[cricket::kCodecParamMinBitrate]);
452  EXPECT_EQ("20", codec.params[cricket::kCodecParamMaxBitrate]);
453  EXPECT_EQ("14", codec.params[cricket::kCodecParamStartBitrate]);
454}
455
456TEST_F(WebRtcVideoEngineTestFake, SetSendCodecsWithMinMaxBitrateInvalid) {
457  EXPECT_TRUE(SetupEngine());
458  std::vector<cricket::VideoCodec> codecs(engine_.codecs());
459  codecs[0].params[cricket::kCodecParamMinBitrate] = "30";
460  codecs[0].params[cricket::kCodecParamMaxBitrate] = "20";
461  EXPECT_FALSE(channel_->SetSendCodecs(codecs));
462}
463
464TEST_F(WebRtcVideoEngineTestFake, SetSendCodecsWithLargeMinMaxBitrate) {
465  EXPECT_TRUE(SetupEngine());
466  int channel_num = vie_.GetLastChannel();
467  std::vector<cricket::VideoCodec> codecs(engine_.codecs());
468  codecs[0].params[cricket::kCodecParamMinBitrate] = "1000";
469  codecs[0].params[cricket::kCodecParamMaxBitrate] = "3000";
470  EXPECT_TRUE(channel_->SetSendCodecs(codecs));
471
472  VerifyVP8SendCodec(
473      channel_num, kVP8Codec.width, kVP8Codec.height, 0, 3000, 1000,
474      1000);
475}
476
477TEST_F(WebRtcVideoEngineTestFake, SetSendCodecsWithMaxQuantization) {
478  EXPECT_TRUE(SetupEngine());
479  int channel_num = vie_.GetLastChannel();
480  std::vector<cricket::VideoCodec> codecs(engine_.codecs());
481  codecs[0].params[cricket::kCodecParamMaxQuantization] = "21";
482  EXPECT_TRUE(channel_->SetSendCodecs(codecs));
483
484  VerifyVP8SendCodec(channel_num,
485                     kVP8Codec.width,
486                     kVP8Codec.height,
487                     0,
488                     kMaxBandwidthKbps,
489                     kMinBandwidthKbps,
490                     300,
491                     30,
492                     21);
493
494  cricket::VideoCodec codec;
495  EXPECT_TRUE(channel_->GetSendCodec(&codec));
496  EXPECT_EQ("21", codec.params[cricket::kCodecParamMaxQuantization]);
497}
498
499TEST_F(WebRtcVideoEngineTestFake, SetOptionsWithMaxBitrate) {
500  EXPECT_TRUE(SetupEngine());
501  int channel_num = vie_.GetLastChannel();
502  std::vector<cricket::VideoCodec> codecs(engine_.codecs());
503  codecs[0].params[cricket::kCodecParamMinBitrate] = "10";
504  codecs[0].params[cricket::kCodecParamMaxBitrate] = "20";
505  EXPECT_TRUE(channel_->SetSendCodecs(codecs));
506
507  VerifyVP8SendCodec(
508      channel_num, kVP8Codec.width, kVP8Codec.height, 0, 20, 10, 20);
509
510  // Verify that max bitrate doesn't change after SetOptions().
511  cricket::VideoOptions options;
512  options.video_noise_reduction.Set(true);
513  EXPECT_TRUE(channel_->SetOptions(options));
514  VerifyVP8SendCodec(
515      channel_num, kVP8Codec.width, kVP8Codec.height, 0, 20, 10, 20);
516
517  options.video_noise_reduction.Set(false);
518  options.conference_mode.Set(false);
519  EXPECT_TRUE(channel_->SetOptions(options));
520  VerifyVP8SendCodec(
521      channel_num, kVP8Codec.width, kVP8Codec.height, 0, 20, 10, 20);
522}
523
524TEST_F(WebRtcVideoEngineTestFake, MaxBitrateResetWithConferenceMode) {
525  EXPECT_TRUE(SetupEngine());
526  int channel_num = vie_.GetLastChannel();
527  std::vector<cricket::VideoCodec> codecs(engine_.codecs());
528  codecs[0].params[cricket::kCodecParamMinBitrate] = "10";
529  codecs[0].params[cricket::kCodecParamMaxBitrate] = "20";
530  EXPECT_TRUE(channel_->SetSendCodecs(codecs));
531
532  VerifyVP8SendCodec(
533      channel_num, kVP8Codec.width, kVP8Codec.height, 0, 20, 10, 20);
534
535  cricket::VideoOptions options;
536  options.conference_mode.Set(true);
537  EXPECT_TRUE(channel_->SetOptions(options));
538  options.conference_mode.Set(false);
539  EXPECT_TRUE(channel_->SetOptions(options));
540  VerifyVP8SendCodec(
541      channel_num, kVP8Codec.width, kVP8Codec.height, 0,
542      kMaxBandwidthKbps, 10, kStartBandwidthKbps);
543}
544
545// Verify the current send bitrate is used as start bitrate when reconfiguring
546// the send codec.
547TEST_F(WebRtcVideoEngineTestFake, StartSendBitrate) {
548  EXPECT_TRUE(SetupEngine());
549  EXPECT_TRUE(channel_->AddSendStream(
550      cricket::StreamParams::CreateLegacy(1)));
551  int send_channel = vie_.GetLastChannel();
552  cricket::VideoCodec codec(kVP8Codec);
553  std::vector<cricket::VideoCodec> codec_list;
554  codec_list.push_back(codec);
555  EXPECT_TRUE(channel_->SetSendCodecs(codec_list));
556  VerifyVP8SendCodec(send_channel, kVP8Codec.width, kVP8Codec.height, 0,
557                     kMaxBandwidthKbps, kMinBandwidthKbps,
558                     kStartBandwidthKbps);
559  EXPECT_EQ(0, vie_.StartSend(send_channel));
560
561  // Increase the send bitrate and verify it is used as start bitrate.
562  const unsigned int kIncreasedSendBitrateBps = 768000;
563  vie_.SetSendBitrates(send_channel, kIncreasedSendBitrateBps, 0, 0);
564  EXPECT_TRUE(channel_->SetSendCodecs(codec_list));
565  VerifyVP8SendCodec(send_channel, kVP8Codec.width, kVP8Codec.height, 0,
566                     kMaxBandwidthKbps, kMinBandwidthKbps,
567                     kIncreasedSendBitrateBps / 1000);
568
569  // Never set a start bitrate higher than the max bitrate.
570  vie_.SetSendBitrates(send_channel, kMaxBandwidthKbps + 500, 0, 0);
571  EXPECT_TRUE(channel_->SetSendCodecs(codec_list));
572  VerifyVP8SendCodec(send_channel, kVP8Codec.width, kVP8Codec.height, 0,
573                     kMaxBandwidthKbps, kMinBandwidthKbps,
574                     kStartBandwidthKbps);
575
576  // Use the default start bitrate if the send bitrate is lower.
577  vie_.SetSendBitrates(send_channel, kStartBandwidthKbps - 50, 0,
578                       0);
579  EXPECT_TRUE(channel_->SetSendCodecs(codec_list));
580  VerifyVP8SendCodec(send_channel, kVP8Codec.width, kVP8Codec.height, 0,
581                     kMaxBandwidthKbps, kMinBandwidthKbps,
582                     kStartBandwidthKbps);
583}
584
585
586// Test that we constrain send codecs properly.
587TEST_F(WebRtcVideoEngineTestFake, ConstrainSendCodecs) {
588  EXPECT_TRUE(SetupEngine());
589  int channel_num = vie_.GetLastChannel();
590
591  // Set max settings of 640x400x30.
592  EXPECT_TRUE(engine_.SetDefaultEncoderConfig(
593    cricket::VideoEncoderConfig(kVP8Codec)));
594
595  // Send codec format bigger than max setting.
596  cricket::VideoCodec codec(kVP8Codec);
597  codec.width = 1280;
598  codec.height = 800;
599  codec.framerate = 60;
600  std::vector<cricket::VideoCodec> codec_list;
601  codec_list.push_back(codec);
602
603  // Set send codec and verify codec has been constrained.
604  EXPECT_TRUE(channel_->SetSendCodecs(codec_list));
605  VerifyVP8SendCodec(channel_num, kVP8Codec.width, kVP8Codec.height);
606}
607
608// Test that SetSendCodecs rejects bad format.
609TEST_F(WebRtcVideoEngineTestFake, SetSendCodecsRejectBadFormat) {
610  EXPECT_TRUE(SetupEngine());
611  int channel_num = vie_.GetLastChannel();
612
613  // Set w = 0.
614  cricket::VideoCodec codec(kVP8Codec);
615  codec.width = 0;
616  std::vector<cricket::VideoCodec> codec_list;
617  codec_list.push_back(codec);
618
619  // Verify SetSendCodecs failed and send codec is not changed on engine.
620  EXPECT_FALSE(channel_->SetSendCodecs(codec_list));
621  webrtc::VideoCodec gcodec;
622  // Set plType to something other than the value to test against ensuring
623  // that failure will happen if it is not changed.
624  gcodec.plType = 1;
625  EXPECT_EQ(0, vie_.GetSendCodec(channel_num, gcodec));
626  EXPECT_EQ(0, gcodec.plType);
627
628  // Set h = 0.
629  codec_list[0].width = 640;
630  codec_list[0].height = 0;
631
632  // Verify SetSendCodecs failed and send codec is not changed on engine.
633  EXPECT_FALSE(channel_->SetSendCodecs(codec_list));
634  // Set plType to something other than the value to test against ensuring
635  // that failure will happen if it is not changed.
636  gcodec.plType = 1;
637  EXPECT_EQ(0, vie_.GetSendCodec(channel_num, gcodec));
638  EXPECT_EQ(0, gcodec.plType);
639}
640
641// Test that SetSendCodecs rejects bad codec.
642TEST_F(WebRtcVideoEngineTestFake, SetSendCodecsRejectBadCodec) {
643  EXPECT_TRUE(SetupEngine());
644  int channel_num = vie_.GetLastChannel();
645
646  // Set bad codec name.
647  cricket::VideoCodec codec(kVP8Codec);
648  codec.name = "bad";
649  std::vector<cricket::VideoCodec> codec_list;
650  codec_list.push_back(codec);
651
652  // Verify SetSendCodecs failed and send codec is not changed on engine.
653  EXPECT_FALSE(channel_->SetSendCodecs(codec_list));
654  webrtc::VideoCodec gcodec;
655  // Set plType to something other than the value to test against ensuring
656  // that failure will happen if it is not changed.
657  gcodec.plType = 1;
658  EXPECT_EQ(0, vie_.GetSendCodec(channel_num, gcodec));
659  EXPECT_EQ(0, gcodec.plType);
660}
661
662// Test that vie send codec is reset on new video frame size.
663TEST_F(WebRtcVideoEngineTestFake, ResetVieSendCodecOnNewFrameSize) {
664  EXPECT_TRUE(SetupEngine());
665  int channel_num = vie_.GetLastChannel();
666
667  // Set send codec.
668  std::vector<cricket::VideoCodec> codec_list;
669  codec_list.push_back(kVP8Codec);
670  EXPECT_TRUE(channel_->SetSendCodecs(codec_list));
671  EXPECT_TRUE(channel_->AddSendStream(
672      cricket::StreamParams::CreateLegacy(123)));
673  EXPECT_TRUE(channel_->SetSend(true));
674
675  // Capture a smaller frame and verify vie send codec has been reset to
676  // the new size.
677  SendI420Frame(kVP8Codec.width / 2, kVP8Codec.height / 2);
678  VerifyVP8SendCodec(channel_num, kVP8Codec.width / 2, kVP8Codec.height / 2);
679
680  // Capture a frame bigger than send_codec_ and verify vie send codec has been
681  // reset (and clipped) to send_codec_.
682  SendI420Frame(kVP8Codec.width * 2, kVP8Codec.height * 2);
683  VerifyVP8SendCodec(channel_num, kVP8Codec.width, kVP8Codec.height);
684}
685
686// Test that we set our inbound codecs properly.
687TEST_F(WebRtcVideoEngineTestFake, SetRecvCodecs) {
688  EXPECT_TRUE(SetupEngine());
689  int channel_num = vie_.GetLastChannel();
690
691  std::vector<cricket::VideoCodec> codecs;
692  codecs.push_back(kVP8Codec);
693  EXPECT_TRUE(channel_->SetRecvCodecs(codecs));
694
695  webrtc::VideoCodec wcodec;
696  EXPECT_TRUE(engine_.ConvertFromCricketVideoCodec(kVP8Codec, &wcodec));
697  EXPECT_TRUE(vie_.ReceiveCodecRegistered(channel_num, wcodec));
698}
699
700// Test that we set our inbound RTX codecs properly.
701TEST_F(WebRtcVideoEngineTestFake, SetRecvCodecsWithRtx) {
702  EXPECT_TRUE(SetupEngine());
703  int channel_num = vie_.GetLastChannel();
704
705  std::vector<cricket::VideoCodec> codecs;
706  cricket::VideoCodec rtx_codec(96, "rtx", 0, 0, 0, 0);
707  codecs.push_back(rtx_codec);
708  // Should fail since there's no associated payload type set.
709  EXPECT_FALSE(channel_->SetRecvCodecs(codecs));
710
711  codecs[0].SetParam("apt", 97);
712  // Should still fail since the we don't support RTX on this APT.
713  EXPECT_FALSE(channel_->SetRecvCodecs(codecs));
714
715  codecs[0].SetParam("apt", kVP8Codec.id);
716  // Should still fail since the associated payload type is unknown.
717  EXPECT_FALSE(channel_->SetRecvCodecs(codecs));
718
719  codecs.push_back(kVP8Codec);
720  EXPECT_TRUE(channel_->SetRecvCodecs(codecs));
721
722  webrtc::VideoCodec wcodec;
723  // Should not have been registered as a WebRTC codec.
724  EXPECT_TRUE(engine_.ConvertFromCricketVideoCodec(rtx_codec, &wcodec));
725  EXPECT_STREQ("rtx", wcodec.plName);
726  EXPECT_FALSE(vie_.ReceiveCodecRegistered(channel_num, wcodec));
727
728  // The RTX payload type should have been set.
729  EXPECT_EQ(rtx_codec.id, vie_.GetRtxRecvPayloadType(channel_num));
730}
731
732// Test that RTX packets are routed to the default video channel if
733// there's only one recv stream.
734TEST_F(WebRtcVideoEngineTestFake, TestReceiveRtxOneStream) {
735  EXPECT_TRUE(SetupEngine());
736
737  // Setup one channel with an associated RTX stream.
738  cricket::StreamParams params =
739    cricket::StreamParams::CreateLegacy(kSsrcs1[0]);
740  params.AddFidSsrc(kSsrcs1[0], kRtxSsrcs1[0]);
741  EXPECT_TRUE(channel_->AddRecvStream(params));
742  int channel_num = vie_.GetLastChannel();
743  EXPECT_EQ(static_cast<int>(kRtxSsrcs1[0]),
744            vie_.GetRemoteRtxSsrc(channel_num));
745
746  // Register codecs.
747  std::vector<cricket::VideoCodec> codec_list;
748  codec_list.push_back(kVP8Codec720p);
749  cricket::VideoCodec rtx_codec(96, "rtx", 0, 0, 0, 0);
750  rtx_codec.SetParam("apt", kVP8Codec.id);
751  codec_list.push_back(rtx_codec);
752  EXPECT_TRUE(channel_->SetRecvCodecs(codec_list));
753
754  // Construct a fake RTX packet and verify that it is passed to the
755  // right WebRTC channel.
756  const size_t kDataLength = 12;
757  uint8_t data[kDataLength];
758  memset(data, 0, sizeof(data));
759  data[0] = 0x80;
760  data[1] = rtx_codec.id;
761  rtc::SetBE32(&data[8], kRtxSsrcs1[0]);
762  rtc::Buffer packet(data, kDataLength);
763  rtc::PacketTime packet_time;
764  channel_->OnPacketReceived(&packet, packet_time);
765  EXPECT_EQ(rtx_codec.id, vie_.GetLastRecvdPayloadType(channel_num));
766}
767
768// Test that RTX packets are routed to the correct video channel.
769TEST_F(WebRtcVideoEngineTestFake, TestReceiveRtxThreeStreams) {
770  EXPECT_TRUE(SetupEngine());
771
772  // Setup three channels with associated RTX streams.
773  int channel_num[ARRAY_SIZE(kSsrcs3)];
774  for (size_t i = 0; i < ARRAY_SIZE(kSsrcs3); ++i) {
775    cricket::StreamParams params =
776      cricket::StreamParams::CreateLegacy(kSsrcs3[i]);
777    params.AddFidSsrc(kSsrcs3[i], kRtxSsrcs3[i]);
778    EXPECT_TRUE(channel_->AddRecvStream(params));
779    channel_num[i] = vie_.GetLastChannel();
780  }
781
782  // Register codecs.
783  std::vector<cricket::VideoCodec> codec_list;
784  codec_list.push_back(kVP8Codec720p);
785  cricket::VideoCodec rtx_codec(96, "rtx", 0, 0, 0, 0);
786  rtx_codec.SetParam("apt", kVP8Codec.id);
787  codec_list.push_back(rtx_codec);
788  EXPECT_TRUE(channel_->SetRecvCodecs(codec_list));
789
790  // Construct a fake RTX packet and verify that it is passed to the
791  // right WebRTC channel.
792  const size_t kDataLength = 12;
793  uint8_t data[kDataLength];
794  memset(data, 0, sizeof(data));
795  data[0] = 0x80;
796  data[1] = rtx_codec.id;
797  rtc::SetBE32(&data[8], kRtxSsrcs3[1]);
798  rtc::Buffer packet(data, kDataLength);
799  rtc::PacketTime packet_time;
800  channel_->OnPacketReceived(&packet, packet_time);
801  EXPECT_NE(rtx_codec.id, vie_.GetLastRecvdPayloadType(channel_num[0]));
802  EXPECT_EQ(rtx_codec.id, vie_.GetLastRecvdPayloadType(channel_num[1]));
803  EXPECT_NE(rtx_codec.id, vie_.GetLastRecvdPayloadType(channel_num[2]));
804}
805
806// Test that channel connects and disconnects external capturer correctly.
807TEST_F(WebRtcVideoEngineTestFake, HasExternalCapturer) {
808  EXPECT_TRUE(SetupEngine());
809  int channel_num = vie_.GetLastChannel();
810
811  EXPECT_EQ(1, vie_.GetNumCapturers());
812  int capture_id = vie_.GetCaptureId(channel_num);
813  EXPECT_EQ(channel_num, vie_.GetCaptureChannelId(capture_id));
814
815  // Delete the channel should disconnect the capturer.
816  delete channel_;
817  channel_ = NULL;
818  EXPECT_EQ(0, vie_.GetNumCapturers());
819}
820
821// Test that channel adds and removes renderer correctly.
822TEST_F(WebRtcVideoEngineTestFake, HasRenderer) {
823  EXPECT_TRUE(SetupEngine());
824  int channel_num = vie_.GetLastChannel();
825
826  EXPECT_TRUE(vie_.GetHasRenderer(channel_num));
827  EXPECT_FALSE(vie_.GetRenderStarted(channel_num));
828}
829
830// Test that rtcp is enabled on the channel.
831TEST_F(WebRtcVideoEngineTestFake, RtcpEnabled) {
832  EXPECT_TRUE(SetupEngine());
833  int channel_num = vie_.GetLastChannel();
834  EXPECT_EQ(webrtc::kRtcpCompound_RFC4585, vie_.GetRtcpStatus(channel_num));
835}
836
837// Test that key frame request method is set on the channel.
838TEST_F(WebRtcVideoEngineTestFake, KeyFrameRequestEnabled) {
839  EXPECT_TRUE(SetupEngine());
840  int channel_num = vie_.GetLastChannel();
841  EXPECT_EQ(webrtc::kViEKeyFrameRequestPliRtcp,
842            vie_.GetKeyFrameRequestMethod(channel_num));
843}
844
845// Test that remb receive and send is enabled for the default channel in a 1:1
846// call.
847TEST_F(WebRtcVideoEngineTestFake, RembEnabled) {
848  EXPECT_TRUE(SetupEngine());
849  int channel_num = vie_.GetLastChannel();
850  EXPECT_TRUE(channel_->AddSendStream(
851      cricket::StreamParams::CreateLegacy(1)));
852  EXPECT_TRUE(channel_->SetSendCodecs(engine_.codecs()));
853  EXPECT_TRUE(vie_.GetRembStatusBwPartition(channel_num));
854  EXPECT_TRUE(channel_->SetSend(true));
855  EXPECT_TRUE(vie_.GetRembStatusBwPartition(channel_num));
856  EXPECT_TRUE(vie_.GetRembStatusContribute(channel_num));
857}
858
859// When in conference mode, test that remb is enabled on a receive channel but
860// not for the default channel and that it uses the default channel for sending
861// remb packets.
862TEST_F(WebRtcVideoEngineTestFake, RembEnabledOnReceiveChannels) {
863  EXPECT_TRUE(SetupEngine());
864  int default_channel = vie_.GetLastChannel();
865  cricket::VideoOptions options;
866  options.conference_mode.Set(true);
867  EXPECT_TRUE(channel_->SetOptions(options));
868  EXPECT_TRUE(channel_->AddSendStream(
869      cricket::StreamParams::CreateLegacy(1)));
870  EXPECT_TRUE(channel_->SetSendCodecs(engine_.codecs()));
871  EXPECT_TRUE(vie_.GetRembStatusBwPartition(default_channel));
872  EXPECT_TRUE(vie_.GetRembStatusContribute(default_channel));
873  EXPECT_TRUE(channel_->SetSend(true));
874  EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(1)));
875  int new_channel_num = vie_.GetLastChannel();
876  EXPECT_NE(default_channel, new_channel_num);
877
878  EXPECT_TRUE(vie_.GetRembStatusBwPartition(default_channel));
879  EXPECT_TRUE(vie_.GetRembStatusContribute(default_channel));
880  EXPECT_FALSE(vie_.GetRembStatusBwPartition(new_channel_num));
881  EXPECT_TRUE(vie_.GetRembStatusContribute(new_channel_num));
882}
883
884TEST_F(WebRtcVideoEngineTestFake, RecvStreamWithRtx) {
885  EXPECT_TRUE(SetupEngine());
886  int default_channel = vie_.GetLastChannel();
887  cricket::VideoOptions options;
888  options.conference_mode.Set(true);
889  EXPECT_TRUE(channel_->SetOptions(options));
890  EXPECT_TRUE(channel_->AddSendStream(
891      cricket::CreateSimWithRtxStreamParams("cname",
892                                            MAKE_VECTOR(kSsrcs3),
893                                            MAKE_VECTOR(kRtxSsrcs3))));
894  EXPECT_TRUE(channel_->SetSendCodecs(engine_.codecs()));
895  EXPECT_TRUE(channel_->SetSend(true));
896  EXPECT_TRUE(channel_->AddRecvStream(
897      cricket::CreateSimWithRtxStreamParams("cname",
898                                            MAKE_VECTOR(kSsrcs1),
899                                            MAKE_VECTOR(kRtxSsrcs1))));
900  int new_channel_num = vie_.GetLastChannel();
901  EXPECT_NE(default_channel, new_channel_num);
902  EXPECT_EQ(4, vie_.GetRemoteRtxSsrc(new_channel_num));
903}
904
905TEST_F(WebRtcVideoEngineTestFake, RecvStreamNoRtx) {
906  EXPECT_TRUE(SetupEngine());
907  int default_channel = vie_.GetLastChannel();
908  cricket::VideoOptions options;
909  options.conference_mode.Set(true);
910  EXPECT_TRUE(channel_->SetOptions(options));
911  EXPECT_TRUE(channel_->AddSendStream(
912      cricket::CreateSimWithRtxStreamParams("cname",
913                                            MAKE_VECTOR(kSsrcs3),
914                                            MAKE_VECTOR(kRtxSsrcs3))));
915  EXPECT_TRUE(channel_->SetSendCodecs(engine_.codecs()));
916  EXPECT_TRUE(channel_->SetSend(true));
917  EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(1)));
918  int new_channel_num = vie_.GetLastChannel();
919  EXPECT_NE(default_channel, new_channel_num);
920  EXPECT_EQ(-1, vie_.GetRemoteRtxSsrc(new_channel_num));
921}
922
923// Test support for RTP timestamp offset header extension.
924TEST_F(WebRtcVideoEngineTestFake, SendRtpTimestampOffsetHeaderExtensions) {
925  TestSetSendRtpHeaderExtensions(kRtpTimestampOffsetHeaderExtension);
926}
927TEST_F(WebRtcVideoEngineTestFake, RecvRtpTimestampOffsetHeaderExtensions) {
928  TestSetRecvRtpHeaderExtensions(kRtpTimestampOffsetHeaderExtension);
929}
930
931// Test support for absolute send time header extension.
932TEST_F(WebRtcVideoEngineTestFake, SendAbsoluteSendTimeHeaderExtensions) {
933  TestSetSendRtpHeaderExtensions(kRtpAbsoluteSenderTimeHeaderExtension);
934}
935TEST_F(WebRtcVideoEngineTestFake, RecvAbsoluteSendTimeHeaderExtensions) {
936  TestSetRecvRtpHeaderExtensions(kRtpAbsoluteSenderTimeHeaderExtension);
937}
938
939TEST_F(WebRtcVideoEngineTestFake, LeakyBucketTest) {
940  EXPECT_TRUE(SetupEngine());
941
942  // Verify this is on by default.
943  EXPECT_TRUE(channel_->AddSendStream(cricket::StreamParams::CreateLegacy(1)));
944  int first_send_channel = vie_.GetLastChannel();
945  EXPECT_TRUE(vie_.GetTransmissionSmoothingStatus(first_send_channel));
946
947  // Disable the experiment and verify.
948  cricket::VideoOptions options;
949  options.conference_mode.Set(true);
950  options.video_leaky_bucket.Set(false);
951  EXPECT_TRUE(channel_->SetOptions(options));
952  EXPECT_FALSE(vie_.GetTransmissionSmoothingStatus(first_send_channel));
953
954  // Add a receive channel and verify leaky bucket isn't enabled.
955  EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(2)));
956  int recv_channel_num = vie_.GetLastChannel();
957  EXPECT_NE(first_send_channel, recv_channel_num);
958  EXPECT_FALSE(vie_.GetTransmissionSmoothingStatus(recv_channel_num));
959
960  // Add a new send stream and verify leaky bucket is disabled from start.
961  EXPECT_TRUE(channel_->AddSendStream(cricket::StreamParams::CreateLegacy(3)));
962  int second_send_channel = vie_.GetLastChannel();
963  EXPECT_NE(first_send_channel, second_send_channel);
964  EXPECT_FALSE(vie_.GetTransmissionSmoothingStatus(second_send_channel));
965
966  // Reenable leaky bucket.
967  options.video_leaky_bucket.Set(true);
968  EXPECT_TRUE(channel_->SetOptions(options));
969  EXPECT_TRUE(vie_.GetTransmissionSmoothingStatus(first_send_channel));
970  EXPECT_TRUE(vie_.GetTransmissionSmoothingStatus(second_send_channel));
971}
972
973// Verify that SuspendBelowMinBitrate is enabled if it is set in the options.
974TEST_F(WebRtcVideoEngineTestFake, SuspendBelowMinBitrateTest) {
975  EXPECT_TRUE(SetupEngine());
976
977  // Verify this is off by default.
978  EXPECT_TRUE(channel_->AddSendStream(cricket::StreamParams::CreateLegacy(1)));
979  int first_send_channel = vie_.GetLastChannel();
980  EXPECT_FALSE(vie_.GetSuspendBelowMinBitrateStatus(first_send_channel));
981
982  // Enable the experiment and verify.
983  cricket::VideoOptions options;
984  options.suspend_below_min_bitrate.Set(true);
985  EXPECT_TRUE(channel_->SetOptions(options));
986  EXPECT_TRUE(vie_.GetSuspendBelowMinBitrateStatus(first_send_channel));
987
988  // Add a new send stream and verify suspend_below_min_bitrate is enabled.
989  EXPECT_TRUE(channel_->AddSendStream(cricket::StreamParams::CreateLegacy(2)));
990  int second_send_channel = vie_.GetLastChannel();
991  EXPECT_NE(first_send_channel, second_send_channel);
992  EXPECT_TRUE(vie_.GetSuspendBelowMinBitrateStatus(second_send_channel));
993}
994
995TEST_F(WebRtcVideoEngineTestFake, BufferedModeLatency) {
996  EXPECT_TRUE(SetupEngine());
997
998  // Verify this is off by default.
999  EXPECT_TRUE(channel_->AddSendStream(cricket::StreamParams::CreateLegacy(1)));
1000  int first_send_channel = vie_.GetLastChannel();
1001  EXPECT_EQ(0, vie_.GetSenderTargetDelay(first_send_channel));
1002  EXPECT_EQ(0, vie_.GetReceiverTargetDelay(first_send_channel));
1003
1004  // Enable the experiment and verify. The default channel will have both
1005  // sender and receiver buffered mode enabled.
1006  cricket::VideoOptions options;
1007  options.conference_mode.Set(true);
1008  options.buffered_mode_latency.Set(100);
1009  EXPECT_TRUE(channel_->SetOptions(options));
1010  EXPECT_EQ(100, vie_.GetSenderTargetDelay(first_send_channel));
1011  EXPECT_EQ(100, vie_.GetReceiverTargetDelay(first_send_channel));
1012
1013  // Add a receive channel and verify sender buffered mode isn't enabled.
1014  EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(2)));
1015  int recv_channel_num = vie_.GetLastChannel();
1016  EXPECT_NE(first_send_channel, recv_channel_num);
1017  EXPECT_EQ(0, vie_.GetSenderTargetDelay(recv_channel_num));
1018  EXPECT_EQ(100, vie_.GetReceiverTargetDelay(recv_channel_num));
1019
1020  // Add a new send stream and verify sender buffered mode is enabled.
1021  EXPECT_TRUE(channel_->AddSendStream(cricket::StreamParams::CreateLegacy(3)));
1022  int second_send_channel = vie_.GetLastChannel();
1023  EXPECT_NE(first_send_channel, second_send_channel);
1024  EXPECT_EQ(100, vie_.GetSenderTargetDelay(second_send_channel));
1025  EXPECT_EQ(0, vie_.GetReceiverTargetDelay(second_send_channel));
1026
1027  // Disable sender buffered mode and verify.
1028  options.buffered_mode_latency.Set(cricket::kBufferedModeDisabled);
1029  EXPECT_TRUE(channel_->SetOptions(options));
1030  EXPECT_EQ(0, vie_.GetSenderTargetDelay(first_send_channel));
1031  EXPECT_EQ(0, vie_.GetReceiverTargetDelay(first_send_channel));
1032  EXPECT_EQ(0, vie_.GetSenderTargetDelay(second_send_channel));
1033  EXPECT_EQ(0, vie_.GetReceiverTargetDelay(second_send_channel));
1034  EXPECT_EQ(0, vie_.GetSenderTargetDelay(recv_channel_num));
1035  EXPECT_EQ(0, vie_.GetReceiverTargetDelay(recv_channel_num));
1036}
1037
1038TEST_F(WebRtcVideoEngineTestFake, AdditiveVideoOptions) {
1039  EXPECT_TRUE(SetupEngine());
1040
1041  EXPECT_TRUE(channel_->AddSendStream(cricket::StreamParams::CreateLegacy(1)));
1042  int first_send_channel = vie_.GetLastChannel();
1043  EXPECT_EQ(0, vie_.GetSenderTargetDelay(first_send_channel));
1044  EXPECT_EQ(0, vie_.GetReceiverTargetDelay(first_send_channel));
1045
1046  cricket::VideoOptions options1;
1047  options1.buffered_mode_latency.Set(100);
1048  EXPECT_TRUE(channel_->SetOptions(options1));
1049  EXPECT_EQ(100, vie_.GetSenderTargetDelay(first_send_channel));
1050  EXPECT_EQ(100, vie_.GetReceiverTargetDelay(first_send_channel));
1051  EXPECT_TRUE(vie_.GetTransmissionSmoothingStatus(first_send_channel));
1052
1053  cricket::VideoOptions options2;
1054  options2.video_leaky_bucket.Set(false);
1055  EXPECT_TRUE(channel_->SetOptions(options2));
1056  EXPECT_FALSE(vie_.GetTransmissionSmoothingStatus(first_send_channel));
1057  // The buffered_mode_latency still takes effect.
1058  EXPECT_EQ(100, vie_.GetSenderTargetDelay(first_send_channel));
1059  EXPECT_EQ(100, vie_.GetReceiverTargetDelay(first_send_channel));
1060
1061  options1.buffered_mode_latency.Set(50);
1062  EXPECT_TRUE(channel_->SetOptions(options1));
1063  EXPECT_EQ(50, vie_.GetSenderTargetDelay(first_send_channel));
1064  EXPECT_EQ(50, vie_.GetReceiverTargetDelay(first_send_channel));
1065  // The video_leaky_bucket still takes effect.
1066  EXPECT_FALSE(vie_.GetTransmissionSmoothingStatus(first_send_channel));
1067}
1068
1069TEST_F(WebRtcVideoEngineTestFake, SetCpuOveruseOptionsWithCaptureJitterMethod) {
1070  EXPECT_TRUE(SetupEngine());
1071
1072  // Verify this is off by default.
1073  EXPECT_TRUE(channel_->AddSendStream(cricket::StreamParams::CreateLegacy(1)));
1074  int first_send_channel = vie_.GetLastChannel();
1075  webrtc::CpuOveruseOptions cpu_option =
1076      vie_.GetCpuOveruseOptions(first_send_channel);
1077  EXPECT_EQ(0, cpu_option.low_capture_jitter_threshold_ms);
1078  EXPECT_EQ(0, cpu_option.high_capture_jitter_threshold_ms);
1079  EXPECT_FALSE(cpu_option.enable_capture_jitter_method);
1080  EXPECT_FALSE(cpu_option.enable_encode_usage_method);
1081
1082  // Set low and high threshold and verify that cpu options are set.
1083  cricket::VideoOptions options;
1084  options.conference_mode.Set(true);
1085  options.cpu_underuse_threshold.Set(10);
1086  options.cpu_overuse_threshold.Set(20);
1087  EXPECT_TRUE(channel_->SetOptions(options));
1088  cpu_option = vie_.GetCpuOveruseOptions(first_send_channel);
1089  EXPECT_EQ(10, cpu_option.low_capture_jitter_threshold_ms);
1090  EXPECT_EQ(20, cpu_option.high_capture_jitter_threshold_ms);
1091  EXPECT_TRUE(cpu_option.enable_capture_jitter_method);
1092  EXPECT_FALSE(cpu_option.enable_encode_usage_method);
1093
1094  // Add a receive channel and verify that cpu options are not set.
1095  EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(2)));
1096  int recv_channel_num = vie_.GetLastChannel();
1097  EXPECT_NE(first_send_channel, recv_channel_num);
1098  cpu_option = vie_.GetCpuOveruseOptions(recv_channel_num);
1099  EXPECT_EQ(0, cpu_option.low_capture_jitter_threshold_ms);
1100  EXPECT_EQ(0, cpu_option.high_capture_jitter_threshold_ms);
1101  EXPECT_FALSE(cpu_option.enable_capture_jitter_method);
1102  EXPECT_FALSE(cpu_option.enable_encode_usage_method);
1103
1104  // Add a new send stream and verify that cpu options are set from start.
1105  EXPECT_TRUE(channel_->AddSendStream(cricket::StreamParams::CreateLegacy(3)));
1106  int second_send_channel = vie_.GetLastChannel();
1107  EXPECT_NE(first_send_channel, second_send_channel);
1108  cpu_option = vie_.GetCpuOveruseOptions(second_send_channel);
1109  EXPECT_EQ(10, cpu_option.low_capture_jitter_threshold_ms);
1110  EXPECT_EQ(20, cpu_option.high_capture_jitter_threshold_ms);
1111  EXPECT_TRUE(cpu_option.enable_capture_jitter_method);
1112  EXPECT_FALSE(cpu_option.enable_encode_usage_method);
1113}
1114
1115TEST_F(WebRtcVideoEngineTestFake, SetInvalidCpuOveruseThresholds) {
1116  EXPECT_TRUE(SetupEngine());
1117  EXPECT_TRUE(channel_->AddSendStream(cricket::StreamParams::CreateLegacy(1)));
1118  int channel_num = vie_.GetLastChannel();
1119
1120  // Only low threshold set. Verify that cpu options are not set.
1121  cricket::VideoOptions options;
1122  options.conference_mode.Set(true);
1123  options.cpu_underuse_threshold.Set(10);
1124  EXPECT_TRUE(channel_->SetOptions(options));
1125  webrtc::CpuOveruseOptions cpu_option = vie_.GetCpuOveruseOptions(channel_num);
1126  EXPECT_EQ(0, cpu_option.low_capture_jitter_threshold_ms);
1127  EXPECT_EQ(0, cpu_option.high_capture_jitter_threshold_ms);
1128  EXPECT_FALSE(cpu_option.enable_capture_jitter_method);
1129  EXPECT_FALSE(cpu_option.enable_encode_usage_method);
1130
1131  // Set high threshold to a negative value. Verify that options are not set.
1132  options.cpu_overuse_threshold.Set(-1);
1133  EXPECT_TRUE(channel_->SetOptions(options));
1134  cpu_option = vie_.GetCpuOveruseOptions(channel_num);
1135  EXPECT_EQ(0, cpu_option.low_capture_jitter_threshold_ms);
1136  EXPECT_EQ(0, cpu_option.high_capture_jitter_threshold_ms);
1137  EXPECT_FALSE(cpu_option.enable_capture_jitter_method);
1138  EXPECT_FALSE(cpu_option.enable_encode_usage_method);
1139
1140  // Low and high threshold valid. Verify that cpu options are set.
1141  options.cpu_overuse_threshold.Set(20);
1142  EXPECT_TRUE(channel_->SetOptions(options));
1143  cpu_option = vie_.GetCpuOveruseOptions(channel_num);
1144  EXPECT_EQ(10, cpu_option.low_capture_jitter_threshold_ms);
1145  EXPECT_EQ(20, cpu_option.high_capture_jitter_threshold_ms);
1146  EXPECT_TRUE(cpu_option.enable_capture_jitter_method);
1147  EXPECT_FALSE(cpu_option.enable_encode_usage_method);
1148}
1149
1150TEST_F(WebRtcVideoEngineTestFake, SetCpuOveruseOptionsWithEncodeUsageMethod) {
1151  EXPECT_TRUE(SetupEngine());
1152  EXPECT_TRUE(channel_->AddSendStream(cricket::StreamParams::CreateLegacy(1)));
1153  int first_send_channel = vie_.GetLastChannel();
1154
1155  // Set low and high threshold and enable encode usage method.
1156  // Verify that cpu options are set.
1157  cricket::VideoOptions options;
1158  options.conference_mode.Set(true);
1159  options.cpu_underuse_threshold.Set(10);
1160  options.cpu_overuse_threshold.Set(20);
1161  options.cpu_overuse_encode_usage.Set(true);
1162  EXPECT_TRUE(channel_->SetOptions(options));
1163  webrtc::CpuOveruseOptions cpu_option =
1164      vie_.GetCpuOveruseOptions(first_send_channel);
1165  EXPECT_EQ(10, cpu_option.low_encode_usage_threshold_percent);
1166  EXPECT_EQ(20, cpu_option.high_encode_usage_threshold_percent);
1167  EXPECT_FALSE(cpu_option.enable_capture_jitter_method);
1168  EXPECT_TRUE(cpu_option.enable_encode_usage_method);
1169#ifdef USE_WEBRTC_DEV_BRANCH
1170  // Verify that optional encode rsd thresholds are not set.
1171  EXPECT_EQ(-1, cpu_option.low_encode_time_rsd_threshold);
1172  EXPECT_EQ(-1, cpu_option.high_encode_time_rsd_threshold);
1173#endif
1174
1175  // Add a new send stream and verify that cpu options are set from start.
1176  EXPECT_TRUE(channel_->AddSendStream(cricket::StreamParams::CreateLegacy(3)));
1177  int second_send_channel = vie_.GetLastChannel();
1178  EXPECT_NE(first_send_channel, second_send_channel);
1179  cpu_option = vie_.GetCpuOveruseOptions(second_send_channel);
1180  EXPECT_EQ(10, cpu_option.low_encode_usage_threshold_percent);
1181  EXPECT_EQ(20, cpu_option.high_encode_usage_threshold_percent);
1182  EXPECT_FALSE(cpu_option.enable_capture_jitter_method);
1183  EXPECT_TRUE(cpu_option.enable_encode_usage_method);
1184#ifdef USE_WEBRTC_DEV_BRANCH
1185  // Verify that optional encode rsd thresholds are not set.
1186  EXPECT_EQ(-1, cpu_option.low_encode_time_rsd_threshold);
1187  EXPECT_EQ(-1, cpu_option.high_encode_time_rsd_threshold);
1188#endif
1189}
1190
1191TEST_F(WebRtcVideoEngineTestFake, SetCpuOveruseOptionsWithEncodeRsdThresholds) {
1192  EXPECT_TRUE(SetupEngine());
1193  EXPECT_TRUE(channel_->AddSendStream(cricket::StreamParams::CreateLegacy(1)));
1194  int first_send_channel = vie_.GetLastChannel();
1195
1196  // Set optional encode rsd thresholds and verify cpu options.
1197  cricket::VideoOptions options;
1198  options.conference_mode.Set(true);
1199  options.cpu_underuse_threshold.Set(10);
1200  options.cpu_overuse_threshold.Set(20);
1201  options.cpu_underuse_encode_rsd_threshold.Set(30);
1202  options.cpu_overuse_encode_rsd_threshold.Set(40);
1203  options.cpu_overuse_encode_usage.Set(true);
1204  EXPECT_TRUE(channel_->SetOptions(options));
1205  webrtc::CpuOveruseOptions cpu_option =
1206      vie_.GetCpuOveruseOptions(first_send_channel);
1207  EXPECT_EQ(10, cpu_option.low_encode_usage_threshold_percent);
1208  EXPECT_EQ(20, cpu_option.high_encode_usage_threshold_percent);
1209  EXPECT_FALSE(cpu_option.enable_capture_jitter_method);
1210  EXPECT_TRUE(cpu_option.enable_encode_usage_method);
1211#ifdef USE_WEBRTC_DEV_BRANCH
1212  EXPECT_EQ(30, cpu_option.low_encode_time_rsd_threshold);
1213  EXPECT_EQ(40, cpu_option.high_encode_time_rsd_threshold);
1214#endif
1215
1216  // Add a new send stream and verify that cpu options are set from start.
1217  EXPECT_TRUE(channel_->AddSendStream(cricket::StreamParams::CreateLegacy(3)));
1218  int second_send_channel = vie_.GetLastChannel();
1219  EXPECT_NE(first_send_channel, second_send_channel);
1220  cpu_option = vie_.GetCpuOveruseOptions(second_send_channel);
1221  EXPECT_EQ(10, cpu_option.low_encode_usage_threshold_percent);
1222  EXPECT_EQ(20, cpu_option.high_encode_usage_threshold_percent);
1223  EXPECT_FALSE(cpu_option.enable_capture_jitter_method);
1224  EXPECT_TRUE(cpu_option.enable_encode_usage_method);
1225#ifdef USE_WEBRTC_DEV_BRANCH
1226  EXPECT_EQ(30, cpu_option.low_encode_time_rsd_threshold);
1227  EXPECT_EQ(40, cpu_option.high_encode_time_rsd_threshold);
1228#endif
1229}
1230
1231// Test that AddRecvStream doesn't create new channel for 1:1 call.
1232TEST_F(WebRtcVideoEngineTestFake, AddRecvStream1On1) {
1233  EXPECT_TRUE(SetupEngine());
1234  int channel_num = vie_.GetLastChannel();
1235  EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(1)));
1236  EXPECT_EQ(channel_num, vie_.GetLastChannel());
1237}
1238
1239// Test that NACK, PLI and REMB are enabled for internal codec.
1240TEST_F(WebRtcVideoEngineTestFake, InternalCodecFeedbackParams) {
1241  EXPECT_TRUE(SetupEngine());
1242
1243  std::vector<cricket::VideoCodec> codecs(engine_.codecs());
1244  // Vp8 will appear at the beginning.
1245  size_t pos = 0;
1246  EXPECT_EQ("VP8", codecs[pos].name);
1247  VerifyCodecFeedbackParams(codecs[pos]);
1248}
1249
1250// Test that AddRecvStream doesn't change remb for 1:1 call.
1251TEST_F(WebRtcVideoEngineTestFake, NoRembChangeAfterAddRecvStream) {
1252  EXPECT_TRUE(SetupEngine());
1253  int channel_num = vie_.GetLastChannel();
1254  EXPECT_TRUE(channel_->AddSendStream(
1255      cricket::StreamParams::CreateLegacy(1)));
1256  EXPECT_TRUE(channel_->SetSendCodecs(engine_.codecs()));
1257  EXPECT_TRUE(vie_.GetRembStatusBwPartition(channel_num));
1258  EXPECT_TRUE(vie_.GetRembStatusContribute(channel_num));
1259  EXPECT_TRUE(channel_->SetSend(true));
1260  EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(1)));
1261  EXPECT_TRUE(vie_.GetRembStatusBwPartition(channel_num));
1262  EXPECT_TRUE(vie_.GetRembStatusContribute(channel_num));
1263}
1264
1265// Verify default REMB setting and that it can be turned on and off.
1266TEST_F(WebRtcVideoEngineTestFake, RembOnOff) {
1267  EXPECT_TRUE(SetupEngine());
1268  int channel_num = vie_.GetLastChannel();
1269  // Verify REMB sending is always off by default.
1270  EXPECT_FALSE(vie_.GetRembStatusBwPartition(channel_num));
1271
1272  // Verify that REMB is turned on when setting default codecs since the
1273  // default codecs have REMB enabled.
1274  EXPECT_TRUE(channel_->SetSendCodecs(engine_.codecs()));
1275  EXPECT_TRUE(vie_.GetRembStatusBwPartition(channel_num));
1276
1277  // Verify that REMB is turned off when codecs without REMB are set.
1278  std::vector<cricket::VideoCodec> codecs = engine_.codecs();
1279  // Clearing the codecs' FeedbackParams and setting send codecs should disable
1280  // REMB.
1281  for (std::vector<cricket::VideoCodec>::iterator iter = codecs.begin();
1282       iter != codecs.end(); ++iter) {
1283    // Intersecting with empty will clear the FeedbackParams.
1284    cricket::FeedbackParams empty_params;
1285    iter->feedback_params.Intersect(empty_params);
1286    EXPECT_TRUE(iter->feedback_params.params().empty());
1287  }
1288  EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1289  EXPECT_FALSE(vie_.GetRembStatusBwPartition(channel_num));
1290}
1291
1292// Test that nack is enabled on the channel if we don't offer red/fec.
1293TEST_F(WebRtcVideoEngineTestFake, NackEnabled) {
1294  EXPECT_TRUE(SetupEngine());
1295  int channel_num = vie_.GetLastChannel();
1296  std::vector<cricket::VideoCodec> codecs(engine_.codecs());
1297  codecs.resize(1);  // toss out red and ulpfec
1298  EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1299  EXPECT_TRUE(vie_.GetNackStatus(channel_num));
1300}
1301
1302// Test that we enable hybrid NACK FEC mode.
1303TEST_F(WebRtcVideoEngineTestFake, HybridNackFec) {
1304  EXPECT_TRUE(SetupEngine());
1305  int channel_num = vie_.GetLastChannel();
1306  EXPECT_TRUE(channel_->SetRecvCodecs(engine_.codecs()));
1307  EXPECT_TRUE(channel_->SetSendCodecs(engine_.codecs()));
1308  EXPECT_TRUE(vie_.GetHybridNackFecStatus(channel_num));
1309  EXPECT_FALSE(vie_.GetNackStatus(channel_num));
1310}
1311
1312// Test that we enable hybrid NACK FEC mode when calling SetSendCodecs and
1313// SetReceiveCodecs in reversed order.
1314TEST_F(WebRtcVideoEngineTestFake, HybridNackFecReversedOrder) {
1315  EXPECT_TRUE(SetupEngine());
1316  int channel_num = vie_.GetLastChannel();
1317  EXPECT_TRUE(channel_->SetSendCodecs(engine_.codecs()));
1318  EXPECT_TRUE(channel_->SetRecvCodecs(engine_.codecs()));
1319  EXPECT_TRUE(vie_.GetHybridNackFecStatus(channel_num));
1320  EXPECT_FALSE(vie_.GetNackStatus(channel_num));
1321}
1322
1323// Test NACK vs Hybrid NACK/FEC interop call setup, i.e. only use NACK even if
1324// red/fec is offered as receive codec.
1325TEST_F(WebRtcVideoEngineTestFake, VideoProtectionInterop) {
1326  EXPECT_TRUE(SetupEngine());
1327  int channel_num = vie_.GetLastChannel();
1328  std::vector<cricket::VideoCodec> recv_codecs(engine_.codecs());
1329  std::vector<cricket::VideoCodec> send_codecs(engine_.codecs());
1330  // Only add VP8 as send codec.
1331  send_codecs.resize(1);
1332  EXPECT_TRUE(channel_->SetRecvCodecs(recv_codecs));
1333  EXPECT_TRUE(channel_->SetSendCodecs(send_codecs));
1334  EXPECT_FALSE(vie_.GetHybridNackFecStatus(channel_num));
1335  EXPECT_TRUE(vie_.GetNackStatus(channel_num));
1336}
1337
1338// Test NACK vs Hybrid NACK/FEC interop call setup, i.e. only use NACK even if
1339// red/fec is offered as receive codec. Call order reversed compared to
1340// VideoProtectionInterop.
1341TEST_F(WebRtcVideoEngineTestFake, VideoProtectionInteropReversed) {
1342  EXPECT_TRUE(SetupEngine());
1343  int channel_num = vie_.GetLastChannel();
1344  std::vector<cricket::VideoCodec> recv_codecs(engine_.codecs());
1345  std::vector<cricket::VideoCodec> send_codecs(engine_.codecs());
1346  // Only add VP8 as send codec.
1347  send_codecs.resize(1);
1348  EXPECT_TRUE(channel_->SetSendCodecs(send_codecs));
1349  EXPECT_TRUE(channel_->SetRecvCodecs(recv_codecs));
1350  EXPECT_FALSE(vie_.GetHybridNackFecStatus(channel_num));
1351  EXPECT_TRUE(vie_.GetNackStatus(channel_num));
1352}
1353
1354// Test that NACK, not hybrid mode, is enabled in conference mode.
1355TEST_F(WebRtcVideoEngineTestFake, HybridNackFecConference) {
1356  EXPECT_TRUE(SetupEngine());
1357  // Setup the send channel.
1358  int send_channel_num = vie_.GetLastChannel();
1359  cricket::VideoOptions options;
1360  options.conference_mode.Set(true);
1361  EXPECT_TRUE(channel_->SetOptions(options));
1362  EXPECT_TRUE(channel_->SetRecvCodecs(engine_.codecs()));
1363  EXPECT_TRUE(channel_->SetSendCodecs(engine_.codecs()));
1364  EXPECT_FALSE(vie_.GetHybridNackFecStatus(send_channel_num));
1365  EXPECT_TRUE(vie_.GetNackStatus(send_channel_num));
1366  // Add a receive stream.
1367  EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(1)));
1368  int receive_channel_num = vie_.GetLastChannel();
1369  EXPECT_FALSE(vie_.GetHybridNackFecStatus(receive_channel_num));
1370  EXPECT_TRUE(vie_.GetNackStatus(receive_channel_num));
1371}
1372
1373// Test that when AddRecvStream in conference mode, a new channel is created
1374// for receiving. And the new channel's "original channel" is the send channel.
1375TEST_F(WebRtcVideoEngineTestFake, AddRemoveRecvStreamConference) {
1376  EXPECT_TRUE(SetupEngine());
1377  // Setup the send channel.
1378  int send_channel_num = vie_.GetLastChannel();
1379  cricket::VideoOptions options;
1380  options.conference_mode.Set(true);
1381  EXPECT_TRUE(channel_->SetOptions(options));
1382  // Add a receive stream.
1383  EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(1)));
1384  int receive_channel_num = vie_.GetLastChannel();
1385  EXPECT_EQ(send_channel_num, vie_.GetOriginalChannelId(receive_channel_num));
1386  EXPECT_TRUE(channel_->RemoveRecvStream(1));
1387  EXPECT_FALSE(vie_.IsChannel(receive_channel_num));
1388}
1389
1390// Test that adding/removing stream with 0 ssrc should fail (and not crash).
1391// For crbug/351699 and 350988.
1392TEST_F(WebRtcVideoEngineTestFake, AddRemoveRecvStreamWith0Ssrc) {
1393  EXPECT_TRUE(SetupEngine());
1394  EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(1)));
1395  EXPECT_FALSE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(0)));
1396  EXPECT_FALSE(channel_->RemoveRecvStream(0));
1397  EXPECT_TRUE(channel_->RemoveRecvStream(1));
1398}
1399
1400TEST_F(WebRtcVideoEngineTestFake, AddRemoveSendStreamWith0Ssrc) {
1401  EXPECT_TRUE(SetupEngine());
1402  EXPECT_TRUE(channel_->AddSendStream(cricket::StreamParams::CreateLegacy(1)));
1403  EXPECT_FALSE(channel_->AddSendStream(cricket::StreamParams::CreateLegacy(0)));
1404  EXPECT_FALSE(channel_->RemoveSendStream(0));
1405  EXPECT_TRUE(channel_->RemoveSendStream(1));
1406}
1407
1408// Test that we can create a channel and start/stop rendering out on it.
1409TEST_F(WebRtcVideoEngineTestFake, SetRender) {
1410  EXPECT_TRUE(SetupEngine());
1411  int channel_num = vie_.GetLastChannel();
1412
1413  // Verify we can start/stop/start/stop rendering.
1414  EXPECT_TRUE(channel_->SetRender(true));
1415  EXPECT_TRUE(vie_.GetRenderStarted(channel_num));
1416  EXPECT_TRUE(channel_->SetRender(false));
1417  EXPECT_FALSE(vie_.GetRenderStarted(channel_num));
1418  EXPECT_TRUE(channel_->SetRender(true));
1419  EXPECT_TRUE(vie_.GetRenderStarted(channel_num));
1420  EXPECT_TRUE(channel_->SetRender(false));
1421  EXPECT_FALSE(vie_.GetRenderStarted(channel_num));
1422}
1423
1424// Test that we can create a channel and start/stop sending out on it.
1425TEST_F(WebRtcVideoEngineTestFake, SetSend) {
1426  EXPECT_TRUE(SetupEngine());
1427  int channel_num = vie_.GetLastChannel();
1428  // Verify receiving is also started.
1429  EXPECT_TRUE(vie_.GetReceive(channel_num));
1430
1431  // Set send codecs on the channel.
1432  std::vector<cricket::VideoCodec> codecs;
1433  codecs.push_back(kVP8Codec);
1434  EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1435  EXPECT_TRUE(channel_->AddSendStream(
1436      cricket::StreamParams::CreateLegacy(123)));
1437
1438  // Verify we can start/stop/start/stop sending.
1439  EXPECT_TRUE(channel_->SetSend(true));
1440  EXPECT_TRUE(vie_.GetSend(channel_num));
1441  EXPECT_TRUE(channel_->SetSend(false));
1442  EXPECT_FALSE(vie_.GetSend(channel_num));
1443  EXPECT_TRUE(channel_->SetSend(true));
1444  EXPECT_TRUE(vie_.GetSend(channel_num));
1445  EXPECT_TRUE(channel_->SetSend(false));
1446  EXPECT_FALSE(vie_.GetSend(channel_num));
1447}
1448
1449// Test that we set bandwidth properly when using full auto bandwidth mode.
1450TEST_F(WebRtcVideoEngineTestFake, SetBandwidthAuto) {
1451  EXPECT_TRUE(SetupEngine());
1452  int channel_num = vie_.GetLastChannel();
1453  EXPECT_TRUE(channel_->SetSendCodecs(engine_.codecs()));
1454  EXPECT_TRUE(channel_->SetMaxSendBandwidth(cricket::kAutoBandwidth));
1455  VerifyVP8SendCodec(channel_num, kVP8Codec.width, kVP8Codec.height);
1456}
1457
1458// Test that we set bandwidth properly when using auto with upper bound.
1459TEST_F(WebRtcVideoEngineTestFake, SetBandwidthCapped) {
1460  EXPECT_TRUE(SetupEngine());
1461  int channel_num = vie_.GetLastChannel();
1462  EXPECT_TRUE(channel_->SetSendCodecs(engine_.codecs()));
1463  EXPECT_TRUE(channel_->SetMaxSendBandwidth(768000));
1464  VerifyVP8SendCodec(channel_num, kVP8Codec.width, kVP8Codec.height, 0, 768U);
1465}
1466
1467// Test that we reduce the start bandwidth when the requested max is less than
1468// the default start bandwidth.
1469TEST_F(WebRtcVideoEngineTestFake, SetMaxBandwidthBelowDefaultStart) {
1470  EXPECT_TRUE(SetupEngine());
1471  int channel_num = vie_.GetLastChannel();
1472  EXPECT_TRUE(channel_->SetSendCodecs(engine_.codecs()));
1473  int max_bandwidth_kbps = (kMinBandwidthKbps + kStartBandwidthKbps) / 2;
1474  EXPECT_TRUE(channel_->SetMaxSendBandwidth(max_bandwidth_kbps * 1000));
1475  VerifyVP8SendCodec(channel_num, kVP8Codec.width, kVP8Codec.height, 0,
1476      max_bandwidth_kbps, kMinBandwidthKbps, max_bandwidth_kbps);
1477}
1478
1479// Test that we reduce the min bandwidth when the requested max is less than
1480// the min bandwidth.
1481TEST_F(WebRtcVideoEngineTestFake, SetMaxBandwidthBelowMin) {
1482  EXPECT_TRUE(SetupEngine());
1483  int channel_num = vie_.GetLastChannel();
1484  EXPECT_TRUE(channel_->SetSendCodecs(engine_.codecs()));
1485  int max_bandwidth_kbps = kMinBandwidthKbps / 2;
1486  EXPECT_TRUE(channel_->SetMaxSendBandwidth(max_bandwidth_kbps * 1000));
1487  VerifyVP8SendCodec(channel_num, kVP8Codec.width, kVP8Codec.height, 0,
1488      max_bandwidth_kbps, max_bandwidth_kbps, max_bandwidth_kbps);
1489}
1490
1491// Test that the start bandwidth can be controlled separately from the max
1492// bandwidth.
1493TEST_F(WebRtcVideoEngineTestFake, SetStartBandwidth) {
1494  EXPECT_TRUE(SetupEngine());
1495  int channel_num = vie_.GetLastChannel();
1496  EXPECT_TRUE(channel_->SetSendCodecs(engine_.codecs()));
1497  int start_bandwidth_kbps = kStartBandwidthKbps + 1;
1498  EXPECT_TRUE(channel_->SetStartSendBandwidth(start_bandwidth_kbps * 1000));
1499  VerifyVP8SendCodec(channel_num, kVP8Codec.width, kVP8Codec.height, 0,
1500      kMaxBandwidthKbps, kMinBandwidthKbps, start_bandwidth_kbps);
1501
1502  // Check that SetMaxSendBandwidth doesn't overwrite the start bandwidth.
1503  int max_bandwidth_kbps = kMaxBandwidthKbps + 1;
1504  EXPECT_TRUE(channel_->SetMaxSendBandwidth(max_bandwidth_kbps * 1000));
1505  VerifyVP8SendCodec(channel_num, kVP8Codec.width, kVP8Codec.height, 0,
1506      max_bandwidth_kbps, kMinBandwidthKbps, start_bandwidth_kbps);
1507}
1508
1509// Test that the start bandwidth can be controlled by experiment.
1510TEST_F(WebRtcVideoEngineTestFake, SetStartBandwidthOption) {
1511  EXPECT_TRUE(SetupEngine());
1512  int channel_num = vie_.GetLastChannel();
1513  EXPECT_TRUE(channel_->SetSendCodecs(engine_.codecs()));
1514  int start_bandwidth_kbps = kStartBandwidthKbps;
1515  EXPECT_TRUE(channel_->SetStartSendBandwidth(start_bandwidth_kbps * 1000));
1516  VerifyVP8SendCodec(channel_num, kVP8Codec.width, kVP8Codec.height, 0,
1517      kMaxBandwidthKbps, kMinBandwidthKbps, start_bandwidth_kbps);
1518
1519  // Set the start bitrate option.
1520  start_bandwidth_kbps = 1000;
1521  cricket::VideoOptions options;
1522  options.video_start_bitrate.Set(
1523      start_bandwidth_kbps);
1524  EXPECT_TRUE(channel_->SetOptions(options));
1525
1526  // Check that start bitrate has changed to the new value.
1527  VerifyVP8SendCodec(channel_num, kVP8Codec.width, kVP8Codec.height, 0,
1528      kMaxBandwidthKbps, kMinBandwidthKbps, start_bandwidth_kbps);
1529}
1530
1531// Test that SetMaxSendBandwidth works as expected in conference mode.
1532TEST_F(WebRtcVideoEngineTestFake, SetBandwidthInConference) {
1533  EXPECT_TRUE(SetupEngine());
1534  int channel_num = vie_.GetLastChannel();
1535  cricket::VideoOptions options;
1536  options.conference_mode.Set(true);
1537  EXPECT_TRUE(channel_->SetOptions(options));
1538  EXPECT_TRUE(channel_->SetSendCodecs(engine_.codecs()));
1539  VerifyVP8SendCodec(channel_num, kVP8Codec.width, kVP8Codec.height);
1540
1541  // Set send bandwidth.
1542  EXPECT_TRUE(channel_->SetMaxSendBandwidth(768000));
1543
1544  // Verify that the max bitrate has changed.
1545  VerifyVP8SendCodec(channel_num, kVP8Codec.width, kVP8Codec.height, 0,
1546                     768, kMinBandwidthKbps, kStartBandwidthKbps);
1547}
1548
1549// Test that sending screencast frames doesn't change bitrate.
1550TEST_F(WebRtcVideoEngineTestFake, SetBandwidthScreencast) {
1551  EXPECT_TRUE(SetupEngine());
1552  int channel_num = vie_.GetLastChannel();
1553
1554  // Set send codec.
1555  cricket::VideoCodec codec(kVP8Codec);
1556  std::vector<cricket::VideoCodec> codec_list;
1557  codec_list.push_back(codec);
1558  EXPECT_TRUE(channel_->AddSendStream(
1559      cricket::StreamParams::CreateLegacy(123)));
1560  EXPECT_TRUE(channel_->SetSendCodecs(codec_list));
1561  EXPECT_TRUE(channel_->SetMaxSendBandwidth(111000));
1562  EXPECT_TRUE(channel_->SetSend(true));
1563
1564  SendI420ScreencastFrame(kVP8Codec.width, kVP8Codec.height);
1565  VerifyVP8SendCodec(channel_num, kVP8Codec.width, kVP8Codec.height, 0, 111);
1566}
1567
1568// Test SetSendSsrc.
1569TEST_F(WebRtcVideoEngineTestFake, SetSendSsrcAndCname) {
1570  EXPECT_TRUE(SetupEngine());
1571  int channel_num = vie_.GetLastChannel();
1572
1573  cricket::StreamParams stream;
1574  stream.ssrcs.push_back(1234);
1575  stream.cname = "cname";
1576  channel_->AddSendStream(stream);
1577
1578  unsigned int ssrc = 0;
1579  EXPECT_EQ(0, vie_.GetLocalSSRC(channel_num, ssrc));
1580  EXPECT_EQ(1234U, ssrc);
1581  EXPECT_EQ(1, vie_.GetNumSsrcs(channel_num));
1582
1583  char rtcp_cname[256];
1584  EXPECT_EQ(0, vie_.GetRTCPCName(channel_num, rtcp_cname));
1585  EXPECT_STREQ("cname", rtcp_cname);
1586}
1587
1588// Test that the local SSRC is the same on sending and receiving channels if the
1589// receive channel is created before the send channel.
1590TEST_F(WebRtcVideoEngineTestFake, SetSendSsrcAfterCreatingReceiveChannel) {
1591  EXPECT_TRUE(SetupEngine());
1592
1593  EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(1)));
1594  int receive_channel_num = vie_.GetLastChannel();
1595  cricket::StreamParams stream = cricket::StreamParams::CreateLegacy(1234);
1596  EXPECT_TRUE(channel_->AddSendStream(stream));
1597  int send_channel_num = vie_.GetLastChannel();
1598  unsigned int ssrc = 0;
1599  EXPECT_EQ(0, vie_.GetLocalSSRC(send_channel_num, ssrc));
1600  EXPECT_EQ(1234U, ssrc);
1601  EXPECT_EQ(1, vie_.GetNumSsrcs(send_channel_num));
1602  ssrc = 0;
1603  EXPECT_EQ(0, vie_.GetLocalSSRC(receive_channel_num, ssrc));
1604  EXPECT_EQ(1234U, ssrc);
1605  EXPECT_EQ(1, vie_.GetNumSsrcs(receive_channel_num));
1606}
1607
1608// Test SetOptions with denoising flag.
1609TEST_F(WebRtcVideoEngineTestFake, SetOptionsWithDenoising) {
1610  EXPECT_TRUE(SetupEngine());
1611  EXPECT_EQ(1, vie_.GetNumCapturers());
1612  int channel_num = vie_.GetLastChannel();
1613  int capture_id = vie_.GetCaptureId(channel_num);
1614  // Set send codecs on the channel.
1615  std::vector<cricket::VideoCodec> codecs;
1616  codecs.push_back(kVP8Codec);
1617  EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1618
1619  // Set options with OPT_VIDEO_NOISE_REDUCTION flag.
1620  cricket::VideoOptions options;
1621  options.video_noise_reduction.Set(true);
1622  EXPECT_TRUE(channel_->SetOptions(options));
1623
1624  // Verify capture has denoising turned on.
1625  webrtc::VideoCodec send_codec;
1626  memset(&send_codec, 0, sizeof(send_codec));  // avoid uninitialized warning
1627  EXPECT_EQ(0, vie_.GetSendCodec(channel_num, send_codec));
1628  EXPECT_TRUE(send_codec.codecSpecific.VP8.denoisingOn);
1629  EXPECT_FALSE(vie_.GetCaptureDenoising(capture_id));
1630
1631  // Set options back to zero.
1632  options.video_noise_reduction.Set(false);
1633  EXPECT_TRUE(channel_->SetOptions(options));
1634
1635  // Verify capture has denoising turned off.
1636  EXPECT_EQ(0, vie_.GetSendCodec(channel_num, send_codec));
1637  EXPECT_FALSE(send_codec.codecSpecific.VP8.denoisingOn);
1638  EXPECT_FALSE(vie_.GetCaptureDenoising(capture_id));
1639}
1640
1641TEST_F(WebRtcVideoEngineTestFake, MultipleSendStreamsWithOneCapturer) {
1642  EXPECT_TRUE(SetupEngine());
1643
1644  // Start the capturer
1645  cricket::FakeVideoCapturer capturer;
1646  cricket::VideoFormat capture_format_vga = cricket::VideoFormat(640, 480,
1647        cricket::VideoFormat::FpsToInterval(30), cricket::FOURCC_I420);
1648  EXPECT_EQ(cricket::CS_RUNNING, capturer.Start(capture_format_vga));
1649
1650  // Add send streams and connect the capturer
1651  for (unsigned int i = 0; i < sizeof(kSsrcs2)/sizeof(kSsrcs2[0]); ++i) {
1652    EXPECT_TRUE(channel_->AddSendStream(
1653        cricket::StreamParams::CreateLegacy(kSsrcs2[i])));
1654    // Register the capturer to the ssrc.
1655    EXPECT_TRUE(channel_->SetCapturer(kSsrcs2[i], &capturer));
1656  }
1657
1658  const int channel0 = vie_.GetChannelFromLocalSsrc(kSsrcs2[0]);
1659  ASSERT_NE(-1, channel0);
1660  const int channel1 = vie_.GetChannelFromLocalSsrc(kSsrcs2[1]);
1661  ASSERT_NE(-1, channel1);
1662  ASSERT_NE(channel0, channel1);
1663
1664  // Both channels should have started receiving after created.
1665  EXPECT_TRUE(vie_.GetReceive(channel0));
1666  EXPECT_TRUE(vie_.GetReceive(channel1));
1667
1668  // Set send codec.
1669  std::vector<cricket::VideoCodec> codecs;
1670  cricket::VideoCodec send_codec(100, "VP8", 640, 480, 30, 0);
1671  codecs.push_back(send_codec);
1672  EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1673
1674  EXPECT_TRUE(channel_->SetSend(true));
1675  EXPECT_TRUE(vie_.GetSend(channel0));
1676  EXPECT_TRUE(vie_.GetSend(channel1));
1677
1678  EXPECT_TRUE(capturer.CaptureFrame());
1679  EXPECT_EQ(1, vie_.GetIncomingFrameNum(channel0));
1680  EXPECT_EQ(1, vie_.GetIncomingFrameNum(channel1));
1681
1682  EXPECT_TRUE(channel_->RemoveSendStream(kSsrcs2[0]));
1683  EXPECT_TRUE(capturer.CaptureFrame());
1684  // channel0 is the default channel, so it won't be deleted.
1685  // But it should be disconnected from the capturer.
1686  EXPECT_EQ(1, vie_.GetIncomingFrameNum(channel0));
1687  EXPECT_EQ(2, vie_.GetIncomingFrameNum(channel1));
1688
1689  EXPECT_TRUE(channel_->RemoveSendStream(kSsrcs2[1]));
1690  EXPECT_TRUE(capturer.CaptureFrame());
1691  EXPECT_EQ(1, vie_.GetIncomingFrameNum(channel0));
1692  // channel1 has already been deleted.
1693  EXPECT_EQ(-1, vie_.GetIncomingFrameNum(channel1));
1694}
1695
1696TEST_F(WebRtcVideoEngineTestFake, SendReceiveBitratesStats) {
1697  EXPECT_TRUE(SetupEngine());
1698  cricket::VideoOptions options;
1699  options.conference_mode.Set(true);
1700  EXPECT_TRUE(channel_->SetOptions(options));
1701  EXPECT_TRUE(channel_->AddSendStream(
1702      cricket::StreamParams::CreateLegacy(1)));
1703  int first_send_channel = vie_.GetLastChannel();
1704  EXPECT_TRUE(channel_->AddSendStream(
1705      cricket::StreamParams::CreateLegacy(2)));
1706  int second_send_channel = vie_.GetLastChannel();
1707  cricket::VideoCodec codec(kVP8Codec720p);
1708  std::vector<cricket::VideoCodec> codec_list;
1709  codec_list.push_back(codec);
1710  EXPECT_TRUE(channel_->SetSendCodecs(codec_list));
1711
1712  EXPECT_TRUE(channel_->AddRecvStream(
1713      cricket::StreamParams::CreateLegacy(3)));
1714  int first_receive_channel = vie_.GetLastChannel();
1715  EXPECT_NE(first_send_channel, first_receive_channel);
1716  EXPECT_TRUE(channel_->AddRecvStream(
1717      cricket::StreamParams::CreateLegacy(4)));
1718  int second_receive_channel = vie_.GetLastChannel();
1719  EXPECT_NE(first_receive_channel, second_receive_channel);
1720
1721  cricket::VideoMediaInfo info;
1722  EXPECT_TRUE(channel_->GetStats(cricket::StatsOptions(), &info));
1723  ASSERT_EQ(1U, info.bw_estimations.size());
1724  ASSERT_EQ(0, info.bw_estimations[0].actual_enc_bitrate);
1725  ASSERT_EQ(0, info.bw_estimations[0].transmit_bitrate);
1726  ASSERT_EQ(0, info.bw_estimations[0].retransmit_bitrate);
1727  ASSERT_EQ(0, info.bw_estimations[0].available_send_bandwidth);
1728  ASSERT_EQ(0, info.bw_estimations[0].available_recv_bandwidth);
1729  ASSERT_EQ(0, info.bw_estimations[0].target_enc_bitrate);
1730
1731  // Start sending and receiving on one of the channels and verify bitrates.
1732  EXPECT_EQ(0, vie_.StartSend(first_send_channel));
1733  int send_video_bitrate = 800;
1734  int send_fec_bitrate = 100;
1735  int send_nack_bitrate = 20;
1736  int send_total_bitrate = send_video_bitrate + send_fec_bitrate +
1737      send_nack_bitrate;
1738  int send_bandwidth = 1900;
1739  vie_.SetSendBitrates(first_send_channel, send_video_bitrate, send_fec_bitrate,
1740                       send_nack_bitrate);
1741  vie_.SetSendBandwidthEstimate(first_send_channel, send_bandwidth);
1742
1743  EXPECT_EQ(0, vie_.StartReceive(first_receive_channel));
1744  int receive_bandwidth = 600;
1745  vie_.SetReceiveBandwidthEstimate(first_receive_channel, receive_bandwidth);
1746
1747  info.Clear();
1748  EXPECT_TRUE(channel_->GetStats(cricket::StatsOptions(), &info));
1749  ASSERT_EQ(1U, info.bw_estimations.size());
1750  ASSERT_EQ(send_video_bitrate, info.bw_estimations[0].actual_enc_bitrate);
1751  ASSERT_EQ(send_total_bitrate, info.bw_estimations[0].transmit_bitrate);
1752  ASSERT_EQ(send_nack_bitrate, info.bw_estimations[0].retransmit_bitrate);
1753  ASSERT_EQ(send_bandwidth, info.bw_estimations[0].available_send_bandwidth);
1754  ASSERT_EQ(receive_bandwidth, info.bw_estimations[0].available_recv_bandwidth);
1755  ASSERT_EQ(send_video_bitrate, info.bw_estimations[0].target_enc_bitrate);
1756
1757  // Start receiving on the second channel and verify received rate.
1758  EXPECT_EQ(0, vie_.StartSend(second_send_channel));
1759  vie_.SetSendBitrates(second_send_channel,
1760                       send_video_bitrate,
1761                       send_fec_bitrate,
1762                       send_nack_bitrate);
1763  EXPECT_EQ(0, vie_.StartReceive(second_receive_channel));
1764
1765  info.Clear();
1766  EXPECT_TRUE(channel_->GetStats(cricket::StatsOptions(), &info));
1767  ASSERT_EQ(1U, info.bw_estimations.size());
1768  ASSERT_EQ(2 * send_video_bitrate, info.bw_estimations[0].actual_enc_bitrate);
1769  ASSERT_EQ(2 * send_total_bitrate, info.bw_estimations[0].transmit_bitrate);
1770  ASSERT_EQ(2 * send_nack_bitrate, info.bw_estimations[0].retransmit_bitrate);
1771  ASSERT_EQ(send_bandwidth, info.bw_estimations[0].available_send_bandwidth);
1772  ASSERT_EQ(receive_bandwidth, info.bw_estimations[0].available_recv_bandwidth);
1773  ASSERT_EQ(2 * send_video_bitrate, info.bw_estimations[0].target_enc_bitrate);
1774}
1775
1776TEST_F(WebRtcVideoEngineTestFake, TestSetAdaptInputToCpuUsage) {
1777  EXPECT_TRUE(SetupEngine());
1778  cricket::VideoOptions options_in, options_out;
1779  bool cpu_adapt = false;
1780  channel_->SetOptions(options_in);
1781  EXPECT_TRUE(channel_->GetOptions(&options_out));
1782  EXPECT_FALSE(options_out.adapt_input_to_cpu_usage.Get(&cpu_adapt));
1783  // Set adapt input CPU usage option.
1784  options_in.adapt_input_to_cpu_usage.Set(true);
1785  EXPECT_TRUE(channel_->SetOptions(options_in));
1786  EXPECT_TRUE(channel_->GetOptions(&options_out));
1787  EXPECT_TRUE(options_out.adapt_input_to_cpu_usage.Get(&cpu_adapt));
1788  EXPECT_TRUE(cpu_adapt);
1789}
1790
1791TEST_F(WebRtcVideoEngineTestFake, TestSetCpuThreshold) {
1792  EXPECT_TRUE(SetupEngine());
1793  float low, high;
1794  cricket::VideoOptions options_in, options_out;
1795  // Verify that initial values are set.
1796  EXPECT_TRUE(channel_->GetOptions(&options_out));
1797  EXPECT_TRUE(options_out.system_low_adaptation_threshhold.Get(&low));
1798  EXPECT_EQ(low, 0.65f);
1799  EXPECT_TRUE(options_out.system_high_adaptation_threshhold.Get(&high));
1800  EXPECT_EQ(high, 0.85f);
1801  // Set new CPU threshold values.
1802  options_in.system_low_adaptation_threshhold.Set(0.45f);
1803  options_in.system_high_adaptation_threshhold.Set(0.95f);
1804  EXPECT_TRUE(channel_->SetOptions(options_in));
1805  EXPECT_TRUE(channel_->GetOptions(&options_out));
1806  EXPECT_TRUE(options_out.system_low_adaptation_threshhold.Get(&low));
1807  EXPECT_EQ(low, 0.45f);
1808  EXPECT_TRUE(options_out.system_high_adaptation_threshhold.Get(&high));
1809  EXPECT_EQ(high, 0.95f);
1810}
1811
1812TEST_F(WebRtcVideoEngineTestFake, TestSetInvalidCpuThreshold) {
1813  EXPECT_TRUE(SetupEngine());
1814  float low, high;
1815  cricket::VideoOptions options_in, options_out;
1816  // Valid range is [0, 1].
1817  options_in.system_low_adaptation_threshhold.Set(-1.5f);
1818  options_in.system_high_adaptation_threshhold.Set(1.5f);
1819  EXPECT_TRUE(channel_->SetOptions(options_in));
1820  EXPECT_TRUE(channel_->GetOptions(&options_out));
1821  EXPECT_TRUE(options_out.system_low_adaptation_threshhold.Get(&low));
1822  EXPECT_EQ(low, 0.0f);
1823  EXPECT_TRUE(options_out.system_high_adaptation_threshhold.Get(&high));
1824  EXPECT_EQ(high, 1.0f);
1825}
1826
1827TEST_F(WebRtcVideoEngineTestFake, ResetCodecOnScreencast) {
1828  EXPECT_TRUE(SetupEngine());
1829  cricket::VideoOptions options;
1830  options.video_noise_reduction.Set(true);
1831  EXPECT_TRUE(channel_->SetOptions(options));
1832
1833  // Set send codec.
1834  cricket::VideoCodec codec(kVP8Codec);
1835  std::vector<cricket::VideoCodec> codec_list;
1836  codec_list.push_back(codec);
1837  EXPECT_TRUE(channel_->AddSendStream(
1838      cricket::StreamParams::CreateLegacy(123)));
1839  EXPECT_TRUE(channel_->SetSendCodecs(codec_list));
1840  EXPECT_TRUE(channel_->SetSend(true));
1841  EXPECT_EQ(1, vie_.GetNumSetSendCodecs());
1842
1843  webrtc::VideoCodec gcodec;
1844  memset(&gcodec, 0, sizeof(gcodec));
1845  int channel_num = vie_.GetLastChannel();
1846  EXPECT_EQ(0, vie_.GetSendCodec(channel_num, gcodec));
1847  EXPECT_TRUE(gcodec.codecSpecific.VP8.denoisingOn);
1848
1849  // Send a screencast frame with the same size.
1850  // Verify that denoising is turned off.
1851  SendI420ScreencastFrame(kVP8Codec.width, kVP8Codec.height);
1852  EXPECT_EQ(2, vie_.GetNumSetSendCodecs());
1853  EXPECT_EQ(0, vie_.GetSendCodec(channel_num, gcodec));
1854  EXPECT_FALSE(gcodec.codecSpecific.VP8.denoisingOn);
1855}
1856
1857TEST_F(WebRtcVideoEngineTestFake, DontRegisterDecoderIfFactoryIsNotGiven) {
1858  engine_.SetExternalDecoderFactory(NULL);
1859  EXPECT_TRUE(SetupEngine());
1860  int channel_num = vie_.GetLastChannel();
1861
1862  std::vector<cricket::VideoCodec> codecs;
1863  codecs.push_back(kVP8Codec);
1864  EXPECT_TRUE(channel_->SetRecvCodecs(codecs));
1865
1866  EXPECT_EQ(0, vie_.GetNumExternalDecoderRegistered(channel_num));
1867}
1868
1869TEST_F(WebRtcVideoEngineTestFake, RegisterDecoderIfFactoryIsGiven) {
1870  decoder_factory_.AddSupportedVideoCodecType(webrtc::kVideoCodecVP8);
1871  engine_.SetExternalDecoderFactory(&decoder_factory_);
1872  EXPECT_TRUE(SetupEngine());
1873  int channel_num = vie_.GetLastChannel();
1874
1875  std::vector<cricket::VideoCodec> codecs;
1876  codecs.push_back(kVP8Codec);
1877  EXPECT_TRUE(channel_->SetRecvCodecs(codecs));
1878
1879  EXPECT_TRUE(vie_.ExternalDecoderRegistered(channel_num, 100));
1880  EXPECT_EQ(1, vie_.GetNumExternalDecoderRegistered(channel_num));
1881}
1882
1883TEST_F(WebRtcVideoEngineTestFake, DontRegisterDecoderMultipleTimes) {
1884  decoder_factory_.AddSupportedVideoCodecType(webrtc::kVideoCodecVP8);
1885  engine_.SetExternalDecoderFactory(&decoder_factory_);
1886  EXPECT_TRUE(SetupEngine());
1887  int channel_num = vie_.GetLastChannel();
1888
1889  std::vector<cricket::VideoCodec> codecs;
1890  codecs.push_back(kVP8Codec);
1891  EXPECT_TRUE(channel_->SetRecvCodecs(codecs));
1892
1893  EXPECT_TRUE(vie_.ExternalDecoderRegistered(channel_num, 100));
1894  EXPECT_EQ(1, vie_.GetNumExternalDecoderRegistered(channel_num));
1895  EXPECT_EQ(1, decoder_factory_.GetNumCreatedDecoders());
1896
1897  EXPECT_TRUE(channel_->SetRecvCodecs(codecs));
1898  EXPECT_EQ(1, vie_.GetNumExternalDecoderRegistered(channel_num));
1899  EXPECT_EQ(1, decoder_factory_.GetNumCreatedDecoders());
1900}
1901
1902TEST_F(WebRtcVideoEngineTestFake, DontRegisterDecoderForNonVP8) {
1903  decoder_factory_.AddSupportedVideoCodecType(webrtc::kVideoCodecVP8);
1904  engine_.SetExternalDecoderFactory(&decoder_factory_);
1905  EXPECT_TRUE(SetupEngine());
1906  int channel_num = vie_.GetLastChannel();
1907
1908  std::vector<cricket::VideoCodec> codecs;
1909  codecs.push_back(kRedCodec);
1910  EXPECT_TRUE(channel_->SetRecvCodecs(codecs));
1911
1912  EXPECT_EQ(0, vie_.GetNumExternalDecoderRegistered(channel_num));
1913}
1914
1915TEST_F(WebRtcVideoEngineTestFake, DontRegisterEncoderIfFactoryIsNotGiven) {
1916  engine_.SetExternalEncoderFactory(NULL);
1917  EXPECT_TRUE(SetupEngine());
1918  int channel_num = vie_.GetLastChannel();
1919
1920  std::vector<cricket::VideoCodec> codecs;
1921  codecs.push_back(kVP8Codec);
1922  EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1923
1924  EXPECT_EQ(0, vie_.GetNumExternalEncoderRegistered(channel_num));
1925}
1926
1927TEST_F(WebRtcVideoEngineTestFake, RegisterEncoderIfFactoryIsGiven) {
1928  encoder_factory_.AddSupportedVideoCodecType(webrtc::kVideoCodecVP8, "VP8");
1929  engine_.SetExternalEncoderFactory(&encoder_factory_);
1930  EXPECT_TRUE(SetupEngine());
1931  int channel_num = vie_.GetLastChannel();
1932
1933  std::vector<cricket::VideoCodec> codecs;
1934  codecs.push_back(kVP8Codec);
1935  EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1936
1937  EXPECT_TRUE(channel_->AddSendStream(
1938      cricket::StreamParams::CreateLegacy(kSsrc)));
1939
1940  EXPECT_TRUE(vie_.ExternalEncoderRegistered(channel_num, 100));
1941  EXPECT_EQ(1, vie_.GetNumExternalEncoderRegistered(channel_num));
1942
1943  // Remove stream previously added to free the external encoder instance.
1944  EXPECT_TRUE(channel_->RemoveSendStream(kSsrc));
1945}
1946
1947TEST_F(WebRtcVideoEngineTestFake, DontRegisterEncoderMultipleTimes) {
1948  encoder_factory_.AddSupportedVideoCodecType(webrtc::kVideoCodecVP8, "VP8");
1949  engine_.SetExternalEncoderFactory(&encoder_factory_);
1950  EXPECT_TRUE(SetupEngine());
1951  int channel_num = vie_.GetLastChannel();
1952
1953  std::vector<cricket::VideoCodec> codecs;
1954  codecs.push_back(kVP8Codec);
1955  EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1956
1957  EXPECT_TRUE(channel_->AddSendStream(
1958      cricket::StreamParams::CreateLegacy(kSsrc)));
1959
1960  EXPECT_TRUE(vie_.ExternalEncoderRegistered(channel_num, 100));
1961  EXPECT_EQ(1, vie_.GetNumExternalEncoderRegistered(channel_num));
1962
1963  EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1964  EXPECT_EQ(1, vie_.GetNumExternalEncoderRegistered(channel_num));
1965
1966  // Remove stream previously added to free the external encoder instance.
1967  EXPECT_TRUE(channel_->RemoveSendStream(kSsrc));
1968}
1969
1970TEST_F(WebRtcVideoEngineTestFake, RegisterEncoderWithMultipleSendStreams) {
1971  encoder_factory_.AddSupportedVideoCodecType(webrtc::kVideoCodecVP8, "VP8");
1972  engine_.SetExternalEncoderFactory(&encoder_factory_);
1973  EXPECT_TRUE(SetupEngine());
1974
1975  std::vector<cricket::VideoCodec> codecs;
1976  codecs.push_back(kVP8Codec);
1977  EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1978  EXPECT_EQ(1, vie_.GetTotalNumExternalEncoderRegistered());
1979
1980  // When we add the first stream (1234), it reuses the default send channel,
1981  // so it doesn't increase the registration count of external encoders.
1982  EXPECT_TRUE(channel_->AddSendStream(
1983      cricket::StreamParams::CreateLegacy(1234)));
1984  EXPECT_EQ(1, vie_.GetTotalNumExternalEncoderRegistered());
1985
1986  // When we add the second stream (2345), it creates a new channel and
1987  // increments the registration count.
1988  EXPECT_TRUE(channel_->AddSendStream(
1989      cricket::StreamParams::CreateLegacy(2345)));
1990  EXPECT_EQ(2, vie_.GetTotalNumExternalEncoderRegistered());
1991
1992  // At this moment the total registration count is two, but only one encoder
1993  // is registered per channel.
1994  int channel_num = vie_.GetLastChannel();
1995  EXPECT_EQ(1, vie_.GetNumExternalEncoderRegistered(channel_num));
1996
1997  // Removing send streams decrements the registration count.
1998  EXPECT_TRUE(channel_->RemoveSendStream(1234));
1999  EXPECT_EQ(1, vie_.GetTotalNumExternalEncoderRegistered());
2000
2001  // When we remove the last send stream, it also destroys the last send
2002  // channel and causes the registration count to drop to zero. It is a little
2003  // weird, but not a bug.
2004  EXPECT_TRUE(channel_->RemoveSendStream(2345));
2005  EXPECT_EQ(0, vie_.GetTotalNumExternalEncoderRegistered());
2006}
2007
2008TEST_F(WebRtcVideoEngineTestFake, DontRegisterEncoderForNonVP8) {
2009  encoder_factory_.AddSupportedVideoCodecType(webrtc::kVideoCodecGeneric,
2010                                              "GENERIC");
2011  engine_.SetExternalEncoderFactory(&encoder_factory_);
2012  EXPECT_TRUE(SetupEngine());
2013  int channel_num = vie_.GetLastChannel();
2014
2015  // Note: unlike the SetRecvCodecs, we must set a valid video codec for
2016  // channel_->SetSendCodecs() to succeed.
2017  std::vector<cricket::VideoCodec> codecs;
2018  codecs.push_back(kVP8Codec);
2019  EXPECT_TRUE(channel_->SetSendCodecs(codecs));
2020
2021  EXPECT_EQ(0, vie_.GetNumExternalEncoderRegistered(channel_num));
2022}
2023
2024// Test that NACK, PLI and REMB are enabled for external codec.
2025TEST_F(WebRtcVideoEngineTestFake, ExternalCodecFeedbackParams) {
2026  encoder_factory_.AddSupportedVideoCodecType(webrtc::kVideoCodecGeneric,
2027                                              "GENERIC");
2028  engine_.SetExternalEncoderFactory(&encoder_factory_);
2029  encoder_factory_.NotifyCodecsAvailable();
2030  EXPECT_TRUE(SetupEngine());
2031
2032  std::vector<cricket::VideoCodec> codecs(engine_.codecs());
2033  // The external codec will appear at last.
2034  size_t pos = codecs.size() - 1;
2035  EXPECT_EQ("GENERIC", codecs[pos].name);
2036  VerifyCodecFeedbackParams(codecs[pos]);
2037}
2038
2039// Test external codec with be added to the end of the supported codec list.
2040TEST_F(WebRtcVideoEngineTestFake, ExternalCodecAddedToTheEnd) {
2041  EXPECT_TRUE(SetupEngine());
2042
2043  std::vector<cricket::VideoCodec> codecs(engine_.codecs());
2044  EXPECT_EQ("VP8", codecs[0].name);
2045
2046  encoder_factory_.AddSupportedVideoCodecType(webrtc::kVideoCodecGeneric,
2047                                              "GENERIC");
2048  engine_.SetExternalEncoderFactory(&encoder_factory_);
2049  encoder_factory_.NotifyCodecsAvailable();
2050
2051  codecs = engine_.codecs();
2052  cricket::VideoCodec internal_codec = codecs[0];
2053  cricket::VideoCodec external_codec = codecs[codecs.size() - 1];
2054  // The external codec will appear at last.
2055  EXPECT_EQ("GENERIC", external_codec.name);
2056  // The internal codec is preferred.
2057  EXPECT_GE(internal_codec.preference, external_codec.preference);
2058}
2059
2060// Test that external codec with be ignored if it has the same name as one of
2061// the internal codecs.
2062TEST_F(WebRtcVideoEngineTestFake, ExternalCodecIgnored) {
2063  EXPECT_TRUE(SetupEngine());
2064
2065  std::vector<cricket::VideoCodec> internal_codecs(engine_.codecs());
2066  EXPECT_EQ("VP8", internal_codecs[0].name);
2067
2068  encoder_factory_.AddSupportedVideoCodecType(webrtc::kVideoCodecVP8, "VP8");
2069  engine_.SetExternalEncoderFactory(&encoder_factory_);
2070  encoder_factory_.NotifyCodecsAvailable();
2071
2072  std::vector<cricket::VideoCodec> codecs = engine_.codecs();
2073  EXPECT_EQ("VP8", codecs[0].name);
2074  EXPECT_EQ(internal_codecs[0].height, codecs[0].height);
2075  EXPECT_EQ(internal_codecs[0].width, codecs[0].width);
2076  // Verify the last codec is not the external codec.
2077  EXPECT_NE("VP8", codecs[codecs.size() - 1].name);
2078}
2079
2080TEST_F(WebRtcVideoEngineTestFake, UpdateEncoderCodecsAfterSetFactory) {
2081  engine_.SetExternalEncoderFactory(&encoder_factory_);
2082  EXPECT_TRUE(SetupEngine());
2083  int channel_num = vie_.GetLastChannel();
2084
2085  encoder_factory_.AddSupportedVideoCodecType(webrtc::kVideoCodecVP8, "VP8");
2086  encoder_factory_.NotifyCodecsAvailable();
2087  std::vector<cricket::VideoCodec> codecs;
2088  codecs.push_back(kVP8Codec);
2089  EXPECT_TRUE(channel_->SetSendCodecs(codecs));
2090
2091  EXPECT_TRUE(channel_->AddSendStream(
2092      cricket::StreamParams::CreateLegacy(kSsrc)));
2093
2094  EXPECT_TRUE(vie_.ExternalEncoderRegistered(channel_num, 100));
2095  EXPECT_EQ(1, vie_.GetNumExternalEncoderRegistered(channel_num));
2096
2097  // Remove stream previously added to free the external encoder instance.
2098  EXPECT_TRUE(channel_->RemoveSendStream(kSsrc));
2099}
2100
2101#ifdef USE_WEBRTC_DEV_BRANCH
2102TEST_F(WebRtcVideoEngineTestFake, SetSendCodecsWithExternalH264) {
2103  encoder_factory_.AddSupportedVideoCodecType(webrtc::kVideoCodecH264, "H264");
2104  engine_.SetExternalEncoderFactory(&encoder_factory_);
2105  EXPECT_TRUE(SetupEngine());
2106  int channel_num = vie_.GetLastChannel();
2107
2108  std::vector<cricket::VideoCodec> codecs;
2109  codecs.push_back(kH264Codec);
2110  cricket::VideoCodec rtx_codec(96, "rtx", 0, 0, 0, 0);
2111  rtx_codec.SetParam("apt", kH264Codec.id);
2112  codecs.push_back(rtx_codec);
2113  EXPECT_TRUE(channel_->SetSendCodecs(codecs));
2114
2115  EXPECT_EQ(96, vie_.GetRtxSendPayloadType(channel_num));
2116
2117  cricket::StreamParams params =
2118    cricket::StreamParams::CreateLegacy(kSsrcs1[0]);
2119  params.AddFidSsrc(kSsrcs1[0], kRtxSsrcs1[0]);
2120  EXPECT_TRUE(channel_->AddSendStream(params));
2121
2122  EXPECT_EQ(1, vie_.GetNumSsrcs(channel_num));
2123  EXPECT_EQ(1, vie_.GetNumRtxSsrcs(channel_num));
2124  EXPECT_EQ(static_cast<int>(kRtxSsrcs1[0]), vie_.GetRtxSsrc(channel_num, 0));
2125
2126  EXPECT_TRUE(vie_.ExternalEncoderRegistered(channel_num, 127));
2127  EXPECT_EQ(1, vie_.GetNumExternalEncoderRegistered(channel_num));
2128  EXPECT_EQ(1, encoder_factory_.GetNumCreatedEncoders());
2129
2130  EXPECT_TRUE(channel_->RemoveSendStream(kSsrcs1[0]));
2131}
2132
2133TEST_F(WebRtcVideoEngineTestFake, SetSendCodecsWithVP8AndExternalH264) {
2134  encoder_factory_.AddSupportedVideoCodecType(webrtc::kVideoCodecH264, "H264");
2135  engine_.SetExternalEncoderFactory(&encoder_factory_);
2136  EXPECT_TRUE(SetupEngine());
2137  int channel_num = vie_.GetLastChannel();
2138
2139  std::vector<cricket::VideoCodec> codecs;
2140  codecs.push_back(kH264Codec);
2141  cricket::VideoCodec rtx_codec(96, "rtx", 0, 0, 0, 0);
2142  rtx_codec.SetParam("apt", kH264Codec.id);
2143  codecs.push_back(rtx_codec);
2144  codecs.push_back(kVP8Codec);
2145  cricket::VideoCodec rtx_codec2(97, "rtx", 0, 0, 0, 0);
2146  rtx_codec2.SetParam("apt", kVP8Codec.id);
2147  codecs.push_back(rtx_codec2);
2148
2149  EXPECT_TRUE(channel_->SetSendCodecs(codecs));
2150
2151  // The first matched codec should be set, i.e., H.264.
2152
2153  EXPECT_EQ(96, vie_.GetRtxSendPayloadType(channel_num));
2154
2155  cricket::StreamParams params =
2156    cricket::StreamParams::CreateLegacy(kSsrcs1[0]);
2157  params.AddFidSsrc(kSsrcs1[0], kRtxSsrcs1[0]);
2158  EXPECT_TRUE(channel_->AddSendStream(params));
2159
2160  EXPECT_EQ(1, vie_.GetNumSsrcs(channel_num));
2161  EXPECT_EQ(1, vie_.GetNumRtxSsrcs(channel_num));
2162  EXPECT_EQ(static_cast<int>(kRtxSsrcs1[0]), vie_.GetRtxSsrc(channel_num, 0));
2163
2164  EXPECT_TRUE(vie_.ExternalEncoderRegistered(channel_num, 127));
2165  EXPECT_EQ(1, vie_.GetNumExternalEncoderRegistered(channel_num));
2166  EXPECT_EQ(1, encoder_factory_.GetNumCreatedEncoders());
2167
2168  EXPECT_TRUE(channel_->RemoveSendStream(kSsrcs1[0]));
2169}
2170
2171TEST_F(WebRtcVideoEngineTestFake, SetRecvCodecsWithExternalH264) {
2172  // WebRtcVideoEngine assumes that if we have encode support for a codec, we
2173  // also have decode support. It doesn't support decode only support. Therefore
2174  // we here have to register both an encoder and a decoder factory with H264
2175  // support, to be able to test the decoder factory.
2176  encoder_factory_.AddSupportedVideoCodecType(webrtc::kVideoCodecH264, "H264");
2177  decoder_factory_.AddSupportedVideoCodecType(webrtc::kVideoCodecH264);
2178  EXPECT_TRUE(SetupEngine());
2179  engine_.SetExternalEncoderFactory(&encoder_factory_);
2180  engine_.SetExternalDecoderFactory(&decoder_factory_);
2181  int channel_num = vie_.GetLastChannel();
2182
2183  std::vector<cricket::VideoCodec> codecs;
2184  codecs.push_back(kH264Codec);
2185  cricket::VideoCodec rtx_codec(96, "rtx", 0, 0, 0, 0);
2186  rtx_codec.SetParam("apt", kH264Codec.id);
2187  codecs.push_back(rtx_codec);
2188  EXPECT_TRUE(channel_->SetRecvCodecs(codecs));
2189
2190  EXPECT_EQ(96, vie_.GetRtxRecvPayloadType(channel_num));
2191
2192  cricket::StreamParams params =
2193    cricket::StreamParams::CreateLegacy(kSsrcs1[0]);
2194    params.AddFidSsrc(kSsrcs1[0], kRtxSsrcs1[0]);
2195  EXPECT_TRUE(channel_->AddRecvStream(params));
2196
2197  EXPECT_EQ(1, vie_.GetNumSsrcs(channel_num));
2198  EXPECT_EQ(static_cast<int>(kRtxSsrcs1[0]),
2199            vie_.GetRemoteRtxSsrc(channel_num));
2200
2201  EXPECT_TRUE(vie_.ExternalDecoderRegistered(channel_num, 127));
2202  EXPECT_EQ(1, vie_.GetNumExternalDecoderRegistered(channel_num));
2203  EXPECT_EQ(1, decoder_factory_.GetNumCreatedDecoders());
2204
2205  EXPECT_TRUE(channel_->RemoveRecvStream(kSsrcs1[0]));
2206}
2207
2208TEST_F(WebRtcVideoEngineTestFake, SetRecvCodecsWithVP8AndExternalH264) {
2209  encoder_factory_.AddSupportedVideoCodecType(webrtc::kVideoCodecH264, "H264");
2210  decoder_factory_.AddSupportedVideoCodecType(webrtc::kVideoCodecH264);
2211  EXPECT_TRUE(SetupEngine());
2212  engine_.SetExternalEncoderFactory(&encoder_factory_);
2213  engine_.SetExternalDecoderFactory(&decoder_factory_);
2214  int channel_num = vie_.GetLastChannel();
2215
2216  std::vector<cricket::VideoCodec> codecs;
2217  cricket::VideoCodec rtx_codec(97, "rtx", 0, 0, 0, 0);
2218  rtx_codec.SetParam("apt", kH264Codec.id);
2219  codecs.push_back(kH264Codec);
2220  codecs.push_back(rtx_codec);
2221
2222  cricket::VideoCodec rtx_codec2(96, "rtx", 0, 0, 0, 0);
2223  rtx_codec2.SetParam("apt", kVP8Codec.id);
2224  codecs.push_back(kVP8Codec);
2225  codecs.push_back(rtx_codec);
2226  // Should fail since WebRTC only supports one RTX codec at a time.
2227  EXPECT_FALSE(channel_->SetRecvCodecs(codecs));
2228
2229  codecs.pop_back();
2230
2231  // One RTX codec should be fine.
2232  EXPECT_TRUE(channel_->SetRecvCodecs(codecs));
2233
2234  // The RTX payload type should have been set.
2235  EXPECT_EQ(rtx_codec.id, vie_.GetRtxRecvPayloadType(channel_num));
2236}
2237#endif
2238
2239// Tests that OnReadyToSend will be propagated into ViE.
2240TEST_F(WebRtcVideoEngineTestFake, OnReadyToSend) {
2241  EXPECT_TRUE(SetupEngine());
2242  int channel_num = vie_.GetLastChannel();
2243  EXPECT_TRUE(vie_.GetIsTransmitting(channel_num));
2244
2245  channel_->OnReadyToSend(false);
2246  EXPECT_FALSE(vie_.GetIsTransmitting(channel_num));
2247
2248  channel_->OnReadyToSend(true);
2249  EXPECT_TRUE(vie_.GetIsTransmitting(channel_num));
2250}
2251
2252#if 0
2253TEST_F(WebRtcVideoEngineTestFake, CaptureFrameTimestampToNtpTimestamp) {
2254  EXPECT_TRUE(SetupEngine());
2255  int capture_id = vie_.GetCaptureId(vie_.GetLastChannel());
2256
2257  // Set send codec.
2258  cricket::VideoCodec codec(kVP8Codec);
2259  std::vector<cricket::VideoCodec> codec_list;
2260  codec_list.push_back(codec);
2261  EXPECT_TRUE(channel_->AddSendStream(
2262      cricket::StreamParams::CreateLegacy(123)));
2263  EXPECT_TRUE(channel_->SetSendCodecs(codec_list));
2264  EXPECT_TRUE(channel_->SetSend(true));
2265
2266  int64 timestamp = time(NULL) * rtc::kNumNanosecsPerSec;
2267  SendI420ScreencastFrameWithTimestamp(
2268      kVP8Codec.width, kVP8Codec.height, timestamp);
2269  EXPECT_EQ(rtc::UnixTimestampNanosecsToNtpMillisecs(timestamp),
2270      vie_.GetCaptureLastTimestamp(capture_id));
2271
2272  SendI420ScreencastFrameWithTimestamp(kVP8Codec.width, kVP8Codec.height, 0);
2273  EXPECT_EQ(0, vie_.GetCaptureLastTimestamp(capture_id));
2274}
2275#endif
2276
2277/////////////////////////
2278// Tests with real ViE //
2279/////////////////////////
2280
2281// Tests that we can find codecs by name or id.
2282TEST_F(WebRtcVideoEngineTest, FindCodec) {
2283  // We should not need to init engine in order to get codecs.
2284  const std::vector<cricket::VideoCodec>& c = engine_.codecs();
2285  EXPECT_EQ(4U, c.size());
2286
2287  cricket::VideoCodec vp8(104, "VP8", 320, 200, 30, 0);
2288  EXPECT_TRUE(engine_.FindCodec(vp8));
2289
2290  cricket::VideoCodec vp8_ci(104, "vp8", 320, 200, 30, 0);
2291  EXPECT_TRUE(engine_.FindCodec(vp8));
2292
2293  cricket::VideoCodec vp8_diff_fr_diff_pref(104, "VP8", 320, 200, 50, 50);
2294  EXPECT_TRUE(engine_.FindCodec(vp8_diff_fr_diff_pref));
2295
2296  cricket::VideoCodec vp8_diff_id(95, "VP8", 320, 200, 30, 0);
2297  EXPECT_FALSE(engine_.FindCodec(vp8_diff_id));
2298  vp8_diff_id.id = 97;
2299  EXPECT_TRUE(engine_.FindCodec(vp8_diff_id));
2300
2301  cricket::VideoCodec vp8_diff_res(104, "VP8", 320, 111, 30, 0);
2302  // FindCodec ignores the codec size.
2303  // Test that FindCodec can accept uncommon codec size.
2304  EXPECT_TRUE(engine_.FindCodec(vp8_diff_res));
2305
2306  // PeerConnection doesn't negotiate the resolution at this point.
2307  // Test that FindCodec can handle the case when width/height is 0.
2308  cricket::VideoCodec vp8_zero_res(104, "VP8", 0, 0, 30, 0);
2309  EXPECT_TRUE(engine_.FindCodec(vp8_zero_res));
2310
2311  cricket::VideoCodec red(101, "RED", 0, 0, 30, 0);
2312  EXPECT_TRUE(engine_.FindCodec(red));
2313
2314  cricket::VideoCodec red_ci(101, "red", 0, 0, 30, 0);
2315  EXPECT_TRUE(engine_.FindCodec(red));
2316
2317  cricket::VideoCodec fec(102, "ULPFEC", 0, 0, 30, 0);
2318  EXPECT_TRUE(engine_.FindCodec(fec));
2319
2320  cricket::VideoCodec fec_ci(102, "ulpfec", 0, 0, 30, 0);
2321  EXPECT_TRUE(engine_.FindCodec(fec));
2322
2323  cricket::VideoCodec rtx(96, "rtx", 0, 0, 30, 0);
2324  rtx.SetParam("apt", kVP8Codec.id);
2325  EXPECT_TRUE(engine_.FindCodec(rtx));
2326}
2327
2328TEST_F(WebRtcVideoEngineTest, RtxCodecHasAptSet) {
2329  std::vector<cricket::VideoCodec>::const_iterator it;
2330  bool apt_checked = false;
2331  for (it = engine_.codecs().begin(); it != engine_.codecs().end(); ++it) {
2332    if (_stricmp(cricket::kRtxCodecName, it->name.c_str()) && it->id != 96) {
2333      continue;
2334    }
2335    int apt;
2336    EXPECT_TRUE(it->GetParam("apt", &apt));
2337    EXPECT_EQ(100, apt);
2338    apt_checked = true;
2339  }
2340  EXPECT_TRUE(apt_checked);
2341}
2342
2343TEST_F(WebRtcVideoEngineTest, StartupShutdown) {
2344  EXPECT_TRUE(engine_.Init(rtc::Thread::Current()));
2345  engine_.Terminate();
2346}
2347
2348TEST_PRE_VIDEOENGINE_INIT(WebRtcVideoEngineTest, ConstrainNewCodec2)
2349TEST_POST_VIDEOENGINE_INIT(WebRtcVideoEngineTest, ConstrainNewCodec2)
2350
2351// TODO(juberti): Figure out why ViE is munging the COM refcount.
2352#ifdef WIN32
2353TEST_F(WebRtcVideoEngineTest, DISABLED_CheckCoInitialize) {
2354  Base::CheckCoInitialize();
2355}
2356#endif
2357
2358TEST_F(WebRtcVideoEngineTest, CreateChannel) {
2359  EXPECT_TRUE(engine_.Init(rtc::Thread::Current()));
2360  cricket::VideoMediaChannel* channel = engine_.CreateChannel(NULL);
2361  EXPECT_TRUE(channel != NULL);
2362  delete channel;
2363}
2364
2365TEST_F(WebRtcVideoMediaChannelTest, SetRecvCodecs) {
2366  std::vector<cricket::VideoCodec> codecs;
2367  codecs.push_back(kVP8Codec);
2368  EXPECT_TRUE(channel_->SetRecvCodecs(codecs));
2369}
2370TEST_F(WebRtcVideoMediaChannelTest, SetRecvCodecsWrongPayloadType) {
2371  std::vector<cricket::VideoCodec> codecs;
2372  codecs.push_back(kVP8Codec);
2373  codecs[0].id = 99;
2374  EXPECT_TRUE(channel_->SetRecvCodecs(codecs));
2375}
2376TEST_F(WebRtcVideoMediaChannelTest, SetRecvCodecsUnsupportedCodec) {
2377  std::vector<cricket::VideoCodec> codecs;
2378  codecs.push_back(kVP8Codec);
2379  codecs.push_back(cricket::VideoCodec(101, "VP1", 640, 400, 30, 0));
2380  EXPECT_FALSE(channel_->SetRecvCodecs(codecs));
2381}
2382
2383TEST_F(WebRtcVideoMediaChannelTest, GetRtpSendTimeExtension) {
2384  // Enable RTP timestamp extension.
2385  const int id = 12;
2386  std::vector<cricket::RtpHeaderExtension> extensions;
2387  extensions.push_back(cricket::RtpHeaderExtension(
2388      "http://www.webrtc.org/experiments/rtp-hdrext/abs-send-time", id));
2389
2390  // Verify the send extension id.
2391  EXPECT_TRUE(channel_->SetSendRtpHeaderExtensions(extensions));
2392  EXPECT_EQ(id, channel_->GetRtpSendTimeExtnId());
2393}
2394
2395TEST_F(WebRtcVideoMediaChannelTest, SetSend) {
2396  Base::SetSend();
2397}
2398TEST_F(WebRtcVideoMediaChannelTest, SetSendWithoutCodecs) {
2399  Base::SetSendWithoutCodecs();
2400}
2401TEST_F(WebRtcVideoMediaChannelTest, SetSendSetsTransportBufferSizes) {
2402  Base::SetSendSetsTransportBufferSizes();
2403}
2404
2405TEST_F(WebRtcVideoMediaChannelTest, SendAndReceiveVp8Vga) {
2406  SendAndReceive(cricket::VideoCodec(100, "VP8", 640, 400, 30, 0));
2407}
2408TEST_F(WebRtcVideoMediaChannelTest, SendAndReceiveVp8Qvga) {
2409  SendAndReceive(cricket::VideoCodec(100, "VP8", 320, 200, 30, 0));
2410}
2411TEST_F(WebRtcVideoMediaChannelTest, SendAndReceiveH264SvcQqvga) {
2412  SendAndReceive(cricket::VideoCodec(100, "VP8", 160, 100, 30, 0));
2413}
2414TEST_F(WebRtcVideoMediaChannelTest, SendManyResizeOnce) {
2415  SendManyResizeOnce();
2416}
2417
2418TEST_F(WebRtcVideoMediaChannelTest, DISABLED_SendVp8HdAndReceiveAdaptedVp8Vga) {
2419  EXPECT_TRUE(channel_->SetCapturer(kSsrc, NULL));
2420  channel_->UpdateAspectRatio(1280, 720);
2421  video_capturer_.reset(new cricket::FakeVideoCapturer);
2422  const std::vector<cricket::VideoFormat>* formats =
2423      video_capturer_->GetSupportedFormats();
2424  cricket::VideoFormat capture_format_hd = (*formats)[0];
2425  EXPECT_EQ(cricket::CS_RUNNING, video_capturer_->Start(capture_format_hd));
2426  EXPECT_TRUE(channel_->SetCapturer(kSsrc, video_capturer_.get()));
2427
2428  // Capture format HD -> adapt (OnOutputFormatRequest VGA) -> VGA.
2429  cricket::VideoCodec codec(100, "VP8", 1280, 720, 30, 0);
2430  EXPECT_TRUE(SetOneCodec(codec));
2431  codec.width /= 2;
2432  codec.height /= 2;
2433  EXPECT_TRUE(SetSend(true));
2434  EXPECT_TRUE(channel_->SetRender(true));
2435  EXPECT_EQ(0, renderer_.num_rendered_frames());
2436  EXPECT_TRUE(SendFrame());
2437  EXPECT_FRAME_WAIT(1, codec.width, codec.height, kTimeout);
2438}
2439
2440#ifdef USE_WEBRTC_DEV_BRANCH
2441TEST_F(WebRtcVideoMediaChannelTest, GetStats) {
2442#else
2443TEST_F(WebRtcVideoMediaChannelTest, DISABLED_GetStats) {
2444#endif
2445  Base::GetStats();
2446}
2447
2448#ifdef USE_WEBRTC_DEV_BRANCH
2449TEST_F(WebRtcVideoMediaChannelTest, GetStatsMultipleRecvStreams) {
2450#else
2451TEST_F(WebRtcVideoMediaChannelTest, DISABLED_GetStatsMultipleRecvStreams) {
2452#endif
2453  Base::GetStatsMultipleRecvStreams();
2454}
2455
2456TEST_F(WebRtcVideoMediaChannelTest, GetStatsMultipleSendStreams) {
2457  Base::GetStatsMultipleSendStreams();
2458}
2459
2460TEST_F(WebRtcVideoMediaChannelTest, SetSendBandwidth) {
2461  Base::SetSendBandwidth();
2462}
2463TEST_F(WebRtcVideoMediaChannelTest, SetSendSsrc) {
2464  Base::SetSendSsrc();
2465}
2466TEST_F(WebRtcVideoMediaChannelTest, SetSendSsrcAfterSetCodecs) {
2467  Base::SetSendSsrcAfterSetCodecs();
2468}
2469
2470TEST_F(WebRtcVideoMediaChannelTest, SetRenderer) {
2471  Base::SetRenderer();
2472}
2473
2474TEST_F(WebRtcVideoMediaChannelTest, AddRemoveRecvStreams) {
2475  Base::AddRemoveRecvStreams();
2476}
2477
2478TEST_F(WebRtcVideoMediaChannelTest, AddRemoveRecvStreamAndRender) {
2479  Base::AddRemoveRecvStreamAndRender();
2480}
2481
2482TEST_F(WebRtcVideoMediaChannelTest, AddRemoveRecvStreamsNoConference) {
2483  Base::AddRemoveRecvStreamsNoConference();
2484}
2485
2486TEST_F(WebRtcVideoMediaChannelTest, AddRemoveSendStreams) {
2487  Base::AddRemoveSendStreams();
2488}
2489
2490TEST_F(WebRtcVideoMediaChannelTest, SimulateConference) {
2491  Base::SimulateConference();
2492}
2493
2494TEST_F(WebRtcVideoMediaChannelTest, AddRemoveCapturer) {
2495  Base::AddRemoveCapturer();
2496}
2497
2498TEST_F(WebRtcVideoMediaChannelTest, RemoveCapturerWithoutAdd) {
2499  Base::RemoveCapturerWithoutAdd();
2500}
2501
2502TEST_F(WebRtcVideoMediaChannelTest, AddRemoveCapturerMultipleSources) {
2503  Base::AddRemoveCapturerMultipleSources();
2504}
2505
2506// This test verifies DSCP settings are properly applied on video media channel.
2507TEST_F(WebRtcVideoMediaChannelTest, TestSetDscpOptions) {
2508  rtc::scoped_ptr<cricket::FakeNetworkInterface> network_interface(
2509      new cricket::FakeNetworkInterface);
2510  channel_->SetInterface(network_interface.get());
2511  cricket::VideoOptions options;
2512  options.dscp.Set(true);
2513  EXPECT_TRUE(channel_->SetOptions(options));
2514  EXPECT_EQ(rtc::DSCP_AF41, network_interface->dscp());
2515  // Verify previous value is not modified if dscp option is not set.
2516  cricket::VideoOptions options1;
2517  EXPECT_TRUE(channel_->SetOptions(options1));
2518  EXPECT_EQ(rtc::DSCP_AF41, network_interface->dscp());
2519  options.dscp.Set(false);
2520  EXPECT_TRUE(channel_->SetOptions(options));
2521  EXPECT_EQ(rtc::DSCP_DEFAULT, network_interface->dscp());
2522  channel_->SetInterface(NULL);
2523}
2524
2525TEST_F(WebRtcVideoMediaChannelTest, HighAspectHighHeightCapturer) {
2526  Base::HighAspectHighHeightCapturer();
2527}
2528
2529TEST_F(WebRtcVideoMediaChannelTest, SetOptionsSucceedsWhenSending) {
2530  cricket::VideoOptions options;
2531  options.conference_mode.Set(true);
2532  EXPECT_TRUE(channel_->SetOptions(options));
2533
2534  // Verify SetOptions returns true on a different options.
2535  cricket::VideoOptions options2;
2536  options2.adapt_input_to_cpu_usage.Set(true);
2537  EXPECT_TRUE(channel_->SetOptions(options2));
2538
2539  // Set send codecs on the channel and start sending.
2540  std::vector<cricket::VideoCodec> codecs;
2541  codecs.push_back(kVP8Codec);
2542  EXPECT_TRUE(channel_->SetSendCodecs(codecs));
2543  EXPECT_TRUE(channel_->SetSend(true));
2544
2545  // Verify SetOptions returns true if channel is already sending.
2546  cricket::VideoOptions options3;
2547  options3.conference_mode.Set(true);
2548  EXPECT_TRUE(channel_->SetOptions(options3));
2549}
2550
2551// Tests empty StreamParams is rejected.
2552TEST_F(WebRtcVideoMediaChannelTest, RejectEmptyStreamParams) {
2553  Base::RejectEmptyStreamParams();
2554}
2555
2556TEST_F(WebRtcVideoMediaChannelTest, AdaptResolution16x10) {
2557  Base::AdaptResolution16x10();
2558}
2559
2560TEST_F(WebRtcVideoMediaChannelTest, AdaptResolution4x3) {
2561  Base::AdaptResolution4x3();
2562}
2563
2564TEST_F(WebRtcVideoMediaChannelTest, MuteStream) {
2565  Base::MuteStream();
2566}
2567
2568TEST_F(WebRtcVideoMediaChannelTest, MultipleSendStreams) {
2569  Base::MultipleSendStreams();
2570}
2571
2572// TODO(juberti): Restore this test once we support sending 0 fps.
2573TEST_F(WebRtcVideoMediaChannelTest, DISABLED_AdaptDropAllFrames) {
2574  Base::AdaptDropAllFrames();
2575}
2576// TODO(juberti): Understand why we get decode errors on this test.
2577TEST_F(WebRtcVideoMediaChannelTest, DISABLED_AdaptFramerate) {
2578  Base::AdaptFramerate();
2579}
2580
2581TEST_F(WebRtcVideoMediaChannelTest, SetSendStreamFormat0x0) {
2582  Base::SetSendStreamFormat0x0();
2583}
2584
2585// TODO(zhurunz): Fix the flakey test.
2586TEST_F(WebRtcVideoMediaChannelTest, DISABLED_SetSendStreamFormat) {
2587  Base::SetSendStreamFormat();
2588}
2589
2590TEST_F(WebRtcVideoMediaChannelTest, TwoStreamsSendAndReceive) {
2591  Base::TwoStreamsSendAndReceive(cricket::VideoCodec(100, "VP8", 640, 400, 30,
2592                                                     0));
2593}
2594
2595TEST_F(WebRtcVideoMediaChannelTest, TwoStreamsReUseFirstStream) {
2596  Base::TwoStreamsReUseFirstStream(cricket::VideoCodec(100, "VP8", 640, 400, 30,
2597                                                       0));
2598}
2599
2600TEST_F(WebRtcVideoMediaChannelTest, DISABLED_TwoStreamsSendAndUnsignalledRecv) {
2601  Base::TwoStreamsSendAndUnsignalledRecv(cricket::VideoCodec(100, "VP8", 640,
2602                                                             400, 30, 0));
2603}
2604
2605TEST_F(WebRtcVideoMediaChannelTest,
2606       TwoStreamsSendAndFailUnsignalledRecv) {
2607  Base::TwoStreamsSendAndFailUnsignalledRecv(
2608      cricket::VideoCodec(100, "VP8", 640, 400, 30, 0));
2609}
2610
2611TEST_F(WebRtcVideoMediaChannelTest,
2612       TwoStreamsSendAndFailUnsignalledRecvInOneToOne) {
2613  Base::TwoStreamsSendAndFailUnsignalledRecvInOneToOne(
2614      cricket::VideoCodec(100, "VP8", 640, 400, 30, 0));
2615}
2616
2617TEST_F(WebRtcVideoMediaChannelTest,
2618       TwoStreamsAddAndRemoveUnsignalledRecv) {
2619  Base::TwoStreamsAddAndRemoveUnsignalledRecv(cricket::VideoCodec(100, "VP8",
2620                                                                  640, 400, 30,
2621                                                                  0));
2622}
2623