Home | History | Annotate | Download | only in webrtc
      1 /*
      2  * libjingle
      3  * Copyright 2012 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 <string>
     29 #include <vector>
     30 
     31 #include "talk/app/webrtc/remotevideocapturer.h"
     32 #include "talk/app/webrtc/test/fakeconstraints.h"
     33 #include "talk/app/webrtc/videosource.h"
     34 #include "talk/media/base/fakemediaengine.h"
     35 #include "talk/media/base/fakevideocapturer.h"
     36 #include "talk/media/base/fakevideorenderer.h"
     37 #include "talk/media/webrtc/webrtcvideoframe.h"
     38 #include "talk/session/media/channelmanager.h"
     39 #include "webrtc/base/gunit.h"
     40 
     41 using webrtc::FakeConstraints;
     42 using webrtc::VideoSource;
     43 using webrtc::MediaConstraintsInterface;
     44 using webrtc::MediaSourceInterface;
     45 using webrtc::ObserverInterface;
     46 using webrtc::VideoSourceInterface;
     47 
     48 namespace {
     49 
     50 // Max wait time for a test.
     51 const int kMaxWaitMs = 100;
     52 
     53 }  // anonymous namespace
     54 
     55 
     56 // TestVideoCapturer extends cricket::FakeVideoCapturer so it can be used for
     57 // testing without known camera formats.
     58 // It keeps its own lists of cricket::VideoFormats for the unit tests in this
     59 // file.
     60 class TestVideoCapturer : public cricket::FakeVideoCapturer {
     61  public:
     62   TestVideoCapturer() : test_without_formats_(false) {
     63     std::vector<cricket::VideoFormat> formats;
     64     formats.push_back(cricket::VideoFormat(1280, 720,
     65         cricket::VideoFormat::FpsToInterval(30), cricket::FOURCC_I420));
     66     formats.push_back(cricket::VideoFormat(640, 480,
     67         cricket::VideoFormat::FpsToInterval(30), cricket::FOURCC_I420));
     68     formats.push_back(cricket::VideoFormat(640, 400,
     69             cricket::VideoFormat::FpsToInterval(30), cricket::FOURCC_I420));
     70     formats.push_back(cricket::VideoFormat(320, 240,
     71         cricket::VideoFormat::FpsToInterval(30), cricket::FOURCC_I420));
     72     formats.push_back(cricket::VideoFormat(352, 288,
     73             cricket::VideoFormat::FpsToInterval(30), cricket::FOURCC_I420));
     74     ResetSupportedFormats(formats);
     75   }
     76 
     77   // This function is used for resetting the supported capture formats and
     78   // simulating a cricket::VideoCapturer implementation that don't support
     79   // capture format enumeration. This is used to simulate the current
     80   // Chrome implementation.
     81   void TestWithoutCameraFormats() {
     82     test_without_formats_ = true;
     83     std::vector<cricket::VideoFormat> formats;
     84     ResetSupportedFormats(formats);
     85   }
     86 
     87   virtual cricket::CaptureState Start(
     88       const cricket::VideoFormat& capture_format) {
     89     if (test_without_formats_) {
     90       std::vector<cricket::VideoFormat> formats;
     91       formats.push_back(capture_format);
     92       ResetSupportedFormats(formats);
     93     }
     94     return FakeVideoCapturer::Start(capture_format);
     95   }
     96 
     97   virtual bool GetBestCaptureFormat(const cricket::VideoFormat& desired,
     98                                     cricket::VideoFormat* best_format) {
     99     if (test_without_formats_) {
    100       *best_format = desired;
    101       return true;
    102     }
    103     return FakeVideoCapturer::GetBestCaptureFormat(desired,
    104                                                    best_format);
    105   }
    106 
    107  private:
    108   bool test_without_formats_;
    109 };
    110 
    111 class StateObserver : public ObserverInterface {
    112  public:
    113   explicit StateObserver(VideoSourceInterface* source)
    114      : state_(source->state()),
    115        source_(source) {
    116   }
    117   virtual void OnChanged() {
    118     state_ = source_->state();
    119   }
    120   MediaSourceInterface::SourceState state() const { return state_; }
    121 
    122  private:
    123   MediaSourceInterface::SourceState state_;
    124   rtc::scoped_refptr<VideoSourceInterface> source_;
    125 };
    126 
    127 class VideoSourceTest : public testing::Test {
    128  protected:
    129   VideoSourceTest()
    130       : capturer_cleanup_(new TestVideoCapturer()),
    131         capturer_(capturer_cleanup_.get()),
    132         channel_manager_(new cricket::ChannelManager(
    133           new cricket::FakeMediaEngine(), rtc::Thread::Current())) {
    134   }
    135 
    136   void SetUp() {
    137     ASSERT_TRUE(channel_manager_->Init());
    138   }
    139 
    140   void CreateVideoSource() {
    141     CreateVideoSource(NULL);
    142   }
    143 
    144   void CreateVideoSource(
    145       const webrtc::MediaConstraintsInterface* constraints) {
    146     // VideoSource take ownership of |capturer_|
    147     source_ =
    148         VideoSource::Create(channel_manager_.get(), capturer_cleanup_.release(),
    149                             constraints, false);
    150 
    151     ASSERT_TRUE(source_.get() != NULL);
    152     EXPECT_EQ(capturer_, source_->GetVideoCapturer());
    153 
    154     state_observer_.reset(new StateObserver(source_));
    155     source_->RegisterObserver(state_observer_.get());
    156     source_->AddSink(&renderer_);
    157   }
    158 
    159   rtc::scoped_ptr<TestVideoCapturer> capturer_cleanup_;
    160   TestVideoCapturer* capturer_;
    161   cricket::FakeVideoRenderer renderer_;
    162   rtc::scoped_ptr<cricket::ChannelManager> channel_manager_;
    163   rtc::scoped_ptr<StateObserver> state_observer_;
    164   rtc::scoped_refptr<VideoSource> source_;
    165 };
    166 
    167 
    168 // Test that a VideoSource transition to kLive state when the capture
    169 // device have started and kEnded if it is stopped.
    170 // It also test that an output can receive video frames.
    171 TEST_F(VideoSourceTest, CapturerStartStop) {
    172   // Initialize without constraints.
    173   CreateVideoSource();
    174   EXPECT_EQ_WAIT(MediaSourceInterface::kLive, state_observer_->state(),
    175                  kMaxWaitMs);
    176 
    177   ASSERT_TRUE(capturer_->CaptureFrame());
    178   EXPECT_EQ(1, renderer_.num_rendered_frames());
    179 
    180   capturer_->Stop();
    181   EXPECT_EQ_WAIT(MediaSourceInterface::kEnded, state_observer_->state(),
    182                  kMaxWaitMs);
    183 }
    184 
    185 // Test that a VideoSource can be stopped and restarted.
    186 TEST_F(VideoSourceTest, StopRestart) {
    187   // Initialize without constraints.
    188   CreateVideoSource();
    189   EXPECT_EQ_WAIT(MediaSourceInterface::kLive, state_observer_->state(),
    190                  kMaxWaitMs);
    191 
    192   ASSERT_TRUE(capturer_->CaptureFrame());
    193   EXPECT_EQ(1, renderer_.num_rendered_frames());
    194 
    195   source_->Stop();
    196   EXPECT_EQ_WAIT(MediaSourceInterface::kEnded, state_observer_->state(),
    197                  kMaxWaitMs);
    198 
    199   source_->Restart();
    200   EXPECT_EQ_WAIT(MediaSourceInterface::kLive, state_observer_->state(),
    201                  kMaxWaitMs);
    202 
    203   ASSERT_TRUE(capturer_->CaptureFrame());
    204   EXPECT_EQ(2, renderer_.num_rendered_frames());
    205 
    206   source_->Stop();
    207 }
    208 
    209 // Test start stop with a remote VideoSource - the video source that has a
    210 // RemoteVideoCapturer and takes video frames from FrameInput.
    211 TEST_F(VideoSourceTest, StartStopRemote) {
    212   source_ = VideoSource::Create(channel_manager_.get(),
    213                                 new webrtc::RemoteVideoCapturer(), NULL, true);
    214 
    215   ASSERT_TRUE(source_.get() != NULL);
    216   EXPECT_TRUE(NULL != source_->GetVideoCapturer());
    217 
    218   state_observer_.reset(new StateObserver(source_));
    219   source_->RegisterObserver(state_observer_.get());
    220   source_->AddSink(&renderer_);
    221 
    222   EXPECT_EQ_WAIT(MediaSourceInterface::kLive, state_observer_->state(),
    223                  kMaxWaitMs);
    224 
    225   cricket::VideoRenderer* frameinput = source_->FrameInput();
    226   cricket::WebRtcVideoFrame test_frame;
    227   frameinput->SetSize(1280, 720, 0);
    228   frameinput->RenderFrame(&test_frame);
    229   EXPECT_EQ(1, renderer_.num_rendered_frames());
    230 
    231   source_->GetVideoCapturer()->Stop();
    232   EXPECT_EQ_WAIT(MediaSourceInterface::kEnded, state_observer_->state(),
    233                  kMaxWaitMs);
    234 }
    235 
    236 // Test that a VideoSource transition to kEnded if the capture device
    237 // fails.
    238 TEST_F(VideoSourceTest, CameraFailed) {
    239   CreateVideoSource();
    240   EXPECT_EQ_WAIT(MediaSourceInterface::kLive, state_observer_->state(),
    241                  kMaxWaitMs);
    242 
    243   capturer_->SignalStateChange(capturer_, cricket::CS_FAILED);
    244   EXPECT_EQ_WAIT(MediaSourceInterface::kEnded, state_observer_->state(),
    245                  kMaxWaitMs);
    246 }
    247 
    248 // Test that the capture output is CIF if we set max constraints to CIF.
    249 // and the capture device support CIF.
    250 TEST_F(VideoSourceTest, MandatoryConstraintCif5Fps) {
    251   FakeConstraints constraints;
    252   constraints.AddMandatory(MediaConstraintsInterface::kMaxWidth, 352);
    253   constraints.AddMandatory(MediaConstraintsInterface::kMaxHeight, 288);
    254   constraints.AddMandatory(MediaConstraintsInterface::kMaxFrameRate, 5);
    255 
    256   CreateVideoSource(&constraints);
    257   EXPECT_EQ_WAIT(MediaSourceInterface::kLive, state_observer_->state(),
    258                  kMaxWaitMs);
    259   const cricket::VideoFormat* format = capturer_->GetCaptureFormat();
    260   ASSERT_TRUE(format != NULL);
    261   EXPECT_EQ(352, format->width);
    262   EXPECT_EQ(288, format->height);
    263   EXPECT_EQ(30, format->framerate());
    264 }
    265 
    266 // Test that the capture output is 720P if the camera support it and the
    267 // optional constraint is set to 720P.
    268 TEST_F(VideoSourceTest, MandatoryMinVgaOptional720P) {
    269   FakeConstraints constraints;
    270   constraints.AddMandatory(MediaConstraintsInterface::kMinWidth, 640);
    271   constraints.AddMandatory(MediaConstraintsInterface::kMinHeight, 480);
    272   constraints.AddOptional(MediaConstraintsInterface::kMinWidth, 1280);
    273   constraints.AddOptional(MediaConstraintsInterface::kMinAspectRatio,
    274                           1280.0 / 720);
    275 
    276   CreateVideoSource(&constraints);
    277   EXPECT_EQ_WAIT(MediaSourceInterface::kLive, state_observer_->state(),
    278                  kMaxWaitMs);
    279   const cricket::VideoFormat* format = capturer_->GetCaptureFormat();
    280   ASSERT_TRUE(format != NULL);
    281   EXPECT_EQ(1280, format->width);
    282   EXPECT_EQ(720, format->height);
    283   EXPECT_EQ(30, format->framerate());
    284 }
    285 
    286 // Test that the capture output have aspect ratio 4:3 if a mandatory constraint
    287 // require it even if an optional constraint request a higher resolution
    288 // that don't have this aspect ratio.
    289 TEST_F(VideoSourceTest, MandatoryAspectRatio4To3) {
    290   FakeConstraints constraints;
    291   constraints.AddMandatory(MediaConstraintsInterface::kMinWidth, 640);
    292   constraints.AddMandatory(MediaConstraintsInterface::kMinHeight, 480);
    293   constraints.AddMandatory(MediaConstraintsInterface::kMaxAspectRatio,
    294                            640.0 / 480);
    295   constraints.AddOptional(MediaConstraintsInterface::kMinWidth, 1280);
    296 
    297   CreateVideoSource(&constraints);
    298   EXPECT_EQ_WAIT(MediaSourceInterface::kLive, state_observer_->state(),
    299                  kMaxWaitMs);
    300   const cricket::VideoFormat* format = capturer_->GetCaptureFormat();
    301   ASSERT_TRUE(format != NULL);
    302   EXPECT_EQ(640, format->width);
    303   EXPECT_EQ(480, format->height);
    304   EXPECT_EQ(30, format->framerate());
    305 }
    306 
    307 
    308 // Test that the source state transition to kEnded if the mandatory aspect ratio
    309 // is set higher than supported.
    310 TEST_F(VideoSourceTest, MandatoryAspectRatioTooHigh) {
    311   FakeConstraints constraints;
    312   constraints.AddMandatory(MediaConstraintsInterface::kMinAspectRatio, 2);
    313   CreateVideoSource(&constraints);
    314   EXPECT_EQ_WAIT(MediaSourceInterface::kEnded, state_observer_->state(),
    315                  kMaxWaitMs);
    316 }
    317 
    318 // Test that the source ignores an optional aspect ratio that is higher than
    319 // supported.
    320 TEST_F(VideoSourceTest, OptionalAspectRatioTooHigh) {
    321   FakeConstraints constraints;
    322   constraints.AddOptional(MediaConstraintsInterface::kMinAspectRatio, 2);
    323   CreateVideoSource(&constraints);
    324   EXPECT_EQ_WAIT(MediaSourceInterface::kLive, state_observer_->state(),
    325                  kMaxWaitMs);
    326   const cricket::VideoFormat* format = capturer_->GetCaptureFormat();
    327   ASSERT_TRUE(format != NULL);
    328   double aspect_ratio = static_cast<double>(format->width) / format->height;
    329   EXPECT_LT(aspect_ratio, 2);
    330 }
    331 
    332 // Test that the source starts video with the default resolution if the
    333 // camera doesn't support capability enumeration and there are no constraints.
    334 TEST_F(VideoSourceTest, NoCameraCapability) {
    335   capturer_->TestWithoutCameraFormats();
    336 
    337   CreateVideoSource();
    338   EXPECT_EQ_WAIT(MediaSourceInterface::kLive, state_observer_->state(),
    339                  kMaxWaitMs);
    340   const cricket::VideoFormat* format = capturer_->GetCaptureFormat();
    341   ASSERT_TRUE(format != NULL);
    342   EXPECT_EQ(640, format->width);
    343   EXPECT_EQ(480, format->height);
    344   EXPECT_EQ(30, format->framerate());
    345 }
    346 
    347 // Test that the source can start the video and get the requested aspect ratio
    348 // if the camera doesn't support capability enumeration and the aspect ratio is
    349 // set.
    350 TEST_F(VideoSourceTest, NoCameraCapability16To9Ratio) {
    351   capturer_->TestWithoutCameraFormats();
    352 
    353   FakeConstraints constraints;
    354   double requested_aspect_ratio = 640.0 / 360;
    355   constraints.AddMandatory(MediaConstraintsInterface::kMinWidth, 640);
    356   constraints.AddMandatory(MediaConstraintsInterface::kMinAspectRatio,
    357                            requested_aspect_ratio);
    358 
    359   CreateVideoSource(&constraints);
    360   EXPECT_EQ_WAIT(MediaSourceInterface::kLive, state_observer_->state(),
    361                  kMaxWaitMs);
    362   const cricket::VideoFormat* format = capturer_->GetCaptureFormat();
    363   double aspect_ratio = static_cast<double>(format->width) / format->height;
    364   EXPECT_LE(requested_aspect_ratio, aspect_ratio);
    365 }
    366 
    367 // Test that the source state transitions to kEnded if an unknown mandatory
    368 // constraint is found.
    369 TEST_F(VideoSourceTest, InvalidMandatoryConstraint) {
    370   FakeConstraints constraints;
    371   constraints.AddMandatory("weird key", 640);
    372 
    373   CreateVideoSource(&constraints);
    374   EXPECT_EQ_WAIT(MediaSourceInterface::kEnded, state_observer_->state(),
    375                  kMaxWaitMs);
    376 }
    377 
    378 // Test that the source ignores an unknown optional constraint.
    379 TEST_F(VideoSourceTest, InvalidOptionalConstraint) {
    380   FakeConstraints constraints;
    381   constraints.AddOptional("weird key", 640);
    382 
    383   CreateVideoSource(&constraints);
    384   EXPECT_EQ_WAIT(MediaSourceInterface::kLive, state_observer_->state(),
    385                  kMaxWaitMs);
    386 }
    387 
    388 TEST_F(VideoSourceTest, SetValidOptionValues) {
    389   FakeConstraints constraints;
    390   constraints.AddMandatory(MediaConstraintsInterface::kNoiseReduction, "false");
    391 
    392   CreateVideoSource(&constraints);
    393 
    394   EXPECT_EQ(rtc::Optional<bool>(false),
    395             source_->options()->video_noise_reduction);
    396 }
    397 
    398 TEST_F(VideoSourceTest, OptionNotSet) {
    399   FakeConstraints constraints;
    400   CreateVideoSource(&constraints);
    401   EXPECT_EQ(rtc::Optional<bool>(), source_->options()->video_noise_reduction);
    402 }
    403 
    404 TEST_F(VideoSourceTest, MandatoryOptionOverridesOptional) {
    405   FakeConstraints constraints;
    406   constraints.AddMandatory(
    407       MediaConstraintsInterface::kNoiseReduction, true);
    408   constraints.AddOptional(
    409       MediaConstraintsInterface::kNoiseReduction, false);
    410 
    411   CreateVideoSource(&constraints);
    412 
    413   EXPECT_EQ(rtc::Optional<bool>(true),
    414             source_->options()->video_noise_reduction);
    415 }
    416 
    417 TEST_F(VideoSourceTest, InvalidOptionKeyOptional) {
    418   FakeConstraints constraints;
    419   constraints.AddOptional(
    420       MediaConstraintsInterface::kNoiseReduction, false);
    421   constraints.AddOptional("invalidKey", false);
    422 
    423   CreateVideoSource(&constraints);
    424 
    425   EXPECT_EQ_WAIT(MediaSourceInterface::kLive, state_observer_->state(),
    426       kMaxWaitMs);
    427   EXPECT_EQ(rtc::Optional<bool>(false),
    428             source_->options()->video_noise_reduction);
    429 }
    430 
    431 TEST_F(VideoSourceTest, InvalidOptionKeyMandatory) {
    432   FakeConstraints constraints;
    433   constraints.AddMandatory(
    434       MediaConstraintsInterface::kNoiseReduction, false);
    435   constraints.AddMandatory("invalidKey", false);
    436 
    437   CreateVideoSource(&constraints);
    438 
    439   EXPECT_EQ_WAIT(MediaSourceInterface::kEnded, state_observer_->state(),
    440       kMaxWaitMs);
    441   EXPECT_EQ(rtc::Optional<bool>(), source_->options()->video_noise_reduction);
    442 }
    443 
    444 TEST_F(VideoSourceTest, InvalidOptionValueOptional) {
    445   FakeConstraints constraints;
    446   constraints.AddOptional(
    447       MediaConstraintsInterface::kNoiseReduction, "not a boolean");
    448 
    449   CreateVideoSource(&constraints);
    450 
    451   EXPECT_EQ_WAIT(MediaSourceInterface::kLive, state_observer_->state(),
    452       kMaxWaitMs);
    453   EXPECT_EQ(rtc::Optional<bool>(), source_->options()->video_noise_reduction);
    454 }
    455 
    456 TEST_F(VideoSourceTest, InvalidOptionValueMandatory) {
    457   FakeConstraints constraints;
    458   // Optional constraints should be ignored if the mandatory constraints fail.
    459   constraints.AddOptional(
    460       MediaConstraintsInterface::kNoiseReduction, "false");
    461   // Values are case-sensitive and must be all lower-case.
    462   constraints.AddMandatory(
    463       MediaConstraintsInterface::kNoiseReduction, "True");
    464 
    465   CreateVideoSource(&constraints);
    466 
    467   EXPECT_EQ_WAIT(MediaSourceInterface::kEnded, state_observer_->state(),
    468       kMaxWaitMs);
    469   EXPECT_EQ(rtc::Optional<bool>(), source_->options()->video_noise_reduction);
    470 }
    471 
    472 TEST_F(VideoSourceTest, MixedOptionsAndConstraints) {
    473   FakeConstraints constraints;
    474   constraints.AddMandatory(MediaConstraintsInterface::kMaxWidth, 352);
    475   constraints.AddMandatory(MediaConstraintsInterface::kMaxHeight, 288);
    476   constraints.AddOptional(MediaConstraintsInterface::kMaxFrameRate, 5);
    477 
    478   constraints.AddMandatory(
    479       MediaConstraintsInterface::kNoiseReduction, false);
    480   constraints.AddOptional(
    481       MediaConstraintsInterface::kNoiseReduction, true);
    482 
    483   CreateVideoSource(&constraints);
    484   EXPECT_EQ_WAIT(MediaSourceInterface::kLive, state_observer_->state(),
    485                  kMaxWaitMs);
    486   const cricket::VideoFormat* format = capturer_->GetCaptureFormat();
    487   ASSERT_TRUE(format != NULL);
    488   EXPECT_EQ(352, format->width);
    489   EXPECT_EQ(288, format->height);
    490   EXPECT_EQ(30, format->framerate());
    491 
    492   EXPECT_EQ(rtc::Optional<bool>(false),
    493             source_->options()->video_noise_reduction);
    494 }
    495 
    496 // Tests that the source starts video with the default resolution for
    497 // screencast if no constraint is set.
    498 TEST_F(VideoSourceTest, ScreencastResolutionNoConstraint) {
    499   capturer_->TestWithoutCameraFormats();
    500   capturer_->SetScreencast(true);
    501 
    502   CreateVideoSource();
    503   EXPECT_EQ_WAIT(MediaSourceInterface::kLive, state_observer_->state(),
    504                  kMaxWaitMs);
    505   const cricket::VideoFormat* format = capturer_->GetCaptureFormat();
    506   ASSERT_TRUE(format != NULL);
    507   EXPECT_EQ(640, format->width);
    508   EXPECT_EQ(480, format->height);
    509   EXPECT_EQ(30, format->framerate());
    510 }
    511 
    512 // Tests that the source starts video with the max width and height set by
    513 // constraints for screencast.
    514 TEST_F(VideoSourceTest, ScreencastResolutionWithConstraint) {
    515   FakeConstraints constraints;
    516   constraints.AddMandatory(MediaConstraintsInterface::kMaxWidth, 480);
    517   constraints.AddMandatory(MediaConstraintsInterface::kMaxHeight, 270);
    518 
    519   capturer_->TestWithoutCameraFormats();
    520   capturer_->SetScreencast(true);
    521 
    522   CreateVideoSource(&constraints);
    523   EXPECT_EQ_WAIT(MediaSourceInterface::kLive, state_observer_->state(),
    524                  kMaxWaitMs);
    525   const cricket::VideoFormat* format = capturer_->GetCaptureFormat();
    526   ASSERT_TRUE(format != NULL);
    527   EXPECT_EQ(480, format->width);
    528   EXPECT_EQ(270, format->height);
    529   EXPECT_EQ(30, format->framerate());
    530 }
    531 
    532 TEST_F(VideoSourceTest, MandatorySubOneFpsConstraints) {
    533   FakeConstraints constraints;
    534   constraints.AddMandatory(MediaConstraintsInterface::kMaxFrameRate, 0.5);
    535 
    536   CreateVideoSource(&constraints);
    537   EXPECT_EQ_WAIT(MediaSourceInterface::kEnded, state_observer_->state(),
    538                  kMaxWaitMs);
    539   ASSERT_TRUE(capturer_->GetCaptureFormat() == NULL);
    540 }
    541 
    542 TEST_F(VideoSourceTest, OptionalSubOneFpsConstraints) {
    543   FakeConstraints constraints;
    544   constraints.AddOptional(MediaConstraintsInterface::kMaxFrameRate, 0.5);
    545 
    546   CreateVideoSource(&constraints);
    547   EXPECT_EQ_WAIT(MediaSourceInterface::kLive, state_observer_->state(),
    548                  kMaxWaitMs);
    549   const cricket::VideoFormat* format = capturer_->GetCaptureFormat();
    550   ASSERT_TRUE(format != NULL);
    551   EXPECT_EQ(30, format->framerate());
    552 }
    553 
    554