Upstream version 10.38.222.0
[platform/framework/web/crosswalk.git] / src / third_party / libjingle / source / talk / media / base / hybridvideoengine_unittest.cc
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/fakemediaengine.h"
29 #include "talk/media/base/fakenetworkinterface.h"
30 #include "talk/media/base/fakevideocapturer.h"
31 #include "talk/media/base/hybridvideoengine.h"
32 #include "talk/media/base/mediachannel.h"
33 #include "talk/media/base/testutils.h"
34 #include "webrtc/base/gunit.h"
35
36 static const cricket::VideoCodec kGenericCodec(97, "Generic", 640, 360, 30, 0);
37 static const cricket::VideoCodec kVp8Codec(100, "VP8", 640, 360, 30, 0);
38 static const cricket::VideoCodec kCodecsVp8Only[] = { kVp8Codec };
39 static const cricket::VideoCodec kCodecsGenericOnly[] = { kGenericCodec };
40 static const cricket::VideoCodec kCodecsVp8First[] = { kVp8Codec,
41                                                        kGenericCodec };
42 static const cricket::VideoCodec kCodecsGenericFirst[] = { kGenericCodec,
43                                                            kVp8Codec };
44
45 using cricket::StreamParams;
46
47 class FakeVp8VideoEngine : public cricket::FakeVideoEngine {
48  public:
49   FakeVp8VideoEngine() {
50     SetCodecs(MAKE_VECTOR(kCodecsVp8Only));
51   }
52 };
53 class FakeGenericVideoEngine : public cricket::FakeVideoEngine {
54  public:
55   FakeGenericVideoEngine() {
56     SetCodecs(MAKE_VECTOR(kCodecsGenericOnly));
57   }
58
59   // For testing purposes, mimic the behavior of a media engine that throws out
60   // resolutions that don't match the codec list. A width or height of 0
61   // trivially will never match the codec list, so this is sufficient for
62   // testing the case we want (0x0).
63   virtual bool FindCodec(const cricket::VideoCodec& codec) {
64     if (codec.width == 0 || codec.height == 0) {
65       return false;
66     } else {
67       return cricket::FakeVideoEngine::FindCodec(codec);
68     }
69   }
70 };
71 class HybridVideoEngineForTest : public cricket::HybridVideoEngine<
72     FakeVp8VideoEngine, FakeGenericVideoEngine> {
73  public:
74   HybridVideoEngineForTest()
75       :
76       num_ch1_send_on_(0),
77       num_ch1_send_off_(0),
78       send_width_(0),
79       send_height_(0) { }
80   cricket::FakeVideoEngine* sub_engine1() { return &video1_; }
81   cricket::FakeVideoEngine* sub_engine2() { return &video2_; }
82
83   // From base class HybridVideoEngine.
84   void OnSendChange1(cricket::VideoMediaChannel* channel1, bool send) {
85     if (send) {
86       ++num_ch1_send_on_;
87     } else {
88       ++num_ch1_send_off_;
89     }
90   }
91   // From base class HybridVideoEngine
92   void OnNewSendResolution(int width, int height) {
93     send_width_ = width;
94     send_height_ = height;
95   }
96
97   int num_ch1_send_on() const { return num_ch1_send_on_; }
98   int num_ch1_send_off() const { return num_ch1_send_off_; }
99
100   int send_width() const { return send_width_; }
101   int send_height() const { return send_height_; }
102
103  private:
104   int num_ch1_send_on_;
105   int num_ch1_send_off_;
106
107   int send_width_;
108   int send_height_;
109 };
110
111 class HybridVideoEngineTest : public testing::Test {
112  public:
113   HybridVideoEngineTest() : sub_channel1_(NULL), sub_channel2_(NULL) {
114   }
115   ~HybridVideoEngineTest() {
116     engine_.Terminate();
117   }
118   bool SetupEngine() {
119     bool result = engine_.Init(rtc::Thread::Current());
120     if (result) {
121       channel_.reset(engine_.CreateChannel(NULL));
122       result = (channel_.get() != NULL);
123       sub_channel1_ = engine_.sub_engine1()->GetChannel(0);
124       sub_channel2_ = engine_.sub_engine2()->GetChannel(0);
125     }
126     return result;
127   }
128   bool SetupRenderAndAddStream(const StreamParams& sp) {
129     if (!SetupEngine())
130       return false;
131     channel_->SetInterface(transport_.get());
132     return channel_->SetRecvCodecs(engine_.codecs()) &&
133         channel_->AddSendStream(sp) &&
134         channel_->SetRender(true);
135   }
136   void DeliverPacket(const void* data, int len) {
137     rtc::Buffer packet(data, len);
138     channel_->OnPacketReceived(&packet, rtc::CreatePacketTime(0));
139   }
140   void DeliverRtcp(const void* data, int len) {
141     rtc::Buffer packet(data, len);
142     channel_->OnRtcpReceived(&packet, rtc::CreatePacketTime(0));
143   }
144
145  protected:
146   void TestSetSendCodecs(cricket::FakeVideoEngine* sub_engine,
147                          const std::vector<cricket::VideoCodec>& codecs) {
148     EXPECT_TRUE(SetupRenderAndAddStream(StreamParams::CreateLegacy(1234)));
149     EXPECT_TRUE(channel_->SetSendCodecs(codecs));
150     cricket::FakeVideoMediaChannel* sub_channel = sub_engine->GetChannel(0);
151     ASSERT_EQ(1U, sub_channel->send_codecs().size());
152     EXPECT_EQ(codecs[0], sub_channel->send_codecs()[0]);
153     EXPECT_TRUE(channel_->SetSend(true));
154     EXPECT_TRUE(sub_channel->sending());
155   }
156   void TestSetSendBandwidth(cricket::FakeVideoEngine* sub_engine,
157                             const std::vector<cricket::VideoCodec>& codecs,
158                             int start_bitrate,
159                             int max_bitrate) {
160     EXPECT_TRUE(SetupRenderAndAddStream(StreamParams::CreateLegacy(1234)));
161     EXPECT_TRUE(channel_->SetSendCodecs(codecs));
162     EXPECT_TRUE(channel_->SetStartSendBandwidth(start_bitrate));
163     EXPECT_TRUE(channel_->SetMaxSendBandwidth(max_bitrate));
164     cricket::FakeVideoMediaChannel* sub_channel = sub_engine->GetChannel(0);
165     EXPECT_EQ(start_bitrate, sub_channel->start_bps());
166     EXPECT_EQ(max_bitrate, sub_channel->max_bps());
167   }
168   HybridVideoEngineForTest engine_;
169   rtc::scoped_ptr<cricket::HybridVideoMediaChannel> channel_;
170   rtc::scoped_ptr<cricket::FakeNetworkInterface> transport_;
171   cricket::FakeVideoMediaChannel* sub_channel1_;
172   cricket::FakeVideoMediaChannel* sub_channel2_;
173 };
174
175 TEST_F(HybridVideoEngineTest, StartupShutdown) {
176   EXPECT_TRUE(engine_.Init(rtc::Thread::Current()));
177   engine_.Terminate();
178 }
179
180 // Tests that SetDefaultVideoEncoderConfig passes down to both engines.
181 TEST_F(HybridVideoEngineTest, SetDefaultVideoEncoderConfig) {
182   cricket::VideoEncoderConfig config(
183       cricket::VideoCodec(105, "", 640, 400, 30, 0), 1, 2);
184   EXPECT_TRUE(engine_.SetDefaultEncoderConfig(config));
185
186   cricket::VideoEncoderConfig config_1 = config;
187   config_1.max_codec.name = kCodecsVp8Only[0].name;
188   EXPECT_EQ(config_1, engine_.sub_engine1()->default_encoder_config());
189
190   cricket::VideoEncoderConfig config_2 = config;
191   config_2.max_codec.name = kCodecsGenericOnly[0].name;
192   EXPECT_EQ(config_2, engine_.sub_engine2()->default_encoder_config());
193 }
194
195 // Tests that GetDefaultVideoEncoderConfig picks a meaningful encoder config
196 // based on the underlying engine config and then after a call to
197 // SetDefaultEncoderConfig on the hybrid engine.
198 TEST_F(HybridVideoEngineTest, SetDefaultVideoEncoderConfigDefaultValue) {
199   cricket::VideoEncoderConfig blank_config;
200   cricket::VideoEncoderConfig meaningful_config1(
201       cricket::VideoCodec(111, "abcd", 320, 240, 30, 0), 1, 2);
202   cricket::VideoEncoderConfig meaningful_config2(
203       cricket::VideoCodec(111, "abcd", 1280, 720, 30, 0), 1, 2);
204   cricket::VideoEncoderConfig meaningful_config3(
205       cricket::VideoCodec(111, "abcd", 640, 360, 30, 0), 1, 2);
206   engine_.sub_engine1()->SetDefaultEncoderConfig(blank_config);
207   engine_.sub_engine2()->SetDefaultEncoderConfig(blank_config);
208   EXPECT_EQ(blank_config, engine_.GetDefaultEncoderConfig());
209
210   engine_.sub_engine2()->SetDefaultEncoderConfig(meaningful_config2);
211   EXPECT_EQ(meaningful_config2, engine_.GetDefaultEncoderConfig());
212
213   engine_.sub_engine1()->SetDefaultEncoderConfig(meaningful_config1);
214   EXPECT_EQ(meaningful_config1, engine_.GetDefaultEncoderConfig());
215
216   EXPECT_TRUE(engine_.SetDefaultEncoderConfig(meaningful_config3));
217   // The overall config should now match, though the codec name will have been
218   // rewritten for the first media engine.
219   meaningful_config3.max_codec.name = kCodecsVp8Only[0].name;
220   EXPECT_EQ(meaningful_config3, engine_.GetDefaultEncoderConfig());
221 }
222
223 // Tests that our engine has the right codecs in the right order.
224 TEST_F(HybridVideoEngineTest, CheckCodecs) {
225   const std::vector<cricket::VideoCodec>& c = engine_.codecs();
226   ASSERT_EQ(2U, c.size());
227   EXPECT_EQ(kVp8Codec, c[0]);
228   EXPECT_EQ(kGenericCodec, c[1]);
229 }
230
231 // Tests that our engine has the right caps.
232 TEST_F(HybridVideoEngineTest, CheckCaps) {
233   EXPECT_EQ(cricket::VIDEO_SEND | cricket::VIDEO_RECV,
234       engine_.GetCapabilities());
235 }
236
237 // Tests that we can create and destroy a channel.
238 TEST_F(HybridVideoEngineTest, CreateChannel) {
239   EXPECT_TRUE(SetupEngine());
240   EXPECT_TRUE(sub_channel1_ != NULL);
241   EXPECT_TRUE(sub_channel2_ != NULL);
242 }
243
244 // Tests that we properly handle failures in CreateChannel.
245 TEST_F(HybridVideoEngineTest, CreateChannelFail) {
246   engine_.sub_engine1()->set_fail_create_channel(true);
247   EXPECT_FALSE(SetupEngine());
248   EXPECT_TRUE(channel_.get() == NULL);
249   EXPECT_TRUE(sub_channel1_ == NULL);
250   EXPECT_TRUE(sub_channel2_ == NULL);
251   engine_.sub_engine1()->set_fail_create_channel(false);
252   engine_.sub_engine2()->set_fail_create_channel(true);
253   EXPECT_FALSE(SetupEngine());
254   EXPECT_TRUE(channel_.get() == NULL);
255   EXPECT_TRUE(sub_channel1_ == NULL);
256   EXPECT_TRUE(sub_channel2_ == NULL);
257 }
258
259 // Test that we set our inbound codecs and settings properly.
260 TEST_F(HybridVideoEngineTest, SetLocalDescription) {
261   EXPECT_TRUE(SetupEngine());
262   channel_->SetInterface(transport_.get());
263   EXPECT_TRUE(channel_->SetRecvCodecs(engine_.codecs()));
264   ASSERT_EQ(1U, sub_channel1_->recv_codecs().size());
265   ASSERT_EQ(1U, sub_channel2_->recv_codecs().size());
266   EXPECT_EQ(kVp8Codec, sub_channel1_->recv_codecs()[0]);
267   EXPECT_EQ(kGenericCodec, sub_channel2_->recv_codecs()[0]);
268   StreamParams stream;
269   stream.id = "TestStream";
270   stream.ssrcs.push_back(1234);
271   stream.cname = "5678";
272   EXPECT_TRUE(channel_->AddSendStream(stream));
273   EXPECT_EQ(1234U, sub_channel1_->send_ssrc());
274   EXPECT_EQ(1234U, sub_channel2_->send_ssrc());
275   EXPECT_EQ("5678", sub_channel1_->rtcp_cname());
276   EXPECT_EQ("5678", sub_channel2_->rtcp_cname());
277   EXPECT_TRUE(channel_->SetRender(true));
278   // We've called SetRender, so we should be playing out, but not yet sending.
279   EXPECT_TRUE(sub_channel1_->playout());
280   EXPECT_TRUE(sub_channel2_->playout());
281   EXPECT_FALSE(sub_channel1_->sending());
282   EXPECT_FALSE(sub_channel2_->sending());
283   // We may get SetSend(false) calls during call setup.
284   // Since this causes no change in state, they should no-op and return true.
285   EXPECT_TRUE(channel_->SetSend(false));
286   EXPECT_FALSE(sub_channel1_->sending());
287   EXPECT_FALSE(sub_channel2_->sending());
288 }
289
290 TEST_F(HybridVideoEngineTest, OnNewSendResolution) {
291   EXPECT_TRUE(SetupEngine());
292   EXPECT_TRUE(channel_->SetSendCodecs(MAKE_VECTOR(kCodecsVp8First)));
293   EXPECT_EQ(640, engine_.send_width());
294   EXPECT_EQ(360, engine_.send_height());
295 }
296
297 // Test that we converge to the active channel for engine 1.
298 TEST_F(HybridVideoEngineTest, SetSendCodecs1) {
299   // This will nuke the object that sub_channel2_ points to.
300   TestSetSendCodecs(engine_.sub_engine1(), MAKE_VECTOR(kCodecsVp8First));
301   EXPECT_TRUE(engine_.sub_engine2()->GetChannel(0) == NULL);
302 }
303
304 // Test that we converge to the active channel for engine 2.
305 TEST_F(HybridVideoEngineTest, SetSendCodecs2) {
306   // This will nuke the object that sub_channel1_ points to.
307   TestSetSendCodecs(engine_.sub_engine2(), MAKE_VECTOR(kCodecsGenericFirst));
308   EXPECT_TRUE(engine_.sub_engine1()->GetChannel(0) == NULL);
309 }
310
311 // Test that we don't accidentally eat 0x0 in SetSendCodecs
312 TEST_F(HybridVideoEngineTest, SetSendCodecs0x0) {
313   EXPECT_TRUE(SetupRenderAndAddStream(StreamParams::CreateLegacy(1234)));
314   // Send using generic codec, but with 0x0 resolution.
315   std::vector<cricket::VideoCodec> codecs(MAKE_VECTOR(kCodecsGenericFirst));
316   codecs.resize(1);
317   codecs[0].width = 0;
318   codecs[0].height = 0;
319   EXPECT_TRUE(channel_->SetSendCodecs(codecs));
320 }
321
322 // Test setting the send bandwidth for VP8.
323 TEST_F(HybridVideoEngineTest, SetSendBandwidth1) {
324   TestSetSendBandwidth(engine_.sub_engine1(),
325                        MAKE_VECTOR(kCodecsVp8First),
326                        100000,
327                        384000);
328 }
329
330 // Test setting the send bandwidth for a generic codec.
331 TEST_F(HybridVideoEngineTest, SetSendBandwidth2) {
332   TestSetSendBandwidth(engine_.sub_engine2(),
333                        MAKE_VECTOR(kCodecsGenericFirst),
334                        100001,
335                        384002);
336 }
337
338 // Test that we dump RTP packets that arrive early.
339 TEST_F(HybridVideoEngineTest, HandleEarlyRtp) {
340   static const uint8 kPacket[1024] = { 0 };
341   static const uint8 kRtcp[1024] = { 1 };
342   EXPECT_TRUE(SetupRenderAndAddStream(StreamParams::CreateLegacy(1234)));
343   DeliverPacket(kPacket, sizeof(kPacket));
344   DeliverRtcp(kRtcp, sizeof(kRtcp));
345   EXPECT_TRUE(sub_channel1_->CheckNoRtp());
346   EXPECT_TRUE(sub_channel2_->CheckNoRtp());
347   EXPECT_TRUE(sub_channel1_->CheckNoRtcp());
348   EXPECT_TRUE(sub_channel2_->CheckNoRtcp());
349 }
350
351 // Test that we properly pass on normal RTP packets.
352 TEST_F(HybridVideoEngineTest, HandleRtp) {
353   static const uint8 kPacket[1024] = { 0 };
354   static const uint8 kRtcp[1024] = { 1 };
355   EXPECT_TRUE(SetupRenderAndAddStream(StreamParams::CreateLegacy(1234)));
356   EXPECT_TRUE(channel_->SetSendCodecs(MAKE_VECTOR(kCodecsVp8First)));
357   EXPECT_TRUE(channel_->SetSend(true));
358   DeliverPacket(kPacket, sizeof(kPacket));
359   DeliverRtcp(kRtcp, sizeof(kRtcp));
360   EXPECT_TRUE(sub_channel1_->CheckRtp(kPacket, sizeof(kPacket)));
361   EXPECT_TRUE(sub_channel1_->CheckRtcp(kRtcp, sizeof(kRtcp)));
362 }
363
364 // Test that we properly connect media error signal.
365 TEST_F(HybridVideoEngineTest, MediaErrorSignal) {
366   cricket::VideoMediaErrorCatcher catcher;
367
368   // Verify no signal from either channel before the active channel is set.
369   EXPECT_TRUE(SetupEngine());
370   channel_->SignalMediaError.connect(&catcher,
371       &cricket::VideoMediaErrorCatcher::OnError);
372   sub_channel1_->SignalMediaError(1, cricket::VideoMediaChannel::ERROR_OTHER);
373   EXPECT_EQ(0U, catcher.ssrc());
374   sub_channel2_->SignalMediaError(2,
375       cricket::VideoMediaChannel::ERROR_REC_DEVICE_OPEN_FAILED);
376   EXPECT_EQ(0U, catcher.ssrc());
377
378   // Set vp8 as active channel and verify that a signal comes from it.
379   EXPECT_TRUE(channel_->SetSendCodecs(MAKE_VECTOR(kCodecsVp8First)));
380   sub_channel1_->SignalMediaError(1, cricket::VideoMediaChannel::ERROR_OTHER);
381   EXPECT_EQ(cricket::VideoMediaChannel::ERROR_OTHER, catcher.error());
382   EXPECT_EQ(1U, catcher.ssrc());
383
384   // Set generic codec as active channel and verify that a signal comes from it.
385   EXPECT_TRUE(SetupEngine());
386   channel_->SignalMediaError.connect(&catcher,
387       &cricket::VideoMediaErrorCatcher::OnError);
388   EXPECT_TRUE(channel_->SetSendCodecs(MAKE_VECTOR(kCodecsGenericFirst)));
389   sub_channel2_->SignalMediaError(2,
390       cricket::VideoMediaChannel::ERROR_REC_DEVICE_OPEN_FAILED);
391   EXPECT_EQ(cricket::VideoMediaChannel::ERROR_REC_DEVICE_OPEN_FAILED,
392       catcher.error());
393   EXPECT_EQ(2U, catcher.ssrc());
394 }
395
396 // Test that SetSend doesn't re-enter.
397 TEST_F(HybridVideoEngineTest, RepeatSetSend) {
398   EXPECT_TRUE(SetupEngine());
399   EXPECT_TRUE(channel_->SetSendCodecs(MAKE_VECTOR(kCodecsVp8First)));
400
401   // Verify initial status.
402   EXPECT_FALSE(channel_->sending());
403   EXPECT_FALSE(sub_channel1_->sending());
404   EXPECT_EQ(0, engine_.num_ch1_send_on());
405   EXPECT_EQ(0, engine_.num_ch1_send_off());
406
407   // Verfiy SetSend(true) works correctly.
408   EXPECT_TRUE(channel_->SetSend(true));
409   EXPECT_TRUE(channel_->sending());
410   EXPECT_TRUE(sub_channel1_->sending());
411   EXPECT_EQ(1, engine_.num_ch1_send_on());
412   EXPECT_EQ(0, engine_.num_ch1_send_off());
413
414   // SetSend(true) again and verify nothing changes.
415   EXPECT_TRUE(channel_->SetSend(true));
416   EXPECT_TRUE(channel_->sending());
417   EXPECT_TRUE(sub_channel1_->sending());
418   EXPECT_EQ(1, engine_.num_ch1_send_on());
419   EXPECT_EQ(0, engine_.num_ch1_send_off());
420
421   // Verify SetSend(false) works correctly.
422   EXPECT_TRUE(channel_->SetSend(false));
423   EXPECT_FALSE(channel_->sending());
424   EXPECT_FALSE(sub_channel1_->sending());
425   EXPECT_EQ(1, engine_.num_ch1_send_on());
426   EXPECT_EQ(1, engine_.num_ch1_send_off());
427
428   // SetSend(false) again and verfiy nothing changes.
429   EXPECT_TRUE(channel_->SetSend(false));
430   EXPECT_FALSE(channel_->sending());
431   EXPECT_FALSE(sub_channel1_->sending());
432   EXPECT_EQ(1, engine_.num_ch1_send_on());
433   EXPECT_EQ(1, engine_.num_ch1_send_off());
434 }
435
436 // Test that SetOptions.
437 TEST_F(HybridVideoEngineTest, SetOptions) {
438   cricket::VideoOptions vmo;
439   vmo.video_high_bitrate.Set(true);
440   vmo.system_low_adaptation_threshhold.Set(0.10f);
441   EXPECT_TRUE(SetupEngine());
442   EXPECT_TRUE(channel_->SetOptions(vmo));
443
444   bool high_bitrate;
445   float low;
446   EXPECT_TRUE(sub_channel1_->GetOptions(&vmo));
447   EXPECT_TRUE(vmo.video_high_bitrate.Get(&high_bitrate));
448   EXPECT_TRUE(high_bitrate);
449   EXPECT_TRUE(vmo.system_low_adaptation_threshhold.Get(&low));
450   EXPECT_EQ(0.10f, low);
451   EXPECT_TRUE(sub_channel2_->GetOptions(&vmo));
452   EXPECT_TRUE(vmo.video_high_bitrate.Get(&high_bitrate));
453   EXPECT_TRUE(high_bitrate);
454   EXPECT_TRUE(vmo.system_low_adaptation_threshhold.Get(&low));
455   EXPECT_EQ(0.10f, low);
456
457   vmo.video_high_bitrate.Set(false);
458   vmo.system_low_adaptation_threshhold.Set(0.50f);
459
460   EXPECT_TRUE(channel_->SetOptions(vmo));
461   EXPECT_TRUE(sub_channel1_->GetOptions(&vmo));
462   EXPECT_TRUE(vmo.video_high_bitrate.Get(&high_bitrate));
463   EXPECT_FALSE(high_bitrate);
464   EXPECT_TRUE(vmo.system_low_adaptation_threshhold.Get(&low));
465   EXPECT_EQ(0.50f, low);
466   EXPECT_TRUE(sub_channel2_->GetOptions(&vmo));
467   EXPECT_TRUE(vmo.video_high_bitrate.Get(&high_bitrate));
468   EXPECT_FALSE(high_bitrate);
469   EXPECT_TRUE(vmo.system_low_adaptation_threshhold.Get(&low));
470   EXPECT_EQ(0.50f, low);
471 }
472
473 TEST_F(HybridVideoEngineTest, SetCapturer) {
474   EXPECT_TRUE(SetupEngine());
475   // Set vp8 as active channel and verify that capturer can be set.
476   EXPECT_TRUE(channel_->SetSendCodecs(MAKE_VECTOR(kCodecsVp8First)));
477   cricket::FakeVideoCapturer fake_video_capturer;
478   EXPECT_TRUE(channel_->SetCapturer(0, &fake_video_capturer));
479   EXPECT_TRUE(channel_->SetCapturer(0, NULL));
480
481   // Set generic codec active channel and verify that capturer can be set.
482   EXPECT_TRUE(SetupEngine());
483   EXPECT_TRUE(channel_->SetSendCodecs(MAKE_VECTOR(kCodecsGenericFirst)));
484   EXPECT_TRUE(channel_->SetCapturer(0, &fake_video_capturer));
485   EXPECT_TRUE(channel_->SetCapturer(0, NULL));
486 }