| OLD | NEW | 
|---|
|  | (Empty) | 
| 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/session/media/channelmanager.h" |  | 
| 35 #include "webrtc/base/gunit.h" |  | 
| 36 #include "webrtc/media/base/fakemediaengine.h" |  | 
| 37 #include "webrtc/media/base/fakevideocapturer.h" |  | 
| 38 #include "webrtc/media/base/fakevideorenderer.h" |  | 
| 39 #include "webrtc/media/webrtc/webrtcvideoframe.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   source_->GetVideoCapturer()->Stop(); |  | 
| 226   EXPECT_EQ_WAIT(MediaSourceInterface::kEnded, state_observer_->state(), |  | 
| 227                  kMaxWaitMs); |  | 
| 228 } |  | 
| 229 |  | 
| 230 // Test that a VideoSource transition to kEnded if the capture device |  | 
| 231 // fails. |  | 
| 232 TEST_F(VideoSourceTest, CameraFailed) { |  | 
| 233   CreateVideoSource(); |  | 
| 234   EXPECT_EQ_WAIT(MediaSourceInterface::kLive, state_observer_->state(), |  | 
| 235                  kMaxWaitMs); |  | 
| 236 |  | 
| 237   capturer_->SignalStateChange(capturer_, cricket::CS_FAILED); |  | 
| 238   EXPECT_EQ_WAIT(MediaSourceInterface::kEnded, state_observer_->state(), |  | 
| 239                  kMaxWaitMs); |  | 
| 240 } |  | 
| 241 |  | 
| 242 // Test that the capture output is CIF if we set max constraints to CIF. |  | 
| 243 // and the capture device support CIF. |  | 
| 244 TEST_F(VideoSourceTest, MandatoryConstraintCif5Fps) { |  | 
| 245   FakeConstraints constraints; |  | 
| 246   constraints.AddMandatory(MediaConstraintsInterface::kMaxWidth, 352); |  | 
| 247   constraints.AddMandatory(MediaConstraintsInterface::kMaxHeight, 288); |  | 
| 248   constraints.AddMandatory(MediaConstraintsInterface::kMaxFrameRate, 5); |  | 
| 249 |  | 
| 250   CreateVideoSource(&constraints); |  | 
| 251   EXPECT_EQ_WAIT(MediaSourceInterface::kLive, state_observer_->state(), |  | 
| 252                  kMaxWaitMs); |  | 
| 253   const cricket::VideoFormat* format = capturer_->GetCaptureFormat(); |  | 
| 254   ASSERT_TRUE(format != NULL); |  | 
| 255   EXPECT_EQ(352, format->width); |  | 
| 256   EXPECT_EQ(288, format->height); |  | 
| 257   EXPECT_EQ(30, format->framerate()); |  | 
| 258 } |  | 
| 259 |  | 
| 260 // Test that the capture output is 720P if the camera support it and the |  | 
| 261 // optional constraint is set to 720P. |  | 
| 262 TEST_F(VideoSourceTest, MandatoryMinVgaOptional720P) { |  | 
| 263   FakeConstraints constraints; |  | 
| 264   constraints.AddMandatory(MediaConstraintsInterface::kMinWidth, 640); |  | 
| 265   constraints.AddMandatory(MediaConstraintsInterface::kMinHeight, 480); |  | 
| 266   constraints.AddOptional(MediaConstraintsInterface::kMinWidth, 1280); |  | 
| 267   constraints.AddOptional(MediaConstraintsInterface::kMinAspectRatio, |  | 
| 268                           1280.0 / 720); |  | 
| 269 |  | 
| 270   CreateVideoSource(&constraints); |  | 
| 271   EXPECT_EQ_WAIT(MediaSourceInterface::kLive, state_observer_->state(), |  | 
| 272                  kMaxWaitMs); |  | 
| 273   const cricket::VideoFormat* format = capturer_->GetCaptureFormat(); |  | 
| 274   ASSERT_TRUE(format != NULL); |  | 
| 275   EXPECT_EQ(1280, format->width); |  | 
| 276   EXPECT_EQ(720, format->height); |  | 
| 277   EXPECT_EQ(30, format->framerate()); |  | 
| 278 } |  | 
| 279 |  | 
| 280 // Test that the capture output have aspect ratio 4:3 if a mandatory constraint |  | 
| 281 // require it even if an optional constraint request a higher resolution |  | 
| 282 // that don't have this aspect ratio. |  | 
| 283 TEST_F(VideoSourceTest, MandatoryAspectRatio4To3) { |  | 
| 284   FakeConstraints constraints; |  | 
| 285   constraints.AddMandatory(MediaConstraintsInterface::kMinWidth, 640); |  | 
| 286   constraints.AddMandatory(MediaConstraintsInterface::kMinHeight, 480); |  | 
| 287   constraints.AddMandatory(MediaConstraintsInterface::kMaxAspectRatio, |  | 
| 288                            640.0 / 480); |  | 
| 289   constraints.AddOptional(MediaConstraintsInterface::kMinWidth, 1280); |  | 
| 290 |  | 
| 291   CreateVideoSource(&constraints); |  | 
| 292   EXPECT_EQ_WAIT(MediaSourceInterface::kLive, state_observer_->state(), |  | 
| 293                  kMaxWaitMs); |  | 
| 294   const cricket::VideoFormat* format = capturer_->GetCaptureFormat(); |  | 
| 295   ASSERT_TRUE(format != NULL); |  | 
| 296   EXPECT_EQ(640, format->width); |  | 
| 297   EXPECT_EQ(480, format->height); |  | 
| 298   EXPECT_EQ(30, format->framerate()); |  | 
| 299 } |  | 
| 300 |  | 
| 301 |  | 
| 302 // Test that the source state transition to kEnded if the mandatory aspect ratio |  | 
| 303 // is set higher than supported. |  | 
| 304 TEST_F(VideoSourceTest, MandatoryAspectRatioTooHigh) { |  | 
| 305   FakeConstraints constraints; |  | 
| 306   constraints.AddMandatory(MediaConstraintsInterface::kMinAspectRatio, 2); |  | 
| 307   CreateVideoSource(&constraints); |  | 
| 308   EXPECT_EQ_WAIT(MediaSourceInterface::kEnded, state_observer_->state(), |  | 
| 309                  kMaxWaitMs); |  | 
| 310 } |  | 
| 311 |  | 
| 312 // Test that the source ignores an optional aspect ratio that is higher than |  | 
| 313 // supported. |  | 
| 314 TEST_F(VideoSourceTest, OptionalAspectRatioTooHigh) { |  | 
| 315   FakeConstraints constraints; |  | 
| 316   constraints.AddOptional(MediaConstraintsInterface::kMinAspectRatio, 2); |  | 
| 317   CreateVideoSource(&constraints); |  | 
| 318   EXPECT_EQ_WAIT(MediaSourceInterface::kLive, state_observer_->state(), |  | 
| 319                  kMaxWaitMs); |  | 
| 320   const cricket::VideoFormat* format = capturer_->GetCaptureFormat(); |  | 
| 321   ASSERT_TRUE(format != NULL); |  | 
| 322   double aspect_ratio = static_cast<double>(format->width) / format->height; |  | 
| 323   EXPECT_LT(aspect_ratio, 2); |  | 
| 324 } |  | 
| 325 |  | 
| 326 // Test that the source starts video with the default resolution if the |  | 
| 327 // camera doesn't support capability enumeration and there are no constraints. |  | 
| 328 TEST_F(VideoSourceTest, NoCameraCapability) { |  | 
| 329   capturer_->TestWithoutCameraFormats(); |  | 
| 330 |  | 
| 331   CreateVideoSource(); |  | 
| 332   EXPECT_EQ_WAIT(MediaSourceInterface::kLive, state_observer_->state(), |  | 
| 333                  kMaxWaitMs); |  | 
| 334   const cricket::VideoFormat* format = capturer_->GetCaptureFormat(); |  | 
| 335   ASSERT_TRUE(format != NULL); |  | 
| 336   EXPECT_EQ(640, format->width); |  | 
| 337   EXPECT_EQ(480, format->height); |  | 
| 338   EXPECT_EQ(30, format->framerate()); |  | 
| 339 } |  | 
| 340 |  | 
| 341 // Test that the source can start the video and get the requested aspect ratio |  | 
| 342 // if the camera doesn't support capability enumeration and the aspect ratio is |  | 
| 343 // set. |  | 
| 344 TEST_F(VideoSourceTest, NoCameraCapability16To9Ratio) { |  | 
| 345   capturer_->TestWithoutCameraFormats(); |  | 
| 346 |  | 
| 347   FakeConstraints constraints; |  | 
| 348   double requested_aspect_ratio = 640.0 / 360; |  | 
| 349   constraints.AddMandatory(MediaConstraintsInterface::kMinWidth, 640); |  | 
| 350   constraints.AddMandatory(MediaConstraintsInterface::kMinAspectRatio, |  | 
| 351                            requested_aspect_ratio); |  | 
| 352 |  | 
| 353   CreateVideoSource(&constraints); |  | 
| 354   EXPECT_EQ_WAIT(MediaSourceInterface::kLive, state_observer_->state(), |  | 
| 355                  kMaxWaitMs); |  | 
| 356   const cricket::VideoFormat* format = capturer_->GetCaptureFormat(); |  | 
| 357   double aspect_ratio = static_cast<double>(format->width) / format->height; |  | 
| 358   EXPECT_LE(requested_aspect_ratio, aspect_ratio); |  | 
| 359 } |  | 
| 360 |  | 
| 361 // Test that the source state transitions to kEnded if an unknown mandatory |  | 
| 362 // constraint is found. |  | 
| 363 TEST_F(VideoSourceTest, InvalidMandatoryConstraint) { |  | 
| 364   FakeConstraints constraints; |  | 
| 365   constraints.AddMandatory("weird key", 640); |  | 
| 366 |  | 
| 367   CreateVideoSource(&constraints); |  | 
| 368   EXPECT_EQ_WAIT(MediaSourceInterface::kEnded, state_observer_->state(), |  | 
| 369                  kMaxWaitMs); |  | 
| 370 } |  | 
| 371 |  | 
| 372 // Test that the source ignores an unknown optional constraint. |  | 
| 373 TEST_F(VideoSourceTest, InvalidOptionalConstraint) { |  | 
| 374   FakeConstraints constraints; |  | 
| 375   constraints.AddOptional("weird key", 640); |  | 
| 376 |  | 
| 377   CreateVideoSource(&constraints); |  | 
| 378   EXPECT_EQ_WAIT(MediaSourceInterface::kLive, state_observer_->state(), |  | 
| 379                  kMaxWaitMs); |  | 
| 380 } |  | 
| 381 |  | 
| 382 TEST_F(VideoSourceTest, SetValidOptionValues) { |  | 
| 383   FakeConstraints constraints; |  | 
| 384   constraints.AddMandatory(MediaConstraintsInterface::kNoiseReduction, "false"); |  | 
| 385 |  | 
| 386   CreateVideoSource(&constraints); |  | 
| 387 |  | 
| 388   EXPECT_EQ(rtc::Optional<bool>(false), |  | 
| 389             source_->options()->video_noise_reduction); |  | 
| 390 } |  | 
| 391 |  | 
| 392 TEST_F(VideoSourceTest, OptionNotSet) { |  | 
| 393   FakeConstraints constraints; |  | 
| 394   CreateVideoSource(&constraints); |  | 
| 395   EXPECT_EQ(rtc::Optional<bool>(), source_->options()->video_noise_reduction); |  | 
| 396 } |  | 
| 397 |  | 
| 398 TEST_F(VideoSourceTest, MandatoryOptionOverridesOptional) { |  | 
| 399   FakeConstraints constraints; |  | 
| 400   constraints.AddMandatory( |  | 
| 401       MediaConstraintsInterface::kNoiseReduction, true); |  | 
| 402   constraints.AddOptional( |  | 
| 403       MediaConstraintsInterface::kNoiseReduction, false); |  | 
| 404 |  | 
| 405   CreateVideoSource(&constraints); |  | 
| 406 |  | 
| 407   EXPECT_EQ(rtc::Optional<bool>(true), |  | 
| 408             source_->options()->video_noise_reduction); |  | 
| 409 } |  | 
| 410 |  | 
| 411 TEST_F(VideoSourceTest, InvalidOptionKeyOptional) { |  | 
| 412   FakeConstraints constraints; |  | 
| 413   constraints.AddOptional( |  | 
| 414       MediaConstraintsInterface::kNoiseReduction, false); |  | 
| 415   constraints.AddOptional("invalidKey", false); |  | 
| 416 |  | 
| 417   CreateVideoSource(&constraints); |  | 
| 418 |  | 
| 419   EXPECT_EQ_WAIT(MediaSourceInterface::kLive, state_observer_->state(), |  | 
| 420       kMaxWaitMs); |  | 
| 421   EXPECT_EQ(rtc::Optional<bool>(false), |  | 
| 422             source_->options()->video_noise_reduction); |  | 
| 423 } |  | 
| 424 |  | 
| 425 TEST_F(VideoSourceTest, InvalidOptionKeyMandatory) { |  | 
| 426   FakeConstraints constraints; |  | 
| 427   constraints.AddMandatory( |  | 
| 428       MediaConstraintsInterface::kNoiseReduction, false); |  | 
| 429   constraints.AddMandatory("invalidKey", false); |  | 
| 430 |  | 
| 431   CreateVideoSource(&constraints); |  | 
| 432 |  | 
| 433   EXPECT_EQ_WAIT(MediaSourceInterface::kEnded, state_observer_->state(), |  | 
| 434       kMaxWaitMs); |  | 
| 435   EXPECT_EQ(rtc::Optional<bool>(), source_->options()->video_noise_reduction); |  | 
| 436 } |  | 
| 437 |  | 
| 438 TEST_F(VideoSourceTest, InvalidOptionValueOptional) { |  | 
| 439   FakeConstraints constraints; |  | 
| 440   constraints.AddOptional( |  | 
| 441       MediaConstraintsInterface::kNoiseReduction, "not a boolean"); |  | 
| 442 |  | 
| 443   CreateVideoSource(&constraints); |  | 
| 444 |  | 
| 445   EXPECT_EQ_WAIT(MediaSourceInterface::kLive, state_observer_->state(), |  | 
| 446       kMaxWaitMs); |  | 
| 447   EXPECT_EQ(rtc::Optional<bool>(), source_->options()->video_noise_reduction); |  | 
| 448 } |  | 
| 449 |  | 
| 450 TEST_F(VideoSourceTest, InvalidOptionValueMandatory) { |  | 
| 451   FakeConstraints constraints; |  | 
| 452   // Optional constraints should be ignored if the mandatory constraints fail. |  | 
| 453   constraints.AddOptional( |  | 
| 454       MediaConstraintsInterface::kNoiseReduction, "false"); |  | 
| 455   // Values are case-sensitive and must be all lower-case. |  | 
| 456   constraints.AddMandatory( |  | 
| 457       MediaConstraintsInterface::kNoiseReduction, "True"); |  | 
| 458 |  | 
| 459   CreateVideoSource(&constraints); |  | 
| 460 |  | 
| 461   EXPECT_EQ_WAIT(MediaSourceInterface::kEnded, state_observer_->state(), |  | 
| 462       kMaxWaitMs); |  | 
| 463   EXPECT_EQ(rtc::Optional<bool>(), source_->options()->video_noise_reduction); |  | 
| 464 } |  | 
| 465 |  | 
| 466 TEST_F(VideoSourceTest, MixedOptionsAndConstraints) { |  | 
| 467   FakeConstraints constraints; |  | 
| 468   constraints.AddMandatory(MediaConstraintsInterface::kMaxWidth, 352); |  | 
| 469   constraints.AddMandatory(MediaConstraintsInterface::kMaxHeight, 288); |  | 
| 470   constraints.AddOptional(MediaConstraintsInterface::kMaxFrameRate, 5); |  | 
| 471 |  | 
| 472   constraints.AddMandatory( |  | 
| 473       MediaConstraintsInterface::kNoiseReduction, false); |  | 
| 474   constraints.AddOptional( |  | 
| 475       MediaConstraintsInterface::kNoiseReduction, true); |  | 
| 476 |  | 
| 477   CreateVideoSource(&constraints); |  | 
| 478   EXPECT_EQ_WAIT(MediaSourceInterface::kLive, state_observer_->state(), |  | 
| 479                  kMaxWaitMs); |  | 
| 480   const cricket::VideoFormat* format = capturer_->GetCaptureFormat(); |  | 
| 481   ASSERT_TRUE(format != NULL); |  | 
| 482   EXPECT_EQ(352, format->width); |  | 
| 483   EXPECT_EQ(288, format->height); |  | 
| 484   EXPECT_EQ(30, format->framerate()); |  | 
| 485 |  | 
| 486   EXPECT_EQ(rtc::Optional<bool>(false), |  | 
| 487             source_->options()->video_noise_reduction); |  | 
| 488 } |  | 
| 489 |  | 
| 490 // Tests that the source starts video with the default resolution for |  | 
| 491 // screencast if no constraint is set. |  | 
| 492 TEST_F(VideoSourceTest, ScreencastResolutionNoConstraint) { |  | 
| 493   capturer_->TestWithoutCameraFormats(); |  | 
| 494   capturer_->SetScreencast(true); |  | 
| 495 |  | 
| 496   CreateVideoSource(); |  | 
| 497   EXPECT_EQ_WAIT(MediaSourceInterface::kLive, state_observer_->state(), |  | 
| 498                  kMaxWaitMs); |  | 
| 499   const cricket::VideoFormat* format = capturer_->GetCaptureFormat(); |  | 
| 500   ASSERT_TRUE(format != NULL); |  | 
| 501   EXPECT_EQ(640, format->width); |  | 
| 502   EXPECT_EQ(480, format->height); |  | 
| 503   EXPECT_EQ(30, format->framerate()); |  | 
| 504 } |  | 
| 505 |  | 
| 506 // Tests that the source starts video with the max width and height set by |  | 
| 507 // constraints for screencast. |  | 
| 508 TEST_F(VideoSourceTest, ScreencastResolutionWithConstraint) { |  | 
| 509   FakeConstraints constraints; |  | 
| 510   constraints.AddMandatory(MediaConstraintsInterface::kMaxWidth, 480); |  | 
| 511   constraints.AddMandatory(MediaConstraintsInterface::kMaxHeight, 270); |  | 
| 512 |  | 
| 513   capturer_->TestWithoutCameraFormats(); |  | 
| 514   capturer_->SetScreencast(true); |  | 
| 515 |  | 
| 516   CreateVideoSource(&constraints); |  | 
| 517   EXPECT_EQ_WAIT(MediaSourceInterface::kLive, state_observer_->state(), |  | 
| 518                  kMaxWaitMs); |  | 
| 519   const cricket::VideoFormat* format = capturer_->GetCaptureFormat(); |  | 
| 520   ASSERT_TRUE(format != NULL); |  | 
| 521   EXPECT_EQ(480, format->width); |  | 
| 522   EXPECT_EQ(270, format->height); |  | 
| 523   EXPECT_EQ(30, format->framerate()); |  | 
| 524 } |  | 
| 525 |  | 
| 526 TEST_F(VideoSourceTest, MandatorySubOneFpsConstraints) { |  | 
| 527   FakeConstraints constraints; |  | 
| 528   constraints.AddMandatory(MediaConstraintsInterface::kMaxFrameRate, 0.5); |  | 
| 529 |  | 
| 530   CreateVideoSource(&constraints); |  | 
| 531   EXPECT_EQ_WAIT(MediaSourceInterface::kEnded, state_observer_->state(), |  | 
| 532                  kMaxWaitMs); |  | 
| 533   ASSERT_TRUE(capturer_->GetCaptureFormat() == NULL); |  | 
| 534 } |  | 
| 535 |  | 
| 536 TEST_F(VideoSourceTest, OptionalSubOneFpsConstraints) { |  | 
| 537   FakeConstraints constraints; |  | 
| 538   constraints.AddOptional(MediaConstraintsInterface::kMaxFrameRate, 0.5); |  | 
| 539 |  | 
| 540   CreateVideoSource(&constraints); |  | 
| 541   EXPECT_EQ_WAIT(MediaSourceInterface::kLive, state_observer_->state(), |  | 
| 542                  kMaxWaitMs); |  | 
| 543   const cricket::VideoFormat* format = capturer_->GetCaptureFormat(); |  | 
| 544   ASSERT_TRUE(format != NULL); |  | 
| 545   EXPECT_EQ(30, format->framerate()); |  | 
| 546 } |  | 
| OLD | NEW | 
|---|