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