1ce8510901416e37afabb0a54c6e10bec6db63a42pbos@webrtc.org/* 2ce8510901416e37afabb0a54c6e10bec6db63a42pbos@webrtc.org * Copyright (c) 2013 The WebRTC project authors. All Rights Reserved. 3ce8510901416e37afabb0a54c6e10bec6db63a42pbos@webrtc.org * 4ce8510901416e37afabb0a54c6e10bec6db63a42pbos@webrtc.org * Use of this source code is governed by a BSD-style license 5ce8510901416e37afabb0a54c6e10bec6db63a42pbos@webrtc.org * that can be found in the LICENSE file in the root of the source 6ce8510901416e37afabb0a54c6e10bec6db63a42pbos@webrtc.org * tree. An additional intellectual property rights grant can be found 7ce8510901416e37afabb0a54c6e10bec6db63a42pbos@webrtc.org * in the file PATENTS. All contributing project authors may 8ce8510901416e37afabb0a54c6e10bec6db63a42pbos@webrtc.org * be found in the AUTHORS file in the root of the source tree. 9ce8510901416e37afabb0a54c6e10bec6db63a42pbos@webrtc.org */ 108ce445ecc8a3fbf2a7517f71e778948f6a8e3d2fpbos@webrtc.org#include <assert.h> 118ce445ecc8a3fbf2a7517f71e778948f6a8e3d2fpbos@webrtc.org 12e028410838cd976c75e379b3c2e2eb0ac52b3c99stefan@webrtc.org#include <algorithm> 13ce8510901416e37afabb0a54c6e10bec6db63a42pbos@webrtc.org#include <map> 14e028410838cd976c75e379b3c2e2eb0ac52b3c99stefan@webrtc.org#include <sstream> 15e028410838cd976c75e379b3c2e2eb0ac52b3c99stefan@webrtc.org#include <string> 16ce8510901416e37afabb0a54c6e10bec6db63a42pbos@webrtc.org 17ce8510901416e37afabb0a54c6e10bec6db63a42pbos@webrtc.org#include "testing/gtest/include/gtest/gtest.h" 18ce8510901416e37afabb0a54c6e10bec6db63a42pbos@webrtc.org 1924e2089750e9e51228b82d6c7ebf4fa064c797bapbos@webrtc.org#include "webrtc/call.h" 202e98d45e2455d3b48ceac1ad5457623d39802c9esprang@webrtc.org#include "webrtc/frame_callback.h" 21ce8510901416e37afabb0a54c6e10bec6db63a42pbos@webrtc.org#include "webrtc/modules/rtp_rtcp/source/rtcp_utility.h" 22ce8510901416e37afabb0a54c6e10bec6db63a42pbos@webrtc.org#include "webrtc/system_wrappers/interface/critical_section_wrapper.h" 23ce8510901416e37afabb0a54c6e10bec6db63a42pbos@webrtc.org#include "webrtc/system_wrappers/interface/event_wrapper.h" 24fa996f226ee327232b854c936d2f706aa71ff090pbos@webrtc.org#include "webrtc/system_wrappers/interface/scoped_ptr.h" 25d60137ff1b936534b04396298b7d2f2ebbc1da82pbos@webrtc.org#include "webrtc/system_wrappers/interface/sleep.h" 26eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org#include "webrtc/test/call_test.h" 2724e2089750e9e51228b82d6c7ebf4fa064c797bapbos@webrtc.org#include "webrtc/test/direct_transport.h" 28e2a7a77646b23fb3704d267e6079e04bde493543pbos@webrtc.org#include "webrtc/test/encoder_settings.h" 29e028410838cd976c75e379b3c2e2eb0ac52b3c99stefan@webrtc.org#include "webrtc/test/fake_audio_device.h" 3024e2089750e9e51228b82d6c7ebf4fa064c797bapbos@webrtc.org#include "webrtc/test/fake_decoder.h" 3124e2089750e9e51228b82d6c7ebf4fa064c797bapbos@webrtc.org#include "webrtc/test/fake_encoder.h" 32c33d37ce205e22c0e090b0b285ed963686bf24dcpbos@webrtc.org#include "webrtc/test/frame_generator.h" 3324e2089750e9e51228b82d6c7ebf4fa064c797bapbos@webrtc.org#include "webrtc/test/frame_generator_capturer.h" 3475e7da3a6108c34768fc56cdb932c2919c0dd867pbos@webrtc.org#include "webrtc/test/null_transport.h" 3524e2089750e9e51228b82d6c7ebf4fa064c797bapbos@webrtc.org#include "webrtc/test/rtp_rtcp_observer.h" 363adf058e962fa6f313d0fa4e6b8981407369924dpbos@webrtc.org#include "webrtc/test/testsupport/fileutils.h" 370ab271b4001169347867b4eeac3035e3442026f9andresp@webrtc.org#include "webrtc/test/testsupport/gtest_disable.h" 38e028410838cd976c75e379b3c2e2eb0ac52b3c99stefan@webrtc.org#include "webrtc/test/testsupport/perf_test.h" 39c33d37ce205e22c0e090b0b285ed963686bf24dcpbos@webrtc.org#include "webrtc/video/transport_adapter.h" 401c655450cf12d21bfa5b2ff277f337335149186apbos@webrtc.org#include "webrtc/video_encoder.h" 41ce8510901416e37afabb0a54c6e10bec6db63a42pbos@webrtc.org 42ce8510901416e37afabb0a54c6e10bec6db63a42pbos@webrtc.orgnamespace webrtc { 43ce8510901416e37afabb0a54c6e10bec6db63a42pbos@webrtc.org 449b707ca664bd22f7a8bfad14a06f9ffdc6129d3dpbos@webrtc.orgstatic const unsigned long kSilenceTimeoutMs = 2000; 4551e010182b9947c9656f9e81a6a12f64a8e21788pbos@webrtc.org 46eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.orgclass EndToEndTest : public test::CallTest { 47ce8510901416e37afabb0a54c6e10bec6db63a42pbos@webrtc.org public: 48eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org EndToEndTest() {} 49ce8510901416e37afabb0a54c6e10bec6db63a42pbos@webrtc.org 50eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org virtual ~EndToEndTest() { 518ce445ecc8a3fbf2a7517f71e778948f6a8e3d2fpbos@webrtc.org EXPECT_EQ(NULL, send_stream_); 5288b558febb8e8f42df6c7482efe76795c3fed399pbos@webrtc.org EXPECT_TRUE(receive_streams_.empty()); 538ce445ecc8a3fbf2a7517f71e778948f6a8e3d2fpbos@webrtc.org } 548ce445ecc8a3fbf2a7517f71e778948f6a8e3d2fpbos@webrtc.org 558ce445ecc8a3fbf2a7517f71e778948f6a8e3d2fpbos@webrtc.org protected: 569b707ca664bd22f7a8bfad14a06f9ffdc6129d3dpbos@webrtc.org class UnusedTransport : public newapi::Transport { 579b707ca664bd22f7a8bfad14a06f9ffdc6129d3dpbos@webrtc.org private: 589b707ca664bd22f7a8bfad14a06f9ffdc6129d3dpbos@webrtc.org virtual bool SendRtp(const uint8_t* packet, size_t length) OVERRIDE { 599b707ca664bd22f7a8bfad14a06f9ffdc6129d3dpbos@webrtc.org ADD_FAILURE() << "Unexpected RTP sent."; 609b707ca664bd22f7a8bfad14a06f9ffdc6129d3dpbos@webrtc.org return false; 619b707ca664bd22f7a8bfad14a06f9ffdc6129d3dpbos@webrtc.org } 629b707ca664bd22f7a8bfad14a06f9ffdc6129d3dpbos@webrtc.org 639b707ca664bd22f7a8bfad14a06f9ffdc6129d3dpbos@webrtc.org virtual bool SendRtcp(const uint8_t* packet, size_t length) OVERRIDE { 649b707ca664bd22f7a8bfad14a06f9ffdc6129d3dpbos@webrtc.org ADD_FAILURE() << "Unexpected RTCP sent."; 659b707ca664bd22f7a8bfad14a06f9ffdc6129d3dpbos@webrtc.org return false; 669b707ca664bd22f7a8bfad14a06f9ffdc6129d3dpbos@webrtc.org } 679b707ca664bd22f7a8bfad14a06f9ffdc6129d3dpbos@webrtc.org }; 689b707ca664bd22f7a8bfad14a06f9ffdc6129d3dpbos@webrtc.org 69c71929dce136f9bc59fcc7ceb172cf74fc507ea9pbos@webrtc.org void DecodesRetransmittedFrame(bool retransmit_over_rtx); 708ce445ecc8a3fbf2a7517f71e778948f6a8e3d2fpbos@webrtc.org void ReceivesPliAndRecovers(int rtp_history_ms); 7151e010182b9947c9656f9e81a6a12f64a8e21788pbos@webrtc.org void RespectsRtcpMode(newapi::RtcpMode rtcp_mode); 72b4263e09399b251e5cf306b2ade0d0f768d3cb61asapersson@webrtc.org void TestXrReceiverReferenceTimeReport(bool enable_rrtr); 7388b558febb8e8f42df6c7482efe76795c3fed399pbos@webrtc.org void TestSendsSetSsrcs(size_t num_ssrcs, bool send_single_ssrc_first); 742fd91bd35094b909b4b3cce636454426fc893ac2pbos@webrtc.org void TestRtpStatePreservation(bool use_rtx); 75ce8510901416e37afabb0a54c6e10bec6db63a42pbos@webrtc.org}; 76ce8510901416e37afabb0a54c6e10bec6db63a42pbos@webrtc.org 77eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.orgTEST_F(EndToEndTest, ReceiverCanBeStartedTwice) { 7875e7da3a6108c34768fc56cdb932c2919c0dd867pbos@webrtc.org test::NullTransport transport; 7975e7da3a6108c34768fc56cdb932c2919c0dd867pbos@webrtc.org CreateCalls(Call::Config(&transport), Call::Config(&transport)); 8075e7da3a6108c34768fc56cdb932c2919c0dd867pbos@webrtc.org 81eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org CreateSendConfig(1); 82eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org CreateMatchingReceiveConfigs(); 83eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org 8475e7da3a6108c34768fc56cdb932c2919c0dd867pbos@webrtc.org CreateStreams(); 8575e7da3a6108c34768fc56cdb932c2919c0dd867pbos@webrtc.org 8688b558febb8e8f42df6c7482efe76795c3fed399pbos@webrtc.org receive_streams_[0]->Start(); 8788b558febb8e8f42df6c7482efe76795c3fed399pbos@webrtc.org receive_streams_[0]->Start(); 8875e7da3a6108c34768fc56cdb932c2919c0dd867pbos@webrtc.org 8975e7da3a6108c34768fc56cdb932c2919c0dd867pbos@webrtc.org DestroyStreams(); 9075e7da3a6108c34768fc56cdb932c2919c0dd867pbos@webrtc.org} 9175e7da3a6108c34768fc56cdb932c2919c0dd867pbos@webrtc.org 92eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.orgTEST_F(EndToEndTest, ReceiverCanBeStoppedTwice) { 9375e7da3a6108c34768fc56cdb932c2919c0dd867pbos@webrtc.org test::NullTransport transport; 9475e7da3a6108c34768fc56cdb932c2919c0dd867pbos@webrtc.org CreateCalls(Call::Config(&transport), Call::Config(&transport)); 9575e7da3a6108c34768fc56cdb932c2919c0dd867pbos@webrtc.org 96eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org CreateSendConfig(1); 97eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org CreateMatchingReceiveConfigs(); 98eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org 9975e7da3a6108c34768fc56cdb932c2919c0dd867pbos@webrtc.org CreateStreams(); 10075e7da3a6108c34768fc56cdb932c2919c0dd867pbos@webrtc.org 10188b558febb8e8f42df6c7482efe76795c3fed399pbos@webrtc.org receive_streams_[0]->Stop(); 10288b558febb8e8f42df6c7482efe76795c3fed399pbos@webrtc.org receive_streams_[0]->Stop(); 10375e7da3a6108c34768fc56cdb932c2919c0dd867pbos@webrtc.org 10475e7da3a6108c34768fc56cdb932c2919c0dd867pbos@webrtc.org DestroyStreams(); 10575e7da3a6108c34768fc56cdb932c2919c0dd867pbos@webrtc.org} 10675e7da3a6108c34768fc56cdb932c2919c0dd867pbos@webrtc.org 107eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.orgTEST_F(EndToEndTest, RendersSingleDelayedFrame) { 108d60137ff1b936534b04396298b7d2f2ebbc1da82pbos@webrtc.org static const int kWidth = 320; 109d60137ff1b936534b04396298b7d2f2ebbc1da82pbos@webrtc.org static const int kHeight = 240; 110d60137ff1b936534b04396298b7d2f2ebbc1da82pbos@webrtc.org // This constant is chosen to be higher than the timeout in the video_render 111d60137ff1b936534b04396298b7d2f2ebbc1da82pbos@webrtc.org // module. This makes sure that frames aren't dropped if there are no other 112d60137ff1b936534b04396298b7d2f2ebbc1da82pbos@webrtc.org // frames in the queue. 113d60137ff1b936534b04396298b7d2f2ebbc1da82pbos@webrtc.org static const int kDelayRenderCallbackMs = 1000; 114d60137ff1b936534b04396298b7d2f2ebbc1da82pbos@webrtc.org 115d60137ff1b936534b04396298b7d2f2ebbc1da82pbos@webrtc.org class Renderer : public VideoRenderer { 116d60137ff1b936534b04396298b7d2f2ebbc1da82pbos@webrtc.org public: 117d60137ff1b936534b04396298b7d2f2ebbc1da82pbos@webrtc.org Renderer() : event_(EventWrapper::Create()) {} 118d60137ff1b936534b04396298b7d2f2ebbc1da82pbos@webrtc.org 119d60137ff1b936534b04396298b7d2f2ebbc1da82pbos@webrtc.org virtual void RenderFrame(const I420VideoFrame& video_frame, 120d60137ff1b936534b04396298b7d2f2ebbc1da82pbos@webrtc.org int /*time_to_render_ms*/) OVERRIDE { 121d60137ff1b936534b04396298b7d2f2ebbc1da82pbos@webrtc.org event_->Set(); 122d60137ff1b936534b04396298b7d2f2ebbc1da82pbos@webrtc.org } 123d60137ff1b936534b04396298b7d2f2ebbc1da82pbos@webrtc.org 124d60137ff1b936534b04396298b7d2f2ebbc1da82pbos@webrtc.org EventTypeWrapper Wait() { return event_->Wait(kDefaultTimeoutMs); } 125d60137ff1b936534b04396298b7d2f2ebbc1da82pbos@webrtc.org 126d60137ff1b936534b04396298b7d2f2ebbc1da82pbos@webrtc.org scoped_ptr<EventWrapper> event_; 127d60137ff1b936534b04396298b7d2f2ebbc1da82pbos@webrtc.org } renderer; 128d60137ff1b936534b04396298b7d2f2ebbc1da82pbos@webrtc.org 129d60137ff1b936534b04396298b7d2f2ebbc1da82pbos@webrtc.org class TestFrameCallback : public I420FrameCallback { 130d60137ff1b936534b04396298b7d2f2ebbc1da82pbos@webrtc.org public: 131d60137ff1b936534b04396298b7d2f2ebbc1da82pbos@webrtc.org TestFrameCallback() : event_(EventWrapper::Create()) {} 132d60137ff1b936534b04396298b7d2f2ebbc1da82pbos@webrtc.org 133d60137ff1b936534b04396298b7d2f2ebbc1da82pbos@webrtc.org EventTypeWrapper Wait() { return event_->Wait(kDefaultTimeoutMs); } 134d60137ff1b936534b04396298b7d2f2ebbc1da82pbos@webrtc.org 135d60137ff1b936534b04396298b7d2f2ebbc1da82pbos@webrtc.org private: 136c71929dce136f9bc59fcc7ceb172cf74fc507ea9pbos@webrtc.org virtual void FrameCallback(I420VideoFrame* frame) OVERRIDE { 137d60137ff1b936534b04396298b7d2f2ebbc1da82pbos@webrtc.org SleepMs(kDelayRenderCallbackMs); 138d60137ff1b936534b04396298b7d2f2ebbc1da82pbos@webrtc.org event_->Set(); 139d60137ff1b936534b04396298b7d2f2ebbc1da82pbos@webrtc.org } 140d60137ff1b936534b04396298b7d2f2ebbc1da82pbos@webrtc.org 141d60137ff1b936534b04396298b7d2f2ebbc1da82pbos@webrtc.org scoped_ptr<EventWrapper> event_; 142d60137ff1b936534b04396298b7d2f2ebbc1da82pbos@webrtc.org }; 143d60137ff1b936534b04396298b7d2f2ebbc1da82pbos@webrtc.org 144d60137ff1b936534b04396298b7d2f2ebbc1da82pbos@webrtc.org test::DirectTransport sender_transport, receiver_transport; 145d60137ff1b936534b04396298b7d2f2ebbc1da82pbos@webrtc.org 146d60137ff1b936534b04396298b7d2f2ebbc1da82pbos@webrtc.org CreateCalls(Call::Config(&sender_transport), 147d60137ff1b936534b04396298b7d2f2ebbc1da82pbos@webrtc.org Call::Config(&receiver_transport)); 148d60137ff1b936534b04396298b7d2f2ebbc1da82pbos@webrtc.org 149d60137ff1b936534b04396298b7d2f2ebbc1da82pbos@webrtc.org sender_transport.SetReceiver(receiver_call_->Receiver()); 150d60137ff1b936534b04396298b7d2f2ebbc1da82pbos@webrtc.org receiver_transport.SetReceiver(sender_call_->Receiver()); 151d60137ff1b936534b04396298b7d2f2ebbc1da82pbos@webrtc.org 152eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org CreateSendConfig(1); 153eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org CreateMatchingReceiveConfigs(); 154d60137ff1b936534b04396298b7d2f2ebbc1da82pbos@webrtc.org 155d60137ff1b936534b04396298b7d2f2ebbc1da82pbos@webrtc.org TestFrameCallback pre_render_callback; 15688b558febb8e8f42df6c7482efe76795c3fed399pbos@webrtc.org receive_configs_[0].pre_render_callback = &pre_render_callback; 15788b558febb8e8f42df6c7482efe76795c3fed399pbos@webrtc.org receive_configs_[0].renderer = &renderer; 158d60137ff1b936534b04396298b7d2f2ebbc1da82pbos@webrtc.org 159d60137ff1b936534b04396298b7d2f2ebbc1da82pbos@webrtc.org CreateStreams(); 16088b558febb8e8f42df6c7482efe76795c3fed399pbos@webrtc.org Start(); 161d60137ff1b936534b04396298b7d2f2ebbc1da82pbos@webrtc.org 162d60137ff1b936534b04396298b7d2f2ebbc1da82pbos@webrtc.org // Create frames that are smaller than the send width/height, this is done to 163d60137ff1b936534b04396298b7d2f2ebbc1da82pbos@webrtc.org // check that the callbacks are done after processing video. 164d60137ff1b936534b04396298b7d2f2ebbc1da82pbos@webrtc.org scoped_ptr<test::FrameGenerator> frame_generator( 165d60137ff1b936534b04396298b7d2f2ebbc1da82pbos@webrtc.org test::FrameGenerator::Create(kWidth, kHeight)); 166d60137ff1b936534b04396298b7d2f2ebbc1da82pbos@webrtc.org send_stream_->Input()->SwapFrame(frame_generator->NextFrame()); 167d60137ff1b936534b04396298b7d2f2ebbc1da82pbos@webrtc.org EXPECT_EQ(kEventSignaled, pre_render_callback.Wait()) 168d60137ff1b936534b04396298b7d2f2ebbc1da82pbos@webrtc.org << "Timed out while waiting for pre-render callback."; 169d60137ff1b936534b04396298b7d2f2ebbc1da82pbos@webrtc.org EXPECT_EQ(kEventSignaled, renderer.Wait()) 170d60137ff1b936534b04396298b7d2f2ebbc1da82pbos@webrtc.org << "Timed out while waiting for the frame to render."; 171d60137ff1b936534b04396298b7d2f2ebbc1da82pbos@webrtc.org 17288b558febb8e8f42df6c7482efe76795c3fed399pbos@webrtc.org Stop(); 173d60137ff1b936534b04396298b7d2f2ebbc1da82pbos@webrtc.org 174d60137ff1b936534b04396298b7d2f2ebbc1da82pbos@webrtc.org sender_transport.StopSending(); 175d60137ff1b936534b04396298b7d2f2ebbc1da82pbos@webrtc.org receiver_transport.StopSending(); 176d60137ff1b936534b04396298b7d2f2ebbc1da82pbos@webrtc.org 177d60137ff1b936534b04396298b7d2f2ebbc1da82pbos@webrtc.org DestroyStreams(); 178d60137ff1b936534b04396298b7d2f2ebbc1da82pbos@webrtc.org} 179d60137ff1b936534b04396298b7d2f2ebbc1da82pbos@webrtc.org 180eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.orgTEST_F(EndToEndTest, TransmitsFirstFrame) { 181c5b5ad1aac76a7379ab0a0a4e6eab0811f5bfc37pbos@webrtc.org class Renderer : public VideoRenderer { 182c5b5ad1aac76a7379ab0a0a4e6eab0811f5bfc37pbos@webrtc.org public: 183c5b5ad1aac76a7379ab0a0a4e6eab0811f5bfc37pbos@webrtc.org Renderer() : event_(EventWrapper::Create()) {} 184c5b5ad1aac76a7379ab0a0a4e6eab0811f5bfc37pbos@webrtc.org 185c5b5ad1aac76a7379ab0a0a4e6eab0811f5bfc37pbos@webrtc.org virtual void RenderFrame(const I420VideoFrame& video_frame, 186c5b5ad1aac76a7379ab0a0a4e6eab0811f5bfc37pbos@webrtc.org int /*time_to_render_ms*/) OVERRIDE { 187c5b5ad1aac76a7379ab0a0a4e6eab0811f5bfc37pbos@webrtc.org event_->Set(); 188c5b5ad1aac76a7379ab0a0a4e6eab0811f5bfc37pbos@webrtc.org } 189c5b5ad1aac76a7379ab0a0a4e6eab0811f5bfc37pbos@webrtc.org 190c5b5ad1aac76a7379ab0a0a4e6eab0811f5bfc37pbos@webrtc.org EventTypeWrapper Wait() { return event_->Wait(kDefaultTimeoutMs); } 191c5b5ad1aac76a7379ab0a0a4e6eab0811f5bfc37pbos@webrtc.org 192c5b5ad1aac76a7379ab0a0a4e6eab0811f5bfc37pbos@webrtc.org scoped_ptr<EventWrapper> event_; 193c5b5ad1aac76a7379ab0a0a4e6eab0811f5bfc37pbos@webrtc.org } renderer; 194c5b5ad1aac76a7379ab0a0a4e6eab0811f5bfc37pbos@webrtc.org 195c5b5ad1aac76a7379ab0a0a4e6eab0811f5bfc37pbos@webrtc.org test::DirectTransport sender_transport, receiver_transport; 196c5b5ad1aac76a7379ab0a0a4e6eab0811f5bfc37pbos@webrtc.org 197c5b5ad1aac76a7379ab0a0a4e6eab0811f5bfc37pbos@webrtc.org CreateCalls(Call::Config(&sender_transport), 198c5b5ad1aac76a7379ab0a0a4e6eab0811f5bfc37pbos@webrtc.org Call::Config(&receiver_transport)); 199c5b5ad1aac76a7379ab0a0a4e6eab0811f5bfc37pbos@webrtc.org 200c5b5ad1aac76a7379ab0a0a4e6eab0811f5bfc37pbos@webrtc.org sender_transport.SetReceiver(receiver_call_->Receiver()); 201c5b5ad1aac76a7379ab0a0a4e6eab0811f5bfc37pbos@webrtc.org receiver_transport.SetReceiver(sender_call_->Receiver()); 202c5b5ad1aac76a7379ab0a0a4e6eab0811f5bfc37pbos@webrtc.org 203eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org CreateSendConfig(1); 204eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org CreateMatchingReceiveConfigs(); 20588b558febb8e8f42df6c7482efe76795c3fed399pbos@webrtc.org receive_configs_[0].renderer = &renderer; 206c5b5ad1aac76a7379ab0a0a4e6eab0811f5bfc37pbos@webrtc.org 207c5b5ad1aac76a7379ab0a0a4e6eab0811f5bfc37pbos@webrtc.org CreateStreams(); 20888b558febb8e8f42df6c7482efe76795c3fed399pbos@webrtc.org Start(); 209c5b5ad1aac76a7379ab0a0a4e6eab0811f5bfc37pbos@webrtc.org 210c5b5ad1aac76a7379ab0a0a4e6eab0811f5bfc37pbos@webrtc.org scoped_ptr<test::FrameGenerator> frame_generator(test::FrameGenerator::Create( 21158b5140b7535ae66c618cc64b0a955b8d47cc86cpbos@webrtc.org encoder_config_.streams[0].width, encoder_config_.streams[0].height)); 212c33d37ce205e22c0e090b0b285ed963686bf24dcpbos@webrtc.org send_stream_->Input()->SwapFrame(frame_generator->NextFrame()); 213c5b5ad1aac76a7379ab0a0a4e6eab0811f5bfc37pbos@webrtc.org 214c5b5ad1aac76a7379ab0a0a4e6eab0811f5bfc37pbos@webrtc.org EXPECT_EQ(kEventSignaled, renderer.Wait()) 215c5b5ad1aac76a7379ab0a0a4e6eab0811f5bfc37pbos@webrtc.org << "Timed out while waiting for the frame to render."; 216c5b5ad1aac76a7379ab0a0a4e6eab0811f5bfc37pbos@webrtc.org 21788b558febb8e8f42df6c7482efe76795c3fed399pbos@webrtc.org Stop(); 218c5b5ad1aac76a7379ab0a0a4e6eab0811f5bfc37pbos@webrtc.org 219c5b5ad1aac76a7379ab0a0a4e6eab0811f5bfc37pbos@webrtc.org sender_transport.StopSending(); 220c5b5ad1aac76a7379ab0a0a4e6eab0811f5bfc37pbos@webrtc.org receiver_transport.StopSending(); 221c5b5ad1aac76a7379ab0a0a4e6eab0811f5bfc37pbos@webrtc.org 222c5b5ad1aac76a7379ab0a0a4e6eab0811f5bfc37pbos@webrtc.org DestroyStreams(); 223c5b5ad1aac76a7379ab0a0a4e6eab0811f5bfc37pbos@webrtc.org} 224c5b5ad1aac76a7379ab0a0a4e6eab0811f5bfc37pbos@webrtc.org 225617e272fea14f31c0b32aa6c47afc81dbb65697bstefan@webrtc.orgTEST_F(EndToEndTest, SendsAndReceivesH264) { 226617e272fea14f31c0b32aa6c47afc81dbb65697bstefan@webrtc.org class H264Observer : public test::EndToEndTest, public VideoRenderer { 227617e272fea14f31c0b32aa6c47afc81dbb65697bstefan@webrtc.org public: 228617e272fea14f31c0b32aa6c47afc81dbb65697bstefan@webrtc.org H264Observer() 229617e272fea14f31c0b32aa6c47afc81dbb65697bstefan@webrtc.org : EndToEndTest(2 * kDefaultTimeoutMs), 230617e272fea14f31c0b32aa6c47afc81dbb65697bstefan@webrtc.org fake_encoder_(Clock::GetRealTimeClock()), 231617e272fea14f31c0b32aa6c47afc81dbb65697bstefan@webrtc.org frame_counter_(0) {} 232617e272fea14f31c0b32aa6c47afc81dbb65697bstefan@webrtc.org 233617e272fea14f31c0b32aa6c47afc81dbb65697bstefan@webrtc.org virtual void PerformTest() OVERRIDE { 234617e272fea14f31c0b32aa6c47afc81dbb65697bstefan@webrtc.org EXPECT_EQ(kEventSignaled, Wait()) 235617e272fea14f31c0b32aa6c47afc81dbb65697bstefan@webrtc.org << "Timed out while waiting for enough frames to be decoded."; 236617e272fea14f31c0b32aa6c47afc81dbb65697bstefan@webrtc.org } 237617e272fea14f31c0b32aa6c47afc81dbb65697bstefan@webrtc.org 238617e272fea14f31c0b32aa6c47afc81dbb65697bstefan@webrtc.org virtual void ModifyConfigs( 239617e272fea14f31c0b32aa6c47afc81dbb65697bstefan@webrtc.org VideoSendStream::Config* send_config, 240617e272fea14f31c0b32aa6c47afc81dbb65697bstefan@webrtc.org std::vector<VideoReceiveStream::Config>* receive_configs, 24158b5140b7535ae66c618cc64b0a955b8d47cc86cpbos@webrtc.org VideoEncoderConfig* encoder_config) OVERRIDE { 242617e272fea14f31c0b32aa6c47afc81dbb65697bstefan@webrtc.org send_config->encoder_settings.encoder = &fake_encoder_; 243617e272fea14f31c0b32aa6c47afc81dbb65697bstefan@webrtc.org send_config->encoder_settings.payload_name = "H264"; 244617e272fea14f31c0b32aa6c47afc81dbb65697bstefan@webrtc.org send_config->encoder_settings.payload_type = kFakeSendPayloadType; 24558b5140b7535ae66c618cc64b0a955b8d47cc86cpbos@webrtc.org encoder_config->streams[0].min_bitrate_bps = 50000; 24658b5140b7535ae66c618cc64b0a955b8d47cc86cpbos@webrtc.org encoder_config->streams[0].target_bitrate_bps = 24758b5140b7535ae66c618cc64b0a955b8d47cc86cpbos@webrtc.org encoder_config->streams[0].max_bitrate_bps = 2000000; 248617e272fea14f31c0b32aa6c47afc81dbb65697bstefan@webrtc.org 249617e272fea14f31c0b32aa6c47afc81dbb65697bstefan@webrtc.org (*receive_configs)[0].renderer = this; 250617e272fea14f31c0b32aa6c47afc81dbb65697bstefan@webrtc.org VideoCodec codec = 251617e272fea14f31c0b32aa6c47afc81dbb65697bstefan@webrtc.org test::CreateDecoderVideoCodec(send_config->encoder_settings); 252617e272fea14f31c0b32aa6c47afc81dbb65697bstefan@webrtc.org (*receive_configs)[0].codecs.resize(1); 253617e272fea14f31c0b32aa6c47afc81dbb65697bstefan@webrtc.org (*receive_configs)[0].codecs[0] = codec; 254617e272fea14f31c0b32aa6c47afc81dbb65697bstefan@webrtc.org (*receive_configs)[0].external_decoders.resize(1); 255617e272fea14f31c0b32aa6c47afc81dbb65697bstefan@webrtc.org (*receive_configs)[0].external_decoders[0].payload_type = 256617e272fea14f31c0b32aa6c47afc81dbb65697bstefan@webrtc.org send_config->encoder_settings.payload_type; 257617e272fea14f31c0b32aa6c47afc81dbb65697bstefan@webrtc.org (*receive_configs)[0].external_decoders[0].decoder = &fake_decoder_; 258617e272fea14f31c0b32aa6c47afc81dbb65697bstefan@webrtc.org } 259617e272fea14f31c0b32aa6c47afc81dbb65697bstefan@webrtc.org 260617e272fea14f31c0b32aa6c47afc81dbb65697bstefan@webrtc.org virtual void RenderFrame(const I420VideoFrame& video_frame, 261617e272fea14f31c0b32aa6c47afc81dbb65697bstefan@webrtc.org int time_to_render_ms) OVERRIDE { 262617e272fea14f31c0b32aa6c47afc81dbb65697bstefan@webrtc.org const int kRequiredFrames = 500; 263617e272fea14f31c0b32aa6c47afc81dbb65697bstefan@webrtc.org if (++frame_counter_ == kRequiredFrames) 264617e272fea14f31c0b32aa6c47afc81dbb65697bstefan@webrtc.org observation_complete_->Set(); 265617e272fea14f31c0b32aa6c47afc81dbb65697bstefan@webrtc.org } 266617e272fea14f31c0b32aa6c47afc81dbb65697bstefan@webrtc.org 267617e272fea14f31c0b32aa6c47afc81dbb65697bstefan@webrtc.org private: 268617e272fea14f31c0b32aa6c47afc81dbb65697bstefan@webrtc.org test::FakeH264Decoder fake_decoder_; 269617e272fea14f31c0b32aa6c47afc81dbb65697bstefan@webrtc.org test::FakeH264Encoder fake_encoder_; 270617e272fea14f31c0b32aa6c47afc81dbb65697bstefan@webrtc.org int frame_counter_; 271617e272fea14f31c0b32aa6c47afc81dbb65697bstefan@webrtc.org } test; 272617e272fea14f31c0b32aa6c47afc81dbb65697bstefan@webrtc.org 273617e272fea14f31c0b32aa6c47afc81dbb65697bstefan@webrtc.org RunBaseTest(&test); 274617e272fea14f31c0b32aa6c47afc81dbb65697bstefan@webrtc.org} 275617e272fea14f31c0b32aa6c47afc81dbb65697bstefan@webrtc.org 276eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.orgTEST_F(EndToEndTest, ReceiverUsesLocalSsrc) { 277eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org class SyncRtcpObserver : public test::EndToEndTest { 2784b50db1f8ce21cc7faf4f7c80b6a492dffb2a1d5pbos@webrtc.org public: 279eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org SyncRtcpObserver() : EndToEndTest(kDefaultTimeoutMs) {} 2804b50db1f8ce21cc7faf4f7c80b6a492dffb2a1d5pbos@webrtc.org 2814b50db1f8ce21cc7faf4f7c80b6a492dffb2a1d5pbos@webrtc.org virtual Action OnReceiveRtcp(const uint8_t* packet, 2824b50db1f8ce21cc7faf4f7c80b6a492dffb2a1d5pbos@webrtc.org size_t length) OVERRIDE { 2834b50db1f8ce21cc7faf4f7c80b6a492dffb2a1d5pbos@webrtc.org RTCPUtility::RTCPParserV2 parser(packet, length, true); 2844b50db1f8ce21cc7faf4f7c80b6a492dffb2a1d5pbos@webrtc.org EXPECT_TRUE(parser.IsValid()); 2854b50db1f8ce21cc7faf4f7c80b6a492dffb2a1d5pbos@webrtc.org uint32_t ssrc = 0; 2864b50db1f8ce21cc7faf4f7c80b6a492dffb2a1d5pbos@webrtc.org ssrc |= static_cast<uint32_t>(packet[4]) << 24; 2874b50db1f8ce21cc7faf4f7c80b6a492dffb2a1d5pbos@webrtc.org ssrc |= static_cast<uint32_t>(packet[5]) << 16; 2884b50db1f8ce21cc7faf4f7c80b6a492dffb2a1d5pbos@webrtc.org ssrc |= static_cast<uint32_t>(packet[6]) << 8; 2894b50db1f8ce21cc7faf4f7c80b6a492dffb2a1d5pbos@webrtc.org ssrc |= static_cast<uint32_t>(packet[7]) << 0; 2904b50db1f8ce21cc7faf4f7c80b6a492dffb2a1d5pbos@webrtc.org EXPECT_EQ(kReceiverLocalSsrc, ssrc); 2914b50db1f8ce21cc7faf4f7c80b6a492dffb2a1d5pbos@webrtc.org observation_complete_->Set(); 2924b50db1f8ce21cc7faf4f7c80b6a492dffb2a1d5pbos@webrtc.org 2934b50db1f8ce21cc7faf4f7c80b6a492dffb2a1d5pbos@webrtc.org return SEND_PACKET; 2944b50db1f8ce21cc7faf4f7c80b6a492dffb2a1d5pbos@webrtc.org } 2954b50db1f8ce21cc7faf4f7c80b6a492dffb2a1d5pbos@webrtc.org 296eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org virtual void PerformTest() OVERRIDE { 297eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org EXPECT_EQ(kEventSignaled, Wait()) 298eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org << "Timed out while waiting for a receiver RTCP packet to be sent."; 299eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org } 300eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org } test; 3014b50db1f8ce21cc7faf4f7c80b6a492dffb2a1d5pbos@webrtc.org 302eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org RunBaseTest(&test); 303eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org} 3044b50db1f8ce21cc7faf4f7c80b6a492dffb2a1d5pbos@webrtc.org 305eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.orgTEST_F(EndToEndTest, ReceivesAndRetransmitsNack) { 306eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org static const int kNumberOfNacksToObserve = 2; 307eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org static const int kLossBurstSize = 2; 308eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org static const int kPacketsBetweenLossBursts = 9; 309eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org class NackObserver : public test::EndToEndTest { 310eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org public: 311eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org NackObserver() 312eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org : EndToEndTest(kLongTimeoutMs), 313eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org rtp_parser_(RtpHeaderParser::Create()), 314eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org sent_rtp_packets_(0), 315eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org packets_left_to_drop_(0), 316eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org nacks_left_(kNumberOfNacksToObserve) {} 3174b50db1f8ce21cc7faf4f7c80b6a492dffb2a1d5pbos@webrtc.org 318eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org private: 319eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org virtual Action OnSendRtp(const uint8_t* packet, size_t length) OVERRIDE { 320eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org RTPHeader header; 3216aae61c2c693fa3425c73c420e7046e95486b592pbos@webrtc.org EXPECT_TRUE(rtp_parser_->Parse(packet, length, &header)); 322eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org 323eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org // Never drop retransmitted packets. 324eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org if (dropped_packets_.find(header.sequenceNumber) != 325eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org dropped_packets_.end()) { 326eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org retransmitted_packets_.insert(header.sequenceNumber); 327eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org if (nacks_left_ == 0 && 328eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org retransmitted_packets_.size() == dropped_packets_.size()) { 329eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org observation_complete_->Set(); 330eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org } 331eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org return SEND_PACKET; 332eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org } 3334b50db1f8ce21cc7faf4f7c80b6a492dffb2a1d5pbos@webrtc.org 334eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org ++sent_rtp_packets_; 3354b50db1f8ce21cc7faf4f7c80b6a492dffb2a1d5pbos@webrtc.org 336eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org // Enough NACKs received, stop dropping packets. 337eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org if (nacks_left_ == 0) 338eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org return SEND_PACKET; 3394b50db1f8ce21cc7faf4f7c80b6a492dffb2a1d5pbos@webrtc.org 340eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org // Check if it's time for a new loss burst. 341eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org if (sent_rtp_packets_ % kPacketsBetweenLossBursts == 0) 342eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org packets_left_to_drop_ = kLossBurstSize; 343ce8510901416e37afabb0a54c6e10bec6db63a42pbos@webrtc.org 344eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org if (packets_left_to_drop_ > 0) { 345eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org --packets_left_to_drop_; 346eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org dropped_packets_.insert(header.sequenceNumber); 347eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org return DROP_PACKET; 348eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org } 349ce8510901416e37afabb0a54c6e10bec6db63a42pbos@webrtc.org 350eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org return SEND_PACKET; 351eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org } 3528ce445ecc8a3fbf2a7517f71e778948f6a8e3d2fpbos@webrtc.org 353eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org virtual Action OnReceiveRtcp(const uint8_t* packet, 354eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org size_t length) OVERRIDE { 355eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org RTCPUtility::RTCPParserV2 parser(packet, length, true); 356eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org EXPECT_TRUE(parser.IsValid()); 357ce8510901416e37afabb0a54c6e10bec6db63a42pbos@webrtc.org 358eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org RTCPUtility::RTCPPacketTypes packet_type = parser.Begin(); 359eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org while (packet_type != RTCPUtility::kRtcpNotValidCode) { 360eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org if (packet_type == RTCPUtility::kRtcpRtpfbNackCode) { 361eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org --nacks_left_; 362eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org break; 363eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org } 364eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org packet_type = parser.Iterate(); 365eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org } 366eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org return SEND_PACKET; 367eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org } 368ce8510901416e37afabb0a54c6e10bec6db63a42pbos@webrtc.org 369eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org virtual void ModifyConfigs( 370eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org VideoSendStream::Config* send_config, 37188b558febb8e8f42df6c7482efe76795c3fed399pbos@webrtc.org std::vector<VideoReceiveStream::Config>* receive_configs, 37258b5140b7535ae66c618cc64b0a955b8d47cc86cpbos@webrtc.org VideoEncoderConfig* encoder_config) OVERRIDE { 373eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org send_config->rtp.nack.rtp_history_ms = kNackRtpHistoryMs; 37488b558febb8e8f42df6c7482efe76795c3fed399pbos@webrtc.org (*receive_configs)[0].rtp.nack.rtp_history_ms = kNackRtpHistoryMs; 375eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org } 3768ce445ecc8a3fbf2a7517f71e778948f6a8e3d2fpbos@webrtc.org 377eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org virtual void PerformTest() OVERRIDE { 378eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org EXPECT_EQ(kEventSignaled, Wait()) 379eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org << "Timed out waiting for packets to be NACKed, retransmitted and " 380eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org "rendered."; 381eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org } 3828ce445ecc8a3fbf2a7517f71e778948f6a8e3d2fpbos@webrtc.org 383eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org scoped_ptr<RtpHeaderParser> rtp_parser_; 384eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org std::set<uint16_t> dropped_packets_; 385eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org std::set<uint16_t> retransmitted_packets_; 386eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org uint64_t sent_rtp_packets_; 387eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org int packets_left_to_drop_; 388eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org int nacks_left_; 389eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org } test; 390ea15f8d77dd35ea068ee01325fb1602e9a0b7771pbos@webrtc.org 391eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org RunBaseTest(&test); 392ea15f8d77dd35ea068ee01325fb1602e9a0b7771pbos@webrtc.org} 393ea15f8d77dd35ea068ee01325fb1602e9a0b7771pbos@webrtc.org 394fb3f14e334ffeeeea5c9f6666b02dfdcdb268375pbos@webrtc.org// TODO(pbos): Flaky, webrtc:3269 395eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.orgTEST_F(EndToEndTest, DISABLED_CanReceiveFec) { 396eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org class FecRenderObserver : public test::EndToEndTest, public VideoRenderer { 397ea15f8d77dd35ea068ee01325fb1602e9a0b7771pbos@webrtc.org public: 398ea15f8d77dd35ea068ee01325fb1602e9a0b7771pbos@webrtc.org FecRenderObserver() 399eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org : EndToEndTest(kDefaultTimeoutMs), 400ea15f8d77dd35ea068ee01325fb1602e9a0b7771pbos@webrtc.org state_(kFirstPacket), 401ea15f8d77dd35ea068ee01325fb1602e9a0b7771pbos@webrtc.org protected_sequence_number_(0), 402ea15f8d77dd35ea068ee01325fb1602e9a0b7771pbos@webrtc.org protected_frame_timestamp_(0) {} 403ea15f8d77dd35ea068ee01325fb1602e9a0b7771pbos@webrtc.org 404ea15f8d77dd35ea068ee01325fb1602e9a0b7771pbos@webrtc.org private: 405c476e64d056c5e342bc5b23eecd493abf6d85d7fpbos@webrtc.org virtual Action OnSendRtp(const uint8_t* packet, size_t length) OVERRIDE 406c476e64d056c5e342bc5b23eecd493abf6d85d7fpbos@webrtc.org EXCLUSIVE_LOCKS_REQUIRED(crit_) { 407ea15f8d77dd35ea068ee01325fb1602e9a0b7771pbos@webrtc.org RTPHeader header; 4086aae61c2c693fa3425c73c420e7046e95486b592pbos@webrtc.org EXPECT_TRUE(parser_->Parse(packet, length, &header)); 409ea15f8d77dd35ea068ee01325fb1602e9a0b7771pbos@webrtc.org 410ea15f8d77dd35ea068ee01325fb1602e9a0b7771pbos@webrtc.org EXPECT_EQ(kRedPayloadType, header.payloadType); 411ea15f8d77dd35ea068ee01325fb1602e9a0b7771pbos@webrtc.org int encapsulated_payload_type = 412ea15f8d77dd35ea068ee01325fb1602e9a0b7771pbos@webrtc.org static_cast<int>(packet[header.headerLength]); 413eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org if (encapsulated_payload_type != kFakeSendPayloadType) 414ea15f8d77dd35ea068ee01325fb1602e9a0b7771pbos@webrtc.org EXPECT_EQ(kUlpfecPayloadType, encapsulated_payload_type); 415ea15f8d77dd35ea068ee01325fb1602e9a0b7771pbos@webrtc.org 416eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org switch (state_) { 417ea15f8d77dd35ea068ee01325fb1602e9a0b7771pbos@webrtc.org case kFirstPacket: 418ea15f8d77dd35ea068ee01325fb1602e9a0b7771pbos@webrtc.org state_ = kDropEveryOtherPacketUntilFec; 419ea15f8d77dd35ea068ee01325fb1602e9a0b7771pbos@webrtc.org break; 420ea15f8d77dd35ea068ee01325fb1602e9a0b7771pbos@webrtc.org case kDropEveryOtherPacketUntilFec: 421ea15f8d77dd35ea068ee01325fb1602e9a0b7771pbos@webrtc.org if (encapsulated_payload_type == kUlpfecPayloadType) { 422ea15f8d77dd35ea068ee01325fb1602e9a0b7771pbos@webrtc.org state_ = kDropNextMediaPacket; 423ea15f8d77dd35ea068ee01325fb1602e9a0b7771pbos@webrtc.org return SEND_PACKET; 424ea15f8d77dd35ea068ee01325fb1602e9a0b7771pbos@webrtc.org } 425ea15f8d77dd35ea068ee01325fb1602e9a0b7771pbos@webrtc.org if (header.sequenceNumber % 2 == 0) 426ea15f8d77dd35ea068ee01325fb1602e9a0b7771pbos@webrtc.org return DROP_PACKET; 427ea15f8d77dd35ea068ee01325fb1602e9a0b7771pbos@webrtc.org break; 428ea15f8d77dd35ea068ee01325fb1602e9a0b7771pbos@webrtc.org case kDropNextMediaPacket: 429eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org if (encapsulated_payload_type == kFakeSendPayloadType) { 430ea15f8d77dd35ea068ee01325fb1602e9a0b7771pbos@webrtc.org protected_sequence_number_ = header.sequenceNumber; 431ea15f8d77dd35ea068ee01325fb1602e9a0b7771pbos@webrtc.org protected_frame_timestamp_ = header.timestamp; 432ea15f8d77dd35ea068ee01325fb1602e9a0b7771pbos@webrtc.org state_ = kProtectedPacketDropped; 433ea15f8d77dd35ea068ee01325fb1602e9a0b7771pbos@webrtc.org return DROP_PACKET; 434ea15f8d77dd35ea068ee01325fb1602e9a0b7771pbos@webrtc.org } 435ea15f8d77dd35ea068ee01325fb1602e9a0b7771pbos@webrtc.org break; 436ea15f8d77dd35ea068ee01325fb1602e9a0b7771pbos@webrtc.org case kProtectedPacketDropped: 437ea15f8d77dd35ea068ee01325fb1602e9a0b7771pbos@webrtc.org EXPECT_NE(header.sequenceNumber, protected_sequence_number_) 438ea15f8d77dd35ea068ee01325fb1602e9a0b7771pbos@webrtc.org << "Protected packet retransmitted. Should not happen with FEC."; 439ea15f8d77dd35ea068ee01325fb1602e9a0b7771pbos@webrtc.org break; 440ea15f8d77dd35ea068ee01325fb1602e9a0b7771pbos@webrtc.org } 441ea15f8d77dd35ea068ee01325fb1602e9a0b7771pbos@webrtc.org 442ea15f8d77dd35ea068ee01325fb1602e9a0b7771pbos@webrtc.org return SEND_PACKET; 443ea15f8d77dd35ea068ee01325fb1602e9a0b7771pbos@webrtc.org } 444ea15f8d77dd35ea068ee01325fb1602e9a0b7771pbos@webrtc.org 445ea15f8d77dd35ea068ee01325fb1602e9a0b7771pbos@webrtc.org virtual void RenderFrame(const I420VideoFrame& video_frame, 446ea15f8d77dd35ea068ee01325fb1602e9a0b7771pbos@webrtc.org int time_to_render_ms) OVERRIDE { 447c476e64d056c5e342bc5b23eecd493abf6d85d7fpbos@webrtc.org CriticalSectionScoped lock(crit_.get()); 448ea15f8d77dd35ea068ee01325fb1602e9a0b7771pbos@webrtc.org // Rendering frame with timestamp associated with dropped packet -> FEC 449ea15f8d77dd35ea068ee01325fb1602e9a0b7771pbos@webrtc.org // protection worked. 450ea15f8d77dd35ea068ee01325fb1602e9a0b7771pbos@webrtc.org if (state_ == kProtectedPacketDropped && 451ea15f8d77dd35ea068ee01325fb1602e9a0b7771pbos@webrtc.org video_frame.timestamp() == protected_frame_timestamp_) { 452ea15f8d77dd35ea068ee01325fb1602e9a0b7771pbos@webrtc.org observation_complete_->Set(); 453ea15f8d77dd35ea068ee01325fb1602e9a0b7771pbos@webrtc.org } 454ea15f8d77dd35ea068ee01325fb1602e9a0b7771pbos@webrtc.org } 455ea15f8d77dd35ea068ee01325fb1602e9a0b7771pbos@webrtc.org 456ea15f8d77dd35ea068ee01325fb1602e9a0b7771pbos@webrtc.org enum { 457ea15f8d77dd35ea068ee01325fb1602e9a0b7771pbos@webrtc.org kFirstPacket, 458ea15f8d77dd35ea068ee01325fb1602e9a0b7771pbos@webrtc.org kDropEveryOtherPacketUntilFec, 459ea15f8d77dd35ea068ee01325fb1602e9a0b7771pbos@webrtc.org kDropNextMediaPacket, 460ea15f8d77dd35ea068ee01325fb1602e9a0b7771pbos@webrtc.org kProtectedPacketDropped, 461ea15f8d77dd35ea068ee01325fb1602e9a0b7771pbos@webrtc.org } state_; 462ea15f8d77dd35ea068ee01325fb1602e9a0b7771pbos@webrtc.org 463eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org virtual void ModifyConfigs( 464eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org VideoSendStream::Config* send_config, 46588b558febb8e8f42df6c7482efe76795c3fed399pbos@webrtc.org std::vector<VideoReceiveStream::Config>* receive_configs, 46658b5140b7535ae66c618cc64b0a955b8d47cc86cpbos@webrtc.org VideoEncoderConfig* encoder_config) OVERRIDE { 467eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org // TODO(pbos): Run this test with combined NACK/FEC enabled as well. 468eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org // int rtp_history_ms = 1000; 46988b558febb8e8f42df6c7482efe76795c3fed399pbos@webrtc.org // (*receive_configs)[0].rtp.nack.rtp_history_ms = rtp_history_ms; 470eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org // send_config->rtp.nack.rtp_history_ms = rtp_history_ms; 471eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org send_config->rtp.fec.red_payload_type = kRedPayloadType; 472eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org send_config->rtp.fec.ulpfec_payload_type = kUlpfecPayloadType; 473eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org 47488b558febb8e8f42df6c7482efe76795c3fed399pbos@webrtc.org (*receive_configs)[0].rtp.fec.red_payload_type = kRedPayloadType; 47588b558febb8e8f42df6c7482efe76795c3fed399pbos@webrtc.org (*receive_configs)[0].rtp.fec.ulpfec_payload_type = kUlpfecPayloadType; 47688b558febb8e8f42df6c7482efe76795c3fed399pbos@webrtc.org (*receive_configs)[0].renderer = this; 477eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org } 478ea15f8d77dd35ea068ee01325fb1602e9a0b7771pbos@webrtc.org 479eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org virtual void PerformTest() OVERRIDE { 480eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org EXPECT_EQ(kEventSignaled, Wait()) 481eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org << "Timed out while waiting for retransmitted NACKed frames to be " 482eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org "rendered again."; 483eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org } 484ea15f8d77dd35ea068ee01325fb1602e9a0b7771pbos@webrtc.org 485eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org uint32_t protected_sequence_number_ GUARDED_BY(crit_); 486eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org uint32_t protected_frame_timestamp_ GUARDED_BY(crit_); 487eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org } test; 488618a0ec1d2c17d485b7ce51cbfd282e6bae8e019pbos@webrtc.org 489eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org RunBaseTest(&test); 4908ce445ecc8a3fbf2a7517f71e778948f6a8e3d2fpbos@webrtc.org} 491ce8510901416e37afabb0a54c6e10bec6db63a42pbos@webrtc.org 492c71929dce136f9bc59fcc7ceb172cf74fc507ea9pbos@webrtc.org// This test drops second RTP packet with a marker bit set, makes sure it's 493c71929dce136f9bc59fcc7ceb172cf74fc507ea9pbos@webrtc.org// retransmitted and renders. Retransmission SSRCs are also checked. 494eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.orgvoid EndToEndTest::DecodesRetransmittedFrame(bool retransmit_over_rtx) { 495c71929dce136f9bc59fcc7ceb172cf74fc507ea9pbos@webrtc.org static const int kDroppedFrameNumber = 2; 496eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org class RetransmissionObserver : public test::EndToEndTest, 497c71929dce136f9bc59fcc7ceb172cf74fc507ea9pbos@webrtc.org public I420FrameCallback { 498c71929dce136f9bc59fcc7ceb172cf74fc507ea9pbos@webrtc.org public: 499eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org explicit RetransmissionObserver(bool expect_rtx) 500eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org : EndToEndTest(kDefaultTimeoutMs), 5012fd91bd35094b909b4b3cce636454426fc893ac2pbos@webrtc.org retransmission_ssrc_(expect_rtx ? kSendRtxSsrcs[0] : kSendSsrcs[0]), 502c71929dce136f9bc59fcc7ceb172cf74fc507ea9pbos@webrtc.org retransmission_payload_type_(expect_rtx ? kSendRtxPayloadType 503eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org : kFakeSendPayloadType), 504c71929dce136f9bc59fcc7ceb172cf74fc507ea9pbos@webrtc.org marker_bits_observed_(0), 505c71929dce136f9bc59fcc7ceb172cf74fc507ea9pbos@webrtc.org retransmitted_timestamp_(0), 506c71929dce136f9bc59fcc7ceb172cf74fc507ea9pbos@webrtc.org frame_retransmitted_(false) {} 507c71929dce136f9bc59fcc7ceb172cf74fc507ea9pbos@webrtc.org 508c71929dce136f9bc59fcc7ceb172cf74fc507ea9pbos@webrtc.org private: 509c71929dce136f9bc59fcc7ceb172cf74fc507ea9pbos@webrtc.org virtual Action OnSendRtp(const uint8_t* packet, size_t length) OVERRIDE { 510c71929dce136f9bc59fcc7ceb172cf74fc507ea9pbos@webrtc.org RTPHeader header; 5116aae61c2c693fa3425c73c420e7046e95486b592pbos@webrtc.org EXPECT_TRUE(parser_->Parse(packet, length, &header)); 512c71929dce136f9bc59fcc7ceb172cf74fc507ea9pbos@webrtc.org 513c71929dce136f9bc59fcc7ceb172cf74fc507ea9pbos@webrtc.org if (header.timestamp == retransmitted_timestamp_) { 514c71929dce136f9bc59fcc7ceb172cf74fc507ea9pbos@webrtc.org EXPECT_EQ(retransmission_ssrc_, header.ssrc); 515c71929dce136f9bc59fcc7ceb172cf74fc507ea9pbos@webrtc.org EXPECT_EQ(retransmission_payload_type_, header.payloadType); 516c71929dce136f9bc59fcc7ceb172cf74fc507ea9pbos@webrtc.org frame_retransmitted_ = true; 517c71929dce136f9bc59fcc7ceb172cf74fc507ea9pbos@webrtc.org return SEND_PACKET; 518c71929dce136f9bc59fcc7ceb172cf74fc507ea9pbos@webrtc.org } 519c71929dce136f9bc59fcc7ceb172cf74fc507ea9pbos@webrtc.org 520eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org EXPECT_EQ(kSendSsrcs[0], header.ssrc); 521eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org EXPECT_EQ(kFakeSendPayloadType, header.payloadType); 522c71929dce136f9bc59fcc7ceb172cf74fc507ea9pbos@webrtc.org 523c71929dce136f9bc59fcc7ceb172cf74fc507ea9pbos@webrtc.org // Found the second frame's final packet, drop this and expect a 524c71929dce136f9bc59fcc7ceb172cf74fc507ea9pbos@webrtc.org // retransmission. 525c71929dce136f9bc59fcc7ceb172cf74fc507ea9pbos@webrtc.org if (header.markerBit && ++marker_bits_observed_ == kDroppedFrameNumber) { 526c71929dce136f9bc59fcc7ceb172cf74fc507ea9pbos@webrtc.org retransmitted_timestamp_ = header.timestamp; 527c71929dce136f9bc59fcc7ceb172cf74fc507ea9pbos@webrtc.org return DROP_PACKET; 528c71929dce136f9bc59fcc7ceb172cf74fc507ea9pbos@webrtc.org } 529c71929dce136f9bc59fcc7ceb172cf74fc507ea9pbos@webrtc.org 530c71929dce136f9bc59fcc7ceb172cf74fc507ea9pbos@webrtc.org return SEND_PACKET; 531c71929dce136f9bc59fcc7ceb172cf74fc507ea9pbos@webrtc.org } 532c71929dce136f9bc59fcc7ceb172cf74fc507ea9pbos@webrtc.org 533c71929dce136f9bc59fcc7ceb172cf74fc507ea9pbos@webrtc.org virtual void FrameCallback(I420VideoFrame* frame) OVERRIDE { 534c476e64d056c5e342bc5b23eecd493abf6d85d7fpbos@webrtc.org CriticalSectionScoped lock(crit_.get()); 535c71929dce136f9bc59fcc7ceb172cf74fc507ea9pbos@webrtc.org if (frame->timestamp() == retransmitted_timestamp_) { 536c71929dce136f9bc59fcc7ceb172cf74fc507ea9pbos@webrtc.org EXPECT_TRUE(frame_retransmitted_); 537c71929dce136f9bc59fcc7ceb172cf74fc507ea9pbos@webrtc.org observation_complete_->Set(); 538c71929dce136f9bc59fcc7ceb172cf74fc507ea9pbos@webrtc.org } 539c71929dce136f9bc59fcc7ceb172cf74fc507ea9pbos@webrtc.org } 540c71929dce136f9bc59fcc7ceb172cf74fc507ea9pbos@webrtc.org 541eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org virtual void ModifyConfigs( 542eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org VideoSendStream::Config* send_config, 54388b558febb8e8f42df6c7482efe76795c3fed399pbos@webrtc.org std::vector<VideoReceiveStream::Config>* receive_configs, 54458b5140b7535ae66c618cc64b0a955b8d47cc86cpbos@webrtc.org VideoEncoderConfig* encoder_config) OVERRIDE { 545eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org send_config->rtp.nack.rtp_history_ms = kNackRtpHistoryMs; 54688b558febb8e8f42df6c7482efe76795c3fed399pbos@webrtc.org (*receive_configs)[0].pre_render_callback = this; 54788b558febb8e8f42df6c7482efe76795c3fed399pbos@webrtc.org (*receive_configs)[0].rtp.nack.rtp_history_ms = kNackRtpHistoryMs; 5482fd91bd35094b909b4b3cce636454426fc893ac2pbos@webrtc.org if (retransmission_ssrc_ == kSendRtxSsrcs[0]) { 5492fd91bd35094b909b4b3cce636454426fc893ac2pbos@webrtc.org send_config->rtp.rtx.ssrcs.push_back(kSendRtxSsrcs[0]); 550eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org send_config->rtp.rtx.payload_type = kSendRtxPayloadType; 5512fd91bd35094b909b4b3cce636454426fc893ac2pbos@webrtc.org (*receive_configs)[0].rtp.rtx[kSendRtxPayloadType].ssrc = 5522fd91bd35094b909b4b3cce636454426fc893ac2pbos@webrtc.org kSendRtxSsrcs[0]; 55388b558febb8e8f42df6c7482efe76795c3fed399pbos@webrtc.org (*receive_configs)[0].rtp.rtx[kSendRtxPayloadType].payload_type = 554eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org kSendRtxPayloadType; 555eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org } 556eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org } 557eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org 558eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org virtual void PerformTest() OVERRIDE { 559eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org EXPECT_EQ(kEventSignaled, Wait()) 560eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org << "Timed out while waiting for retransmission to render."; 561eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org } 562eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org 563c71929dce136f9bc59fcc7ceb172cf74fc507ea9pbos@webrtc.org const uint32_t retransmission_ssrc_; 564c71929dce136f9bc59fcc7ceb172cf74fc507ea9pbos@webrtc.org const int retransmission_payload_type_; 565c71929dce136f9bc59fcc7ceb172cf74fc507ea9pbos@webrtc.org int marker_bits_observed_; 566c71929dce136f9bc59fcc7ceb172cf74fc507ea9pbos@webrtc.org uint32_t retransmitted_timestamp_; 567c71929dce136f9bc59fcc7ceb172cf74fc507ea9pbos@webrtc.org bool frame_retransmitted_; 568eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org } test(retransmit_over_rtx); 569c71929dce136f9bc59fcc7ceb172cf74fc507ea9pbos@webrtc.org 570eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org RunBaseTest(&test); 571c71929dce136f9bc59fcc7ceb172cf74fc507ea9pbos@webrtc.org} 572c71929dce136f9bc59fcc7ceb172cf74fc507ea9pbos@webrtc.org 573eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.orgTEST_F(EndToEndTest, DecodesRetransmittedFrame) { 574c71929dce136f9bc59fcc7ceb172cf74fc507ea9pbos@webrtc.org DecodesRetransmittedFrame(false); 575c71929dce136f9bc59fcc7ceb172cf74fc507ea9pbos@webrtc.org} 576c71929dce136f9bc59fcc7ceb172cf74fc507ea9pbos@webrtc.org 577eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.orgTEST_F(EndToEndTest, DecodesRetransmittedFrameOverRtx) { 578c71929dce136f9bc59fcc7ceb172cf74fc507ea9pbos@webrtc.org DecodesRetransmittedFrame(true); 579c71929dce136f9bc59fcc7ceb172cf74fc507ea9pbos@webrtc.org} 580c71929dce136f9bc59fcc7ceb172cf74fc507ea9pbos@webrtc.org 58129c4d870efc8877b99ee583e8904cfba3d654b10andresp@webrtc.orgTEST_F(EndToEndTest, UsesFrameCallbacks) { 58263301bd03e009d309d1fdca1217f8708be610f32pbos@webrtc.org static const int kWidth = 320; 58363301bd03e009d309d1fdca1217f8708be610f32pbos@webrtc.org static const int kHeight = 240; 58463301bd03e009d309d1fdca1217f8708be610f32pbos@webrtc.org 58563301bd03e009d309d1fdca1217f8708be610f32pbos@webrtc.org class Renderer : public VideoRenderer { 58663301bd03e009d309d1fdca1217f8708be610f32pbos@webrtc.org public: 58763301bd03e009d309d1fdca1217f8708be610f32pbos@webrtc.org Renderer() : event_(EventWrapper::Create()) {} 58863301bd03e009d309d1fdca1217f8708be610f32pbos@webrtc.org 58963301bd03e009d309d1fdca1217f8708be610f32pbos@webrtc.org virtual void RenderFrame(const I420VideoFrame& video_frame, 59063301bd03e009d309d1fdca1217f8708be610f32pbos@webrtc.org int /*time_to_render_ms*/) OVERRIDE { 59163301bd03e009d309d1fdca1217f8708be610f32pbos@webrtc.org EXPECT_EQ(0, *video_frame.buffer(kYPlane)) 59263301bd03e009d309d1fdca1217f8708be610f32pbos@webrtc.org << "Rendered frame should have zero luma which is applied by the " 59363301bd03e009d309d1fdca1217f8708be610f32pbos@webrtc.org "pre-render callback."; 59463301bd03e009d309d1fdca1217f8708be610f32pbos@webrtc.org event_->Set(); 59563301bd03e009d309d1fdca1217f8708be610f32pbos@webrtc.org } 59663301bd03e009d309d1fdca1217f8708be610f32pbos@webrtc.org 59763301bd03e009d309d1fdca1217f8708be610f32pbos@webrtc.org EventTypeWrapper Wait() { return event_->Wait(kDefaultTimeoutMs); } 59863301bd03e009d309d1fdca1217f8708be610f32pbos@webrtc.org scoped_ptr<EventWrapper> event_; 59963301bd03e009d309d1fdca1217f8708be610f32pbos@webrtc.org } renderer; 60063301bd03e009d309d1fdca1217f8708be610f32pbos@webrtc.org 60163301bd03e009d309d1fdca1217f8708be610f32pbos@webrtc.org class TestFrameCallback : public I420FrameCallback { 60263301bd03e009d309d1fdca1217f8708be610f32pbos@webrtc.org public: 60363301bd03e009d309d1fdca1217f8708be610f32pbos@webrtc.org TestFrameCallback(int expected_luma_byte, int next_luma_byte) 60463301bd03e009d309d1fdca1217f8708be610f32pbos@webrtc.org : event_(EventWrapper::Create()), 60563301bd03e009d309d1fdca1217f8708be610f32pbos@webrtc.org expected_luma_byte_(expected_luma_byte), 60663301bd03e009d309d1fdca1217f8708be610f32pbos@webrtc.org next_luma_byte_(next_luma_byte) {} 60763301bd03e009d309d1fdca1217f8708be610f32pbos@webrtc.org 60863301bd03e009d309d1fdca1217f8708be610f32pbos@webrtc.org EventTypeWrapper Wait() { return event_->Wait(kDefaultTimeoutMs); } 60963301bd03e009d309d1fdca1217f8708be610f32pbos@webrtc.org 61063301bd03e009d309d1fdca1217f8708be610f32pbos@webrtc.org private: 61163301bd03e009d309d1fdca1217f8708be610f32pbos@webrtc.org virtual void FrameCallback(I420VideoFrame* frame) { 61263301bd03e009d309d1fdca1217f8708be610f32pbos@webrtc.org EXPECT_EQ(kWidth, frame->width()) 61363301bd03e009d309d1fdca1217f8708be610f32pbos@webrtc.org << "Width not as expected, callback done before resize?"; 61463301bd03e009d309d1fdca1217f8708be610f32pbos@webrtc.org EXPECT_EQ(kHeight, frame->height()) 61563301bd03e009d309d1fdca1217f8708be610f32pbos@webrtc.org << "Height not as expected, callback done before resize?"; 61663301bd03e009d309d1fdca1217f8708be610f32pbos@webrtc.org 61763301bd03e009d309d1fdca1217f8708be610f32pbos@webrtc.org // Previous luma specified, observed luma should be fairly close. 61863301bd03e009d309d1fdca1217f8708be610f32pbos@webrtc.org if (expected_luma_byte_ != -1) { 61963301bd03e009d309d1fdca1217f8708be610f32pbos@webrtc.org EXPECT_NEAR(expected_luma_byte_, *frame->buffer(kYPlane), 10); 62063301bd03e009d309d1fdca1217f8708be610f32pbos@webrtc.org } 62163301bd03e009d309d1fdca1217f8708be610f32pbos@webrtc.org 62263301bd03e009d309d1fdca1217f8708be610f32pbos@webrtc.org memset(frame->buffer(kYPlane), 62363301bd03e009d309d1fdca1217f8708be610f32pbos@webrtc.org next_luma_byte_, 62463301bd03e009d309d1fdca1217f8708be610f32pbos@webrtc.org frame->allocated_size(kYPlane)); 62563301bd03e009d309d1fdca1217f8708be610f32pbos@webrtc.org 62663301bd03e009d309d1fdca1217f8708be610f32pbos@webrtc.org event_->Set(); 62763301bd03e009d309d1fdca1217f8708be610f32pbos@webrtc.org } 62863301bd03e009d309d1fdca1217f8708be610f32pbos@webrtc.org 62963301bd03e009d309d1fdca1217f8708be610f32pbos@webrtc.org scoped_ptr<EventWrapper> event_; 63063301bd03e009d309d1fdca1217f8708be610f32pbos@webrtc.org int expected_luma_byte_; 63163301bd03e009d309d1fdca1217f8708be610f32pbos@webrtc.org int next_luma_byte_; 63263301bd03e009d309d1fdca1217f8708be610f32pbos@webrtc.org }; 63363301bd03e009d309d1fdca1217f8708be610f32pbos@webrtc.org 63463301bd03e009d309d1fdca1217f8708be610f32pbos@webrtc.org TestFrameCallback pre_encode_callback(-1, 255); // Changes luma to 255. 63563301bd03e009d309d1fdca1217f8708be610f32pbos@webrtc.org TestFrameCallback pre_render_callback(255, 0); // Changes luma from 255 to 0. 63663301bd03e009d309d1fdca1217f8708be610f32pbos@webrtc.org 63763301bd03e009d309d1fdca1217f8708be610f32pbos@webrtc.org test::DirectTransport sender_transport, receiver_transport; 63863301bd03e009d309d1fdca1217f8708be610f32pbos@webrtc.org 63963301bd03e009d309d1fdca1217f8708be610f32pbos@webrtc.org CreateCalls(Call::Config(&sender_transport), 64063301bd03e009d309d1fdca1217f8708be610f32pbos@webrtc.org Call::Config(&receiver_transport)); 64163301bd03e009d309d1fdca1217f8708be610f32pbos@webrtc.org 64263301bd03e009d309d1fdca1217f8708be610f32pbos@webrtc.org sender_transport.SetReceiver(receiver_call_->Receiver()); 64363301bd03e009d309d1fdca1217f8708be610f32pbos@webrtc.org receiver_transport.SetReceiver(sender_call_->Receiver()); 64463301bd03e009d309d1fdca1217f8708be610f32pbos@webrtc.org 645eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org CreateSendConfig(1); 6461c655450cf12d21bfa5b2ff277f337335149186apbos@webrtc.org scoped_ptr<VideoEncoder> encoder( 6471c655450cf12d21bfa5b2ff277f337335149186apbos@webrtc.org VideoEncoder::Create(VideoEncoder::kVp8)); 648e2a7a77646b23fb3704d267e6079e04bde493543pbos@webrtc.org send_config_.encoder_settings.encoder = encoder.get(); 649e2a7a77646b23fb3704d267e6079e04bde493543pbos@webrtc.org send_config_.encoder_settings.payload_name = "VP8"; 65058b5140b7535ae66c618cc64b0a955b8d47cc86cpbos@webrtc.org ASSERT_EQ(1u, encoder_config_.streams.size()) << "Test setup error."; 65158b5140b7535ae66c618cc64b0a955b8d47cc86cpbos@webrtc.org encoder_config_.streams[0].width = kWidth; 65258b5140b7535ae66c618cc64b0a955b8d47cc86cpbos@webrtc.org encoder_config_.streams[0].height = kHeight; 65363301bd03e009d309d1fdca1217f8708be610f32pbos@webrtc.org send_config_.pre_encode_callback = &pre_encode_callback; 654eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org 655eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org CreateMatchingReceiveConfigs(); 65688b558febb8e8f42df6c7482efe76795c3fed399pbos@webrtc.org receive_configs_[0].pre_render_callback = &pre_render_callback; 65788b558febb8e8f42df6c7482efe76795c3fed399pbos@webrtc.org receive_configs_[0].renderer = &renderer; 65863301bd03e009d309d1fdca1217f8708be610f32pbos@webrtc.org 65963301bd03e009d309d1fdca1217f8708be610f32pbos@webrtc.org CreateStreams(); 66088b558febb8e8f42df6c7482efe76795c3fed399pbos@webrtc.org Start(); 66163301bd03e009d309d1fdca1217f8708be610f32pbos@webrtc.org 66263301bd03e009d309d1fdca1217f8708be610f32pbos@webrtc.org // Create frames that are smaller than the send width/height, this is done to 66363301bd03e009d309d1fdca1217f8708be610f32pbos@webrtc.org // check that the callbacks are done after processing video. 66463301bd03e009d309d1fdca1217f8708be610f32pbos@webrtc.org scoped_ptr<test::FrameGenerator> frame_generator( 66563301bd03e009d309d1fdca1217f8708be610f32pbos@webrtc.org test::FrameGenerator::Create(kWidth / 2, kHeight / 2)); 666c33d37ce205e22c0e090b0b285ed963686bf24dcpbos@webrtc.org send_stream_->Input()->SwapFrame(frame_generator->NextFrame()); 66763301bd03e009d309d1fdca1217f8708be610f32pbos@webrtc.org 66863301bd03e009d309d1fdca1217f8708be610f32pbos@webrtc.org EXPECT_EQ(kEventSignaled, pre_encode_callback.Wait()) 66963301bd03e009d309d1fdca1217f8708be610f32pbos@webrtc.org << "Timed out while waiting for pre-encode callback."; 67063301bd03e009d309d1fdca1217f8708be610f32pbos@webrtc.org EXPECT_EQ(kEventSignaled, pre_render_callback.Wait()) 67163301bd03e009d309d1fdca1217f8708be610f32pbos@webrtc.org << "Timed out while waiting for pre-render callback."; 67263301bd03e009d309d1fdca1217f8708be610f32pbos@webrtc.org EXPECT_EQ(kEventSignaled, renderer.Wait()) 67363301bd03e009d309d1fdca1217f8708be610f32pbos@webrtc.org << "Timed out while waiting for the frame to render."; 67463301bd03e009d309d1fdca1217f8708be610f32pbos@webrtc.org 67588b558febb8e8f42df6c7482efe76795c3fed399pbos@webrtc.org Stop(); 67663301bd03e009d309d1fdca1217f8708be610f32pbos@webrtc.org 67763301bd03e009d309d1fdca1217f8708be610f32pbos@webrtc.org sender_transport.StopSending(); 67863301bd03e009d309d1fdca1217f8708be610f32pbos@webrtc.org receiver_transport.StopSending(); 67963301bd03e009d309d1fdca1217f8708be610f32pbos@webrtc.org 68063301bd03e009d309d1fdca1217f8708be610f32pbos@webrtc.org DestroyStreams(); 68163301bd03e009d309d1fdca1217f8708be610f32pbos@webrtc.org} 68263301bd03e009d309d1fdca1217f8708be610f32pbos@webrtc.org 683eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.orgvoid EndToEndTest::ReceivesPliAndRecovers(int rtp_history_ms) { 684eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org static const int kPacketsToDrop = 1; 6858ce445ecc8a3fbf2a7517f71e778948f6a8e3d2fpbos@webrtc.org 686eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org class PliObserver : public test::EndToEndTest, public VideoRenderer { 687eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org public: 688eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org explicit PliObserver(int rtp_history_ms) 689eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org : EndToEndTest(kLongTimeoutMs), 690eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org rtp_history_ms_(rtp_history_ms), 691eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org nack_enabled_(rtp_history_ms > 0), 692eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org highest_dropped_timestamp_(0), 693eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org frames_to_drop_(0), 694eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org received_pli_(false) {} 695ce8510901416e37afabb0a54c6e10bec6db63a42pbos@webrtc.org 696eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org private: 697eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org virtual Action OnSendRtp(const uint8_t* packet, size_t length) OVERRIDE { 698eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org RTPHeader header; 6996aae61c2c693fa3425c73c420e7046e95486b592pbos@webrtc.org EXPECT_TRUE(parser_->Parse(packet, length, &header)); 7008ce445ecc8a3fbf2a7517f71e778948f6a8e3d2fpbos@webrtc.org 701eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org // Drop all retransmitted packets to force a PLI. 702eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org if (header.timestamp <= highest_dropped_timestamp_) 703eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org return DROP_PACKET; 7048ce445ecc8a3fbf2a7517f71e778948f6a8e3d2fpbos@webrtc.org 705eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org if (frames_to_drop_ > 0) { 706eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org highest_dropped_timestamp_ = header.timestamp; 707eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org --frames_to_drop_; 708eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org return DROP_PACKET; 7098ce445ecc8a3fbf2a7517f71e778948f6a8e3d2fpbos@webrtc.org } 710ce8510901416e37afabb0a54c6e10bec6db63a42pbos@webrtc.org 711eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org return SEND_PACKET; 7128ce445ecc8a3fbf2a7517f71e778948f6a8e3d2fpbos@webrtc.org } 7136c172c5af42b2d10e71b12ef0ed74864dce1ecfdmflodman@webrtc.org 714eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org virtual Action OnReceiveRtcp(const uint8_t* packet, 715eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org size_t length) OVERRIDE { 716eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org RTCPUtility::RTCPParserV2 parser(packet, length, true); 717eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org EXPECT_TRUE(parser.IsValid()); 718ce8510901416e37afabb0a54c6e10bec6db63a42pbos@webrtc.org 719eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org for (RTCPUtility::RTCPPacketTypes packet_type = parser.Begin(); 720eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org packet_type != RTCPUtility::kRtcpNotValidCode; 721eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org packet_type = parser.Iterate()) { 722eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org if (!nack_enabled_) 723eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org EXPECT_NE(packet_type, RTCPUtility::kRtcpRtpfbNackCode); 724ce8510901416e37afabb0a54c6e10bec6db63a42pbos@webrtc.org 725eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org if (packet_type == RTCPUtility::kRtcpPsfbPliCode) { 726eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org received_pli_ = true; 727eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org break; 728eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org } 729eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org } 730eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org return SEND_PACKET; 731eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org } 732ce8510901416e37afabb0a54c6e10bec6db63a42pbos@webrtc.org 733eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org virtual void RenderFrame(const I420VideoFrame& video_frame, 734eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org int time_to_render_ms) OVERRIDE { 735eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org CriticalSectionScoped lock(crit_.get()); 736eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org if (received_pli_ && 737eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org video_frame.timestamp() > highest_dropped_timestamp_) { 738eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org observation_complete_->Set(); 739eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org } 740eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org if (!received_pli_) 741eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org frames_to_drop_ = kPacketsToDrop; 742eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org } 743ce8510901416e37afabb0a54c6e10bec6db63a42pbos@webrtc.org 744eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org virtual void ModifyConfigs( 745eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org VideoSendStream::Config* send_config, 74688b558febb8e8f42df6c7482efe76795c3fed399pbos@webrtc.org std::vector<VideoReceiveStream::Config>* receive_configs, 74758b5140b7535ae66c618cc64b0a955b8d47cc86cpbos@webrtc.org VideoEncoderConfig* encoder_config) OVERRIDE { 748eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org send_config->rtp.nack.rtp_history_ms = rtp_history_ms_; 74988b558febb8e8f42df6c7482efe76795c3fed399pbos@webrtc.org (*receive_configs)[0].rtp.nack.rtp_history_ms = rtp_history_ms_; 75088b558febb8e8f42df6c7482efe76795c3fed399pbos@webrtc.org (*receive_configs)[0].renderer = this; 751eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org } 752ce8510901416e37afabb0a54c6e10bec6db63a42pbos@webrtc.org 753eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org virtual void PerformTest() OVERRIDE { 754eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org EXPECT_EQ(kEventSignaled, Wait()) << "Timed out waiting for PLI to be " 755eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org "received and a frame to be " 756eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org "rendered afterwards."; 757eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org } 7588ce445ecc8a3fbf2a7517f71e778948f6a8e3d2fpbos@webrtc.org 759eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org int rtp_history_ms_; 760eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org bool nack_enabled_; 761eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org uint32_t highest_dropped_timestamp_; 762eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org int frames_to_drop_; 763eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org bool received_pli_; 764eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org } test(rtp_history_ms); 765618a0ec1d2c17d485b7ce51cbfd282e6bae8e019pbos@webrtc.org 766eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org RunBaseTest(&test); 767ce8510901416e37afabb0a54c6e10bec6db63a42pbos@webrtc.org} 768ce8510901416e37afabb0a54c6e10bec6db63a42pbos@webrtc.org 769eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.orgTEST_F(EndToEndTest, ReceivesPliAndRecoversWithNack) { 7708ce445ecc8a3fbf2a7517f71e778948f6a8e3d2fpbos@webrtc.org ReceivesPliAndRecovers(1000); 7718ce445ecc8a3fbf2a7517f71e778948f6a8e3d2fpbos@webrtc.org} 7728ce445ecc8a3fbf2a7517f71e778948f6a8e3d2fpbos@webrtc.org 7738ce445ecc8a3fbf2a7517f71e778948f6a8e3d2fpbos@webrtc.org// TODO(pbos): Enable this when 2250 is resolved. 774eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.orgTEST_F(EndToEndTest, DISABLED_ReceivesPliAndRecoversWithoutNack) { 7758ce445ecc8a3fbf2a7517f71e778948f6a8e3d2fpbos@webrtc.org ReceivesPliAndRecovers(0); 7768ce445ecc8a3fbf2a7517f71e778948f6a8e3d2fpbos@webrtc.org} 7778ce445ecc8a3fbf2a7517f71e778948f6a8e3d2fpbos@webrtc.org 778eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.orgTEST_F(EndToEndTest, UnknownRtpPacketGivesUnknownSsrcReturnCode) { 7790020858e503d18322766b76443d83bfa5db4bffbpbos@webrtc.org class PacketInputObserver : public PacketReceiver { 7800020858e503d18322766b76443d83bfa5db4bffbpbos@webrtc.org public: 7810020858e503d18322766b76443d83bfa5db4bffbpbos@webrtc.org explicit PacketInputObserver(PacketReceiver* receiver) 7820020858e503d18322766b76443d83bfa5db4bffbpbos@webrtc.org : receiver_(receiver), delivered_packet_(EventWrapper::Create()) {} 7830020858e503d18322766b76443d83bfa5db4bffbpbos@webrtc.org 78451e010182b9947c9656f9e81a6a12f64a8e21788pbos@webrtc.org EventTypeWrapper Wait() { 78551e010182b9947c9656f9e81a6a12f64a8e21788pbos@webrtc.org return delivered_packet_->Wait(kDefaultTimeoutMs); 78651e010182b9947c9656f9e81a6a12f64a8e21788pbos@webrtc.org } 7870020858e503d18322766b76443d83bfa5db4bffbpbos@webrtc.org 7880020858e503d18322766b76443d83bfa5db4bffbpbos@webrtc.org private: 789bc57e0f1a00227c0cec3d429fc58cc442d07b509pbos@webrtc.org virtual DeliveryStatus DeliverPacket(const uint8_t* packet, 790bc57e0f1a00227c0cec3d429fc58cc442d07b509pbos@webrtc.org size_t length) OVERRIDE { 7916aae61c2c693fa3425c73c420e7046e95486b592pbos@webrtc.org if (RtpHeaderParser::IsRtcp(packet, length)) { 7920020858e503d18322766b76443d83bfa5db4bffbpbos@webrtc.org return receiver_->DeliverPacket(packet, length); 7930020858e503d18322766b76443d83bfa5db4bffbpbos@webrtc.org } else { 794bc57e0f1a00227c0cec3d429fc58cc442d07b509pbos@webrtc.org DeliveryStatus delivery_status = 795bc57e0f1a00227c0cec3d429fc58cc442d07b509pbos@webrtc.org receiver_->DeliverPacket(packet, length); 796bc57e0f1a00227c0cec3d429fc58cc442d07b509pbos@webrtc.org EXPECT_EQ(DELIVERY_UNKNOWN_SSRC, delivery_status); 7970020858e503d18322766b76443d83bfa5db4bffbpbos@webrtc.org delivered_packet_->Set(); 798bc57e0f1a00227c0cec3d429fc58cc442d07b509pbos@webrtc.org return delivery_status; 7990020858e503d18322766b76443d83bfa5db4bffbpbos@webrtc.org } 8000020858e503d18322766b76443d83bfa5db4bffbpbos@webrtc.org } 8010020858e503d18322766b76443d83bfa5db4bffbpbos@webrtc.org 8020020858e503d18322766b76443d83bfa5db4bffbpbos@webrtc.org PacketReceiver* receiver_; 8030020858e503d18322766b76443d83bfa5db4bffbpbos@webrtc.org scoped_ptr<EventWrapper> delivered_packet_; 8040020858e503d18322766b76443d83bfa5db4bffbpbos@webrtc.org }; 8050020858e503d18322766b76443d83bfa5db4bffbpbos@webrtc.org 8060020858e503d18322766b76443d83bfa5db4bffbpbos@webrtc.org test::DirectTransport send_transport, receive_transport; 8070020858e503d18322766b76443d83bfa5db4bffbpbos@webrtc.org 808b5d2d165c78331b337bc372babc3a1a3e62172afpbos@webrtc.org CreateCalls(Call::Config(&send_transport), Call::Config(&receive_transport)); 8090020858e503d18322766b76443d83bfa5db4bffbpbos@webrtc.org PacketInputObserver input_observer(receiver_call_->Receiver()); 8100020858e503d18322766b76443d83bfa5db4bffbpbos@webrtc.org 8110020858e503d18322766b76443d83bfa5db4bffbpbos@webrtc.org send_transport.SetReceiver(&input_observer); 8120020858e503d18322766b76443d83bfa5db4bffbpbos@webrtc.org receive_transport.SetReceiver(sender_call_->Receiver()); 8130020858e503d18322766b76443d83bfa5db4bffbpbos@webrtc.org 814eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org CreateSendConfig(1); 815eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org CreateMatchingReceiveConfigs(); 8160020858e503d18322766b76443d83bfa5db4bffbpbos@webrtc.org 8170020858e503d18322766b76443d83bfa5db4bffbpbos@webrtc.org CreateStreams(); 81888b558febb8e8f42df6c7482efe76795c3fed399pbos@webrtc.org CreateFrameGeneratorCapturer(); 81988b558febb8e8f42df6c7482efe76795c3fed399pbos@webrtc.org Start(); 8200020858e503d18322766b76443d83bfa5db4bffbpbos@webrtc.org 82188b558febb8e8f42df6c7482efe76795c3fed399pbos@webrtc.org receiver_call_->DestroyVideoReceiveStream(receive_streams_[0]); 82288b558febb8e8f42df6c7482efe76795c3fed399pbos@webrtc.org receive_streams_.clear(); 8230020858e503d18322766b76443d83bfa5db4bffbpbos@webrtc.org 8240020858e503d18322766b76443d83bfa5db4bffbpbos@webrtc.org // Wait() waits for a received packet. 8250020858e503d18322766b76443d83bfa5db4bffbpbos@webrtc.org EXPECT_EQ(kEventSignaled, input_observer.Wait()); 8260020858e503d18322766b76443d83bfa5db4bffbpbos@webrtc.org 82788b558febb8e8f42df6c7482efe76795c3fed399pbos@webrtc.org Stop(); 8280020858e503d18322766b76443d83bfa5db4bffbpbos@webrtc.org 8290020858e503d18322766b76443d83bfa5db4bffbpbos@webrtc.org DestroyStreams(); 8300020858e503d18322766b76443d83bfa5db4bffbpbos@webrtc.org 8310020858e503d18322766b76443d83bfa5db4bffbpbos@webrtc.org send_transport.StopSending(); 8320020858e503d18322766b76443d83bfa5db4bffbpbos@webrtc.org receive_transport.StopSending(); 8330020858e503d18322766b76443d83bfa5db4bffbpbos@webrtc.org} 834c5080a993e1be0ee14292f5fe8cd7a5b30033f5fpbos@webrtc.org 835eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.orgvoid EndToEndTest::RespectsRtcpMode(newapi::RtcpMode rtcp_mode) { 83651e010182b9947c9656f9e81a6a12f64a8e21788pbos@webrtc.org static const int kNumCompoundRtcpPacketsToObserve = 10; 837eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org class RtcpModeObserver : public test::EndToEndTest { 83851e010182b9947c9656f9e81a6a12f64a8e21788pbos@webrtc.org public: 839d05597a15dd2d01c8e172df86b960b7d4ac9647fpbos@webrtc.org explicit RtcpModeObserver(newapi::RtcpMode rtcp_mode) 840eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org : EndToEndTest(kDefaultTimeoutMs), 84151e010182b9947c9656f9e81a6a12f64a8e21788pbos@webrtc.org rtcp_mode_(rtcp_mode), 84251e010182b9947c9656f9e81a6a12f64a8e21788pbos@webrtc.org sent_rtp_(0), 84351e010182b9947c9656f9e81a6a12f64a8e21788pbos@webrtc.org sent_rtcp_(0) {} 84451e010182b9947c9656f9e81a6a12f64a8e21788pbos@webrtc.org 84551e010182b9947c9656f9e81a6a12f64a8e21788pbos@webrtc.org private: 84651e010182b9947c9656f9e81a6a12f64a8e21788pbos@webrtc.org virtual Action OnSendRtp(const uint8_t* packet, size_t length) OVERRIDE { 84751e010182b9947c9656f9e81a6a12f64a8e21788pbos@webrtc.org if (++sent_rtp_ % 3 == 0) 84851e010182b9947c9656f9e81a6a12f64a8e21788pbos@webrtc.org return DROP_PACKET; 84951e010182b9947c9656f9e81a6a12f64a8e21788pbos@webrtc.org 85051e010182b9947c9656f9e81a6a12f64a8e21788pbos@webrtc.org return SEND_PACKET; 85151e010182b9947c9656f9e81a6a12f64a8e21788pbos@webrtc.org } 85251e010182b9947c9656f9e81a6a12f64a8e21788pbos@webrtc.org 85351e010182b9947c9656f9e81a6a12f64a8e21788pbos@webrtc.org virtual Action OnReceiveRtcp(const uint8_t* packet, 85451e010182b9947c9656f9e81a6a12f64a8e21788pbos@webrtc.org size_t length) OVERRIDE { 85551e010182b9947c9656f9e81a6a12f64a8e21788pbos@webrtc.org ++sent_rtcp_; 85651e010182b9947c9656f9e81a6a12f64a8e21788pbos@webrtc.org RTCPUtility::RTCPParserV2 parser(packet, length, true); 85751e010182b9947c9656f9e81a6a12f64a8e21788pbos@webrtc.org EXPECT_TRUE(parser.IsValid()); 85851e010182b9947c9656f9e81a6a12f64a8e21788pbos@webrtc.org 85951e010182b9947c9656f9e81a6a12f64a8e21788pbos@webrtc.org RTCPUtility::RTCPPacketTypes packet_type = parser.Begin(); 86051e010182b9947c9656f9e81a6a12f64a8e21788pbos@webrtc.org bool has_report_block = false; 86151e010182b9947c9656f9e81a6a12f64a8e21788pbos@webrtc.org while (packet_type != RTCPUtility::kRtcpNotValidCode) { 86251e010182b9947c9656f9e81a6a12f64a8e21788pbos@webrtc.org EXPECT_NE(RTCPUtility::kRtcpSrCode, packet_type); 86351e010182b9947c9656f9e81a6a12f64a8e21788pbos@webrtc.org if (packet_type == RTCPUtility::kRtcpRrCode) { 86451e010182b9947c9656f9e81a6a12f64a8e21788pbos@webrtc.org has_report_block = true; 86551e010182b9947c9656f9e81a6a12f64a8e21788pbos@webrtc.org break; 86651e010182b9947c9656f9e81a6a12f64a8e21788pbos@webrtc.org } 86751e010182b9947c9656f9e81a6a12f64a8e21788pbos@webrtc.org packet_type = parser.Iterate(); 86851e010182b9947c9656f9e81a6a12f64a8e21788pbos@webrtc.org } 86951e010182b9947c9656f9e81a6a12f64a8e21788pbos@webrtc.org 87051e010182b9947c9656f9e81a6a12f64a8e21788pbos@webrtc.org switch (rtcp_mode_) { 87151e010182b9947c9656f9e81a6a12f64a8e21788pbos@webrtc.org case newapi::kRtcpCompound: 87251e010182b9947c9656f9e81a6a12f64a8e21788pbos@webrtc.org if (!has_report_block) { 87351e010182b9947c9656f9e81a6a12f64a8e21788pbos@webrtc.org ADD_FAILURE() << "Received RTCP packet without receiver report for " 87451e010182b9947c9656f9e81a6a12f64a8e21788pbos@webrtc.org "kRtcpCompound."; 87551e010182b9947c9656f9e81a6a12f64a8e21788pbos@webrtc.org observation_complete_->Set(); 87651e010182b9947c9656f9e81a6a12f64a8e21788pbos@webrtc.org } 87751e010182b9947c9656f9e81a6a12f64a8e21788pbos@webrtc.org 87851e010182b9947c9656f9e81a6a12f64a8e21788pbos@webrtc.org if (sent_rtcp_ >= kNumCompoundRtcpPacketsToObserve) 87951e010182b9947c9656f9e81a6a12f64a8e21788pbos@webrtc.org observation_complete_->Set(); 88051e010182b9947c9656f9e81a6a12f64a8e21788pbos@webrtc.org 88151e010182b9947c9656f9e81a6a12f64a8e21788pbos@webrtc.org break; 88251e010182b9947c9656f9e81a6a12f64a8e21788pbos@webrtc.org case newapi::kRtcpReducedSize: 88351e010182b9947c9656f9e81a6a12f64a8e21788pbos@webrtc.org if (!has_report_block) 88451e010182b9947c9656f9e81a6a12f64a8e21788pbos@webrtc.org observation_complete_->Set(); 88551e010182b9947c9656f9e81a6a12f64a8e21788pbos@webrtc.org break; 88651e010182b9947c9656f9e81a6a12f64a8e21788pbos@webrtc.org } 88751e010182b9947c9656f9e81a6a12f64a8e21788pbos@webrtc.org 88851e010182b9947c9656f9e81a6a12f64a8e21788pbos@webrtc.org return SEND_PACKET; 88951e010182b9947c9656f9e81a6a12f64a8e21788pbos@webrtc.org } 89051e010182b9947c9656f9e81a6a12f64a8e21788pbos@webrtc.org 891eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org virtual void ModifyConfigs( 892eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org VideoSendStream::Config* send_config, 89388b558febb8e8f42df6c7482efe76795c3fed399pbos@webrtc.org std::vector<VideoReceiveStream::Config>* receive_configs, 89458b5140b7535ae66c618cc64b0a955b8d47cc86cpbos@webrtc.org VideoEncoderConfig* encoder_config) OVERRIDE { 895eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org send_config->rtp.nack.rtp_history_ms = kNackRtpHistoryMs; 89688b558febb8e8f42df6c7482efe76795c3fed399pbos@webrtc.org (*receive_configs)[0].rtp.nack.rtp_history_ms = kNackRtpHistoryMs; 89788b558febb8e8f42df6c7482efe76795c3fed399pbos@webrtc.org (*receive_configs)[0].rtp.rtcp_mode = rtcp_mode_; 898eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org } 899eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org 900eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org virtual void PerformTest() OVERRIDE { 901eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org EXPECT_EQ(kEventSignaled, Wait()) 902eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org << (rtcp_mode_ == newapi::kRtcpCompound 903eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org ? "Timed out before observing enough compound packets." 904eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org : "Timed out before receiving a non-compound RTCP packet."); 905eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org } 906eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org 90751e010182b9947c9656f9e81a6a12f64a8e21788pbos@webrtc.org newapi::RtcpMode rtcp_mode_; 90851e010182b9947c9656f9e81a6a12f64a8e21788pbos@webrtc.org int sent_rtp_; 90951e010182b9947c9656f9e81a6a12f64a8e21788pbos@webrtc.org int sent_rtcp_; 910eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org } test(rtcp_mode); 91151e010182b9947c9656f9e81a6a12f64a8e21788pbos@webrtc.org 912eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org RunBaseTest(&test); 91351e010182b9947c9656f9e81a6a12f64a8e21788pbos@webrtc.org} 91451e010182b9947c9656f9e81a6a12f64a8e21788pbos@webrtc.org 915eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.orgTEST_F(EndToEndTest, UsesRtcpCompoundMode) { 91651e010182b9947c9656f9e81a6a12f64a8e21788pbos@webrtc.org RespectsRtcpMode(newapi::kRtcpCompound); 91751e010182b9947c9656f9e81a6a12f64a8e21788pbos@webrtc.org} 91851e010182b9947c9656f9e81a6a12f64a8e21788pbos@webrtc.org 919eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.orgTEST_F(EndToEndTest, UsesRtcpReducedSizeMode) { 92051e010182b9947c9656f9e81a6a12f64a8e21788pbos@webrtc.org RespectsRtcpMode(newapi::kRtcpReducedSize); 92151e010182b9947c9656f9e81a6a12f64a8e21788pbos@webrtc.org} 92251e010182b9947c9656f9e81a6a12f64a8e21788pbos@webrtc.org 923c5080a993e1be0ee14292f5fe8cd7a5b30033f5fpbos@webrtc.org// Test sets up a Call multiple senders with different resolutions and SSRCs. 924c5080a993e1be0ee14292f5fe8cd7a5b30033f5fpbos@webrtc.org// Another is set up to receive all three of these with different renderers. 925c5080a993e1be0ee14292f5fe8cd7a5b30033f5fpbos@webrtc.org// Each renderer verifies that it receives the expected resolution, and as soon 926c5080a993e1be0ee14292f5fe8cd7a5b30033f5fpbos@webrtc.org// as every renderer has received a frame, the test finishes. 92729c4d870efc8877b99ee583e8904cfba3d654b10andresp@webrtc.orgTEST_F(EndToEndTest, SendsAndReceivesMultipleStreams) { 928c5080a993e1be0ee14292f5fe8cd7a5b30033f5fpbos@webrtc.org static const size_t kNumStreams = 3; 929c5080a993e1be0ee14292f5fe8cd7a5b30033f5fpbos@webrtc.org 930c5080a993e1be0ee14292f5fe8cd7a5b30033f5fpbos@webrtc.org class VideoOutputObserver : public VideoRenderer { 931c5080a993e1be0ee14292f5fe8cd7a5b30033f5fpbos@webrtc.org public: 9324383539b27ae877337679901c1cc9120f3a83fefpbos@webrtc.org VideoOutputObserver(test::FrameGeneratorCapturer** capturer, 9334383539b27ae877337679901c1cc9120f3a83fefpbos@webrtc.org int width, 9344383539b27ae877337679901c1cc9120f3a83fefpbos@webrtc.org int height) 9354383539b27ae877337679901c1cc9120f3a83fefpbos@webrtc.org : capturer_(capturer), 9364383539b27ae877337679901c1cc9120f3a83fefpbos@webrtc.org width_(width), 9374383539b27ae877337679901c1cc9120f3a83fefpbos@webrtc.org height_(height), 9384383539b27ae877337679901c1cc9120f3a83fefpbos@webrtc.org done_(EventWrapper::Create()) {} 939c5080a993e1be0ee14292f5fe8cd7a5b30033f5fpbos@webrtc.org 940c5080a993e1be0ee14292f5fe8cd7a5b30033f5fpbos@webrtc.org virtual void RenderFrame(const I420VideoFrame& video_frame, 941c5080a993e1be0ee14292f5fe8cd7a5b30033f5fpbos@webrtc.org int time_to_render_ms) OVERRIDE { 942c5080a993e1be0ee14292f5fe8cd7a5b30033f5fpbos@webrtc.org EXPECT_EQ(width_, video_frame.width()); 943c5080a993e1be0ee14292f5fe8cd7a5b30033f5fpbos@webrtc.org EXPECT_EQ(height_, video_frame.height()); 9444383539b27ae877337679901c1cc9120f3a83fefpbos@webrtc.org (*capturer_)->Stop(); 945c5080a993e1be0ee14292f5fe8cd7a5b30033f5fpbos@webrtc.org done_->Set(); 946c5080a993e1be0ee14292f5fe8cd7a5b30033f5fpbos@webrtc.org } 947c5080a993e1be0ee14292f5fe8cd7a5b30033f5fpbos@webrtc.org 948e2a7a77646b23fb3704d267e6079e04bde493543pbos@webrtc.org EventTypeWrapper Wait() { return done_->Wait(kDefaultTimeoutMs); } 949c5080a993e1be0ee14292f5fe8cd7a5b30033f5fpbos@webrtc.org 950c5080a993e1be0ee14292f5fe8cd7a5b30033f5fpbos@webrtc.org private: 9514383539b27ae877337679901c1cc9120f3a83fefpbos@webrtc.org test::FrameGeneratorCapturer** capturer_; 952c5080a993e1be0ee14292f5fe8cd7a5b30033f5fpbos@webrtc.org int width_; 953c5080a993e1be0ee14292f5fe8cd7a5b30033f5fpbos@webrtc.org int height_; 954c5080a993e1be0ee14292f5fe8cd7a5b30033f5fpbos@webrtc.org scoped_ptr<EventWrapper> done_; 955c5080a993e1be0ee14292f5fe8cd7a5b30033f5fpbos@webrtc.org }; 956c5080a993e1be0ee14292f5fe8cd7a5b30033f5fpbos@webrtc.org 957c5080a993e1be0ee14292f5fe8cd7a5b30033f5fpbos@webrtc.org struct { 958c5080a993e1be0ee14292f5fe8cd7a5b30033f5fpbos@webrtc.org uint32_t ssrc; 959c5080a993e1be0ee14292f5fe8cd7a5b30033f5fpbos@webrtc.org int width; 960c5080a993e1be0ee14292f5fe8cd7a5b30033f5fpbos@webrtc.org int height; 961c5080a993e1be0ee14292f5fe8cd7a5b30033f5fpbos@webrtc.org } codec_settings[kNumStreams] = {{1, 640, 480}, {2, 320, 240}, {3, 240, 160}}; 962c5080a993e1be0ee14292f5fe8cd7a5b30033f5fpbos@webrtc.org 963c5080a993e1be0ee14292f5fe8cd7a5b30033f5fpbos@webrtc.org test::DirectTransport sender_transport, receiver_transport; 964c5080a993e1be0ee14292f5fe8cd7a5b30033f5fpbos@webrtc.org scoped_ptr<Call> sender_call(Call::Create(Call::Config(&sender_transport))); 965c5080a993e1be0ee14292f5fe8cd7a5b30033f5fpbos@webrtc.org scoped_ptr<Call> receiver_call( 966c5080a993e1be0ee14292f5fe8cd7a5b30033f5fpbos@webrtc.org Call::Create(Call::Config(&receiver_transport))); 967c5080a993e1be0ee14292f5fe8cd7a5b30033f5fpbos@webrtc.org sender_transport.SetReceiver(receiver_call->Receiver()); 968c5080a993e1be0ee14292f5fe8cd7a5b30033f5fpbos@webrtc.org receiver_transport.SetReceiver(sender_call->Receiver()); 969c5080a993e1be0ee14292f5fe8cd7a5b30033f5fpbos@webrtc.org 970c5080a993e1be0ee14292f5fe8cd7a5b30033f5fpbos@webrtc.org VideoSendStream* send_streams[kNumStreams]; 971c5080a993e1be0ee14292f5fe8cd7a5b30033f5fpbos@webrtc.org VideoReceiveStream* receive_streams[kNumStreams]; 972c5080a993e1be0ee14292f5fe8cd7a5b30033f5fpbos@webrtc.org 973c5080a993e1be0ee14292f5fe8cd7a5b30033f5fpbos@webrtc.org VideoOutputObserver* observers[kNumStreams]; 974c5080a993e1be0ee14292f5fe8cd7a5b30033f5fpbos@webrtc.org test::FrameGeneratorCapturer* frame_generators[kNumStreams]; 975c5080a993e1be0ee14292f5fe8cd7a5b30033f5fpbos@webrtc.org 9761c655450cf12d21bfa5b2ff277f337335149186apbos@webrtc.org scoped_ptr<VideoEncoder> encoders[kNumStreams]; 977e2a7a77646b23fb3704d267e6079e04bde493543pbos@webrtc.org for (size_t i = 0; i < kNumStreams; ++i) 9781c655450cf12d21bfa5b2ff277f337335149186apbos@webrtc.org encoders[i].reset(VideoEncoder::Create(VideoEncoder::kVp8)); 979e2a7a77646b23fb3704d267e6079e04bde493543pbos@webrtc.org 980c5080a993e1be0ee14292f5fe8cd7a5b30033f5fpbos@webrtc.org for (size_t i = 0; i < kNumStreams; ++i) { 981c5080a993e1be0ee14292f5fe8cd7a5b30033f5fpbos@webrtc.org uint32_t ssrc = codec_settings[i].ssrc; 982c5080a993e1be0ee14292f5fe8cd7a5b30033f5fpbos@webrtc.org int width = codec_settings[i].width; 983c5080a993e1be0ee14292f5fe8cd7a5b30033f5fpbos@webrtc.org int height = codec_settings[i].height; 9844383539b27ae877337679901c1cc9120f3a83fefpbos@webrtc.org observers[i] = new VideoOutputObserver(&frame_generators[i], width, height); 985c5080a993e1be0ee14292f5fe8cd7a5b30033f5fpbos@webrtc.org 9867f0b309745ae589ded2bec817c390249fdb10ad3pbos@webrtc.org VideoSendStream::Config send_config; 987e2a7a77646b23fb3704d267e6079e04bde493543pbos@webrtc.org send_config.rtp.ssrcs.push_back(ssrc); 988bdfcddf7091e92134143e9a2d9ccce908e43979epbos@webrtc.org send_config.encoder_settings.encoder = encoders[i].get(); 989bdfcddf7091e92134143e9a2d9ccce908e43979epbos@webrtc.org send_config.encoder_settings.payload_name = "VP8"; 990bdfcddf7091e92134143e9a2d9ccce908e43979epbos@webrtc.org send_config.encoder_settings.payload_type = 124; 99158b5140b7535ae66c618cc64b0a955b8d47cc86cpbos@webrtc.org VideoEncoderConfig encoder_config; 99258b5140b7535ae66c618cc64b0a955b8d47cc86cpbos@webrtc.org encoder_config.streams = test::CreateVideoStreams(1); 99358b5140b7535ae66c618cc64b0a955b8d47cc86cpbos@webrtc.org VideoStream* stream = &encoder_config.streams[0]; 994e2a7a77646b23fb3704d267e6079e04bde493543pbos@webrtc.org stream->width = width; 995e2a7a77646b23fb3704d267e6079e04bde493543pbos@webrtc.org stream->height = height; 996e2a7a77646b23fb3704d267e6079e04bde493543pbos@webrtc.org stream->max_framerate = 5; 997e2a7a77646b23fb3704d267e6079e04bde493543pbos@webrtc.org stream->min_bitrate_bps = stream->target_bitrate_bps = 998e2a7a77646b23fb3704d267e6079e04bde493543pbos@webrtc.org stream->max_bitrate_bps = 100000; 999bdfcddf7091e92134143e9a2d9ccce908e43979epbos@webrtc.org send_streams[i] = 100058b5140b7535ae66c618cc64b0a955b8d47cc86cpbos@webrtc.org sender_call->CreateVideoSendStream(send_config, encoder_config); 100116a058a180164c32a13f3406d35cc3ef1ad569c4pbos@webrtc.org send_streams[i]->Start(); 1002e2a7a77646b23fb3704d267e6079e04bde493543pbos@webrtc.org 10037f0b309745ae589ded2bec817c390249fdb10ad3pbos@webrtc.org VideoReceiveStream::Config receive_config; 1004c5080a993e1be0ee14292f5fe8cd7a5b30033f5fpbos@webrtc.org receive_config.renderer = observers[i]; 10054b50db1f8ce21cc7faf4f7c80b6a492dffb2a1d5pbos@webrtc.org receive_config.rtp.remote_ssrc = ssrc; 10064b50db1f8ce21cc7faf4f7c80b6a492dffb2a1d5pbos@webrtc.org receive_config.rtp.local_ssrc = kReceiverLocalSsrc; 1007e2a7a77646b23fb3704d267e6079e04bde493543pbos@webrtc.org VideoCodec codec = 1008e2a7a77646b23fb3704d267e6079e04bde493543pbos@webrtc.org test::CreateDecoderVideoCodec(send_config.encoder_settings); 1009e2a7a77646b23fb3704d267e6079e04bde493543pbos@webrtc.org receive_config.codecs.push_back(codec); 1010964d78e5c80ec8e4cbaeece5f119806b1ef9ea22pbos@webrtc.org receive_streams[i] = 1011964d78e5c80ec8e4cbaeece5f119806b1ef9ea22pbos@webrtc.org receiver_call->CreateVideoReceiveStream(receive_config); 101216a058a180164c32a13f3406d35cc3ef1ad569c4pbos@webrtc.org receive_streams[i]->Start(); 1013c5080a993e1be0ee14292f5fe8cd7a5b30033f5fpbos@webrtc.org 1014c5080a993e1be0ee14292f5fe8cd7a5b30033f5fpbos@webrtc.org frame_generators[i] = test::FrameGeneratorCapturer::Create( 1015c5080a993e1be0ee14292f5fe8cd7a5b30033f5fpbos@webrtc.org send_streams[i]->Input(), width, height, 30, Clock::GetRealTimeClock()); 1016c5080a993e1be0ee14292f5fe8cd7a5b30033f5fpbos@webrtc.org frame_generators[i]->Start(); 1017c5080a993e1be0ee14292f5fe8cd7a5b30033f5fpbos@webrtc.org } 1018c5080a993e1be0ee14292f5fe8cd7a5b30033f5fpbos@webrtc.org 1019c5080a993e1be0ee14292f5fe8cd7a5b30033f5fpbos@webrtc.org for (size_t i = 0; i < kNumStreams; ++i) { 1020e2a7a77646b23fb3704d267e6079e04bde493543pbos@webrtc.org EXPECT_EQ(kEventSignaled, observers[i]->Wait()) 1021e2a7a77646b23fb3704d267e6079e04bde493543pbos@webrtc.org << "Timed out while waiting for observer " << i << " to render."; 1022c5080a993e1be0ee14292f5fe8cd7a5b30033f5fpbos@webrtc.org } 1023c5080a993e1be0ee14292f5fe8cd7a5b30033f5fpbos@webrtc.org 1024c5080a993e1be0ee14292f5fe8cd7a5b30033f5fpbos@webrtc.org for (size_t i = 0; i < kNumStreams; ++i) { 1025c5080a993e1be0ee14292f5fe8cd7a5b30033f5fpbos@webrtc.org frame_generators[i]->Stop(); 102612a93e063c94500f8fe0a045fc381a816fdf3c69pbos@webrtc.org sender_call->DestroyVideoSendStream(send_streams[i]); 102712a93e063c94500f8fe0a045fc381a816fdf3c69pbos@webrtc.org receiver_call->DestroyVideoReceiveStream(receive_streams[i]); 1028471354f94ed73da7195e2f8e72c5a2239b9a9afbpbos@webrtc.org delete frame_generators[i]; 1029c5080a993e1be0ee14292f5fe8cd7a5b30033f5fpbos@webrtc.org delete observers[i]; 1030c5080a993e1be0ee14292f5fe8cd7a5b30033f5fpbos@webrtc.org } 1031c5080a993e1be0ee14292f5fe8cd7a5b30033f5fpbos@webrtc.org 1032c5080a993e1be0ee14292f5fe8cd7a5b30033f5fpbos@webrtc.org sender_transport.StopSending(); 1033c5080a993e1be0ee14292f5fe8cd7a5b30033f5fpbos@webrtc.org receiver_transport.StopSending(); 1034eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org} 1035e028410838cd976c75e379b3c2e2eb0ac52b3c99stefan@webrtc.org 1036eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.orgTEST_F(EndToEndTest, ObserversEncodedFrames) { 10372e98d45e2455d3b48ceac1ad5457623d39802c9esprang@webrtc.org class EncodedFrameTestObserver : public EncodedFrameObserver { 10382e98d45e2455d3b48ceac1ad5457623d39802c9esprang@webrtc.org public: 1039c71929dce136f9bc59fcc7ceb172cf74fc507ea9pbos@webrtc.org EncodedFrameTestObserver() 1040c71929dce136f9bc59fcc7ceb172cf74fc507ea9pbos@webrtc.org : length_(0), 1041c71929dce136f9bc59fcc7ceb172cf74fc507ea9pbos@webrtc.org frame_type_(kFrameEmpty), 1042c71929dce136f9bc59fcc7ceb172cf74fc507ea9pbos@webrtc.org called_(EventWrapper::Create()) {} 10432e98d45e2455d3b48ceac1ad5457623d39802c9esprang@webrtc.org virtual ~EncodedFrameTestObserver() {} 10442e98d45e2455d3b48ceac1ad5457623d39802c9esprang@webrtc.org 10452e98d45e2455d3b48ceac1ad5457623d39802c9esprang@webrtc.org virtual void EncodedFrameCallback(const EncodedFrame& encoded_frame) { 10462e98d45e2455d3b48ceac1ad5457623d39802c9esprang@webrtc.org frame_type_ = encoded_frame.frame_type_; 10472e98d45e2455d3b48ceac1ad5457623d39802c9esprang@webrtc.org length_ = encoded_frame.length_; 10482e98d45e2455d3b48ceac1ad5457623d39802c9esprang@webrtc.org buffer_.reset(new uint8_t[length_]); 10492e98d45e2455d3b48ceac1ad5457623d39802c9esprang@webrtc.org memcpy(buffer_.get(), encoded_frame.data_, length_); 10502e98d45e2455d3b48ceac1ad5457623d39802c9esprang@webrtc.org called_->Set(); 10512e98d45e2455d3b48ceac1ad5457623d39802c9esprang@webrtc.org } 10522e98d45e2455d3b48ceac1ad5457623d39802c9esprang@webrtc.org 1053c71929dce136f9bc59fcc7ceb172cf74fc507ea9pbos@webrtc.org EventTypeWrapper Wait() { return called_->Wait(kDefaultTimeoutMs); } 10542e98d45e2455d3b48ceac1ad5457623d39802c9esprang@webrtc.org 10552e98d45e2455d3b48ceac1ad5457623d39802c9esprang@webrtc.org void ExpectEqualFrames(const EncodedFrameTestObserver& observer) { 10562e98d45e2455d3b48ceac1ad5457623d39802c9esprang@webrtc.org ASSERT_EQ(length_, observer.length_) 10572e98d45e2455d3b48ceac1ad5457623d39802c9esprang@webrtc.org << "Observed frames are of different lengths."; 10582e98d45e2455d3b48ceac1ad5457623d39802c9esprang@webrtc.org EXPECT_EQ(frame_type_, observer.frame_type_) 10592e98d45e2455d3b48ceac1ad5457623d39802c9esprang@webrtc.org << "Observed frames have different frame types."; 10602e98d45e2455d3b48ceac1ad5457623d39802c9esprang@webrtc.org EXPECT_EQ(0, memcmp(buffer_.get(), observer.buffer_.get(), length_)) 10612e98d45e2455d3b48ceac1ad5457623d39802c9esprang@webrtc.org << "Observed encoded frames have different content."; 10622e98d45e2455d3b48ceac1ad5457623d39802c9esprang@webrtc.org } 10632e98d45e2455d3b48ceac1ad5457623d39802c9esprang@webrtc.org 10642e98d45e2455d3b48ceac1ad5457623d39802c9esprang@webrtc.org private: 10652e98d45e2455d3b48ceac1ad5457623d39802c9esprang@webrtc.org scoped_ptr<uint8_t[]> buffer_; 10662e98d45e2455d3b48ceac1ad5457623d39802c9esprang@webrtc.org size_t length_; 10672e98d45e2455d3b48ceac1ad5457623d39802c9esprang@webrtc.org FrameType frame_type_; 10682e98d45e2455d3b48ceac1ad5457623d39802c9esprang@webrtc.org scoped_ptr<EventWrapper> called_; 10692e98d45e2455d3b48ceac1ad5457623d39802c9esprang@webrtc.org }; 10702e98d45e2455d3b48ceac1ad5457623d39802c9esprang@webrtc.org 10712e98d45e2455d3b48ceac1ad5457623d39802c9esprang@webrtc.org EncodedFrameTestObserver post_encode_observer; 10722e98d45e2455d3b48ceac1ad5457623d39802c9esprang@webrtc.org EncodedFrameTestObserver pre_decode_observer; 10732e98d45e2455d3b48ceac1ad5457623d39802c9esprang@webrtc.org 10742e98d45e2455d3b48ceac1ad5457623d39802c9esprang@webrtc.org test::DirectTransport sender_transport, receiver_transport; 10752e98d45e2455d3b48ceac1ad5457623d39802c9esprang@webrtc.org 10762e98d45e2455d3b48ceac1ad5457623d39802c9esprang@webrtc.org CreateCalls(Call::Config(&sender_transport), 10772e98d45e2455d3b48ceac1ad5457623d39802c9esprang@webrtc.org Call::Config(&receiver_transport)); 10782e98d45e2455d3b48ceac1ad5457623d39802c9esprang@webrtc.org 10792e98d45e2455d3b48ceac1ad5457623d39802c9esprang@webrtc.org sender_transport.SetReceiver(receiver_call_->Receiver()); 10802e98d45e2455d3b48ceac1ad5457623d39802c9esprang@webrtc.org receiver_transport.SetReceiver(sender_call_->Receiver()); 10812e98d45e2455d3b48ceac1ad5457623d39802c9esprang@webrtc.org 1082eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org CreateSendConfig(1); 1083eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org CreateMatchingReceiveConfigs(); 10842e98d45e2455d3b48ceac1ad5457623d39802c9esprang@webrtc.org send_config_.post_encode_callback = &post_encode_observer; 108588b558febb8e8f42df6c7482efe76795c3fed399pbos@webrtc.org receive_configs_[0].pre_decode_callback = &pre_decode_observer; 10862e98d45e2455d3b48ceac1ad5457623d39802c9esprang@webrtc.org 10872e98d45e2455d3b48ceac1ad5457623d39802c9esprang@webrtc.org CreateStreams(); 108888b558febb8e8f42df6c7482efe76795c3fed399pbos@webrtc.org Start(); 10892e98d45e2455d3b48ceac1ad5457623d39802c9esprang@webrtc.org 10902e98d45e2455d3b48ceac1ad5457623d39802c9esprang@webrtc.org scoped_ptr<test::FrameGenerator> frame_generator(test::FrameGenerator::Create( 109158b5140b7535ae66c618cc64b0a955b8d47cc86cpbos@webrtc.org encoder_config_.streams[0].width, encoder_config_.streams[0].height)); 1092c33d37ce205e22c0e090b0b285ed963686bf24dcpbos@webrtc.org send_stream_->Input()->SwapFrame(frame_generator->NextFrame()); 10932e98d45e2455d3b48ceac1ad5457623d39802c9esprang@webrtc.org 10942e98d45e2455d3b48ceac1ad5457623d39802c9esprang@webrtc.org EXPECT_EQ(kEventSignaled, post_encode_observer.Wait()) 10952e98d45e2455d3b48ceac1ad5457623d39802c9esprang@webrtc.org << "Timed out while waiting for send-side encoded-frame callback."; 10962e98d45e2455d3b48ceac1ad5457623d39802c9esprang@webrtc.org 10972e98d45e2455d3b48ceac1ad5457623d39802c9esprang@webrtc.org EXPECT_EQ(kEventSignaled, pre_decode_observer.Wait()) 10982e98d45e2455d3b48ceac1ad5457623d39802c9esprang@webrtc.org << "Timed out while waiting for pre-decode encoded-frame callback."; 10992e98d45e2455d3b48ceac1ad5457623d39802c9esprang@webrtc.org 11002e98d45e2455d3b48ceac1ad5457623d39802c9esprang@webrtc.org post_encode_observer.ExpectEqualFrames(pre_decode_observer); 11012e98d45e2455d3b48ceac1ad5457623d39802c9esprang@webrtc.org 110288b558febb8e8f42df6c7482efe76795c3fed399pbos@webrtc.org Stop(); 11032e98d45e2455d3b48ceac1ad5457623d39802c9esprang@webrtc.org 11042e98d45e2455d3b48ceac1ad5457623d39802c9esprang@webrtc.org sender_transport.StopSending(); 11052e98d45e2455d3b48ceac1ad5457623d39802c9esprang@webrtc.org receiver_transport.StopSending(); 11062e98d45e2455d3b48ceac1ad5457623d39802c9esprang@webrtc.org 11072e98d45e2455d3b48ceac1ad5457623d39802c9esprang@webrtc.org DestroyStreams(); 11082e98d45e2455d3b48ceac1ad5457623d39802c9esprang@webrtc.org} 11097ff4089bfcce71ba2a5d21d5adc0467782a914a0mflodman@webrtc.org 1110eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.orgTEST_F(EndToEndTest, ReceiveStreamSendsRemb) { 1111eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org class RembObserver : public test::EndToEndTest { 11127ff4089bfcce71ba2a5d21d5adc0467782a914a0mflodman@webrtc.org public: 1113eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org RembObserver() : EndToEndTest(kDefaultTimeoutMs) {} 11147ff4089bfcce71ba2a5d21d5adc0467782a914a0mflodman@webrtc.org 11157ff4089bfcce71ba2a5d21d5adc0467782a914a0mflodman@webrtc.org virtual Action OnReceiveRtcp(const uint8_t* packet, 11167ff4089bfcce71ba2a5d21d5adc0467782a914a0mflodman@webrtc.org size_t length) OVERRIDE { 11177ff4089bfcce71ba2a5d21d5adc0467782a914a0mflodman@webrtc.org RTCPUtility::RTCPParserV2 parser(packet, length, true); 11187ff4089bfcce71ba2a5d21d5adc0467782a914a0mflodman@webrtc.org EXPECT_TRUE(parser.IsValid()); 11197ff4089bfcce71ba2a5d21d5adc0467782a914a0mflodman@webrtc.org 11207ff4089bfcce71ba2a5d21d5adc0467782a914a0mflodman@webrtc.org bool received_psfb = false; 11217ff4089bfcce71ba2a5d21d5adc0467782a914a0mflodman@webrtc.org bool received_remb = false; 11227ff4089bfcce71ba2a5d21d5adc0467782a914a0mflodman@webrtc.org RTCPUtility::RTCPPacketTypes packet_type = parser.Begin(); 11237ff4089bfcce71ba2a5d21d5adc0467782a914a0mflodman@webrtc.org while (packet_type != RTCPUtility::kRtcpNotValidCode) { 11247ff4089bfcce71ba2a5d21d5adc0467782a914a0mflodman@webrtc.org if (packet_type == RTCPUtility::kRtcpPsfbRembCode) { 11257ff4089bfcce71ba2a5d21d5adc0467782a914a0mflodman@webrtc.org const RTCPUtility::RTCPPacket& packet = parser.Packet(); 11267ff4089bfcce71ba2a5d21d5adc0467782a914a0mflodman@webrtc.org EXPECT_EQ(packet.PSFBAPP.SenderSSRC, kReceiverLocalSsrc); 11277ff4089bfcce71ba2a5d21d5adc0467782a914a0mflodman@webrtc.org received_psfb = true; 11287ff4089bfcce71ba2a5d21d5adc0467782a914a0mflodman@webrtc.org } else if (packet_type == RTCPUtility::kRtcpPsfbRembItemCode) { 11297ff4089bfcce71ba2a5d21d5adc0467782a914a0mflodman@webrtc.org const RTCPUtility::RTCPPacket& packet = parser.Packet(); 11307ff4089bfcce71ba2a5d21d5adc0467782a914a0mflodman@webrtc.org EXPECT_GT(packet.REMBItem.BitRate, 0u); 11317ff4089bfcce71ba2a5d21d5adc0467782a914a0mflodman@webrtc.org EXPECT_EQ(packet.REMBItem.NumberOfSSRCs, 1u); 1132eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org EXPECT_EQ(packet.REMBItem.SSRCs[0], kSendSsrcs[0]); 11337ff4089bfcce71ba2a5d21d5adc0467782a914a0mflodman@webrtc.org received_remb = true; 11347ff4089bfcce71ba2a5d21d5adc0467782a914a0mflodman@webrtc.org } 11357ff4089bfcce71ba2a5d21d5adc0467782a914a0mflodman@webrtc.org packet_type = parser.Iterate(); 11367ff4089bfcce71ba2a5d21d5adc0467782a914a0mflodman@webrtc.org } 11377ff4089bfcce71ba2a5d21d5adc0467782a914a0mflodman@webrtc.org if (received_psfb && received_remb) 11387ff4089bfcce71ba2a5d21d5adc0467782a914a0mflodman@webrtc.org observation_complete_->Set(); 11397ff4089bfcce71ba2a5d21d5adc0467782a914a0mflodman@webrtc.org return SEND_PACKET; 11407ff4089bfcce71ba2a5d21d5adc0467782a914a0mflodman@webrtc.org } 1141eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org virtual void PerformTest() OVERRIDE { 1142eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org EXPECT_EQ(kEventSignaled, Wait()) << "Timed out while waiting for a " 1143eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org "receiver RTCP REMB packet to be " 1144eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org "sent."; 1145eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org } 1146eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org } test; 11477ff4089bfcce71ba2a5d21d5adc0467782a914a0mflodman@webrtc.org 1148eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org RunBaseTest(&test); 11497ff4089bfcce71ba2a5d21d5adc0467782a914a0mflodman@webrtc.org} 1150b4263e09399b251e5cf306b2ade0d0f768d3cb61asapersson@webrtc.org 1151eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.orgvoid EndToEndTest::TestXrReceiverReferenceTimeReport(bool enable_rrtr) { 1152b4263e09399b251e5cf306b2ade0d0f768d3cb61asapersson@webrtc.org static const int kNumRtcpReportPacketsToObserve = 5; 1153eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org class RtcpXrObserver : public test::EndToEndTest { 1154b4263e09399b251e5cf306b2ade0d0f768d3cb61asapersson@webrtc.org public: 1155b4263e09399b251e5cf306b2ade0d0f768d3cb61asapersson@webrtc.org explicit RtcpXrObserver(bool enable_rrtr) 1156eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org : EndToEndTest(kDefaultTimeoutMs), 1157b4263e09399b251e5cf306b2ade0d0f768d3cb61asapersson@webrtc.org enable_rrtr_(enable_rrtr), 1158b4263e09399b251e5cf306b2ade0d0f768d3cb61asapersson@webrtc.org sent_rtcp_sr_(0), 1159b4263e09399b251e5cf306b2ade0d0f768d3cb61asapersson@webrtc.org sent_rtcp_rr_(0), 1160b4263e09399b251e5cf306b2ade0d0f768d3cb61asapersson@webrtc.org sent_rtcp_rrtr_(0), 1161b4263e09399b251e5cf306b2ade0d0f768d3cb61asapersson@webrtc.org sent_rtcp_dlrr_(0) {} 1162c71929dce136f9bc59fcc7ceb172cf74fc507ea9pbos@webrtc.org 1163b4263e09399b251e5cf306b2ade0d0f768d3cb61asapersson@webrtc.org private: 1164b4263e09399b251e5cf306b2ade0d0f768d3cb61asapersson@webrtc.org // Receive stream should send RR packets (and RRTR packets if enabled). 1165b4263e09399b251e5cf306b2ade0d0f768d3cb61asapersson@webrtc.org virtual Action OnReceiveRtcp(const uint8_t* packet, 1166b4263e09399b251e5cf306b2ade0d0f768d3cb61asapersson@webrtc.org size_t length) OVERRIDE { 1167b4263e09399b251e5cf306b2ade0d0f768d3cb61asapersson@webrtc.org RTCPUtility::RTCPParserV2 parser(packet, length, true); 1168b4263e09399b251e5cf306b2ade0d0f768d3cb61asapersson@webrtc.org EXPECT_TRUE(parser.IsValid()); 1169b4263e09399b251e5cf306b2ade0d0f768d3cb61asapersson@webrtc.org 1170b4263e09399b251e5cf306b2ade0d0f768d3cb61asapersson@webrtc.org RTCPUtility::RTCPPacketTypes packet_type = parser.Begin(); 1171b4263e09399b251e5cf306b2ade0d0f768d3cb61asapersson@webrtc.org while (packet_type != RTCPUtility::kRtcpNotValidCode) { 1172b4263e09399b251e5cf306b2ade0d0f768d3cb61asapersson@webrtc.org if (packet_type == RTCPUtility::kRtcpRrCode) { 1173b4263e09399b251e5cf306b2ade0d0f768d3cb61asapersson@webrtc.org ++sent_rtcp_rr_; 1174c71929dce136f9bc59fcc7ceb172cf74fc507ea9pbos@webrtc.org } else if (packet_type == 1175c71929dce136f9bc59fcc7ceb172cf74fc507ea9pbos@webrtc.org RTCPUtility::kRtcpXrReceiverReferenceTimeCode) { 1176b4263e09399b251e5cf306b2ade0d0f768d3cb61asapersson@webrtc.org ++sent_rtcp_rrtr_; 1177b4263e09399b251e5cf306b2ade0d0f768d3cb61asapersson@webrtc.org } 1178b4263e09399b251e5cf306b2ade0d0f768d3cb61asapersson@webrtc.org EXPECT_NE(packet_type, RTCPUtility::kRtcpSrCode); 1179b4263e09399b251e5cf306b2ade0d0f768d3cb61asapersson@webrtc.org EXPECT_NE(packet_type, RTCPUtility::kRtcpXrDlrrReportBlockItemCode); 1180b4263e09399b251e5cf306b2ade0d0f768d3cb61asapersson@webrtc.org packet_type = parser.Iterate(); 1181b4263e09399b251e5cf306b2ade0d0f768d3cb61asapersson@webrtc.org } 1182b4263e09399b251e5cf306b2ade0d0f768d3cb61asapersson@webrtc.org return SEND_PACKET; 1183b4263e09399b251e5cf306b2ade0d0f768d3cb61asapersson@webrtc.org } 1184b4263e09399b251e5cf306b2ade0d0f768d3cb61asapersson@webrtc.org // Send stream should send SR packets (and DLRR packets if enabled). 1185b4263e09399b251e5cf306b2ade0d0f768d3cb61asapersson@webrtc.org virtual Action OnSendRtcp(const uint8_t* packet, size_t length) { 1186b4263e09399b251e5cf306b2ade0d0f768d3cb61asapersson@webrtc.org RTCPUtility::RTCPParserV2 parser(packet, length, true); 1187b4263e09399b251e5cf306b2ade0d0f768d3cb61asapersson@webrtc.org EXPECT_TRUE(parser.IsValid()); 1188b4263e09399b251e5cf306b2ade0d0f768d3cb61asapersson@webrtc.org 1189b4263e09399b251e5cf306b2ade0d0f768d3cb61asapersson@webrtc.org RTCPUtility::RTCPPacketTypes packet_type = parser.Begin(); 1190b4263e09399b251e5cf306b2ade0d0f768d3cb61asapersson@webrtc.org while (packet_type != RTCPUtility::kRtcpNotValidCode) { 1191b4263e09399b251e5cf306b2ade0d0f768d3cb61asapersson@webrtc.org if (packet_type == RTCPUtility::kRtcpSrCode) { 1192b4263e09399b251e5cf306b2ade0d0f768d3cb61asapersson@webrtc.org ++sent_rtcp_sr_; 1193b4263e09399b251e5cf306b2ade0d0f768d3cb61asapersson@webrtc.org } else if (packet_type == RTCPUtility::kRtcpXrDlrrReportBlockItemCode) { 1194b4263e09399b251e5cf306b2ade0d0f768d3cb61asapersson@webrtc.org ++sent_rtcp_dlrr_; 1195b4263e09399b251e5cf306b2ade0d0f768d3cb61asapersson@webrtc.org } 1196b4263e09399b251e5cf306b2ade0d0f768d3cb61asapersson@webrtc.org EXPECT_NE(packet_type, RTCPUtility::kRtcpXrReceiverReferenceTimeCode); 1197b4263e09399b251e5cf306b2ade0d0f768d3cb61asapersson@webrtc.org packet_type = parser.Iterate(); 1198b4263e09399b251e5cf306b2ade0d0f768d3cb61asapersson@webrtc.org } 1199b4263e09399b251e5cf306b2ade0d0f768d3cb61asapersson@webrtc.org if (sent_rtcp_sr_ > kNumRtcpReportPacketsToObserve && 1200b4263e09399b251e5cf306b2ade0d0f768d3cb61asapersson@webrtc.org sent_rtcp_rr_ > kNumRtcpReportPacketsToObserve) { 1201b4263e09399b251e5cf306b2ade0d0f768d3cb61asapersson@webrtc.org if (enable_rrtr_) { 1202b4263e09399b251e5cf306b2ade0d0f768d3cb61asapersson@webrtc.org EXPECT_GT(sent_rtcp_rrtr_, 0); 1203b4263e09399b251e5cf306b2ade0d0f768d3cb61asapersson@webrtc.org EXPECT_GT(sent_rtcp_dlrr_, 0); 1204b4263e09399b251e5cf306b2ade0d0f768d3cb61asapersson@webrtc.org } else { 1205b4263e09399b251e5cf306b2ade0d0f768d3cb61asapersson@webrtc.org EXPECT_EQ(0, sent_rtcp_rrtr_); 1206b4263e09399b251e5cf306b2ade0d0f768d3cb61asapersson@webrtc.org EXPECT_EQ(0, sent_rtcp_dlrr_); 1207b4263e09399b251e5cf306b2ade0d0f768d3cb61asapersson@webrtc.org } 1208b4263e09399b251e5cf306b2ade0d0f768d3cb61asapersson@webrtc.org observation_complete_->Set(); 1209b4263e09399b251e5cf306b2ade0d0f768d3cb61asapersson@webrtc.org } 1210b4263e09399b251e5cf306b2ade0d0f768d3cb61asapersson@webrtc.org return SEND_PACKET; 1211b4263e09399b251e5cf306b2ade0d0f768d3cb61asapersson@webrtc.org } 1212eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org 1213eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org virtual void ModifyConfigs( 1214eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org VideoSendStream::Config* send_config, 121588b558febb8e8f42df6c7482efe76795c3fed399pbos@webrtc.org std::vector<VideoReceiveStream::Config>* receive_configs, 121658b5140b7535ae66c618cc64b0a955b8d47cc86cpbos@webrtc.org VideoEncoderConfig* encoder_config) OVERRIDE { 121788b558febb8e8f42df6c7482efe76795c3fed399pbos@webrtc.org (*receive_configs)[0].rtp.rtcp_mode = newapi::kRtcpReducedSize; 121888b558febb8e8f42df6c7482efe76795c3fed399pbos@webrtc.org (*receive_configs)[0].rtp.rtcp_xr.receiver_reference_time_report = 121988b558febb8e8f42df6c7482efe76795c3fed399pbos@webrtc.org enable_rrtr_; 1220eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org } 1221eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org 1222eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org virtual void PerformTest() OVERRIDE { 1223eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org EXPECT_EQ(kEventSignaled, Wait()) 1224eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org << "Timed out while waiting for RTCP SR/RR packets to be sent."; 1225eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org } 1226eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org 1227b4263e09399b251e5cf306b2ade0d0f768d3cb61asapersson@webrtc.org bool enable_rrtr_; 1228b4263e09399b251e5cf306b2ade0d0f768d3cb61asapersson@webrtc.org int sent_rtcp_sr_; 1229b4263e09399b251e5cf306b2ade0d0f768d3cb61asapersson@webrtc.org int sent_rtcp_rr_; 1230b4263e09399b251e5cf306b2ade0d0f768d3cb61asapersson@webrtc.org int sent_rtcp_rrtr_; 1231b4263e09399b251e5cf306b2ade0d0f768d3cb61asapersson@webrtc.org int sent_rtcp_dlrr_; 1232eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org } test(enable_rrtr); 1233b4263e09399b251e5cf306b2ade0d0f768d3cb61asapersson@webrtc.org 1234eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org RunBaseTest(&test); 1235b4263e09399b251e5cf306b2ade0d0f768d3cb61asapersson@webrtc.org} 1236b4263e09399b251e5cf306b2ade0d0f768d3cb61asapersson@webrtc.org 123788b558febb8e8f42df6c7482efe76795c3fed399pbos@webrtc.orgvoid EndToEndTest::TestSendsSetSsrcs(size_t num_ssrcs, 123888b558febb8e8f42df6c7482efe76795c3fed399pbos@webrtc.org bool send_single_ssrc_first) { 123988b558febb8e8f42df6c7482efe76795c3fed399pbos@webrtc.org class SendsSetSsrcs : public test::EndToEndTest { 124088b558febb8e8f42df6c7482efe76795c3fed399pbos@webrtc.org public: 124188b558febb8e8f42df6c7482efe76795c3fed399pbos@webrtc.org SendsSetSsrcs(const uint32_t* ssrcs, 124288b558febb8e8f42df6c7482efe76795c3fed399pbos@webrtc.org size_t num_ssrcs, 124388b558febb8e8f42df6c7482efe76795c3fed399pbos@webrtc.org bool send_single_ssrc_first) 124488b558febb8e8f42df6c7482efe76795c3fed399pbos@webrtc.org : EndToEndTest(kDefaultTimeoutMs), 124588b558febb8e8f42df6c7482efe76795c3fed399pbos@webrtc.org num_ssrcs_(num_ssrcs), 124688b558febb8e8f42df6c7482efe76795c3fed399pbos@webrtc.org send_single_ssrc_first_(send_single_ssrc_first), 124788b558febb8e8f42df6c7482efe76795c3fed399pbos@webrtc.org ssrcs_to_observe_(num_ssrcs), 124888b558febb8e8f42df6c7482efe76795c3fed399pbos@webrtc.org expect_single_ssrc_(send_single_ssrc_first) { 124988b558febb8e8f42df6c7482efe76795c3fed399pbos@webrtc.org for (size_t i = 0; i < num_ssrcs; ++i) 125088b558febb8e8f42df6c7482efe76795c3fed399pbos@webrtc.org valid_ssrcs_[ssrcs[i]] = true; 125188b558febb8e8f42df6c7482efe76795c3fed399pbos@webrtc.org } 125288b558febb8e8f42df6c7482efe76795c3fed399pbos@webrtc.org 125388b558febb8e8f42df6c7482efe76795c3fed399pbos@webrtc.org private: 125488b558febb8e8f42df6c7482efe76795c3fed399pbos@webrtc.org virtual Action OnSendRtp(const uint8_t* packet, size_t length) OVERRIDE { 125588b558febb8e8f42df6c7482efe76795c3fed399pbos@webrtc.org RTPHeader header; 12566aae61c2c693fa3425c73c420e7046e95486b592pbos@webrtc.org EXPECT_TRUE(parser_->Parse(packet, length, &header)); 125788b558febb8e8f42df6c7482efe76795c3fed399pbos@webrtc.org 125888b558febb8e8f42df6c7482efe76795c3fed399pbos@webrtc.org EXPECT_TRUE(valid_ssrcs_[header.ssrc]) 125988b558febb8e8f42df6c7482efe76795c3fed399pbos@webrtc.org << "Received unknown SSRC: " << header.ssrc; 126088b558febb8e8f42df6c7482efe76795c3fed399pbos@webrtc.org 126188b558febb8e8f42df6c7482efe76795c3fed399pbos@webrtc.org if (!valid_ssrcs_[header.ssrc]) 126288b558febb8e8f42df6c7482efe76795c3fed399pbos@webrtc.org observation_complete_->Set(); 126388b558febb8e8f42df6c7482efe76795c3fed399pbos@webrtc.org 126488b558febb8e8f42df6c7482efe76795c3fed399pbos@webrtc.org if (!is_observed_[header.ssrc]) { 126588b558febb8e8f42df6c7482efe76795c3fed399pbos@webrtc.org is_observed_[header.ssrc] = true; 126688b558febb8e8f42df6c7482efe76795c3fed399pbos@webrtc.org --ssrcs_to_observe_; 126788b558febb8e8f42df6c7482efe76795c3fed399pbos@webrtc.org if (expect_single_ssrc_) { 126888b558febb8e8f42df6c7482efe76795c3fed399pbos@webrtc.org expect_single_ssrc_ = false; 126988b558febb8e8f42df6c7482efe76795c3fed399pbos@webrtc.org observation_complete_->Set(); 127088b558febb8e8f42df6c7482efe76795c3fed399pbos@webrtc.org } 127188b558febb8e8f42df6c7482efe76795c3fed399pbos@webrtc.org } 127288b558febb8e8f42df6c7482efe76795c3fed399pbos@webrtc.org 127388b558febb8e8f42df6c7482efe76795c3fed399pbos@webrtc.org if (ssrcs_to_observe_ == 0) 127488b558febb8e8f42df6c7482efe76795c3fed399pbos@webrtc.org observation_complete_->Set(); 127588b558febb8e8f42df6c7482efe76795c3fed399pbos@webrtc.org 127688b558febb8e8f42df6c7482efe76795c3fed399pbos@webrtc.org return SEND_PACKET; 127788b558febb8e8f42df6c7482efe76795c3fed399pbos@webrtc.org } 127888b558febb8e8f42df6c7482efe76795c3fed399pbos@webrtc.org 127988b558febb8e8f42df6c7482efe76795c3fed399pbos@webrtc.org virtual size_t GetNumStreams() const OVERRIDE { return num_ssrcs_; } 128088b558febb8e8f42df6c7482efe76795c3fed399pbos@webrtc.org 128188b558febb8e8f42df6c7482efe76795c3fed399pbos@webrtc.org virtual void ModifyConfigs( 128288b558febb8e8f42df6c7482efe76795c3fed399pbos@webrtc.org VideoSendStream::Config* send_config, 128388b558febb8e8f42df6c7482efe76795c3fed399pbos@webrtc.org std::vector<VideoReceiveStream::Config>* receive_configs, 128458b5140b7535ae66c618cc64b0a955b8d47cc86cpbos@webrtc.org VideoEncoderConfig* encoder_config) OVERRIDE { 128588b558febb8e8f42df6c7482efe76795c3fed399pbos@webrtc.org if (num_ssrcs_ > 1) { 128688b558febb8e8f42df6c7482efe76795c3fed399pbos@webrtc.org // Set low simulcast bitrates to not have to wait for bandwidth ramp-up. 128758b5140b7535ae66c618cc64b0a955b8d47cc86cpbos@webrtc.org for (size_t i = 0; i < encoder_config->streams.size(); ++i) { 128858b5140b7535ae66c618cc64b0a955b8d47cc86cpbos@webrtc.org encoder_config->streams[i].min_bitrate_bps = 10000; 128958b5140b7535ae66c618cc64b0a955b8d47cc86cpbos@webrtc.org encoder_config->streams[i].target_bitrate_bps = 15000; 129058b5140b7535ae66c618cc64b0a955b8d47cc86cpbos@webrtc.org encoder_config->streams[i].max_bitrate_bps = 20000; 129188b558febb8e8f42df6c7482efe76795c3fed399pbos@webrtc.org } 129288b558febb8e8f42df6c7482efe76795c3fed399pbos@webrtc.org } 129388b558febb8e8f42df6c7482efe76795c3fed399pbos@webrtc.org 129458b5140b7535ae66c618cc64b0a955b8d47cc86cpbos@webrtc.org encoder_config_all_streams_ = *encoder_config; 129588b558febb8e8f42df6c7482efe76795c3fed399pbos@webrtc.org if (send_single_ssrc_first_) 129658b5140b7535ae66c618cc64b0a955b8d47cc86cpbos@webrtc.org encoder_config->streams.resize(1); 129788b558febb8e8f42df6c7482efe76795c3fed399pbos@webrtc.org } 129888b558febb8e8f42df6c7482efe76795c3fed399pbos@webrtc.org 129988b558febb8e8f42df6c7482efe76795c3fed399pbos@webrtc.org virtual void OnStreamsCreated( 130088b558febb8e8f42df6c7482efe76795c3fed399pbos@webrtc.org VideoSendStream* send_stream, 130188b558febb8e8f42df6c7482efe76795c3fed399pbos@webrtc.org const std::vector<VideoReceiveStream*>& receive_streams) OVERRIDE { 130288b558febb8e8f42df6c7482efe76795c3fed399pbos@webrtc.org send_stream_ = send_stream; 130388b558febb8e8f42df6c7482efe76795c3fed399pbos@webrtc.org } 130488b558febb8e8f42df6c7482efe76795c3fed399pbos@webrtc.org 130588b558febb8e8f42df6c7482efe76795c3fed399pbos@webrtc.org virtual void PerformTest() OVERRIDE { 130688b558febb8e8f42df6c7482efe76795c3fed399pbos@webrtc.org EXPECT_EQ(kEventSignaled, Wait()) 130788b558febb8e8f42df6c7482efe76795c3fed399pbos@webrtc.org << "Timed out while waiting for " 130888b558febb8e8f42df6c7482efe76795c3fed399pbos@webrtc.org << (send_single_ssrc_first_ ? "first SSRC." : "SSRCs."); 130988b558febb8e8f42df6c7482efe76795c3fed399pbos@webrtc.org 131088b558febb8e8f42df6c7482efe76795c3fed399pbos@webrtc.org if (send_single_ssrc_first_) { 131188b558febb8e8f42df6c7482efe76795c3fed399pbos@webrtc.org // Set full simulcast and continue with the rest of the SSRCs. 131258b5140b7535ae66c618cc64b0a955b8d47cc86cpbos@webrtc.org send_stream_->ReconfigureVideoEncoder(encoder_config_all_streams_); 131388b558febb8e8f42df6c7482efe76795c3fed399pbos@webrtc.org EXPECT_EQ(kEventSignaled, Wait()) 131488b558febb8e8f42df6c7482efe76795c3fed399pbos@webrtc.org << "Timed out while waiting on additional SSRCs."; 131588b558febb8e8f42df6c7482efe76795c3fed399pbos@webrtc.org } 131688b558febb8e8f42df6c7482efe76795c3fed399pbos@webrtc.org } 131788b558febb8e8f42df6c7482efe76795c3fed399pbos@webrtc.org 131888b558febb8e8f42df6c7482efe76795c3fed399pbos@webrtc.org private: 131988b558febb8e8f42df6c7482efe76795c3fed399pbos@webrtc.org std::map<uint32_t, bool> valid_ssrcs_; 132088b558febb8e8f42df6c7482efe76795c3fed399pbos@webrtc.org std::map<uint32_t, bool> is_observed_; 132188b558febb8e8f42df6c7482efe76795c3fed399pbos@webrtc.org 132288b558febb8e8f42df6c7482efe76795c3fed399pbos@webrtc.org const size_t num_ssrcs_; 132388b558febb8e8f42df6c7482efe76795c3fed399pbos@webrtc.org const bool send_single_ssrc_first_; 132488b558febb8e8f42df6c7482efe76795c3fed399pbos@webrtc.org 132588b558febb8e8f42df6c7482efe76795c3fed399pbos@webrtc.org size_t ssrcs_to_observe_; 132688b558febb8e8f42df6c7482efe76795c3fed399pbos@webrtc.org bool expect_single_ssrc_; 132788b558febb8e8f42df6c7482efe76795c3fed399pbos@webrtc.org 132888b558febb8e8f42df6c7482efe76795c3fed399pbos@webrtc.org VideoSendStream* send_stream_; 132958b5140b7535ae66c618cc64b0a955b8d47cc86cpbos@webrtc.org VideoEncoderConfig encoder_config_all_streams_; 133088b558febb8e8f42df6c7482efe76795c3fed399pbos@webrtc.org } test(kSendSsrcs, num_ssrcs, send_single_ssrc_first); 133188b558febb8e8f42df6c7482efe76795c3fed399pbos@webrtc.org 133288b558febb8e8f42df6c7482efe76795c3fed399pbos@webrtc.org RunBaseTest(&test); 133388b558febb8e8f42df6c7482efe76795c3fed399pbos@webrtc.org} 133488b558febb8e8f42df6c7482efe76795c3fed399pbos@webrtc.org 1335eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.orgTEST_F(EndToEndTest, GetStats) { 1336eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org class StatsObserver : public test::EndToEndTest, public I420FrameCallback { 1337eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org public: 1338eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org StatsObserver() 1339eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org : EndToEndTest(kLongTimeoutMs), 1340eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org receive_stream_(NULL), 1341eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org send_stream_(NULL), 1342eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org expected_receive_ssrc_(), 1343eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org expected_send_ssrcs_(), 1344eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org check_stats_event_(EventWrapper::Create()) {} 1345c8ab7215c005f95e375f6e07f2a08ab6c7431f51sprang@webrtc.org 1346eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org private: 1347eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org virtual Action OnSendRtp(const uint8_t* packet, size_t length) OVERRIDE { 1348eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org check_stats_event_->Set(); 1349eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org return SEND_PACKET; 1350c8ab7215c005f95e375f6e07f2a08ab6c7431f51sprang@webrtc.org } 1351c8ab7215c005f95e375f6e07f2a08ab6c7431f51sprang@webrtc.org 1352eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org virtual Action OnSendRtcp(const uint8_t* packet, size_t length) OVERRIDE { 1353eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org check_stats_event_->Set(); 1354eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org return SEND_PACKET; 1355c8ab7215c005f95e375f6e07f2a08ab6c7431f51sprang@webrtc.org } 1356c8ab7215c005f95e375f6e07f2a08ab6c7431f51sprang@webrtc.org 1357eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org virtual Action OnReceiveRtp(const uint8_t* packet, size_t length) OVERRIDE { 1358eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org check_stats_event_->Set(); 1359eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org return SEND_PACKET; 1360c8ab7215c005f95e375f6e07f2a08ab6c7431f51sprang@webrtc.org } 1361c8ab7215c005f95e375f6e07f2a08ab6c7431f51sprang@webrtc.org 1362eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org virtual Action OnReceiveRtcp(const uint8_t* packet, 1363eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org size_t length) OVERRIDE { 1364eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org check_stats_event_->Set(); 1365eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org return SEND_PACKET; 1366eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org } 1367c8ab7215c005f95e375f6e07f2a08ab6c7431f51sprang@webrtc.org 1368eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org virtual void FrameCallback(I420VideoFrame* video_frame) OVERRIDE { 1369eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org // Ensure that we have at least 5ms send side delay. 1370eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org int64_t render_time = video_frame->render_time_ms(); 1371eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org if (render_time > 0) 1372eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org video_frame->set_render_time_ms(render_time - 5); 1373eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org } 1374c8ab7215c005f95e375f6e07f2a08ab6c7431f51sprang@webrtc.org 1375eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org bool CheckReceiveStats() { 1376eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org assert(receive_stream_ != NULL); 1377eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org VideoReceiveStream::Stats stats = receive_stream_->GetStats(); 1378eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org EXPECT_EQ(expected_receive_ssrc_, stats.ssrc); 1379c8ab7215c005f95e375f6e07f2a08ab6c7431f51sprang@webrtc.org 1380eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org // Make sure all fields have been populated. 1381c8ab7215c005f95e375f6e07f2a08ab6c7431f51sprang@webrtc.org 1382eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org receive_stats_filled_["IncomingRate"] |= 1383eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org stats.network_frame_rate != 0 || stats.bitrate_bps != 0; 1384c8ab7215c005f95e375f6e07f2a08ab6c7431f51sprang@webrtc.org 1385eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org receive_stats_filled_["FrameCallback"] |= stats.decode_frame_rate != 0; 1386c8ab7215c005f95e375f6e07f2a08ab6c7431f51sprang@webrtc.org 1387eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org receive_stats_filled_["FrameRendered"] |= stats.render_frame_rate != 0; 1388c8ab7215c005f95e375f6e07f2a08ab6c7431f51sprang@webrtc.org 1389eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org receive_stats_filled_["StatisticsUpdated"] |= 1390eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org stats.rtcp_stats.cumulative_lost != 0 || 1391eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org stats.rtcp_stats.extended_max_sequence_number != 0 || 1392eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org stats.rtcp_stats.fraction_lost != 0 || stats.rtcp_stats.jitter != 0; 1393c8ab7215c005f95e375f6e07f2a08ab6c7431f51sprang@webrtc.org 1394eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org receive_stats_filled_["DataCountersUpdated"] |= 1395eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org stats.rtp_stats.bytes != 0 || stats.rtp_stats.fec_packets != 0 || 1396eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org stats.rtp_stats.header_bytes != 0 || stats.rtp_stats.packets != 0 || 1397eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org stats.rtp_stats.padding_bytes != 0 || 1398eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org stats.rtp_stats.retransmitted_packets != 0; 1399c8ab7215c005f95e375f6e07f2a08ab6c7431f51sprang@webrtc.org 1400eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org receive_stats_filled_["CodecStats"] |= 1401eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org stats.avg_delay_ms != 0 || stats.discarded_packets != 0 || 1402eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org stats.key_frames != 0 || stats.delta_frames != 0; 1403c8ab7215c005f95e375f6e07f2a08ab6c7431f51sprang@webrtc.org 1404eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org return AllStatsFilled(receive_stats_filled_); 1405eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org } 1406c8ab7215c005f95e375f6e07f2a08ab6c7431f51sprang@webrtc.org 1407eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org bool CheckSendStats() { 1408eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org assert(send_stream_ != NULL); 1409eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org VideoSendStream::Stats stats = send_stream_->GetStats(); 1410c8ab7215c005f95e375f6e07f2a08ab6c7431f51sprang@webrtc.org 1411eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org send_stats_filled_["NumStreams"] |= 1412eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org stats.substreams.size() == expected_send_ssrcs_.size(); 1413c8ab7215c005f95e375f6e07f2a08ab6c7431f51sprang@webrtc.org 1414eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org for (std::map<uint32_t, StreamStats>::const_iterator it = 1415eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org stats.substreams.begin(); 1416eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org it != stats.substreams.end(); 1417eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org ++it) { 1418eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org EXPECT_TRUE(expected_send_ssrcs_.find(it->first) != 1419eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org expected_send_ssrcs_.end()); 1420c8ab7215c005f95e375f6e07f2a08ab6c7431f51sprang@webrtc.org 1421eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org send_stats_filled_[CompoundKey("IncomingRate", it->first)] |= 1422eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org stats.input_frame_rate != 0; 1423c8ab7215c005f95e375f6e07f2a08ab6c7431f51sprang@webrtc.org 1424eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org const StreamStats& stream_stats = it->second; 1425c8ab7215c005f95e375f6e07f2a08ab6c7431f51sprang@webrtc.org 1426eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org send_stats_filled_[CompoundKey("StatisticsUpdated", it->first)] |= 1427eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org stream_stats.rtcp_stats.cumulative_lost != 0 || 1428eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org stream_stats.rtcp_stats.extended_max_sequence_number != 0 || 1429eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org stream_stats.rtcp_stats.fraction_lost != 0; 1430c8ab7215c005f95e375f6e07f2a08ab6c7431f51sprang@webrtc.org 1431eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org send_stats_filled_[CompoundKey("DataCountersUpdated", it->first)] |= 1432eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org stream_stats.rtp_stats.fec_packets != 0 || 1433eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org stream_stats.rtp_stats.padding_bytes != 0 || 1434eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org stream_stats.rtp_stats.retransmitted_packets != 0 || 1435eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org stream_stats.rtp_stats.packets != 0; 1436c8ab7215c005f95e375f6e07f2a08ab6c7431f51sprang@webrtc.org 1437eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org send_stats_filled_[CompoundKey("BitrateStatisticsObserver", 1438eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org it->first)] |= 1439eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org stream_stats.bitrate_bps != 0; 1440c8ab7215c005f95e375f6e07f2a08ab6c7431f51sprang@webrtc.org 1441eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org send_stats_filled_[CompoundKey("FrameCountObserver", it->first)] |= 1442eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org stream_stats.delta_frames != 0 || stream_stats.key_frames != 0; 1443c8ab7215c005f95e375f6e07f2a08ab6c7431f51sprang@webrtc.org 1444eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org send_stats_filled_[CompoundKey("OutgoingRate", it->first)] |= 1445eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org stats.encode_frame_rate != 0; 144655b0f2e500fac8fc0932ea5b60359d268371f8c5stefan@webrtc.org 144755b0f2e500fac8fc0932ea5b60359d268371f8c5stefan@webrtc.org send_stats_filled_[CompoundKey("Delay", it->first)] |= 144855b0f2e500fac8fc0932ea5b60359d268371f8c5stefan@webrtc.org stream_stats.avg_delay_ms != 0 || stream_stats.max_delay_ms != 0; 1449eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org } 1450c8ab7215c005f95e375f6e07f2a08ab6c7431f51sprang@webrtc.org 1451eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org return AllStatsFilled(send_stats_filled_); 1452c8ab7215c005f95e375f6e07f2a08ab6c7431f51sprang@webrtc.org } 1453c8ab7215c005f95e375f6e07f2a08ab6c7431f51sprang@webrtc.org 1454eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org std::string CompoundKey(const char* name, uint32_t ssrc) { 1455eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org std::ostringstream oss; 1456eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org oss << name << "_" << ssrc; 1457eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org return oss.str(); 1458eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org } 1459c8ab7215c005f95e375f6e07f2a08ab6c7431f51sprang@webrtc.org 1460eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org bool AllStatsFilled(const std::map<std::string, bool>& stats_map) { 1461eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org for (std::map<std::string, bool>::const_iterator it = stats_map.begin(); 1462eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org it != stats_map.end(); 1463eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org ++it) { 1464eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org if (!it->second) 1465eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org return false; 1466eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org } 1467eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org return true; 1468c8ab7215c005f95e375f6e07f2a08ab6c7431f51sprang@webrtc.org } 1469c8ab7215c005f95e375f6e07f2a08ab6c7431f51sprang@webrtc.org 1470eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org virtual void ModifyConfigs( 1471eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org VideoSendStream::Config* send_config, 147288b558febb8e8f42df6c7482efe76795c3fed399pbos@webrtc.org std::vector<VideoReceiveStream::Config>* receive_configs, 147358b5140b7535ae66c618cc64b0a955b8d47cc86cpbos@webrtc.org VideoEncoderConfig* encoder_config) OVERRIDE { 1474eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org send_config->pre_encode_callback = this; // Used to inject delay. 1475eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org send_config->rtp.c_name = "SomeCName"; 1476c8ab7215c005f95e375f6e07f2a08ab6c7431f51sprang@webrtc.org 147788b558febb8e8f42df6c7482efe76795c3fed399pbos@webrtc.org expected_receive_ssrc_ = (*receive_configs)[0].rtp.local_ssrc; 1478eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org const std::vector<uint32_t>& ssrcs = send_config->rtp.ssrcs; 1479eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org for (size_t i = 0; i < ssrcs.size(); ++i) 1480eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org expected_send_ssrcs_.insert(ssrcs[i]); 1481c8ab7215c005f95e375f6e07f2a08ab6c7431f51sprang@webrtc.org 1482eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org expected_cname_ = send_config->rtp.c_name; 1483eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org } 1484c8ab7215c005f95e375f6e07f2a08ab6c7431f51sprang@webrtc.org 148588b558febb8e8f42df6c7482efe76795c3fed399pbos@webrtc.org virtual void OnStreamsCreated( 148688b558febb8e8f42df6c7482efe76795c3fed399pbos@webrtc.org VideoSendStream* send_stream, 148788b558febb8e8f42df6c7482efe76795c3fed399pbos@webrtc.org const std::vector<VideoReceiveStream*>& receive_streams) OVERRIDE { 1488eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org send_stream_ = send_stream; 148988b558febb8e8f42df6c7482efe76795c3fed399pbos@webrtc.org receive_stream_ = receive_streams[0]; 1490eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org } 1491c8ab7215c005f95e375f6e07f2a08ab6c7431f51sprang@webrtc.org 1492eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org virtual void PerformTest() OVERRIDE { 1493eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org Clock* clock = Clock::GetRealTimeClock(); 1494eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org int64_t now = clock->TimeInMilliseconds(); 1495eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org int64_t stop_time = now + test::CallTest::kLongTimeoutMs; 1496eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org bool receive_ok = false; 1497eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org bool send_ok = false; 1498eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org 1499eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org while (now < stop_time) { 1500eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org if (!receive_ok) 1501eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org receive_ok = CheckReceiveStats(); 1502eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org if (!send_ok) 1503eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org send_ok = CheckSendStats(); 1504eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org 1505eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org if (receive_ok && send_ok) 1506eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org return; 1507eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org 1508eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org int64_t time_until_timout_ = stop_time - now; 1509eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org if (time_until_timout_ > 0) 1510eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org check_stats_event_->Wait(time_until_timout_); 1511eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org now = clock->TimeInMilliseconds(); 1512eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org } 1513c8ab7215c005f95e375f6e07f2a08ab6c7431f51sprang@webrtc.org 1514eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org ADD_FAILURE() << "Timed out waiting for filled stats."; 1515eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org for (std::map<std::string, bool>::const_iterator it = 1516eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org receive_stats_filled_.begin(); 1517eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org it != receive_stats_filled_.end(); 1518eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org ++it) { 1519eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org if (!it->second) { 1520eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org ADD_FAILURE() << "Missing receive stats: " << it->first; 1521eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org } 1522eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org } 1523c8ab7215c005f95e375f6e07f2a08ab6c7431f51sprang@webrtc.org 1524eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org for (std::map<std::string, bool>::const_iterator it = 1525eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org send_stats_filled_.begin(); 1526eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org it != send_stats_filled_.end(); 1527eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org ++it) { 1528eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org if (!it->second) { 1529eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org ADD_FAILURE() << "Missing send stats: " << it->first; 1530eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org } 1531eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org } 1532eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org } 1533c8ab7215c005f95e375f6e07f2a08ab6c7431f51sprang@webrtc.org 1534eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org VideoReceiveStream* receive_stream_; 1535eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org std::map<std::string, bool> receive_stats_filled_; 1536c8ab7215c005f95e375f6e07f2a08ab6c7431f51sprang@webrtc.org 1537eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org VideoSendStream* send_stream_; 1538eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org std::map<std::string, bool> send_stats_filled_; 1539c8ab7215c005f95e375f6e07f2a08ab6c7431f51sprang@webrtc.org 1540eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org uint32_t expected_receive_ssrc_; 1541eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org std::set<uint32_t> expected_send_ssrcs_; 1542eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org std::string expected_cname_; 1543c8ab7215c005f95e375f6e07f2a08ab6c7431f51sprang@webrtc.org 1544eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org scoped_ptr<EventWrapper> check_stats_event_; 1545eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org } test; 1546c8ab7215c005f95e375f6e07f2a08ab6c7431f51sprang@webrtc.org 1547eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org RunBaseTest(&test); 1548c8ab7215c005f95e375f6e07f2a08ab6c7431f51sprang@webrtc.org} 1549c8ab7215c005f95e375f6e07f2a08ab6c7431f51sprang@webrtc.org 1550eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.orgTEST_F(EndToEndTest, ReceiverReferenceTimeReportEnabled) { 1551b4263e09399b251e5cf306b2ade0d0f768d3cb61asapersson@webrtc.org TestXrReceiverReferenceTimeReport(true); 1552b4263e09399b251e5cf306b2ade0d0f768d3cb61asapersson@webrtc.org} 1553b4263e09399b251e5cf306b2ade0d0f768d3cb61asapersson@webrtc.org 1554eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.orgTEST_F(EndToEndTest, ReceiverReferenceTimeReportDisabled) { 1555b4263e09399b251e5cf306b2ade0d0f768d3cb61asapersson@webrtc.org TestXrReceiverReferenceTimeReport(false); 1556b4263e09399b251e5cf306b2ade0d0f768d3cb61asapersson@webrtc.org} 15573f83f9cae99b605aee71b46839e902653baeb3f6pbos@webrtc.org 1558eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.orgTEST_F(EndToEndTest, TestReceivedRtpPacketStats) { 155999153baa13d2a844373be5fa45eeb5be492b3445asapersson@webrtc.org static const size_t kNumRtpPacketsToSend = 5; 1560eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org class ReceivedRtpStatsObserver : public test::EndToEndTest { 156199153baa13d2a844373be5fa45eeb5be492b3445asapersson@webrtc.org public: 156299153baa13d2a844373be5fa45eeb5be492b3445asapersson@webrtc.org ReceivedRtpStatsObserver() 1563eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org : EndToEndTest(kDefaultTimeoutMs), 156499153baa13d2a844373be5fa45eeb5be492b3445asapersson@webrtc.org receive_stream_(NULL), 156599153baa13d2a844373be5fa45eeb5be492b3445asapersson@webrtc.org sent_rtp_(0) {} 156699153baa13d2a844373be5fa45eeb5be492b3445asapersson@webrtc.org 1567eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org private: 156888b558febb8e8f42df6c7482efe76795c3fed399pbos@webrtc.org virtual void OnStreamsCreated( 156988b558febb8e8f42df6c7482efe76795c3fed399pbos@webrtc.org VideoSendStream* send_stream, 157088b558febb8e8f42df6c7482efe76795c3fed399pbos@webrtc.org const std::vector<VideoReceiveStream*>& receive_streams) OVERRIDE { 157188b558febb8e8f42df6c7482efe76795c3fed399pbos@webrtc.org receive_stream_ = receive_streams[0]; 157299153baa13d2a844373be5fa45eeb5be492b3445asapersson@webrtc.org } 157399153baa13d2a844373be5fa45eeb5be492b3445asapersson@webrtc.org 157499153baa13d2a844373be5fa45eeb5be492b3445asapersson@webrtc.org virtual Action OnSendRtp(const uint8_t* packet, size_t length) OVERRIDE { 157599153baa13d2a844373be5fa45eeb5be492b3445asapersson@webrtc.org if (sent_rtp_ >= kNumRtpPacketsToSend) { 157699153baa13d2a844373be5fa45eeb5be492b3445asapersson@webrtc.org VideoReceiveStream::Stats stats = receive_stream_->GetStats(); 157799153baa13d2a844373be5fa45eeb5be492b3445asapersson@webrtc.org if (kNumRtpPacketsToSend == stats.rtp_stats.packets) { 157899153baa13d2a844373be5fa45eeb5be492b3445asapersson@webrtc.org observation_complete_->Set(); 157999153baa13d2a844373be5fa45eeb5be492b3445asapersson@webrtc.org } 158099153baa13d2a844373be5fa45eeb5be492b3445asapersson@webrtc.org return DROP_PACKET; 158199153baa13d2a844373be5fa45eeb5be492b3445asapersson@webrtc.org } 158299153baa13d2a844373be5fa45eeb5be492b3445asapersson@webrtc.org ++sent_rtp_; 158399153baa13d2a844373be5fa45eeb5be492b3445asapersson@webrtc.org return SEND_PACKET; 158499153baa13d2a844373be5fa45eeb5be492b3445asapersson@webrtc.org } 158599153baa13d2a844373be5fa45eeb5be492b3445asapersson@webrtc.org 1586eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org virtual void PerformTest() OVERRIDE { 1587eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org EXPECT_EQ(kEventSignaled, Wait()) 1588eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org << "Timed out while verifying number of received RTP packets."; 1589eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org } 1590eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org 159199153baa13d2a844373be5fa45eeb5be492b3445asapersson@webrtc.org VideoReceiveStream* receive_stream_; 159299153baa13d2a844373be5fa45eeb5be492b3445asapersson@webrtc.org uint32_t sent_rtp_; 1593eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org } test; 159499153baa13d2a844373be5fa45eeb5be492b3445asapersson@webrtc.org 1595eb67a6be101fe1ac8f2a4c062dbe6250f2e36bc0pbos@webrtc.org RunBaseTest(&test); 159699153baa13d2a844373be5fa45eeb5be492b3445asapersson@webrtc.org} 159799153baa13d2a844373be5fa45eeb5be492b3445asapersson@webrtc.org 159888b558febb8e8f42df6c7482efe76795c3fed399pbos@webrtc.orgTEST_F(EndToEndTest, SendsSetSsrc) { TestSendsSetSsrcs(1, false); } 159988b558febb8e8f42df6c7482efe76795c3fed399pbos@webrtc.org 160088b558febb8e8f42df6c7482efe76795c3fed399pbos@webrtc.orgTEST_F(EndToEndTest, SendsSetSimulcastSsrcs) { 160188b558febb8e8f42df6c7482efe76795c3fed399pbos@webrtc.org TestSendsSetSsrcs(kNumSsrcs, false); 160288b558febb8e8f42df6c7482efe76795c3fed399pbos@webrtc.org} 160388b558febb8e8f42df6c7482efe76795c3fed399pbos@webrtc.org 160488b558febb8e8f42df6c7482efe76795c3fed399pbos@webrtc.orgTEST_F(EndToEndTest, CanSwitchToUseAllSsrcs) { 160588b558febb8e8f42df6c7482efe76795c3fed399pbos@webrtc.org TestSendsSetSsrcs(kNumSsrcs, true); 160688b558febb8e8f42df6c7482efe76795c3fed399pbos@webrtc.org} 160788b558febb8e8f42df6c7482efe76795c3fed399pbos@webrtc.org 16084a1b3e3a69d349b0d3e91f607f24e02d8b975688mflodman@webrtc.orgTEST_F(EndToEndTest, DISABLED_RedundantPayloadsTransmittedOnAllSsrcs) { 160965afbf3e1da598f94f47eb0c11fe2b668e4f30f4pbos@webrtc.org class ObserveRedundantPayloads: public test::EndToEndTest { 161065afbf3e1da598f94f47eb0c11fe2b668e4f30f4pbos@webrtc.org public: 161165afbf3e1da598f94f47eb0c11fe2b668e4f30f4pbos@webrtc.org ObserveRedundantPayloads() 161265afbf3e1da598f94f47eb0c11fe2b668e4f30f4pbos@webrtc.org : EndToEndTest(kDefaultTimeoutMs), ssrcs_to_observe_(kNumSsrcs) { 16136c0337de402c181603ef7d499b2102ccb260ca80pbos@webrtc.org for (size_t i = 0; i < kNumSsrcs; ++i) { 161465afbf3e1da598f94f47eb0c11fe2b668e4f30f4pbos@webrtc.org registered_rtx_ssrc_[kSendRtxSsrcs[i]] = true; 161565afbf3e1da598f94f47eb0c11fe2b668e4f30f4pbos@webrtc.org } 161665afbf3e1da598f94f47eb0c11fe2b668e4f30f4pbos@webrtc.org } 161765afbf3e1da598f94f47eb0c11fe2b668e4f30f4pbos@webrtc.org 161865afbf3e1da598f94f47eb0c11fe2b668e4f30f4pbos@webrtc.org private: 161965afbf3e1da598f94f47eb0c11fe2b668e4f30f4pbos@webrtc.org virtual Action OnSendRtp(const uint8_t* packet, size_t length) OVERRIDE { 162065afbf3e1da598f94f47eb0c11fe2b668e4f30f4pbos@webrtc.org RTPHeader header; 16216aae61c2c693fa3425c73c420e7046e95486b592pbos@webrtc.org EXPECT_TRUE(parser_->Parse(packet, length, &header)); 162265afbf3e1da598f94f47eb0c11fe2b668e4f30f4pbos@webrtc.org 162365afbf3e1da598f94f47eb0c11fe2b668e4f30f4pbos@webrtc.org if (!registered_rtx_ssrc_[header.ssrc]) 162465afbf3e1da598f94f47eb0c11fe2b668e4f30f4pbos@webrtc.org return SEND_PACKET; 162565afbf3e1da598f94f47eb0c11fe2b668e4f30f4pbos@webrtc.org 162665afbf3e1da598f94f47eb0c11fe2b668e4f30f4pbos@webrtc.org EXPECT_LE(static_cast<size_t>(header.headerLength + header.paddingLength), 162765afbf3e1da598f94f47eb0c11fe2b668e4f30f4pbos@webrtc.org length); 162865afbf3e1da598f94f47eb0c11fe2b668e4f30f4pbos@webrtc.org const bool packet_is_redundant_payload = 162965afbf3e1da598f94f47eb0c11fe2b668e4f30f4pbos@webrtc.org static_cast<size_t>(header.headerLength + header.paddingLength) < 163065afbf3e1da598f94f47eb0c11fe2b668e4f30f4pbos@webrtc.org length; 163165afbf3e1da598f94f47eb0c11fe2b668e4f30f4pbos@webrtc.org 163265afbf3e1da598f94f47eb0c11fe2b668e4f30f4pbos@webrtc.org if (!packet_is_redundant_payload) 163365afbf3e1da598f94f47eb0c11fe2b668e4f30f4pbos@webrtc.org return SEND_PACKET; 163465afbf3e1da598f94f47eb0c11fe2b668e4f30f4pbos@webrtc.org 163565afbf3e1da598f94f47eb0c11fe2b668e4f30f4pbos@webrtc.org if (!observed_redundant_retransmission_[header.ssrc]) { 163665afbf3e1da598f94f47eb0c11fe2b668e4f30f4pbos@webrtc.org observed_redundant_retransmission_[header.ssrc] = true; 163765afbf3e1da598f94f47eb0c11fe2b668e4f30f4pbos@webrtc.org if (--ssrcs_to_observe_ == 0) 163865afbf3e1da598f94f47eb0c11fe2b668e4f30f4pbos@webrtc.org observation_complete_->Set(); 163965afbf3e1da598f94f47eb0c11fe2b668e4f30f4pbos@webrtc.org } 164065afbf3e1da598f94f47eb0c11fe2b668e4f30f4pbos@webrtc.org 164165afbf3e1da598f94f47eb0c11fe2b668e4f30f4pbos@webrtc.org return SEND_PACKET; 164265afbf3e1da598f94f47eb0c11fe2b668e4f30f4pbos@webrtc.org } 164365afbf3e1da598f94f47eb0c11fe2b668e4f30f4pbos@webrtc.org 164465afbf3e1da598f94f47eb0c11fe2b668e4f30f4pbos@webrtc.org virtual size_t GetNumStreams() const OVERRIDE { return kNumSsrcs; } 164565afbf3e1da598f94f47eb0c11fe2b668e4f30f4pbos@webrtc.org 164665afbf3e1da598f94f47eb0c11fe2b668e4f30f4pbos@webrtc.org virtual void ModifyConfigs( 164765afbf3e1da598f94f47eb0c11fe2b668e4f30f4pbos@webrtc.org VideoSendStream::Config* send_config, 164865afbf3e1da598f94f47eb0c11fe2b668e4f30f4pbos@webrtc.org std::vector<VideoReceiveStream::Config>* receive_configs, 164958b5140b7535ae66c618cc64b0a955b8d47cc86cpbos@webrtc.org VideoEncoderConfig* encoder_config) OVERRIDE { 165065afbf3e1da598f94f47eb0c11fe2b668e4f30f4pbos@webrtc.org // Set low simulcast bitrates to not have to wait for bandwidth ramp-up. 165158b5140b7535ae66c618cc64b0a955b8d47cc86cpbos@webrtc.org for (size_t i = 0; i < encoder_config->streams.size(); ++i) { 165258b5140b7535ae66c618cc64b0a955b8d47cc86cpbos@webrtc.org encoder_config->streams[i].min_bitrate_bps = 10000; 165358b5140b7535ae66c618cc64b0a955b8d47cc86cpbos@webrtc.org encoder_config->streams[i].target_bitrate_bps = 15000; 165458b5140b7535ae66c618cc64b0a955b8d47cc86cpbos@webrtc.org encoder_config->streams[i].max_bitrate_bps = 20000; 165565afbf3e1da598f94f47eb0c11fe2b668e4f30f4pbos@webrtc.org } 165665afbf3e1da598f94f47eb0c11fe2b668e4f30f4pbos@webrtc.org // Significantly higher than max bitrates for all video streams -> forcing 165765afbf3e1da598f94f47eb0c11fe2b668e4f30f4pbos@webrtc.org // padding to trigger redundant padding on all RTX SSRCs. 165865afbf3e1da598f94f47eb0c11fe2b668e4f30f4pbos@webrtc.org send_config->rtp.min_transmit_bitrate_bps = 100000; 165965afbf3e1da598f94f47eb0c11fe2b668e4f30f4pbos@webrtc.org 166065afbf3e1da598f94f47eb0c11fe2b668e4f30f4pbos@webrtc.org send_config->rtp.rtx.payload_type = kSendRtxPayloadType; 166165afbf3e1da598f94f47eb0c11fe2b668e4f30f4pbos@webrtc.org send_config->rtp.rtx.pad_with_redundant_payloads = true; 166265afbf3e1da598f94f47eb0c11fe2b668e4f30f4pbos@webrtc.org 166365afbf3e1da598f94f47eb0c11fe2b668e4f30f4pbos@webrtc.org for (size_t i = 0; i < kNumSsrcs; ++i) 166465afbf3e1da598f94f47eb0c11fe2b668e4f30f4pbos@webrtc.org send_config->rtp.rtx.ssrcs.push_back(kSendRtxSsrcs[i]); 166565afbf3e1da598f94f47eb0c11fe2b668e4f30f4pbos@webrtc.org } 166665afbf3e1da598f94f47eb0c11fe2b668e4f30f4pbos@webrtc.org 166765afbf3e1da598f94f47eb0c11fe2b668e4f30f4pbos@webrtc.org virtual void PerformTest() OVERRIDE { 166865afbf3e1da598f94f47eb0c11fe2b668e4f30f4pbos@webrtc.org EXPECT_EQ(kEventSignaled, Wait()) 166965afbf3e1da598f94f47eb0c11fe2b668e4f30f4pbos@webrtc.org << "Timed out while waiting for redundant payloads on all SSRCs."; 167065afbf3e1da598f94f47eb0c11fe2b668e4f30f4pbos@webrtc.org } 167165afbf3e1da598f94f47eb0c11fe2b668e4f30f4pbos@webrtc.org 167265afbf3e1da598f94f47eb0c11fe2b668e4f30f4pbos@webrtc.org private: 167365afbf3e1da598f94f47eb0c11fe2b668e4f30f4pbos@webrtc.org size_t ssrcs_to_observe_; 167465afbf3e1da598f94f47eb0c11fe2b668e4f30f4pbos@webrtc.org std::map<uint32_t, bool> observed_redundant_retransmission_; 167565afbf3e1da598f94f47eb0c11fe2b668e4f30f4pbos@webrtc.org std::map<uint32_t, bool> registered_rtx_ssrc_; 167665afbf3e1da598f94f47eb0c11fe2b668e4f30f4pbos@webrtc.org } test; 167765afbf3e1da598f94f47eb0c11fe2b668e4f30f4pbos@webrtc.org 167865afbf3e1da598f94f47eb0c11fe2b668e4f30f4pbos@webrtc.org RunBaseTest(&test); 167965afbf3e1da598f94f47eb0c11fe2b668e4f30f4pbos@webrtc.org} 168065afbf3e1da598f94f47eb0c11fe2b668e4f30f4pbos@webrtc.org 16812fd91bd35094b909b4b3cce636454426fc893ac2pbos@webrtc.orgvoid EndToEndTest::TestRtpStatePreservation(bool use_rtx) { 16822fd91bd35094b909b4b3cce636454426fc893ac2pbos@webrtc.org static const uint32_t kMaxSequenceNumberGap = 100; 16832fd91bd35094b909b4b3cce636454426fc893ac2pbos@webrtc.org static const uint64_t kMaxTimestampGap = kDefaultTimeoutMs * 90; 16842fd91bd35094b909b4b3cce636454426fc893ac2pbos@webrtc.org class RtpSequenceObserver : public test::RtpRtcpObserver { 16852fd91bd35094b909b4b3cce636454426fc893ac2pbos@webrtc.org public: 16866c0337de402c181603ef7d499b2102ccb260ca80pbos@webrtc.org explicit RtpSequenceObserver(bool use_rtx) 16872fd91bd35094b909b4b3cce636454426fc893ac2pbos@webrtc.org : test::RtpRtcpObserver(kDefaultTimeoutMs), 16882fd91bd35094b909b4b3cce636454426fc893ac2pbos@webrtc.org crit_(CriticalSectionWrapper::CreateCriticalSection()), 16892fd91bd35094b909b4b3cce636454426fc893ac2pbos@webrtc.org ssrcs_to_observe_(kNumSsrcs) { 16902fd91bd35094b909b4b3cce636454426fc893ac2pbos@webrtc.org for (size_t i = 0; i < kNumSsrcs; ++i) { 16912fd91bd35094b909b4b3cce636454426fc893ac2pbos@webrtc.org configured_ssrcs_[kSendSsrcs[i]] = true; 16922fd91bd35094b909b4b3cce636454426fc893ac2pbos@webrtc.org if (use_rtx) 16932fd91bd35094b909b4b3cce636454426fc893ac2pbos@webrtc.org configured_ssrcs_[kSendRtxSsrcs[i]] = true; 16942fd91bd35094b909b4b3cce636454426fc893ac2pbos@webrtc.org } 16952fd91bd35094b909b4b3cce636454426fc893ac2pbos@webrtc.org } 16962fd91bd35094b909b4b3cce636454426fc893ac2pbos@webrtc.org 16972fd91bd35094b909b4b3cce636454426fc893ac2pbos@webrtc.org void ResetExpectedSsrcs(size_t num_expected_ssrcs) { 16982fd91bd35094b909b4b3cce636454426fc893ac2pbos@webrtc.org CriticalSectionScoped lock(crit_.get()); 16992fd91bd35094b909b4b3cce636454426fc893ac2pbos@webrtc.org ssrc_observed_.clear(); 17002fd91bd35094b909b4b3cce636454426fc893ac2pbos@webrtc.org ssrcs_to_observe_ = num_expected_ssrcs; 17012fd91bd35094b909b4b3cce636454426fc893ac2pbos@webrtc.org } 17022fd91bd35094b909b4b3cce636454426fc893ac2pbos@webrtc.org 17032fd91bd35094b909b4b3cce636454426fc893ac2pbos@webrtc.org private: 17042fd91bd35094b909b4b3cce636454426fc893ac2pbos@webrtc.org virtual Action OnSendRtp(const uint8_t* packet, size_t length) OVERRIDE { 17052fd91bd35094b909b4b3cce636454426fc893ac2pbos@webrtc.org RTPHeader header; 17066aae61c2c693fa3425c73c420e7046e95486b592pbos@webrtc.org EXPECT_TRUE(parser_->Parse(packet, length, &header)); 17072fd91bd35094b909b4b3cce636454426fc893ac2pbos@webrtc.org const uint32_t ssrc = header.ssrc; 17082fd91bd35094b909b4b3cce636454426fc893ac2pbos@webrtc.org const uint16_t sequence_number = header.sequenceNumber; 17092fd91bd35094b909b4b3cce636454426fc893ac2pbos@webrtc.org const uint32_t timestamp = header.timestamp; 17102fd91bd35094b909b4b3cce636454426fc893ac2pbos@webrtc.org const bool only_padding = 17112fd91bd35094b909b4b3cce636454426fc893ac2pbos@webrtc.org static_cast<size_t>(header.headerLength + header.paddingLength) == 17122fd91bd35094b909b4b3cce636454426fc893ac2pbos@webrtc.org length; 17132fd91bd35094b909b4b3cce636454426fc893ac2pbos@webrtc.org 17142fd91bd35094b909b4b3cce636454426fc893ac2pbos@webrtc.org EXPECT_TRUE(configured_ssrcs_[ssrc]) 17152fd91bd35094b909b4b3cce636454426fc893ac2pbos@webrtc.org << "Received SSRC that wasn't configured: " << ssrc; 17162fd91bd35094b909b4b3cce636454426fc893ac2pbos@webrtc.org 17172fd91bd35094b909b4b3cce636454426fc893ac2pbos@webrtc.org std::map<uint32_t, uint16_t>::iterator it = 17182fd91bd35094b909b4b3cce636454426fc893ac2pbos@webrtc.org last_observed_sequence_number_.find(header.ssrc); 17192fd91bd35094b909b4b3cce636454426fc893ac2pbos@webrtc.org if (it == last_observed_sequence_number_.end()) { 17202fd91bd35094b909b4b3cce636454426fc893ac2pbos@webrtc.org last_observed_sequence_number_[ssrc] = sequence_number; 17212fd91bd35094b909b4b3cce636454426fc893ac2pbos@webrtc.org last_observed_timestamp_[ssrc] = timestamp; 17222fd91bd35094b909b4b3cce636454426fc893ac2pbos@webrtc.org } else { 17232fd91bd35094b909b4b3cce636454426fc893ac2pbos@webrtc.org // Verify sequence numbers are reasonably close. 17242fd91bd35094b909b4b3cce636454426fc893ac2pbos@webrtc.org uint32_t extended_sequence_number = sequence_number; 17252fd91bd35094b909b4b3cce636454426fc893ac2pbos@webrtc.org // Check for roll-over. 17262fd91bd35094b909b4b3cce636454426fc893ac2pbos@webrtc.org if (sequence_number < last_observed_sequence_number_[ssrc]) 17272fd91bd35094b909b4b3cce636454426fc893ac2pbos@webrtc.org extended_sequence_number += 0xFFFFu + 1; 17282fd91bd35094b909b4b3cce636454426fc893ac2pbos@webrtc.org EXPECT_LE( 17292fd91bd35094b909b4b3cce636454426fc893ac2pbos@webrtc.org extended_sequence_number - last_observed_sequence_number_[ssrc], 17302fd91bd35094b909b4b3cce636454426fc893ac2pbos@webrtc.org kMaxSequenceNumberGap) 17312fd91bd35094b909b4b3cce636454426fc893ac2pbos@webrtc.org << "Gap in sequence numbers (" 17322fd91bd35094b909b4b3cce636454426fc893ac2pbos@webrtc.org << last_observed_sequence_number_[ssrc] << " -> " << sequence_number 17332fd91bd35094b909b4b3cce636454426fc893ac2pbos@webrtc.org << ") too large for SSRC: " << ssrc << "."; 17342fd91bd35094b909b4b3cce636454426fc893ac2pbos@webrtc.org last_observed_sequence_number_[ssrc] = sequence_number; 17352fd91bd35094b909b4b3cce636454426fc893ac2pbos@webrtc.org 17362fd91bd35094b909b4b3cce636454426fc893ac2pbos@webrtc.org // TODO(pbos): Remove this check if we ever have monotonically 17372fd91bd35094b909b4b3cce636454426fc893ac2pbos@webrtc.org // increasing timestamps. Right now padding packets add a delta which 17382fd91bd35094b909b4b3cce636454426fc893ac2pbos@webrtc.org // can cause reordering between padding packets and regular packets, 17392fd91bd35094b909b4b3cce636454426fc893ac2pbos@webrtc.org // hence we drop padding-only packets to not flake. 17402fd91bd35094b909b4b3cce636454426fc893ac2pbos@webrtc.org if (only_padding) { 17412fd91bd35094b909b4b3cce636454426fc893ac2pbos@webrtc.org // Verify that timestamps are reasonably close. 17422fd91bd35094b909b4b3cce636454426fc893ac2pbos@webrtc.org uint64_t extended_timestamp = timestamp; 17432fd91bd35094b909b4b3cce636454426fc893ac2pbos@webrtc.org // Check for roll-over. 17442fd91bd35094b909b4b3cce636454426fc893ac2pbos@webrtc.org if (timestamp < last_observed_timestamp_[ssrc]) 17452fd91bd35094b909b4b3cce636454426fc893ac2pbos@webrtc.org extended_timestamp += static_cast<uint64_t>(0xFFFFFFFFu) + 1; 17462fd91bd35094b909b4b3cce636454426fc893ac2pbos@webrtc.org EXPECT_LE(extended_timestamp - last_observed_timestamp_[ssrc], 17472fd91bd35094b909b4b3cce636454426fc893ac2pbos@webrtc.org kMaxTimestampGap) 17482fd91bd35094b909b4b3cce636454426fc893ac2pbos@webrtc.org << "Gap in timestamps (" << last_observed_timestamp_[ssrc] 17492fd91bd35094b909b4b3cce636454426fc893ac2pbos@webrtc.org << " -> " << timestamp << ") too large for SSRC: " << ssrc << "."; 17502fd91bd35094b909b4b3cce636454426fc893ac2pbos@webrtc.org } 17512fd91bd35094b909b4b3cce636454426fc893ac2pbos@webrtc.org last_observed_timestamp_[ssrc] = timestamp; 17522fd91bd35094b909b4b3cce636454426fc893ac2pbos@webrtc.org } 17532fd91bd35094b909b4b3cce636454426fc893ac2pbos@webrtc.org 17542fd91bd35094b909b4b3cce636454426fc893ac2pbos@webrtc.org CriticalSectionScoped lock(crit_.get()); 17552fd91bd35094b909b4b3cce636454426fc893ac2pbos@webrtc.org // Wait for media packets on all ssrcs. 17562fd91bd35094b909b4b3cce636454426fc893ac2pbos@webrtc.org if (!ssrc_observed_[ssrc] && !only_padding) { 17572fd91bd35094b909b4b3cce636454426fc893ac2pbos@webrtc.org ssrc_observed_[ssrc] = true; 17582fd91bd35094b909b4b3cce636454426fc893ac2pbos@webrtc.org if (--ssrcs_to_observe_ == 0) 17592fd91bd35094b909b4b3cce636454426fc893ac2pbos@webrtc.org observation_complete_->Set(); 17602fd91bd35094b909b4b3cce636454426fc893ac2pbos@webrtc.org } 17612fd91bd35094b909b4b3cce636454426fc893ac2pbos@webrtc.org 17622fd91bd35094b909b4b3cce636454426fc893ac2pbos@webrtc.org return SEND_PACKET; 17632fd91bd35094b909b4b3cce636454426fc893ac2pbos@webrtc.org } 17642fd91bd35094b909b4b3cce636454426fc893ac2pbos@webrtc.org 17652fd91bd35094b909b4b3cce636454426fc893ac2pbos@webrtc.org std::map<uint32_t, uint16_t> last_observed_sequence_number_; 17662fd91bd35094b909b4b3cce636454426fc893ac2pbos@webrtc.org std::map<uint32_t, uint32_t> last_observed_timestamp_; 17672fd91bd35094b909b4b3cce636454426fc893ac2pbos@webrtc.org std::map<uint32_t, bool> configured_ssrcs_; 17682fd91bd35094b909b4b3cce636454426fc893ac2pbos@webrtc.org 17692fd91bd35094b909b4b3cce636454426fc893ac2pbos@webrtc.org scoped_ptr<CriticalSectionWrapper> crit_; 17702fd91bd35094b909b4b3cce636454426fc893ac2pbos@webrtc.org size_t ssrcs_to_observe_ GUARDED_BY(crit_); 17712fd91bd35094b909b4b3cce636454426fc893ac2pbos@webrtc.org std::map<uint32_t, bool> ssrc_observed_ GUARDED_BY(crit_); 17722fd91bd35094b909b4b3cce636454426fc893ac2pbos@webrtc.org } observer(use_rtx); 17732fd91bd35094b909b4b3cce636454426fc893ac2pbos@webrtc.org 17742fd91bd35094b909b4b3cce636454426fc893ac2pbos@webrtc.org CreateCalls(Call::Config(observer.SendTransport()), 17752fd91bd35094b909b4b3cce636454426fc893ac2pbos@webrtc.org Call::Config(observer.ReceiveTransport())); 17762fd91bd35094b909b4b3cce636454426fc893ac2pbos@webrtc.org observer.SetReceivers(sender_call_->Receiver(), NULL); 17772fd91bd35094b909b4b3cce636454426fc893ac2pbos@webrtc.org 17782fd91bd35094b909b4b3cce636454426fc893ac2pbos@webrtc.org CreateSendConfig(kNumSsrcs); 17792fd91bd35094b909b4b3cce636454426fc893ac2pbos@webrtc.org 17802fd91bd35094b909b4b3cce636454426fc893ac2pbos@webrtc.org if (use_rtx) { 17812fd91bd35094b909b4b3cce636454426fc893ac2pbos@webrtc.org for (size_t i = 0; i < kNumSsrcs; ++i) { 17822fd91bd35094b909b4b3cce636454426fc893ac2pbos@webrtc.org send_config_.rtp.rtx.ssrcs.push_back(kSendRtxSsrcs[i]); 17832fd91bd35094b909b4b3cce636454426fc893ac2pbos@webrtc.org } 17842fd91bd35094b909b4b3cce636454426fc893ac2pbos@webrtc.org send_config_.rtp.rtx.payload_type = kSendRtxPayloadType; 17852fd91bd35094b909b4b3cce636454426fc893ac2pbos@webrtc.org } 17862fd91bd35094b909b4b3cce636454426fc893ac2pbos@webrtc.org 17872fd91bd35094b909b4b3cce636454426fc893ac2pbos@webrtc.org // Lower bitrates so that all streams send initially. 178858b5140b7535ae66c618cc64b0a955b8d47cc86cpbos@webrtc.org for (size_t i = 0; i < encoder_config_.streams.size(); ++i) { 178958b5140b7535ae66c618cc64b0a955b8d47cc86cpbos@webrtc.org encoder_config_.streams[i].min_bitrate_bps = 10000; 179058b5140b7535ae66c618cc64b0a955b8d47cc86cpbos@webrtc.org encoder_config_.streams[i].target_bitrate_bps = 15000; 179158b5140b7535ae66c618cc64b0a955b8d47cc86cpbos@webrtc.org encoder_config_.streams[i].max_bitrate_bps = 20000; 17922fd91bd35094b909b4b3cce636454426fc893ac2pbos@webrtc.org } 17932fd91bd35094b909b4b3cce636454426fc893ac2pbos@webrtc.org 17942fd91bd35094b909b4b3cce636454426fc893ac2pbos@webrtc.org CreateMatchingReceiveConfigs(); 17952fd91bd35094b909b4b3cce636454426fc893ac2pbos@webrtc.org 17962fd91bd35094b909b4b3cce636454426fc893ac2pbos@webrtc.org CreateStreams(); 17972fd91bd35094b909b4b3cce636454426fc893ac2pbos@webrtc.org CreateFrameGeneratorCapturer(); 17982fd91bd35094b909b4b3cce636454426fc893ac2pbos@webrtc.org 17992fd91bd35094b909b4b3cce636454426fc893ac2pbos@webrtc.org Start(); 18002fd91bd35094b909b4b3cce636454426fc893ac2pbos@webrtc.org EXPECT_EQ(kEventSignaled, observer.Wait()) 18012fd91bd35094b909b4b3cce636454426fc893ac2pbos@webrtc.org << "Timed out waiting for all SSRCs to send packets."; 18022fd91bd35094b909b4b3cce636454426fc893ac2pbos@webrtc.org 18032fd91bd35094b909b4b3cce636454426fc893ac2pbos@webrtc.org // Test stream resetting more than once to make sure that the state doesn't 18042fd91bd35094b909b4b3cce636454426fc893ac2pbos@webrtc.org // get set once (this could be due to using std::map::insert for instance). 18052fd91bd35094b909b4b3cce636454426fc893ac2pbos@webrtc.org for (size_t i = 0; i < 3; ++i) { 18062fd91bd35094b909b4b3cce636454426fc893ac2pbos@webrtc.org frame_generator_capturer_->Stop(); 18072fd91bd35094b909b4b3cce636454426fc893ac2pbos@webrtc.org sender_call_->DestroyVideoSendStream(send_stream_); 18082fd91bd35094b909b4b3cce636454426fc893ac2pbos@webrtc.org 18092fd91bd35094b909b4b3cce636454426fc893ac2pbos@webrtc.org // Re-create VideoSendStream with only one stream. 181058b5140b7535ae66c618cc64b0a955b8d47cc86cpbos@webrtc.org VideoEncoderConfig one_stream = encoder_config_; 181158b5140b7535ae66c618cc64b0a955b8d47cc86cpbos@webrtc.org one_stream.streams.resize(1); 18122fd91bd35094b909b4b3cce636454426fc893ac2pbos@webrtc.org send_stream_ = 181358b5140b7535ae66c618cc64b0a955b8d47cc86cpbos@webrtc.org sender_call_->CreateVideoSendStream(send_config_, one_stream); 18142fd91bd35094b909b4b3cce636454426fc893ac2pbos@webrtc.org send_stream_->Start(); 18152fd91bd35094b909b4b3cce636454426fc893ac2pbos@webrtc.org CreateFrameGeneratorCapturer(); 18162fd91bd35094b909b4b3cce636454426fc893ac2pbos@webrtc.org frame_generator_capturer_->Start(); 18172fd91bd35094b909b4b3cce636454426fc893ac2pbos@webrtc.org 18182fd91bd35094b909b4b3cce636454426fc893ac2pbos@webrtc.org observer.ResetExpectedSsrcs(1); 18192fd91bd35094b909b4b3cce636454426fc893ac2pbos@webrtc.org EXPECT_EQ(kEventSignaled, observer.Wait()) 18202fd91bd35094b909b4b3cce636454426fc893ac2pbos@webrtc.org << "Timed out waiting for single RTP packet."; 18212fd91bd35094b909b4b3cce636454426fc893ac2pbos@webrtc.org 18222fd91bd35094b909b4b3cce636454426fc893ac2pbos@webrtc.org // Reconfigure back to use all streams. 182358b5140b7535ae66c618cc64b0a955b8d47cc86cpbos@webrtc.org send_stream_->ReconfigureVideoEncoder(encoder_config_); 18242fd91bd35094b909b4b3cce636454426fc893ac2pbos@webrtc.org observer.ResetExpectedSsrcs(kNumSsrcs); 18252fd91bd35094b909b4b3cce636454426fc893ac2pbos@webrtc.org EXPECT_EQ(kEventSignaled, observer.Wait()) 18262fd91bd35094b909b4b3cce636454426fc893ac2pbos@webrtc.org << "Timed out waiting for all SSRCs to send packets."; 18272fd91bd35094b909b4b3cce636454426fc893ac2pbos@webrtc.org 18282fd91bd35094b909b4b3cce636454426fc893ac2pbos@webrtc.org // Reconfigure down to one stream. 182958b5140b7535ae66c618cc64b0a955b8d47cc86cpbos@webrtc.org send_stream_->ReconfigureVideoEncoder(one_stream); 18302fd91bd35094b909b4b3cce636454426fc893ac2pbos@webrtc.org observer.ResetExpectedSsrcs(1); 18312fd91bd35094b909b4b3cce636454426fc893ac2pbos@webrtc.org EXPECT_EQ(kEventSignaled, observer.Wait()) 18322fd91bd35094b909b4b3cce636454426fc893ac2pbos@webrtc.org << "Timed out waiting for single RTP packet."; 18332fd91bd35094b909b4b3cce636454426fc893ac2pbos@webrtc.org 18342fd91bd35094b909b4b3cce636454426fc893ac2pbos@webrtc.org // Reconfigure back to use all streams. 183558b5140b7535ae66c618cc64b0a955b8d47cc86cpbos@webrtc.org send_stream_->ReconfigureVideoEncoder(encoder_config_); 18362fd91bd35094b909b4b3cce636454426fc893ac2pbos@webrtc.org observer.ResetExpectedSsrcs(kNumSsrcs); 18372fd91bd35094b909b4b3cce636454426fc893ac2pbos@webrtc.org EXPECT_EQ(kEventSignaled, observer.Wait()) 18382fd91bd35094b909b4b3cce636454426fc893ac2pbos@webrtc.org << "Timed out waiting for all SSRCs to send packets."; 18392fd91bd35094b909b4b3cce636454426fc893ac2pbos@webrtc.org } 18402fd91bd35094b909b4b3cce636454426fc893ac2pbos@webrtc.org 18412fd91bd35094b909b4b3cce636454426fc893ac2pbos@webrtc.org observer.StopSending(); 18422fd91bd35094b909b4b3cce636454426fc893ac2pbos@webrtc.org 18432fd91bd35094b909b4b3cce636454426fc893ac2pbos@webrtc.org Stop(); 18442fd91bd35094b909b4b3cce636454426fc893ac2pbos@webrtc.org DestroyStreams(); 18452fd91bd35094b909b4b3cce636454426fc893ac2pbos@webrtc.org} 18462fd91bd35094b909b4b3cce636454426fc893ac2pbos@webrtc.org 1847cd35c434c6c9358f87893d0116a3ee528203a975aluebs@webrtc.orgTEST_F(EndToEndTest, DISABLED_RestartingSendStreamPreservesRtpState) { 18482fd91bd35094b909b4b3cce636454426fc893ac2pbos@webrtc.org TestRtpStatePreservation(false); 18492fd91bd35094b909b4b3cce636454426fc893ac2pbos@webrtc.org} 18502fd91bd35094b909b4b3cce636454426fc893ac2pbos@webrtc.org 18512fd91bd35094b909b4b3cce636454426fc893ac2pbos@webrtc.orgTEST_F(EndToEndTest, RestartingSendStreamPreservesRtpStatesWithRtx) { 18522fd91bd35094b909b4b3cce636454426fc893ac2pbos@webrtc.org TestRtpStatePreservation(true); 18532fd91bd35094b909b4b3cce636454426fc893ac2pbos@webrtc.org} 18542fd91bd35094b909b4b3cce636454426fc893ac2pbos@webrtc.org 18559b707ca664bd22f7a8bfad14a06f9ffdc6129d3dpbos@webrtc.orgTEST_F(EndToEndTest, RespectsNetworkState) { 18569b707ca664bd22f7a8bfad14a06f9ffdc6129d3dpbos@webrtc.org // TODO(pbos): Remove accepted downtime packets etc. when signaling network 18579b707ca664bd22f7a8bfad14a06f9ffdc6129d3dpbos@webrtc.org // down blocks until no more packets will be sent. 18589b707ca664bd22f7a8bfad14a06f9ffdc6129d3dpbos@webrtc.org 18599b707ca664bd22f7a8bfad14a06f9ffdc6129d3dpbos@webrtc.org // Pacer will send from its packet list and then send required padding before 18609b707ca664bd22f7a8bfad14a06f9ffdc6129d3dpbos@webrtc.org // checking paused_ again. This should be enough for one round of pacing, 18619b707ca664bd22f7a8bfad14a06f9ffdc6129d3dpbos@webrtc.org // otherwise increase. 18629b707ca664bd22f7a8bfad14a06f9ffdc6129d3dpbos@webrtc.org static const int kNumAcceptedDowntimeRtp = 5; 18639b707ca664bd22f7a8bfad14a06f9ffdc6129d3dpbos@webrtc.org // A single RTCP may be in the pipeline. 18649b707ca664bd22f7a8bfad14a06f9ffdc6129d3dpbos@webrtc.org static const int kNumAcceptedDowntimeRtcp = 1; 18659b707ca664bd22f7a8bfad14a06f9ffdc6129d3dpbos@webrtc.org class NetworkStateTest : public test::EndToEndTest, public test::FakeEncoder { 18669b707ca664bd22f7a8bfad14a06f9ffdc6129d3dpbos@webrtc.org public: 18679b707ca664bd22f7a8bfad14a06f9ffdc6129d3dpbos@webrtc.org NetworkStateTest() 18689b707ca664bd22f7a8bfad14a06f9ffdc6129d3dpbos@webrtc.org : EndToEndTest(kDefaultTimeoutMs), 18699b707ca664bd22f7a8bfad14a06f9ffdc6129d3dpbos@webrtc.org FakeEncoder(Clock::GetRealTimeClock()), 18709b707ca664bd22f7a8bfad14a06f9ffdc6129d3dpbos@webrtc.org test_crit_(CriticalSectionWrapper::CreateCriticalSection()), 18719b707ca664bd22f7a8bfad14a06f9ffdc6129d3dpbos@webrtc.org encoded_frames_(EventWrapper::Create()), 18729b707ca664bd22f7a8bfad14a06f9ffdc6129d3dpbos@webrtc.org sender_packets_(EventWrapper::Create()), 18739b707ca664bd22f7a8bfad14a06f9ffdc6129d3dpbos@webrtc.org receiver_packets_(EventWrapper::Create()), 18749b707ca664bd22f7a8bfad14a06f9ffdc6129d3dpbos@webrtc.org sender_state_(Call::kNetworkUp), 18759b707ca664bd22f7a8bfad14a06f9ffdc6129d3dpbos@webrtc.org down_sender_rtp_(0), 18769b707ca664bd22f7a8bfad14a06f9ffdc6129d3dpbos@webrtc.org down_sender_rtcp_(0), 18779b707ca664bd22f7a8bfad14a06f9ffdc6129d3dpbos@webrtc.org receiver_state_(Call::kNetworkUp), 18789b707ca664bd22f7a8bfad14a06f9ffdc6129d3dpbos@webrtc.org down_receiver_rtcp_(0), 18799b707ca664bd22f7a8bfad14a06f9ffdc6129d3dpbos@webrtc.org down_frames_(0) {} 18809b707ca664bd22f7a8bfad14a06f9ffdc6129d3dpbos@webrtc.org 18819b707ca664bd22f7a8bfad14a06f9ffdc6129d3dpbos@webrtc.org virtual Action OnSendRtp(const uint8_t* packet, size_t length) OVERRIDE { 18829b707ca664bd22f7a8bfad14a06f9ffdc6129d3dpbos@webrtc.org CriticalSectionScoped lock(test_crit_.get()); 18839b707ca664bd22f7a8bfad14a06f9ffdc6129d3dpbos@webrtc.org if (sender_state_ == Call::kNetworkDown) { 18849b707ca664bd22f7a8bfad14a06f9ffdc6129d3dpbos@webrtc.org ++down_sender_rtp_; 18859b707ca664bd22f7a8bfad14a06f9ffdc6129d3dpbos@webrtc.org EXPECT_LE(down_sender_rtp_, kNumAcceptedDowntimeRtp) 18869b707ca664bd22f7a8bfad14a06f9ffdc6129d3dpbos@webrtc.org << "RTP sent during sender-side downtime."; 18879b707ca664bd22f7a8bfad14a06f9ffdc6129d3dpbos@webrtc.org if (down_sender_rtp_> kNumAcceptedDowntimeRtp) 18889b707ca664bd22f7a8bfad14a06f9ffdc6129d3dpbos@webrtc.org sender_packets_->Set(); 18899b707ca664bd22f7a8bfad14a06f9ffdc6129d3dpbos@webrtc.org } else { 18909b707ca664bd22f7a8bfad14a06f9ffdc6129d3dpbos@webrtc.org sender_packets_->Set(); 18919b707ca664bd22f7a8bfad14a06f9ffdc6129d3dpbos@webrtc.org } 18929b707ca664bd22f7a8bfad14a06f9ffdc6129d3dpbos@webrtc.org return SEND_PACKET; 18939b707ca664bd22f7a8bfad14a06f9ffdc6129d3dpbos@webrtc.org } 18949b707ca664bd22f7a8bfad14a06f9ffdc6129d3dpbos@webrtc.org 18959b707ca664bd22f7a8bfad14a06f9ffdc6129d3dpbos@webrtc.org virtual Action OnSendRtcp(const uint8_t* packet, size_t length) OVERRIDE { 18969b707ca664bd22f7a8bfad14a06f9ffdc6129d3dpbos@webrtc.org CriticalSectionScoped lock(test_crit_.get()); 18979b707ca664bd22f7a8bfad14a06f9ffdc6129d3dpbos@webrtc.org if (sender_state_ == Call::kNetworkDown) { 18989b707ca664bd22f7a8bfad14a06f9ffdc6129d3dpbos@webrtc.org ++down_sender_rtcp_; 18999b707ca664bd22f7a8bfad14a06f9ffdc6129d3dpbos@webrtc.org EXPECT_LE(down_sender_rtcp_, kNumAcceptedDowntimeRtcp) 19009b707ca664bd22f7a8bfad14a06f9ffdc6129d3dpbos@webrtc.org << "RTCP sent during sender-side downtime."; 19019b707ca664bd22f7a8bfad14a06f9ffdc6129d3dpbos@webrtc.org if (down_sender_rtcp_ > kNumAcceptedDowntimeRtcp) 19029b707ca664bd22f7a8bfad14a06f9ffdc6129d3dpbos@webrtc.org sender_packets_->Set(); 19039b707ca664bd22f7a8bfad14a06f9ffdc6129d3dpbos@webrtc.org } else { 19049b707ca664bd22f7a8bfad14a06f9ffdc6129d3dpbos@webrtc.org sender_packets_->Set(); 19059b707ca664bd22f7a8bfad14a06f9ffdc6129d3dpbos@webrtc.org } 19069b707ca664bd22f7a8bfad14a06f9ffdc6129d3dpbos@webrtc.org return SEND_PACKET; 19079b707ca664bd22f7a8bfad14a06f9ffdc6129d3dpbos@webrtc.org } 19089b707ca664bd22f7a8bfad14a06f9ffdc6129d3dpbos@webrtc.org 19099b707ca664bd22f7a8bfad14a06f9ffdc6129d3dpbos@webrtc.org virtual Action OnReceiveRtp(const uint8_t* packet, size_t length) OVERRIDE { 19109b707ca664bd22f7a8bfad14a06f9ffdc6129d3dpbos@webrtc.org ADD_FAILURE() << "Unexpected receiver RTP, should not be sending."; 19119b707ca664bd22f7a8bfad14a06f9ffdc6129d3dpbos@webrtc.org return SEND_PACKET; 19129b707ca664bd22f7a8bfad14a06f9ffdc6129d3dpbos@webrtc.org } 19139b707ca664bd22f7a8bfad14a06f9ffdc6129d3dpbos@webrtc.org 19149b707ca664bd22f7a8bfad14a06f9ffdc6129d3dpbos@webrtc.org virtual Action OnReceiveRtcp(const uint8_t* packet, 19159b707ca664bd22f7a8bfad14a06f9ffdc6129d3dpbos@webrtc.org size_t length) OVERRIDE { 19169b707ca664bd22f7a8bfad14a06f9ffdc6129d3dpbos@webrtc.org CriticalSectionScoped lock(test_crit_.get()); 19179b707ca664bd22f7a8bfad14a06f9ffdc6129d3dpbos@webrtc.org if (receiver_state_ == Call::kNetworkDown) { 19189b707ca664bd22f7a8bfad14a06f9ffdc6129d3dpbos@webrtc.org ++down_receiver_rtcp_; 19199b707ca664bd22f7a8bfad14a06f9ffdc6129d3dpbos@webrtc.org EXPECT_LE(down_receiver_rtcp_, kNumAcceptedDowntimeRtcp) 19209b707ca664bd22f7a8bfad14a06f9ffdc6129d3dpbos@webrtc.org << "RTCP sent during receiver-side downtime."; 19219b707ca664bd22f7a8bfad14a06f9ffdc6129d3dpbos@webrtc.org if (down_receiver_rtcp_ > kNumAcceptedDowntimeRtcp) 19229b707ca664bd22f7a8bfad14a06f9ffdc6129d3dpbos@webrtc.org receiver_packets_->Set(); 19239b707ca664bd22f7a8bfad14a06f9ffdc6129d3dpbos@webrtc.org } else { 19249b707ca664bd22f7a8bfad14a06f9ffdc6129d3dpbos@webrtc.org receiver_packets_->Set(); 19259b707ca664bd22f7a8bfad14a06f9ffdc6129d3dpbos@webrtc.org } 19269b707ca664bd22f7a8bfad14a06f9ffdc6129d3dpbos@webrtc.org return SEND_PACKET; 19279b707ca664bd22f7a8bfad14a06f9ffdc6129d3dpbos@webrtc.org } 19289b707ca664bd22f7a8bfad14a06f9ffdc6129d3dpbos@webrtc.org 19299b707ca664bd22f7a8bfad14a06f9ffdc6129d3dpbos@webrtc.org virtual void OnCallsCreated(Call* sender_call, 19309b707ca664bd22f7a8bfad14a06f9ffdc6129d3dpbos@webrtc.org Call* receiver_call) OVERRIDE { 19319b707ca664bd22f7a8bfad14a06f9ffdc6129d3dpbos@webrtc.org sender_call_ = sender_call; 19329b707ca664bd22f7a8bfad14a06f9ffdc6129d3dpbos@webrtc.org receiver_call_ = receiver_call; 19339b707ca664bd22f7a8bfad14a06f9ffdc6129d3dpbos@webrtc.org } 19349b707ca664bd22f7a8bfad14a06f9ffdc6129d3dpbos@webrtc.org 19359b707ca664bd22f7a8bfad14a06f9ffdc6129d3dpbos@webrtc.org virtual void ModifyConfigs( 19369b707ca664bd22f7a8bfad14a06f9ffdc6129d3dpbos@webrtc.org VideoSendStream::Config* send_config, 19379b707ca664bd22f7a8bfad14a06f9ffdc6129d3dpbos@webrtc.org std::vector<VideoReceiveStream::Config>* receive_configs, 193858b5140b7535ae66c618cc64b0a955b8d47cc86cpbos@webrtc.org VideoEncoderConfig* encoder_config) OVERRIDE { 19399b707ca664bd22f7a8bfad14a06f9ffdc6129d3dpbos@webrtc.org send_config->encoder_settings.encoder = this; 19409b707ca664bd22f7a8bfad14a06f9ffdc6129d3dpbos@webrtc.org } 19419b707ca664bd22f7a8bfad14a06f9ffdc6129d3dpbos@webrtc.org 19429b707ca664bd22f7a8bfad14a06f9ffdc6129d3dpbos@webrtc.org virtual void PerformTest() OVERRIDE { 19439b707ca664bd22f7a8bfad14a06f9ffdc6129d3dpbos@webrtc.org EXPECT_EQ(kEventSignaled, encoded_frames_->Wait(kDefaultTimeoutMs)) 19449b707ca664bd22f7a8bfad14a06f9ffdc6129d3dpbos@webrtc.org << "No frames received by the encoder."; 19459b707ca664bd22f7a8bfad14a06f9ffdc6129d3dpbos@webrtc.org EXPECT_EQ(kEventSignaled, sender_packets_->Wait(kDefaultTimeoutMs)) 19469b707ca664bd22f7a8bfad14a06f9ffdc6129d3dpbos@webrtc.org << "Timed out waiting for send-side packets."; 19479b707ca664bd22f7a8bfad14a06f9ffdc6129d3dpbos@webrtc.org EXPECT_EQ(kEventSignaled, receiver_packets_->Wait(kDefaultTimeoutMs)) 19489b707ca664bd22f7a8bfad14a06f9ffdc6129d3dpbos@webrtc.org << "Timed out waiting for receiver-side packets."; 19499b707ca664bd22f7a8bfad14a06f9ffdc6129d3dpbos@webrtc.org 19509b707ca664bd22f7a8bfad14a06f9ffdc6129d3dpbos@webrtc.org // Sender-side network down. 19519b707ca664bd22f7a8bfad14a06f9ffdc6129d3dpbos@webrtc.org sender_call_->SignalNetworkState(Call::kNetworkDown); 19529b707ca664bd22f7a8bfad14a06f9ffdc6129d3dpbos@webrtc.org { 19539b707ca664bd22f7a8bfad14a06f9ffdc6129d3dpbos@webrtc.org CriticalSectionScoped lock(test_crit_.get()); 19549b707ca664bd22f7a8bfad14a06f9ffdc6129d3dpbos@webrtc.org sender_packets_->Reset(); // Earlier packets should not count. 19559b707ca664bd22f7a8bfad14a06f9ffdc6129d3dpbos@webrtc.org sender_state_ = Call::kNetworkDown; 19569b707ca664bd22f7a8bfad14a06f9ffdc6129d3dpbos@webrtc.org } 19579b707ca664bd22f7a8bfad14a06f9ffdc6129d3dpbos@webrtc.org EXPECT_EQ(kEventTimeout, sender_packets_->Wait(kSilenceTimeoutMs)) 19589b707ca664bd22f7a8bfad14a06f9ffdc6129d3dpbos@webrtc.org << "Packets sent during sender-network downtime."; 19599b707ca664bd22f7a8bfad14a06f9ffdc6129d3dpbos@webrtc.org EXPECT_EQ(kEventSignaled, receiver_packets_->Wait(kDefaultTimeoutMs)) 19609b707ca664bd22f7a8bfad14a06f9ffdc6129d3dpbos@webrtc.org << "Timed out waiting for receiver-side packets."; 19619b707ca664bd22f7a8bfad14a06f9ffdc6129d3dpbos@webrtc.org // Receiver-side network down. 19629b707ca664bd22f7a8bfad14a06f9ffdc6129d3dpbos@webrtc.org receiver_call_->SignalNetworkState(Call::kNetworkDown); 19639b707ca664bd22f7a8bfad14a06f9ffdc6129d3dpbos@webrtc.org { 19649b707ca664bd22f7a8bfad14a06f9ffdc6129d3dpbos@webrtc.org CriticalSectionScoped lock(test_crit_.get()); 19659b707ca664bd22f7a8bfad14a06f9ffdc6129d3dpbos@webrtc.org receiver_packets_->Reset(); // Earlier packets should not count. 19669b707ca664bd22f7a8bfad14a06f9ffdc6129d3dpbos@webrtc.org receiver_state_ = Call::kNetworkDown; 19679b707ca664bd22f7a8bfad14a06f9ffdc6129d3dpbos@webrtc.org } 19689b707ca664bd22f7a8bfad14a06f9ffdc6129d3dpbos@webrtc.org EXPECT_EQ(kEventTimeout, receiver_packets_->Wait(kSilenceTimeoutMs)) 19699b707ca664bd22f7a8bfad14a06f9ffdc6129d3dpbos@webrtc.org << "Packets sent during receiver-network downtime."; 19709b707ca664bd22f7a8bfad14a06f9ffdc6129d3dpbos@webrtc.org 19719b707ca664bd22f7a8bfad14a06f9ffdc6129d3dpbos@webrtc.org // Network back up again for both. 19729b707ca664bd22f7a8bfad14a06f9ffdc6129d3dpbos@webrtc.org { 19739b707ca664bd22f7a8bfad14a06f9ffdc6129d3dpbos@webrtc.org CriticalSectionScoped lock(test_crit_.get()); 19749b707ca664bd22f7a8bfad14a06f9ffdc6129d3dpbos@webrtc.org sender_packets_->Reset(); // Earlier packets should not count. 19759b707ca664bd22f7a8bfad14a06f9ffdc6129d3dpbos@webrtc.org receiver_packets_->Reset(); // Earlier packets should not count. 19769b707ca664bd22f7a8bfad14a06f9ffdc6129d3dpbos@webrtc.org sender_state_ = receiver_state_ = Call::kNetworkUp; 19779b707ca664bd22f7a8bfad14a06f9ffdc6129d3dpbos@webrtc.org } 19789b707ca664bd22f7a8bfad14a06f9ffdc6129d3dpbos@webrtc.org sender_call_->SignalNetworkState(Call::kNetworkUp); 19799b707ca664bd22f7a8bfad14a06f9ffdc6129d3dpbos@webrtc.org receiver_call_->SignalNetworkState(Call::kNetworkUp); 19809b707ca664bd22f7a8bfad14a06f9ffdc6129d3dpbos@webrtc.org EXPECT_EQ(kEventSignaled, sender_packets_->Wait(kDefaultTimeoutMs)) 19819b707ca664bd22f7a8bfad14a06f9ffdc6129d3dpbos@webrtc.org << "Timed out waiting for send-side packets."; 19829b707ca664bd22f7a8bfad14a06f9ffdc6129d3dpbos@webrtc.org EXPECT_EQ(kEventSignaled, receiver_packets_->Wait(kDefaultTimeoutMs)) 19839b707ca664bd22f7a8bfad14a06f9ffdc6129d3dpbos@webrtc.org << "Timed out waiting for receiver-side packets."; 19849b707ca664bd22f7a8bfad14a06f9ffdc6129d3dpbos@webrtc.org } 19859b707ca664bd22f7a8bfad14a06f9ffdc6129d3dpbos@webrtc.org 19869b707ca664bd22f7a8bfad14a06f9ffdc6129d3dpbos@webrtc.org virtual int32_t Encode(const I420VideoFrame& input_image, 19879b707ca664bd22f7a8bfad14a06f9ffdc6129d3dpbos@webrtc.org const CodecSpecificInfo* codec_specific_info, 19889b707ca664bd22f7a8bfad14a06f9ffdc6129d3dpbos@webrtc.org const std::vector<VideoFrameType>* frame_types) 19899b707ca664bd22f7a8bfad14a06f9ffdc6129d3dpbos@webrtc.org OVERRIDE { 19909b707ca664bd22f7a8bfad14a06f9ffdc6129d3dpbos@webrtc.org { 19919b707ca664bd22f7a8bfad14a06f9ffdc6129d3dpbos@webrtc.org CriticalSectionScoped lock(test_crit_.get()); 19929b707ca664bd22f7a8bfad14a06f9ffdc6129d3dpbos@webrtc.org if (sender_state_ == Call::kNetworkDown) { 19939b707ca664bd22f7a8bfad14a06f9ffdc6129d3dpbos@webrtc.org ++down_frames_; 19949b707ca664bd22f7a8bfad14a06f9ffdc6129d3dpbos@webrtc.org EXPECT_LE(down_frames_, 1) 19959b707ca664bd22f7a8bfad14a06f9ffdc6129d3dpbos@webrtc.org << "Encoding more than one frame while network is down."; 19969b707ca664bd22f7a8bfad14a06f9ffdc6129d3dpbos@webrtc.org if (down_frames_ > 1) 19979b707ca664bd22f7a8bfad14a06f9ffdc6129d3dpbos@webrtc.org encoded_frames_->Set(); 19989b707ca664bd22f7a8bfad14a06f9ffdc6129d3dpbos@webrtc.org } else { 19999b707ca664bd22f7a8bfad14a06f9ffdc6129d3dpbos@webrtc.org encoded_frames_->Set(); 20009b707ca664bd22f7a8bfad14a06f9ffdc6129d3dpbos@webrtc.org } 20019b707ca664bd22f7a8bfad14a06f9ffdc6129d3dpbos@webrtc.org } 20029b707ca664bd22f7a8bfad14a06f9ffdc6129d3dpbos@webrtc.org return test::FakeEncoder::Encode( 20039b707ca664bd22f7a8bfad14a06f9ffdc6129d3dpbos@webrtc.org input_image, codec_specific_info, frame_types); 20049b707ca664bd22f7a8bfad14a06f9ffdc6129d3dpbos@webrtc.org } 20059b707ca664bd22f7a8bfad14a06f9ffdc6129d3dpbos@webrtc.org 20069b707ca664bd22f7a8bfad14a06f9ffdc6129d3dpbos@webrtc.org private: 20079b707ca664bd22f7a8bfad14a06f9ffdc6129d3dpbos@webrtc.org const scoped_ptr<CriticalSectionWrapper> test_crit_; 20089b707ca664bd22f7a8bfad14a06f9ffdc6129d3dpbos@webrtc.org scoped_ptr<EventWrapper> encoded_frames_; 20099b707ca664bd22f7a8bfad14a06f9ffdc6129d3dpbos@webrtc.org scoped_ptr<EventWrapper> sender_packets_; 20109b707ca664bd22f7a8bfad14a06f9ffdc6129d3dpbos@webrtc.org scoped_ptr<EventWrapper> receiver_packets_; 20119b707ca664bd22f7a8bfad14a06f9ffdc6129d3dpbos@webrtc.org Call* sender_call_; 20129b707ca664bd22f7a8bfad14a06f9ffdc6129d3dpbos@webrtc.org Call* receiver_call_; 20139b707ca664bd22f7a8bfad14a06f9ffdc6129d3dpbos@webrtc.org Call::NetworkState sender_state_ GUARDED_BY(test_crit_); 20149b707ca664bd22f7a8bfad14a06f9ffdc6129d3dpbos@webrtc.org int down_sender_rtp_ GUARDED_BY(test_crit_); 20159b707ca664bd22f7a8bfad14a06f9ffdc6129d3dpbos@webrtc.org int down_sender_rtcp_ GUARDED_BY(test_crit_); 20169b707ca664bd22f7a8bfad14a06f9ffdc6129d3dpbos@webrtc.org Call::NetworkState receiver_state_ GUARDED_BY(test_crit_); 20179b707ca664bd22f7a8bfad14a06f9ffdc6129d3dpbos@webrtc.org int down_receiver_rtcp_ GUARDED_BY(test_crit_); 20189b707ca664bd22f7a8bfad14a06f9ffdc6129d3dpbos@webrtc.org int down_frames_ GUARDED_BY(test_crit_); 20199b707ca664bd22f7a8bfad14a06f9ffdc6129d3dpbos@webrtc.org } test; 20209b707ca664bd22f7a8bfad14a06f9ffdc6129d3dpbos@webrtc.org 20219b707ca664bd22f7a8bfad14a06f9ffdc6129d3dpbos@webrtc.org RunBaseTest(&test); 20229b707ca664bd22f7a8bfad14a06f9ffdc6129d3dpbos@webrtc.org} 20239b707ca664bd22f7a8bfad14a06f9ffdc6129d3dpbos@webrtc.org 20249b707ca664bd22f7a8bfad14a06f9ffdc6129d3dpbos@webrtc.orgTEST_F(EndToEndTest, NewSendStreamsRespectNetworkDown) { 20259b707ca664bd22f7a8bfad14a06f9ffdc6129d3dpbos@webrtc.org class UnusedEncoder : public test::FakeEncoder { 20269b707ca664bd22f7a8bfad14a06f9ffdc6129d3dpbos@webrtc.org public: 20279b707ca664bd22f7a8bfad14a06f9ffdc6129d3dpbos@webrtc.org UnusedEncoder() : FakeEncoder(Clock::GetRealTimeClock()) {} 20289b707ca664bd22f7a8bfad14a06f9ffdc6129d3dpbos@webrtc.org virtual int32_t Encode(const I420VideoFrame& input_image, 20299b707ca664bd22f7a8bfad14a06f9ffdc6129d3dpbos@webrtc.org const CodecSpecificInfo* codec_specific_info, 20309b707ca664bd22f7a8bfad14a06f9ffdc6129d3dpbos@webrtc.org const std::vector<VideoFrameType>* frame_types) 20319b707ca664bd22f7a8bfad14a06f9ffdc6129d3dpbos@webrtc.org OVERRIDE { 20329b707ca664bd22f7a8bfad14a06f9ffdc6129d3dpbos@webrtc.org ADD_FAILURE() << "Unexpected frame encode."; 20339b707ca664bd22f7a8bfad14a06f9ffdc6129d3dpbos@webrtc.org return test::FakeEncoder::Encode( 20349b707ca664bd22f7a8bfad14a06f9ffdc6129d3dpbos@webrtc.org input_image, codec_specific_info, frame_types); 20359b707ca664bd22f7a8bfad14a06f9ffdc6129d3dpbos@webrtc.org } 20369b707ca664bd22f7a8bfad14a06f9ffdc6129d3dpbos@webrtc.org }; 20379b707ca664bd22f7a8bfad14a06f9ffdc6129d3dpbos@webrtc.org 20389b707ca664bd22f7a8bfad14a06f9ffdc6129d3dpbos@webrtc.org UnusedTransport transport; 20399b707ca664bd22f7a8bfad14a06f9ffdc6129d3dpbos@webrtc.org CreateSenderCall(Call::Config(&transport)); 20409b707ca664bd22f7a8bfad14a06f9ffdc6129d3dpbos@webrtc.org sender_call_->SignalNetworkState(Call::kNetworkDown); 20419b707ca664bd22f7a8bfad14a06f9ffdc6129d3dpbos@webrtc.org 20429b707ca664bd22f7a8bfad14a06f9ffdc6129d3dpbos@webrtc.org CreateSendConfig(1); 20439b707ca664bd22f7a8bfad14a06f9ffdc6129d3dpbos@webrtc.org UnusedEncoder unused_encoder; 20449b707ca664bd22f7a8bfad14a06f9ffdc6129d3dpbos@webrtc.org send_config_.encoder_settings.encoder = &unused_encoder; 20459b707ca664bd22f7a8bfad14a06f9ffdc6129d3dpbos@webrtc.org CreateStreams(); 20469b707ca664bd22f7a8bfad14a06f9ffdc6129d3dpbos@webrtc.org CreateFrameGeneratorCapturer(); 20479b707ca664bd22f7a8bfad14a06f9ffdc6129d3dpbos@webrtc.org 20489b707ca664bd22f7a8bfad14a06f9ffdc6129d3dpbos@webrtc.org Start(); 20499b707ca664bd22f7a8bfad14a06f9ffdc6129d3dpbos@webrtc.org SleepMs(kSilenceTimeoutMs); 20509b707ca664bd22f7a8bfad14a06f9ffdc6129d3dpbos@webrtc.org Stop(); 20519b707ca664bd22f7a8bfad14a06f9ffdc6129d3dpbos@webrtc.org 20529b707ca664bd22f7a8bfad14a06f9ffdc6129d3dpbos@webrtc.org DestroyStreams(); 20539b707ca664bd22f7a8bfad14a06f9ffdc6129d3dpbos@webrtc.org} 20549b707ca664bd22f7a8bfad14a06f9ffdc6129d3dpbos@webrtc.org 20559b707ca664bd22f7a8bfad14a06f9ffdc6129d3dpbos@webrtc.orgTEST_F(EndToEndTest, NewReceiveStreamsRespectNetworkDown) { 20569b707ca664bd22f7a8bfad14a06f9ffdc6129d3dpbos@webrtc.org test::DirectTransport sender_transport; 20579b707ca664bd22f7a8bfad14a06f9ffdc6129d3dpbos@webrtc.org CreateSenderCall(Call::Config(&sender_transport)); 20589b707ca664bd22f7a8bfad14a06f9ffdc6129d3dpbos@webrtc.org UnusedTransport transport; 20599b707ca664bd22f7a8bfad14a06f9ffdc6129d3dpbos@webrtc.org CreateReceiverCall(Call::Config(&transport)); 20609b707ca664bd22f7a8bfad14a06f9ffdc6129d3dpbos@webrtc.org sender_transport.SetReceiver(receiver_call_->Receiver()); 20619b707ca664bd22f7a8bfad14a06f9ffdc6129d3dpbos@webrtc.org 20629b707ca664bd22f7a8bfad14a06f9ffdc6129d3dpbos@webrtc.org receiver_call_->SignalNetworkState(Call::kNetworkDown); 20639b707ca664bd22f7a8bfad14a06f9ffdc6129d3dpbos@webrtc.org 20649b707ca664bd22f7a8bfad14a06f9ffdc6129d3dpbos@webrtc.org CreateSendConfig(1); 20659b707ca664bd22f7a8bfad14a06f9ffdc6129d3dpbos@webrtc.org CreateMatchingReceiveConfigs(); 20669b707ca664bd22f7a8bfad14a06f9ffdc6129d3dpbos@webrtc.org CreateStreams(); 20679b707ca664bd22f7a8bfad14a06f9ffdc6129d3dpbos@webrtc.org CreateFrameGeneratorCapturer(); 20689b707ca664bd22f7a8bfad14a06f9ffdc6129d3dpbos@webrtc.org 20699b707ca664bd22f7a8bfad14a06f9ffdc6129d3dpbos@webrtc.org Start(); 20709b707ca664bd22f7a8bfad14a06f9ffdc6129d3dpbos@webrtc.org SleepMs(kSilenceTimeoutMs); 20719b707ca664bd22f7a8bfad14a06f9ffdc6129d3dpbos@webrtc.org Stop(); 20729b707ca664bd22f7a8bfad14a06f9ffdc6129d3dpbos@webrtc.org 20739b707ca664bd22f7a8bfad14a06f9ffdc6129d3dpbos@webrtc.org sender_transport.StopSending(); 20749b707ca664bd22f7a8bfad14a06f9ffdc6129d3dpbos@webrtc.org 20759b707ca664bd22f7a8bfad14a06f9ffdc6129d3dpbos@webrtc.org DestroyStreams(); 20769b707ca664bd22f7a8bfad14a06f9ffdc6129d3dpbos@webrtc.org} 2077ce8510901416e37afabb0a54c6e10bec6db63a42pbos@webrtc.org} // namespace webrtc 2078