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" 22e2a7a77646b23fb3704d267e6079e04bde493543pbos@webrtc.org#include "webrtc/modules/video_coding/codecs/vp8/include/vp8.h" 23ce8510901416e37afabb0a54c6e10bec6db63a42pbos@webrtc.org#include "webrtc/system_wrappers/interface/critical_section_wrapper.h" 24ce8510901416e37afabb0a54c6e10bec6db63a42pbos@webrtc.org#include "webrtc/system_wrappers/interface/event_wrapper.h" 25fa996f226ee327232b854c936d2f706aa71ff090pbos@webrtc.org#include "webrtc/system_wrappers/interface/scoped_ptr.h" 26d60137ff1b936534b04396298b7d2f2ebbc1da82pbos@webrtc.org#include "webrtc/system_wrappers/interface/sleep.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" 37e028410838cd976c75e379b3c2e2eb0ac52b3c99stefan@webrtc.org#include "webrtc/test/testsupport/perf_test.h" 38c33d37ce205e22c0e090b0b285ed963686bf24dcpbos@webrtc.org#include "webrtc/video/transport_adapter.h" 39ce8510901416e37afabb0a54c6e10bec6db63a42pbos@webrtc.org 40ce8510901416e37afabb0a54c6e10bec6db63a42pbos@webrtc.orgnamespace webrtc { 41ce8510901416e37afabb0a54c6e10bec6db63a42pbos@webrtc.org 4251e010182b9947c9656f9e81a6a12f64a8e21788pbos@webrtc.orgstatic unsigned int kDefaultTimeoutMs = 30 * 1000; 4351e010182b9947c9656f9e81a6a12f64a8e21788pbos@webrtc.orgstatic unsigned int kLongTimeoutMs = 120 * 1000; 444b50db1f8ce21cc7faf4f7c80b6a492dffb2a1d5pbos@webrtc.orgstatic const uint32_t kSendSsrc = 0x654321; 45c71929dce136f9bc59fcc7ceb172cf74fc507ea9pbos@webrtc.orgstatic const uint32_t kSendRtxSsrc = 0x424242; 464b50db1f8ce21cc7faf4f7c80b6a492dffb2a1d5pbos@webrtc.orgstatic const uint32_t kReceiverLocalSsrc = 0x123456; 474985c7b14f9ec3840d1f49007145abe7d889fd96stefan@webrtc.orgstatic const uint8_t kSendPayloadType = 125; 48c71929dce136f9bc59fcc7ceb172cf74fc507ea9pbos@webrtc.orgstatic const uint8_t kSendRtxPayloadType = 126; 49ea15f8d77dd35ea068ee01325fb1602e9a0b7771pbos@webrtc.orgstatic const int kRedPayloadType = 118; 50ea15f8d77dd35ea068ee01325fb1602e9a0b7771pbos@webrtc.orgstatic const int kUlpfecPayloadType = 119; 5151e010182b9947c9656f9e81a6a12f64a8e21788pbos@webrtc.org 52362e3e55056af7675a4d79dc94f1c30bbbf90569pbos@webrtc.orgclass CallTest : public ::testing::Test { 53ce8510901416e37afabb0a54c6e10bec6db63a42pbos@webrtc.org public: 5428a116612e93168906d26fc69c43b10afe434c68pbos@webrtc.org CallTest() 55618a0ec1d2c17d485b7ce51cbfd282e6bae8e019pbos@webrtc.org : send_stream_(NULL), 56618a0ec1d2c17d485b7ce51cbfd282e6bae8e019pbos@webrtc.org receive_stream_(NULL), 57618a0ec1d2c17d485b7ce51cbfd282e6bae8e019pbos@webrtc.org fake_encoder_(Clock::GetRealTimeClock()) {} 58ce8510901416e37afabb0a54c6e10bec6db63a42pbos@webrtc.org 5946f72884ad5c4078fa324626aa69e4860e4d4ae2pbos@webrtc.org virtual ~CallTest() { 608ce445ecc8a3fbf2a7517f71e778948f6a8e3d2fpbos@webrtc.org EXPECT_EQ(NULL, send_stream_); 618ce445ecc8a3fbf2a7517f71e778948f6a8e3d2fpbos@webrtc.org EXPECT_EQ(NULL, receive_stream_); 628ce445ecc8a3fbf2a7517f71e778948f6a8e3d2fpbos@webrtc.org } 638ce445ecc8a3fbf2a7517f71e778948f6a8e3d2fpbos@webrtc.org 648ce445ecc8a3fbf2a7517f71e778948f6a8e3d2fpbos@webrtc.org protected: 65b5d2d165c78331b337bc372babc3a1a3e62172afpbos@webrtc.org void CreateCalls(const Call::Config& sender_config, 66b5d2d165c78331b337bc372babc3a1a3e62172afpbos@webrtc.org const Call::Config& receiver_config) { 67bf6d5729629fc98dbbf8a4965cec1efe93cad895pbos@webrtc.org sender_call_.reset(Call::Create(sender_config)); 68bf6d5729629fc98dbbf8a4965cec1efe93cad895pbos@webrtc.org receiver_call_.reset(Call::Create(receiver_config)); 698ce445ecc8a3fbf2a7517f71e778948f6a8e3d2fpbos@webrtc.org } 70ce8510901416e37afabb0a54c6e10bec6db63a42pbos@webrtc.org 718ce445ecc8a3fbf2a7517f71e778948f6a8e3d2fpbos@webrtc.org void CreateTestConfigs() { 728ce445ecc8a3fbf2a7517f71e778948f6a8e3d2fpbos@webrtc.org send_config_ = sender_call_->GetDefaultSendConfig(); 738ce445ecc8a3fbf2a7517f71e778948f6a8e3d2fpbos@webrtc.org receive_config_ = receiver_call_->GetDefaultReceiveConfig(); 74ce8510901416e37afabb0a54c6e10bec6db63a42pbos@webrtc.org 754b50db1f8ce21cc7faf4f7c80b6a492dffb2a1d5pbos@webrtc.org send_config_.rtp.ssrcs.push_back(kSendSsrc); 76bdfcddf7091e92134143e9a2d9ccce908e43979epbos@webrtc.org send_config_.encoder_settings.encoder = &fake_encoder_; 77bdfcddf7091e92134143e9a2d9ccce908e43979epbos@webrtc.org send_config_.encoder_settings.payload_name = "FAKE"; 78bdfcddf7091e92134143e9a2d9ccce908e43979epbos@webrtc.org send_config_.encoder_settings.payload_type = kSendPayloadType; 79bdfcddf7091e92134143e9a2d9ccce908e43979epbos@webrtc.org video_streams_ = test::CreateVideoStreams(1); 80618a0ec1d2c17d485b7ce51cbfd282e6bae8e019pbos@webrtc.org 81e2a7a77646b23fb3704d267e6079e04bde493543pbos@webrtc.org assert(receive_config_.codecs.empty()); 82e2a7a77646b23fb3704d267e6079e04bde493543pbos@webrtc.org VideoCodec codec = 83e2a7a77646b23fb3704d267e6079e04bde493543pbos@webrtc.org test::CreateDecoderVideoCodec(send_config_.encoder_settings); 84e2a7a77646b23fb3704d267e6079e04bde493543pbos@webrtc.org receive_config_.codecs.push_back(codec); 85618a0ec1d2c17d485b7ce51cbfd282e6bae8e019pbos@webrtc.org ExternalVideoDecoder decoder; 86618a0ec1d2c17d485b7ce51cbfd282e6bae8e019pbos@webrtc.org decoder.decoder = &fake_decoder_; 87e2a7a77646b23fb3704d267e6079e04bde493543pbos@webrtc.org decoder.payload_type = send_config_.encoder_settings.payload_type; 88618a0ec1d2c17d485b7ce51cbfd282e6bae8e019pbos@webrtc.org receive_config_.external_decoders.push_back(decoder); 894b50db1f8ce21cc7faf4f7c80b6a492dffb2a1d5pbos@webrtc.org receive_config_.rtp.remote_ssrc = send_config_.rtp.ssrcs[0]; 904b50db1f8ce21cc7faf4f7c80b6a492dffb2a1d5pbos@webrtc.org receive_config_.rtp.local_ssrc = kReceiverLocalSsrc; 918ce445ecc8a3fbf2a7517f71e778948f6a8e3d2fpbos@webrtc.org } 92ce8510901416e37afabb0a54c6e10bec6db63a42pbos@webrtc.org 938ce445ecc8a3fbf2a7517f71e778948f6a8e3d2fpbos@webrtc.org void CreateStreams() { 948ce445ecc8a3fbf2a7517f71e778948f6a8e3d2fpbos@webrtc.org assert(send_stream_ == NULL); 958ce445ecc8a3fbf2a7517f71e778948f6a8e3d2fpbos@webrtc.org assert(receive_stream_ == NULL); 96ce8510901416e37afabb0a54c6e10bec6db63a42pbos@webrtc.org 97bdfcddf7091e92134143e9a2d9ccce908e43979epbos@webrtc.org send_stream_ = 98bdfcddf7091e92134143e9a2d9ccce908e43979epbos@webrtc.org sender_call_->CreateVideoSendStream(send_config_, video_streams_, NULL); 99964d78e5c80ec8e4cbaeece5f119806b1ef9ea22pbos@webrtc.org receive_stream_ = receiver_call_->CreateVideoReceiveStream(receive_config_); 1008ce445ecc8a3fbf2a7517f71e778948f6a8e3d2fpbos@webrtc.org } 101ce8510901416e37afabb0a54c6e10bec6db63a42pbos@webrtc.org 1028ce445ecc8a3fbf2a7517f71e778948f6a8e3d2fpbos@webrtc.org void CreateFrameGenerator() { 103bdfcddf7091e92134143e9a2d9ccce908e43979epbos@webrtc.org frame_generator_capturer_.reset( 104bdfcddf7091e92134143e9a2d9ccce908e43979epbos@webrtc.org test::FrameGeneratorCapturer::Create(send_stream_->Input(), 105bdfcddf7091e92134143e9a2d9ccce908e43979epbos@webrtc.org video_streams_[0].width, 106bdfcddf7091e92134143e9a2d9ccce908e43979epbos@webrtc.org video_streams_[0].height, 107bdfcddf7091e92134143e9a2d9ccce908e43979epbos@webrtc.org 30, 108bdfcddf7091e92134143e9a2d9ccce908e43979epbos@webrtc.org Clock::GetRealTimeClock())); 1098ce445ecc8a3fbf2a7517f71e778948f6a8e3d2fpbos@webrtc.org } 110ce8510901416e37afabb0a54c6e10bec6db63a42pbos@webrtc.org 1118ce445ecc8a3fbf2a7517f71e778948f6a8e3d2fpbos@webrtc.org void StartSending() { 11216a058a180164c32a13f3406d35cc3ef1ad569c4pbos@webrtc.org receive_stream_->Start(); 11316a058a180164c32a13f3406d35cc3ef1ad569c4pbos@webrtc.org send_stream_->Start(); 114c5b5ad1aac76a7379ab0a0a4e6eab0811f5bfc37pbos@webrtc.org if (frame_generator_capturer_.get() != NULL) 115c5b5ad1aac76a7379ab0a0a4e6eab0811f5bfc37pbos@webrtc.org frame_generator_capturer_->Start(); 1168ce445ecc8a3fbf2a7517f71e778948f6a8e3d2fpbos@webrtc.org } 1178ce445ecc8a3fbf2a7517f71e778948f6a8e3d2fpbos@webrtc.org 1188ce445ecc8a3fbf2a7517f71e778948f6a8e3d2fpbos@webrtc.org void StopSending() { 119c5b5ad1aac76a7379ab0a0a4e6eab0811f5bfc37pbos@webrtc.org if (frame_generator_capturer_.get() != NULL) 120c5b5ad1aac76a7379ab0a0a4e6eab0811f5bfc37pbos@webrtc.org frame_generator_capturer_->Stop(); 1210020858e503d18322766b76443d83bfa5db4bffbpbos@webrtc.org if (send_stream_ != NULL) 12216a058a180164c32a13f3406d35cc3ef1ad569c4pbos@webrtc.org send_stream_->Stop(); 1230020858e503d18322766b76443d83bfa5db4bffbpbos@webrtc.org if (receive_stream_ != NULL) 12416a058a180164c32a13f3406d35cc3ef1ad569c4pbos@webrtc.org receive_stream_->Stop(); 1258ce445ecc8a3fbf2a7517f71e778948f6a8e3d2fpbos@webrtc.org } 1268ce445ecc8a3fbf2a7517f71e778948f6a8e3d2fpbos@webrtc.org 1278ce445ecc8a3fbf2a7517f71e778948f6a8e3d2fpbos@webrtc.org void DestroyStreams() { 1280020858e503d18322766b76443d83bfa5db4bffbpbos@webrtc.org if (send_stream_ != NULL) 12912a93e063c94500f8fe0a045fc381a816fdf3c69pbos@webrtc.org sender_call_->DestroyVideoSendStream(send_stream_); 1300020858e503d18322766b76443d83bfa5db4bffbpbos@webrtc.org if (receive_stream_ != NULL) 13112a93e063c94500f8fe0a045fc381a816fdf3c69pbos@webrtc.org receiver_call_->DestroyVideoReceiveStream(receive_stream_); 132bf6d5729629fc98dbbf8a4965cec1efe93cad895pbos@webrtc.org send_stream_ = NULL; 1338ce445ecc8a3fbf2a7517f71e778948f6a8e3d2fpbos@webrtc.org receive_stream_ = NULL; 1348ce445ecc8a3fbf2a7517f71e778948f6a8e3d2fpbos@webrtc.org } 135ce8510901416e37afabb0a54c6e10bec6db63a42pbos@webrtc.org 136c71929dce136f9bc59fcc7ceb172cf74fc507ea9pbos@webrtc.org void DecodesRetransmittedFrame(bool retransmit_over_rtx); 1378ce445ecc8a3fbf2a7517f71e778948f6a8e3d2fpbos@webrtc.org void ReceivesPliAndRecovers(int rtp_history_ms); 13851e010182b9947c9656f9e81a6a12f64a8e21788pbos@webrtc.org void RespectsRtcpMode(newapi::RtcpMode rtcp_mode); 139b4263e09399b251e5cf306b2ade0d0f768d3cb61asapersson@webrtc.org void TestXrReceiverReferenceTimeReport(bool enable_rrtr); 140ce8510901416e37afabb0a54c6e10bec6db63a42pbos@webrtc.org 141bf6d5729629fc98dbbf8a4965cec1efe93cad895pbos@webrtc.org scoped_ptr<Call> sender_call_; 142bf6d5729629fc98dbbf8a4965cec1efe93cad895pbos@webrtc.org scoped_ptr<Call> receiver_call_; 1438ce445ecc8a3fbf2a7517f71e778948f6a8e3d2fpbos@webrtc.org 144c1797061756f40b9b1f3f3e82fc040ce18ecd43cpbos@webrtc.org VideoSendStream::Config send_config_; 145bdfcddf7091e92134143e9a2d9ccce908e43979epbos@webrtc.org std::vector<VideoStream> video_streams_; 146c1797061756f40b9b1f3f3e82fc040ce18ecd43cpbos@webrtc.org VideoReceiveStream::Config receive_config_; 1478ce445ecc8a3fbf2a7517f71e778948f6a8e3d2fpbos@webrtc.org 148c1797061756f40b9b1f3f3e82fc040ce18ecd43cpbos@webrtc.org VideoSendStream* send_stream_; 149c1797061756f40b9b1f3f3e82fc040ce18ecd43cpbos@webrtc.org VideoReceiveStream* receive_stream_; 1508ce445ecc8a3fbf2a7517f71e778948f6a8e3d2fpbos@webrtc.org 1518ce445ecc8a3fbf2a7517f71e778948f6a8e3d2fpbos@webrtc.org scoped_ptr<test::FrameGeneratorCapturer> frame_generator_capturer_; 1528ce445ecc8a3fbf2a7517f71e778948f6a8e3d2fpbos@webrtc.org 153618a0ec1d2c17d485b7ce51cbfd282e6bae8e019pbos@webrtc.org test::FakeEncoder fake_encoder_; 154618a0ec1d2c17d485b7ce51cbfd282e6bae8e019pbos@webrtc.org test::FakeDecoder fake_decoder_; 1558ce445ecc8a3fbf2a7517f71e778948f6a8e3d2fpbos@webrtc.org}; 1568ce445ecc8a3fbf2a7517f71e778948f6a8e3d2fpbos@webrtc.org 1578ce445ecc8a3fbf2a7517f71e778948f6a8e3d2fpbos@webrtc.orgclass NackObserver : public test::RtpRtcpObserver { 1585e252aced18e522340f8cd5bab35baaf8a57aa66mflodman@webrtc.org static const int kNumberOfNacksToObserve = 2; 1595e252aced18e522340f8cd5bab35baaf8a57aa66mflodman@webrtc.org static const int kLossBurstSize = 2; 1605e252aced18e522340f8cd5bab35baaf8a57aa66mflodman@webrtc.org static const int kPacketsBetweenLossBursts = 9; 161bf6d5729629fc98dbbf8a4965cec1efe93cad895pbos@webrtc.org 1628ce445ecc8a3fbf2a7517f71e778948f6a8e3d2fpbos@webrtc.org public: 163ce8510901416e37afabb0a54c6e10bec6db63a42pbos@webrtc.org NackObserver() 16451e010182b9947c9656f9e81a6a12f64a8e21788pbos@webrtc.org : test::RtpRtcpObserver(kLongTimeoutMs), 165ce8510901416e37afabb0a54c6e10bec6db63a42pbos@webrtc.org rtp_parser_(RtpHeaderParser::Create()), 166ce8510901416e37afabb0a54c6e10bec6db63a42pbos@webrtc.org sent_rtp_packets_(0), 1675e252aced18e522340f8cd5bab35baaf8a57aa66mflodman@webrtc.org packets_left_to_drop_(0), 1688ce445ecc8a3fbf2a7517f71e778948f6a8e3d2fpbos@webrtc.org nacks_left_(kNumberOfNacksToObserve) {} 169ce8510901416e37afabb0a54c6e10bec6db63a42pbos@webrtc.org 170ce8510901416e37afabb0a54c6e10bec6db63a42pbos@webrtc.org private: 1718ce445ecc8a3fbf2a7517f71e778948f6a8e3d2fpbos@webrtc.org virtual Action OnSendRtp(const uint8_t* packet, size_t length) OVERRIDE { 172ce8510901416e37afabb0a54c6e10bec6db63a42pbos@webrtc.org RTPHeader header; 173ce8510901416e37afabb0a54c6e10bec6db63a42pbos@webrtc.org EXPECT_TRUE(rtp_parser_->Parse(packet, static_cast<int>(length), &header)); 174ce8510901416e37afabb0a54c6e10bec6db63a42pbos@webrtc.org 175ce8510901416e37afabb0a54c6e10bec6db63a42pbos@webrtc.org // Never drop retransmitted packets. 176ce8510901416e37afabb0a54c6e10bec6db63a42pbos@webrtc.org if (dropped_packets_.find(header.sequenceNumber) != 177ce8510901416e37afabb0a54c6e10bec6db63a42pbos@webrtc.org dropped_packets_.end()) { 178ce8510901416e37afabb0a54c6e10bec6db63a42pbos@webrtc.org retransmitted_packets_.insert(header.sequenceNumber); 1795e252aced18e522340f8cd5bab35baaf8a57aa66mflodman@webrtc.org if (nacks_left_ == 0 && 1805e252aced18e522340f8cd5bab35baaf8a57aa66mflodman@webrtc.org retransmitted_packets_.size() == dropped_packets_.size()) { 1815e252aced18e522340f8cd5bab35baaf8a57aa66mflodman@webrtc.org observation_complete_->Set(); 1825e252aced18e522340f8cd5bab35baaf8a57aa66mflodman@webrtc.org } 1838ce445ecc8a3fbf2a7517f71e778948f6a8e3d2fpbos@webrtc.org return SEND_PACKET; 184ce8510901416e37afabb0a54c6e10bec6db63a42pbos@webrtc.org } 185ce8510901416e37afabb0a54c6e10bec6db63a42pbos@webrtc.org 1865e252aced18e522340f8cd5bab35baaf8a57aa66mflodman@webrtc.org ++sent_rtp_packets_; 1875e252aced18e522340f8cd5bab35baaf8a57aa66mflodman@webrtc.org 188ce8510901416e37afabb0a54c6e10bec6db63a42pbos@webrtc.org // Enough NACKs received, stop dropping packets. 1895e252aced18e522340f8cd5bab35baaf8a57aa66mflodman@webrtc.org if (nacks_left_ == 0) 1908ce445ecc8a3fbf2a7517f71e778948f6a8e3d2fpbos@webrtc.org return SEND_PACKET; 191ce8510901416e37afabb0a54c6e10bec6db63a42pbos@webrtc.org 1925e252aced18e522340f8cd5bab35baaf8a57aa66mflodman@webrtc.org // Check if it's time for a new loss burst. 1935e252aced18e522340f8cd5bab35baaf8a57aa66mflodman@webrtc.org if (sent_rtp_packets_ % kPacketsBetweenLossBursts == 0) 1945e252aced18e522340f8cd5bab35baaf8a57aa66mflodman@webrtc.org packets_left_to_drop_ = kLossBurstSize; 195ce8510901416e37afabb0a54c6e10bec6db63a42pbos@webrtc.org 1965e252aced18e522340f8cd5bab35baaf8a57aa66mflodman@webrtc.org if (packets_left_to_drop_ > 0) { 1975e252aced18e522340f8cd5bab35baaf8a57aa66mflodman@webrtc.org --packets_left_to_drop_; 198ce8510901416e37afabb0a54c6e10bec6db63a42pbos@webrtc.org dropped_packets_.insert(header.sequenceNumber); 1998ce445ecc8a3fbf2a7517f71e778948f6a8e3d2fpbos@webrtc.org return DROP_PACKET; 200ce8510901416e37afabb0a54c6e10bec6db63a42pbos@webrtc.org } 201ce8510901416e37afabb0a54c6e10bec6db63a42pbos@webrtc.org 2028ce445ecc8a3fbf2a7517f71e778948f6a8e3d2fpbos@webrtc.org return SEND_PACKET; 2038ce445ecc8a3fbf2a7517f71e778948f6a8e3d2fpbos@webrtc.org } 2048ce445ecc8a3fbf2a7517f71e778948f6a8e3d2fpbos@webrtc.org 2058ce445ecc8a3fbf2a7517f71e778948f6a8e3d2fpbos@webrtc.org virtual Action OnReceiveRtcp(const uint8_t* packet, size_t length) OVERRIDE { 2068ce445ecc8a3fbf2a7517f71e778948f6a8e3d2fpbos@webrtc.org RTCPUtility::RTCPParserV2 parser(packet, length, true); 2078ce445ecc8a3fbf2a7517f71e778948f6a8e3d2fpbos@webrtc.org EXPECT_TRUE(parser.IsValid()); 2088ce445ecc8a3fbf2a7517f71e778948f6a8e3d2fpbos@webrtc.org 2098ce445ecc8a3fbf2a7517f71e778948f6a8e3d2fpbos@webrtc.org RTCPUtility::RTCPPacketTypes packet_type = parser.Begin(); 2108ce445ecc8a3fbf2a7517f71e778948f6a8e3d2fpbos@webrtc.org while (packet_type != RTCPUtility::kRtcpNotValidCode) { 2115e252aced18e522340f8cd5bab35baaf8a57aa66mflodman@webrtc.org if (packet_type == RTCPUtility::kRtcpRtpfbNackCode) { 2125e252aced18e522340f8cd5bab35baaf8a57aa66mflodman@webrtc.org --nacks_left_; 2135e252aced18e522340f8cd5bab35baaf8a57aa66mflodman@webrtc.org break; 2145e252aced18e522340f8cd5bab35baaf8a57aa66mflodman@webrtc.org } 2158ce445ecc8a3fbf2a7517f71e778948f6a8e3d2fpbos@webrtc.org packet_type = parser.Iterate(); 2168ce445ecc8a3fbf2a7517f71e778948f6a8e3d2fpbos@webrtc.org } 2178ce445ecc8a3fbf2a7517f71e778948f6a8e3d2fpbos@webrtc.org return SEND_PACKET; 218ce8510901416e37afabb0a54c6e10bec6db63a42pbos@webrtc.org } 219ce8510901416e37afabb0a54c6e10bec6db63a42pbos@webrtc.org 2208ce445ecc8a3fbf2a7517f71e778948f6a8e3d2fpbos@webrtc.org private: 221ce8510901416e37afabb0a54c6e10bec6db63a42pbos@webrtc.org scoped_ptr<RtpHeaderParser> rtp_parser_; 222ce8510901416e37afabb0a54c6e10bec6db63a42pbos@webrtc.org std::set<uint16_t> dropped_packets_; 223ce8510901416e37afabb0a54c6e10bec6db63a42pbos@webrtc.org std::set<uint16_t> retransmitted_packets_; 224ce8510901416e37afabb0a54c6e10bec6db63a42pbos@webrtc.org uint64_t sent_rtp_packets_; 2255e252aced18e522340f8cd5bab35baaf8a57aa66mflodman@webrtc.org int packets_left_to_drop_; 226ce8510901416e37afabb0a54c6e10bec6db63a42pbos@webrtc.org int nacks_left_; 227ce8510901416e37afabb0a54c6e10bec6db63a42pbos@webrtc.org}; 228ce8510901416e37afabb0a54c6e10bec6db63a42pbos@webrtc.org 22975e7da3a6108c34768fc56cdb932c2919c0dd867pbos@webrtc.orgTEST_F(CallTest, ReceiverCanBeStartedTwice) { 23075e7da3a6108c34768fc56cdb932c2919c0dd867pbos@webrtc.org test::NullTransport transport; 23175e7da3a6108c34768fc56cdb932c2919c0dd867pbos@webrtc.org CreateCalls(Call::Config(&transport), Call::Config(&transport)); 23275e7da3a6108c34768fc56cdb932c2919c0dd867pbos@webrtc.org 23375e7da3a6108c34768fc56cdb932c2919c0dd867pbos@webrtc.org CreateTestConfigs(); 23475e7da3a6108c34768fc56cdb932c2919c0dd867pbos@webrtc.org CreateStreams(); 23575e7da3a6108c34768fc56cdb932c2919c0dd867pbos@webrtc.org 23616a058a180164c32a13f3406d35cc3ef1ad569c4pbos@webrtc.org receive_stream_->Start(); 23716a058a180164c32a13f3406d35cc3ef1ad569c4pbos@webrtc.org receive_stream_->Start(); 23875e7da3a6108c34768fc56cdb932c2919c0dd867pbos@webrtc.org 23975e7da3a6108c34768fc56cdb932c2919c0dd867pbos@webrtc.org DestroyStreams(); 24075e7da3a6108c34768fc56cdb932c2919c0dd867pbos@webrtc.org} 24175e7da3a6108c34768fc56cdb932c2919c0dd867pbos@webrtc.org 24275e7da3a6108c34768fc56cdb932c2919c0dd867pbos@webrtc.orgTEST_F(CallTest, ReceiverCanBeStoppedTwice) { 24375e7da3a6108c34768fc56cdb932c2919c0dd867pbos@webrtc.org test::NullTransport transport; 24475e7da3a6108c34768fc56cdb932c2919c0dd867pbos@webrtc.org CreateCalls(Call::Config(&transport), Call::Config(&transport)); 24575e7da3a6108c34768fc56cdb932c2919c0dd867pbos@webrtc.org 24675e7da3a6108c34768fc56cdb932c2919c0dd867pbos@webrtc.org CreateTestConfigs(); 24775e7da3a6108c34768fc56cdb932c2919c0dd867pbos@webrtc.org CreateStreams(); 24875e7da3a6108c34768fc56cdb932c2919c0dd867pbos@webrtc.org 24916a058a180164c32a13f3406d35cc3ef1ad569c4pbos@webrtc.org receive_stream_->Stop(); 25016a058a180164c32a13f3406d35cc3ef1ad569c4pbos@webrtc.org receive_stream_->Stop(); 25175e7da3a6108c34768fc56cdb932c2919c0dd867pbos@webrtc.org 25275e7da3a6108c34768fc56cdb932c2919c0dd867pbos@webrtc.org DestroyStreams(); 25375e7da3a6108c34768fc56cdb932c2919c0dd867pbos@webrtc.org} 25475e7da3a6108c34768fc56cdb932c2919c0dd867pbos@webrtc.org 255d60137ff1b936534b04396298b7d2f2ebbc1da82pbos@webrtc.orgTEST_F(CallTest, RendersSingleDelayedFrame) { 256d60137ff1b936534b04396298b7d2f2ebbc1da82pbos@webrtc.org static const int kWidth = 320; 257d60137ff1b936534b04396298b7d2f2ebbc1da82pbos@webrtc.org static const int kHeight = 240; 258d60137ff1b936534b04396298b7d2f2ebbc1da82pbos@webrtc.org // This constant is chosen to be higher than the timeout in the video_render 259d60137ff1b936534b04396298b7d2f2ebbc1da82pbos@webrtc.org // module. This makes sure that frames aren't dropped if there are no other 260d60137ff1b936534b04396298b7d2f2ebbc1da82pbos@webrtc.org // frames in the queue. 261d60137ff1b936534b04396298b7d2f2ebbc1da82pbos@webrtc.org static const int kDelayRenderCallbackMs = 1000; 262d60137ff1b936534b04396298b7d2f2ebbc1da82pbos@webrtc.org 263d60137ff1b936534b04396298b7d2f2ebbc1da82pbos@webrtc.org class Renderer : public VideoRenderer { 264d60137ff1b936534b04396298b7d2f2ebbc1da82pbos@webrtc.org public: 265d60137ff1b936534b04396298b7d2f2ebbc1da82pbos@webrtc.org Renderer() : event_(EventWrapper::Create()) {} 266d60137ff1b936534b04396298b7d2f2ebbc1da82pbos@webrtc.org 267d60137ff1b936534b04396298b7d2f2ebbc1da82pbos@webrtc.org virtual void RenderFrame(const I420VideoFrame& video_frame, 268d60137ff1b936534b04396298b7d2f2ebbc1da82pbos@webrtc.org int /*time_to_render_ms*/) OVERRIDE { 269d60137ff1b936534b04396298b7d2f2ebbc1da82pbos@webrtc.org event_->Set(); 270d60137ff1b936534b04396298b7d2f2ebbc1da82pbos@webrtc.org } 271d60137ff1b936534b04396298b7d2f2ebbc1da82pbos@webrtc.org 272d60137ff1b936534b04396298b7d2f2ebbc1da82pbos@webrtc.org EventTypeWrapper Wait() { return event_->Wait(kDefaultTimeoutMs); } 273d60137ff1b936534b04396298b7d2f2ebbc1da82pbos@webrtc.org 274d60137ff1b936534b04396298b7d2f2ebbc1da82pbos@webrtc.org scoped_ptr<EventWrapper> event_; 275d60137ff1b936534b04396298b7d2f2ebbc1da82pbos@webrtc.org } renderer; 276d60137ff1b936534b04396298b7d2f2ebbc1da82pbos@webrtc.org 277d60137ff1b936534b04396298b7d2f2ebbc1da82pbos@webrtc.org class TestFrameCallback : public I420FrameCallback { 278d60137ff1b936534b04396298b7d2f2ebbc1da82pbos@webrtc.org public: 279d60137ff1b936534b04396298b7d2f2ebbc1da82pbos@webrtc.org TestFrameCallback() : event_(EventWrapper::Create()) {} 280d60137ff1b936534b04396298b7d2f2ebbc1da82pbos@webrtc.org 281d60137ff1b936534b04396298b7d2f2ebbc1da82pbos@webrtc.org EventTypeWrapper Wait() { return event_->Wait(kDefaultTimeoutMs); } 282d60137ff1b936534b04396298b7d2f2ebbc1da82pbos@webrtc.org 283d60137ff1b936534b04396298b7d2f2ebbc1da82pbos@webrtc.org private: 284c71929dce136f9bc59fcc7ceb172cf74fc507ea9pbos@webrtc.org virtual void FrameCallback(I420VideoFrame* frame) OVERRIDE { 285d60137ff1b936534b04396298b7d2f2ebbc1da82pbos@webrtc.org SleepMs(kDelayRenderCallbackMs); 286d60137ff1b936534b04396298b7d2f2ebbc1da82pbos@webrtc.org event_->Set(); 287d60137ff1b936534b04396298b7d2f2ebbc1da82pbos@webrtc.org } 288d60137ff1b936534b04396298b7d2f2ebbc1da82pbos@webrtc.org 289d60137ff1b936534b04396298b7d2f2ebbc1da82pbos@webrtc.org scoped_ptr<EventWrapper> event_; 290d60137ff1b936534b04396298b7d2f2ebbc1da82pbos@webrtc.org }; 291d60137ff1b936534b04396298b7d2f2ebbc1da82pbos@webrtc.org 292d60137ff1b936534b04396298b7d2f2ebbc1da82pbos@webrtc.org test::DirectTransport sender_transport, receiver_transport; 293d60137ff1b936534b04396298b7d2f2ebbc1da82pbos@webrtc.org 294d60137ff1b936534b04396298b7d2f2ebbc1da82pbos@webrtc.org CreateCalls(Call::Config(&sender_transport), 295d60137ff1b936534b04396298b7d2f2ebbc1da82pbos@webrtc.org Call::Config(&receiver_transport)); 296d60137ff1b936534b04396298b7d2f2ebbc1da82pbos@webrtc.org 297d60137ff1b936534b04396298b7d2f2ebbc1da82pbos@webrtc.org sender_transport.SetReceiver(receiver_call_->Receiver()); 298d60137ff1b936534b04396298b7d2f2ebbc1da82pbos@webrtc.org receiver_transport.SetReceiver(sender_call_->Receiver()); 299d60137ff1b936534b04396298b7d2f2ebbc1da82pbos@webrtc.org 300d60137ff1b936534b04396298b7d2f2ebbc1da82pbos@webrtc.org CreateTestConfigs(); 301d60137ff1b936534b04396298b7d2f2ebbc1da82pbos@webrtc.org 302d60137ff1b936534b04396298b7d2f2ebbc1da82pbos@webrtc.org TestFrameCallback pre_render_callback; 303d60137ff1b936534b04396298b7d2f2ebbc1da82pbos@webrtc.org receive_config_.pre_render_callback = &pre_render_callback; 304d60137ff1b936534b04396298b7d2f2ebbc1da82pbos@webrtc.org receive_config_.renderer = &renderer; 305d60137ff1b936534b04396298b7d2f2ebbc1da82pbos@webrtc.org 306d60137ff1b936534b04396298b7d2f2ebbc1da82pbos@webrtc.org CreateStreams(); 307d60137ff1b936534b04396298b7d2f2ebbc1da82pbos@webrtc.org StartSending(); 308d60137ff1b936534b04396298b7d2f2ebbc1da82pbos@webrtc.org 309d60137ff1b936534b04396298b7d2f2ebbc1da82pbos@webrtc.org // Create frames that are smaller than the send width/height, this is done to 310d60137ff1b936534b04396298b7d2f2ebbc1da82pbos@webrtc.org // check that the callbacks are done after processing video. 311d60137ff1b936534b04396298b7d2f2ebbc1da82pbos@webrtc.org scoped_ptr<test::FrameGenerator> frame_generator( 312d60137ff1b936534b04396298b7d2f2ebbc1da82pbos@webrtc.org test::FrameGenerator::Create(kWidth, kHeight)); 313d60137ff1b936534b04396298b7d2f2ebbc1da82pbos@webrtc.org send_stream_->Input()->SwapFrame(frame_generator->NextFrame()); 314d60137ff1b936534b04396298b7d2f2ebbc1da82pbos@webrtc.org EXPECT_EQ(kEventSignaled, pre_render_callback.Wait()) 315d60137ff1b936534b04396298b7d2f2ebbc1da82pbos@webrtc.org << "Timed out while waiting for pre-render callback."; 316d60137ff1b936534b04396298b7d2f2ebbc1da82pbos@webrtc.org EXPECT_EQ(kEventSignaled, renderer.Wait()) 317d60137ff1b936534b04396298b7d2f2ebbc1da82pbos@webrtc.org << "Timed out while waiting for the frame to render."; 318d60137ff1b936534b04396298b7d2f2ebbc1da82pbos@webrtc.org 319d60137ff1b936534b04396298b7d2f2ebbc1da82pbos@webrtc.org StopSending(); 320d60137ff1b936534b04396298b7d2f2ebbc1da82pbos@webrtc.org 321d60137ff1b936534b04396298b7d2f2ebbc1da82pbos@webrtc.org sender_transport.StopSending(); 322d60137ff1b936534b04396298b7d2f2ebbc1da82pbos@webrtc.org receiver_transport.StopSending(); 323d60137ff1b936534b04396298b7d2f2ebbc1da82pbos@webrtc.org 324d60137ff1b936534b04396298b7d2f2ebbc1da82pbos@webrtc.org DestroyStreams(); 325d60137ff1b936534b04396298b7d2f2ebbc1da82pbos@webrtc.org} 326d60137ff1b936534b04396298b7d2f2ebbc1da82pbos@webrtc.org 327c5b5ad1aac76a7379ab0a0a4e6eab0811f5bfc37pbos@webrtc.orgTEST_F(CallTest, TransmitsFirstFrame) { 328c5b5ad1aac76a7379ab0a0a4e6eab0811f5bfc37pbos@webrtc.org class Renderer : public VideoRenderer { 329c5b5ad1aac76a7379ab0a0a4e6eab0811f5bfc37pbos@webrtc.org public: 330c5b5ad1aac76a7379ab0a0a4e6eab0811f5bfc37pbos@webrtc.org Renderer() : event_(EventWrapper::Create()) {} 331c5b5ad1aac76a7379ab0a0a4e6eab0811f5bfc37pbos@webrtc.org 332c5b5ad1aac76a7379ab0a0a4e6eab0811f5bfc37pbos@webrtc.org virtual void RenderFrame(const I420VideoFrame& video_frame, 333c5b5ad1aac76a7379ab0a0a4e6eab0811f5bfc37pbos@webrtc.org int /*time_to_render_ms*/) OVERRIDE { 334c5b5ad1aac76a7379ab0a0a4e6eab0811f5bfc37pbos@webrtc.org event_->Set(); 335c5b5ad1aac76a7379ab0a0a4e6eab0811f5bfc37pbos@webrtc.org } 336c5b5ad1aac76a7379ab0a0a4e6eab0811f5bfc37pbos@webrtc.org 337c5b5ad1aac76a7379ab0a0a4e6eab0811f5bfc37pbos@webrtc.org EventTypeWrapper Wait() { return event_->Wait(kDefaultTimeoutMs); } 338c5b5ad1aac76a7379ab0a0a4e6eab0811f5bfc37pbos@webrtc.org 339c5b5ad1aac76a7379ab0a0a4e6eab0811f5bfc37pbos@webrtc.org scoped_ptr<EventWrapper> event_; 340c5b5ad1aac76a7379ab0a0a4e6eab0811f5bfc37pbos@webrtc.org } renderer; 341c5b5ad1aac76a7379ab0a0a4e6eab0811f5bfc37pbos@webrtc.org 342c5b5ad1aac76a7379ab0a0a4e6eab0811f5bfc37pbos@webrtc.org test::DirectTransport sender_transport, receiver_transport; 343c5b5ad1aac76a7379ab0a0a4e6eab0811f5bfc37pbos@webrtc.org 344c5b5ad1aac76a7379ab0a0a4e6eab0811f5bfc37pbos@webrtc.org CreateCalls(Call::Config(&sender_transport), 345c5b5ad1aac76a7379ab0a0a4e6eab0811f5bfc37pbos@webrtc.org Call::Config(&receiver_transport)); 346c5b5ad1aac76a7379ab0a0a4e6eab0811f5bfc37pbos@webrtc.org 347c5b5ad1aac76a7379ab0a0a4e6eab0811f5bfc37pbos@webrtc.org sender_transport.SetReceiver(receiver_call_->Receiver()); 348c5b5ad1aac76a7379ab0a0a4e6eab0811f5bfc37pbos@webrtc.org receiver_transport.SetReceiver(sender_call_->Receiver()); 349c5b5ad1aac76a7379ab0a0a4e6eab0811f5bfc37pbos@webrtc.org 350c5b5ad1aac76a7379ab0a0a4e6eab0811f5bfc37pbos@webrtc.org CreateTestConfigs(); 351c5b5ad1aac76a7379ab0a0a4e6eab0811f5bfc37pbos@webrtc.org receive_config_.renderer = &renderer; 352c5b5ad1aac76a7379ab0a0a4e6eab0811f5bfc37pbos@webrtc.org 353c5b5ad1aac76a7379ab0a0a4e6eab0811f5bfc37pbos@webrtc.org CreateStreams(); 354c5b5ad1aac76a7379ab0a0a4e6eab0811f5bfc37pbos@webrtc.org StartSending(); 355c5b5ad1aac76a7379ab0a0a4e6eab0811f5bfc37pbos@webrtc.org 356c5b5ad1aac76a7379ab0a0a4e6eab0811f5bfc37pbos@webrtc.org scoped_ptr<test::FrameGenerator> frame_generator(test::FrameGenerator::Create( 357bdfcddf7091e92134143e9a2d9ccce908e43979epbos@webrtc.org video_streams_[0].width, video_streams_[0].height)); 358c33d37ce205e22c0e090b0b285ed963686bf24dcpbos@webrtc.org send_stream_->Input()->SwapFrame(frame_generator->NextFrame()); 359c5b5ad1aac76a7379ab0a0a4e6eab0811f5bfc37pbos@webrtc.org 360c5b5ad1aac76a7379ab0a0a4e6eab0811f5bfc37pbos@webrtc.org EXPECT_EQ(kEventSignaled, renderer.Wait()) 361c5b5ad1aac76a7379ab0a0a4e6eab0811f5bfc37pbos@webrtc.org << "Timed out while waiting for the frame to render."; 362c5b5ad1aac76a7379ab0a0a4e6eab0811f5bfc37pbos@webrtc.org 363c5b5ad1aac76a7379ab0a0a4e6eab0811f5bfc37pbos@webrtc.org StopSending(); 364c5b5ad1aac76a7379ab0a0a4e6eab0811f5bfc37pbos@webrtc.org 365c5b5ad1aac76a7379ab0a0a4e6eab0811f5bfc37pbos@webrtc.org sender_transport.StopSending(); 366c5b5ad1aac76a7379ab0a0a4e6eab0811f5bfc37pbos@webrtc.org receiver_transport.StopSending(); 367c5b5ad1aac76a7379ab0a0a4e6eab0811f5bfc37pbos@webrtc.org 368c5b5ad1aac76a7379ab0a0a4e6eab0811f5bfc37pbos@webrtc.org DestroyStreams(); 369c5b5ad1aac76a7379ab0a0a4e6eab0811f5bfc37pbos@webrtc.org} 370c5b5ad1aac76a7379ab0a0a4e6eab0811f5bfc37pbos@webrtc.org 3714b50db1f8ce21cc7faf4f7c80b6a492dffb2a1d5pbos@webrtc.orgTEST_F(CallTest, ReceiverUsesLocalSsrc) { 3724b50db1f8ce21cc7faf4f7c80b6a492dffb2a1d5pbos@webrtc.org class SyncRtcpObserver : public test::RtpRtcpObserver { 3734b50db1f8ce21cc7faf4f7c80b6a492dffb2a1d5pbos@webrtc.org public: 3744b50db1f8ce21cc7faf4f7c80b6a492dffb2a1d5pbos@webrtc.org SyncRtcpObserver() : test::RtpRtcpObserver(kDefaultTimeoutMs) {} 3754b50db1f8ce21cc7faf4f7c80b6a492dffb2a1d5pbos@webrtc.org 3764b50db1f8ce21cc7faf4f7c80b6a492dffb2a1d5pbos@webrtc.org virtual Action OnReceiveRtcp(const uint8_t* packet, 3774b50db1f8ce21cc7faf4f7c80b6a492dffb2a1d5pbos@webrtc.org size_t length) OVERRIDE { 3784b50db1f8ce21cc7faf4f7c80b6a492dffb2a1d5pbos@webrtc.org RTCPUtility::RTCPParserV2 parser(packet, length, true); 3794b50db1f8ce21cc7faf4f7c80b6a492dffb2a1d5pbos@webrtc.org EXPECT_TRUE(parser.IsValid()); 3804b50db1f8ce21cc7faf4f7c80b6a492dffb2a1d5pbos@webrtc.org uint32_t ssrc = 0; 3814b50db1f8ce21cc7faf4f7c80b6a492dffb2a1d5pbos@webrtc.org ssrc |= static_cast<uint32_t>(packet[4]) << 24; 3824b50db1f8ce21cc7faf4f7c80b6a492dffb2a1d5pbos@webrtc.org ssrc |= static_cast<uint32_t>(packet[5]) << 16; 3834b50db1f8ce21cc7faf4f7c80b6a492dffb2a1d5pbos@webrtc.org ssrc |= static_cast<uint32_t>(packet[6]) << 8; 3844b50db1f8ce21cc7faf4f7c80b6a492dffb2a1d5pbos@webrtc.org ssrc |= static_cast<uint32_t>(packet[7]) << 0; 3854b50db1f8ce21cc7faf4f7c80b6a492dffb2a1d5pbos@webrtc.org EXPECT_EQ(kReceiverLocalSsrc, ssrc); 3864b50db1f8ce21cc7faf4f7c80b6a492dffb2a1d5pbos@webrtc.org observation_complete_->Set(); 3874b50db1f8ce21cc7faf4f7c80b6a492dffb2a1d5pbos@webrtc.org 3884b50db1f8ce21cc7faf4f7c80b6a492dffb2a1d5pbos@webrtc.org return SEND_PACKET; 3894b50db1f8ce21cc7faf4f7c80b6a492dffb2a1d5pbos@webrtc.org } 3904b50db1f8ce21cc7faf4f7c80b6a492dffb2a1d5pbos@webrtc.org } observer; 3914b50db1f8ce21cc7faf4f7c80b6a492dffb2a1d5pbos@webrtc.org 3924b50db1f8ce21cc7faf4f7c80b6a492dffb2a1d5pbos@webrtc.org CreateCalls(Call::Config(observer.SendTransport()), 3934b50db1f8ce21cc7faf4f7c80b6a492dffb2a1d5pbos@webrtc.org Call::Config(observer.ReceiveTransport())); 3944b50db1f8ce21cc7faf4f7c80b6a492dffb2a1d5pbos@webrtc.org 3954b50db1f8ce21cc7faf4f7c80b6a492dffb2a1d5pbos@webrtc.org observer.SetReceivers(receiver_call_->Receiver(), sender_call_->Receiver()); 3964b50db1f8ce21cc7faf4f7c80b6a492dffb2a1d5pbos@webrtc.org 3974b50db1f8ce21cc7faf4f7c80b6a492dffb2a1d5pbos@webrtc.org CreateTestConfigs(); 3984b50db1f8ce21cc7faf4f7c80b6a492dffb2a1d5pbos@webrtc.org 3994b50db1f8ce21cc7faf4f7c80b6a492dffb2a1d5pbos@webrtc.org CreateStreams(); 4004b50db1f8ce21cc7faf4f7c80b6a492dffb2a1d5pbos@webrtc.org CreateFrameGenerator(); 4014b50db1f8ce21cc7faf4f7c80b6a492dffb2a1d5pbos@webrtc.org StartSending(); 4024b50db1f8ce21cc7faf4f7c80b6a492dffb2a1d5pbos@webrtc.org 4034b50db1f8ce21cc7faf4f7c80b6a492dffb2a1d5pbos@webrtc.org EXPECT_EQ(kEventSignaled, observer.Wait()) 4044b50db1f8ce21cc7faf4f7c80b6a492dffb2a1d5pbos@webrtc.org << "Timed out while waiting for a receiver RTCP packet to be sent."; 4054b50db1f8ce21cc7faf4f7c80b6a492dffb2a1d5pbos@webrtc.org 4064b50db1f8ce21cc7faf4f7c80b6a492dffb2a1d5pbos@webrtc.org StopSending(); 4074b50db1f8ce21cc7faf4f7c80b6a492dffb2a1d5pbos@webrtc.org 4084b50db1f8ce21cc7faf4f7c80b6a492dffb2a1d5pbos@webrtc.org observer.StopSending(); 4094b50db1f8ce21cc7faf4f7c80b6a492dffb2a1d5pbos@webrtc.org 4104b50db1f8ce21cc7faf4f7c80b6a492dffb2a1d5pbos@webrtc.org DestroyStreams(); 4114b50db1f8ce21cc7faf4f7c80b6a492dffb2a1d5pbos@webrtc.org} 4124b50db1f8ce21cc7faf4f7c80b6a492dffb2a1d5pbos@webrtc.org 413362e3e55056af7675a4d79dc94f1c30bbbf90569pbos@webrtc.orgTEST_F(CallTest, ReceivesAndRetransmitsNack) { 4148ce445ecc8a3fbf2a7517f71e778948f6a8e3d2fpbos@webrtc.org NackObserver observer; 415ce8510901416e37afabb0a54c6e10bec6db63a42pbos@webrtc.org 416b5d2d165c78331b337bc372babc3a1a3e62172afpbos@webrtc.org CreateCalls(Call::Config(observer.SendTransport()), 417b5d2d165c78331b337bc372babc3a1a3e62172afpbos@webrtc.org Call::Config(observer.ReceiveTransport())); 418ce8510901416e37afabb0a54c6e10bec6db63a42pbos@webrtc.org 4198ce445ecc8a3fbf2a7517f71e778948f6a8e3d2fpbos@webrtc.org observer.SetReceivers(receiver_call_->Receiver(), sender_call_->Receiver()); 4208ce445ecc8a3fbf2a7517f71e778948f6a8e3d2fpbos@webrtc.org 4218ce445ecc8a3fbf2a7517f71e778948f6a8e3d2fpbos@webrtc.org CreateTestConfigs(); 4228ce445ecc8a3fbf2a7517f71e778948f6a8e3d2fpbos@webrtc.org int rtp_history_ms = 1000; 4238ce445ecc8a3fbf2a7517f71e778948f6a8e3d2fpbos@webrtc.org send_config_.rtp.nack.rtp_history_ms = rtp_history_ms; 4248ce445ecc8a3fbf2a7517f71e778948f6a8e3d2fpbos@webrtc.org receive_config_.rtp.nack.rtp_history_ms = rtp_history_ms; 425ce8510901416e37afabb0a54c6e10bec6db63a42pbos@webrtc.org 4268ce445ecc8a3fbf2a7517f71e778948f6a8e3d2fpbos@webrtc.org CreateStreams(); 4278ce445ecc8a3fbf2a7517f71e778948f6a8e3d2fpbos@webrtc.org CreateFrameGenerator(); 4288ce445ecc8a3fbf2a7517f71e778948f6a8e3d2fpbos@webrtc.org StartSending(); 429ce8510901416e37afabb0a54c6e10bec6db63a42pbos@webrtc.org 4308ce445ecc8a3fbf2a7517f71e778948f6a8e3d2fpbos@webrtc.org // Wait() waits for an event triggered when NACKs have been received, NACKed 4318ce445ecc8a3fbf2a7517f71e778948f6a8e3d2fpbos@webrtc.org // packets retransmitted and frames rendered again. 4328ce445ecc8a3fbf2a7517f71e778948f6a8e3d2fpbos@webrtc.org EXPECT_EQ(kEventSignaled, observer.Wait()); 4338ce445ecc8a3fbf2a7517f71e778948f6a8e3d2fpbos@webrtc.org 4348ce445ecc8a3fbf2a7517f71e778948f6a8e3d2fpbos@webrtc.org StopSending(); 4358ce445ecc8a3fbf2a7517f71e778948f6a8e3d2fpbos@webrtc.org 4368ce445ecc8a3fbf2a7517f71e778948f6a8e3d2fpbos@webrtc.org observer.StopSending(); 437ea15f8d77dd35ea068ee01325fb1602e9a0b7771pbos@webrtc.org 438ea15f8d77dd35ea068ee01325fb1602e9a0b7771pbos@webrtc.org DestroyStreams(); 439ea15f8d77dd35ea068ee01325fb1602e9a0b7771pbos@webrtc.org} 440ea15f8d77dd35ea068ee01325fb1602e9a0b7771pbos@webrtc.org 441fb3f14e334ffeeeea5c9f6666b02dfdcdb268375pbos@webrtc.org// TODO(pbos): Flaky, webrtc:3269 442fb3f14e334ffeeeea5c9f6666b02dfdcdb268375pbos@webrtc.orgTEST_F(CallTest, DISABLED_CanReceiveFec) { 443ea15f8d77dd35ea068ee01325fb1602e9a0b7771pbos@webrtc.org class FecRenderObserver : public test::RtpRtcpObserver, public VideoRenderer { 444ea15f8d77dd35ea068ee01325fb1602e9a0b7771pbos@webrtc.org public: 445ea15f8d77dd35ea068ee01325fb1602e9a0b7771pbos@webrtc.org FecRenderObserver() 446ea15f8d77dd35ea068ee01325fb1602e9a0b7771pbos@webrtc.org : RtpRtcpObserver(kDefaultTimeoutMs), 447ea15f8d77dd35ea068ee01325fb1602e9a0b7771pbos@webrtc.org state_(kFirstPacket), 448ea15f8d77dd35ea068ee01325fb1602e9a0b7771pbos@webrtc.org protected_sequence_number_(0), 449ea15f8d77dd35ea068ee01325fb1602e9a0b7771pbos@webrtc.org protected_frame_timestamp_(0) {} 450ea15f8d77dd35ea068ee01325fb1602e9a0b7771pbos@webrtc.org 451ea15f8d77dd35ea068ee01325fb1602e9a0b7771pbos@webrtc.org private: 452c476e64d056c5e342bc5b23eecd493abf6d85d7fpbos@webrtc.org virtual Action OnSendRtp(const uint8_t* packet, size_t length) OVERRIDE 453c476e64d056c5e342bc5b23eecd493abf6d85d7fpbos@webrtc.org EXCLUSIVE_LOCKS_REQUIRED(crit_) { 454ea15f8d77dd35ea068ee01325fb1602e9a0b7771pbos@webrtc.org RTPHeader header; 455ea15f8d77dd35ea068ee01325fb1602e9a0b7771pbos@webrtc.org EXPECT_TRUE(parser_->Parse(packet, static_cast<int>(length), &header)); 456ea15f8d77dd35ea068ee01325fb1602e9a0b7771pbos@webrtc.org 457ea15f8d77dd35ea068ee01325fb1602e9a0b7771pbos@webrtc.org EXPECT_EQ(kRedPayloadType, header.payloadType); 458ea15f8d77dd35ea068ee01325fb1602e9a0b7771pbos@webrtc.org int encapsulated_payload_type = 459ea15f8d77dd35ea068ee01325fb1602e9a0b7771pbos@webrtc.org static_cast<int>(packet[header.headerLength]); 460ea15f8d77dd35ea068ee01325fb1602e9a0b7771pbos@webrtc.org if (encapsulated_payload_type != kSendPayloadType) 461ea15f8d77dd35ea068ee01325fb1602e9a0b7771pbos@webrtc.org EXPECT_EQ(kUlpfecPayloadType, encapsulated_payload_type); 462ea15f8d77dd35ea068ee01325fb1602e9a0b7771pbos@webrtc.org 463ea15f8d77dd35ea068ee01325fb1602e9a0b7771pbos@webrtc.org switch(state_) { 464ea15f8d77dd35ea068ee01325fb1602e9a0b7771pbos@webrtc.org case kFirstPacket: 465ea15f8d77dd35ea068ee01325fb1602e9a0b7771pbos@webrtc.org state_ = kDropEveryOtherPacketUntilFec; 466ea15f8d77dd35ea068ee01325fb1602e9a0b7771pbos@webrtc.org break; 467ea15f8d77dd35ea068ee01325fb1602e9a0b7771pbos@webrtc.org case kDropEveryOtherPacketUntilFec: 468ea15f8d77dd35ea068ee01325fb1602e9a0b7771pbos@webrtc.org if (encapsulated_payload_type == kUlpfecPayloadType) { 469ea15f8d77dd35ea068ee01325fb1602e9a0b7771pbos@webrtc.org state_ = kDropNextMediaPacket; 470ea15f8d77dd35ea068ee01325fb1602e9a0b7771pbos@webrtc.org return SEND_PACKET; 471ea15f8d77dd35ea068ee01325fb1602e9a0b7771pbos@webrtc.org } 472ea15f8d77dd35ea068ee01325fb1602e9a0b7771pbos@webrtc.org if (header.sequenceNumber % 2 == 0) 473ea15f8d77dd35ea068ee01325fb1602e9a0b7771pbos@webrtc.org return DROP_PACKET; 474ea15f8d77dd35ea068ee01325fb1602e9a0b7771pbos@webrtc.org break; 475ea15f8d77dd35ea068ee01325fb1602e9a0b7771pbos@webrtc.org case kDropNextMediaPacket: 476ea15f8d77dd35ea068ee01325fb1602e9a0b7771pbos@webrtc.org if (encapsulated_payload_type == kSendPayloadType) { 477ea15f8d77dd35ea068ee01325fb1602e9a0b7771pbos@webrtc.org protected_sequence_number_ = header.sequenceNumber; 478ea15f8d77dd35ea068ee01325fb1602e9a0b7771pbos@webrtc.org protected_frame_timestamp_ = header.timestamp; 479ea15f8d77dd35ea068ee01325fb1602e9a0b7771pbos@webrtc.org state_ = kProtectedPacketDropped; 480ea15f8d77dd35ea068ee01325fb1602e9a0b7771pbos@webrtc.org return DROP_PACKET; 481ea15f8d77dd35ea068ee01325fb1602e9a0b7771pbos@webrtc.org } 482ea15f8d77dd35ea068ee01325fb1602e9a0b7771pbos@webrtc.org break; 483ea15f8d77dd35ea068ee01325fb1602e9a0b7771pbos@webrtc.org case kProtectedPacketDropped: 484ea15f8d77dd35ea068ee01325fb1602e9a0b7771pbos@webrtc.org EXPECT_NE(header.sequenceNumber, protected_sequence_number_) 485ea15f8d77dd35ea068ee01325fb1602e9a0b7771pbos@webrtc.org << "Protected packet retransmitted. Should not happen with FEC."; 486ea15f8d77dd35ea068ee01325fb1602e9a0b7771pbos@webrtc.org break; 487ea15f8d77dd35ea068ee01325fb1602e9a0b7771pbos@webrtc.org } 488ea15f8d77dd35ea068ee01325fb1602e9a0b7771pbos@webrtc.org 489ea15f8d77dd35ea068ee01325fb1602e9a0b7771pbos@webrtc.org return SEND_PACKET; 490ea15f8d77dd35ea068ee01325fb1602e9a0b7771pbos@webrtc.org } 491ea15f8d77dd35ea068ee01325fb1602e9a0b7771pbos@webrtc.org 492ea15f8d77dd35ea068ee01325fb1602e9a0b7771pbos@webrtc.org virtual void RenderFrame(const I420VideoFrame& video_frame, 493ea15f8d77dd35ea068ee01325fb1602e9a0b7771pbos@webrtc.org int time_to_render_ms) OVERRIDE { 494c476e64d056c5e342bc5b23eecd493abf6d85d7fpbos@webrtc.org CriticalSectionScoped lock(crit_.get()); 495ea15f8d77dd35ea068ee01325fb1602e9a0b7771pbos@webrtc.org // Rendering frame with timestamp associated with dropped packet -> FEC 496ea15f8d77dd35ea068ee01325fb1602e9a0b7771pbos@webrtc.org // protection worked. 497ea15f8d77dd35ea068ee01325fb1602e9a0b7771pbos@webrtc.org if (state_ == kProtectedPacketDropped && 498ea15f8d77dd35ea068ee01325fb1602e9a0b7771pbos@webrtc.org video_frame.timestamp() == protected_frame_timestamp_) { 499ea15f8d77dd35ea068ee01325fb1602e9a0b7771pbos@webrtc.org observation_complete_->Set(); 500ea15f8d77dd35ea068ee01325fb1602e9a0b7771pbos@webrtc.org } 501ea15f8d77dd35ea068ee01325fb1602e9a0b7771pbos@webrtc.org } 502ea15f8d77dd35ea068ee01325fb1602e9a0b7771pbos@webrtc.org 503ea15f8d77dd35ea068ee01325fb1602e9a0b7771pbos@webrtc.org enum { 504ea15f8d77dd35ea068ee01325fb1602e9a0b7771pbos@webrtc.org kFirstPacket, 505ea15f8d77dd35ea068ee01325fb1602e9a0b7771pbos@webrtc.org kDropEveryOtherPacketUntilFec, 506ea15f8d77dd35ea068ee01325fb1602e9a0b7771pbos@webrtc.org kDropNextMediaPacket, 507ea15f8d77dd35ea068ee01325fb1602e9a0b7771pbos@webrtc.org kProtectedPacketDropped, 508ea15f8d77dd35ea068ee01325fb1602e9a0b7771pbos@webrtc.org } state_; 509ea15f8d77dd35ea068ee01325fb1602e9a0b7771pbos@webrtc.org 510c476e64d056c5e342bc5b23eecd493abf6d85d7fpbos@webrtc.org uint32_t protected_sequence_number_ GUARDED_BY(crit_); 511c476e64d056c5e342bc5b23eecd493abf6d85d7fpbos@webrtc.org uint32_t protected_frame_timestamp_ GUARDED_BY(crit_); 512ea15f8d77dd35ea068ee01325fb1602e9a0b7771pbos@webrtc.org } observer; 513ea15f8d77dd35ea068ee01325fb1602e9a0b7771pbos@webrtc.org 514ea15f8d77dd35ea068ee01325fb1602e9a0b7771pbos@webrtc.org CreateCalls(Call::Config(observer.SendTransport()), 515ea15f8d77dd35ea068ee01325fb1602e9a0b7771pbos@webrtc.org Call::Config(observer.ReceiveTransport())); 516ea15f8d77dd35ea068ee01325fb1602e9a0b7771pbos@webrtc.org 517ea15f8d77dd35ea068ee01325fb1602e9a0b7771pbos@webrtc.org observer.SetReceivers(receiver_call_->Receiver(), sender_call_->Receiver()); 518ea15f8d77dd35ea068ee01325fb1602e9a0b7771pbos@webrtc.org 519ea15f8d77dd35ea068ee01325fb1602e9a0b7771pbos@webrtc.org CreateTestConfigs(); 520ea15f8d77dd35ea068ee01325fb1602e9a0b7771pbos@webrtc.org // TODO(pbos): Run this test with combined NACK/FEC enabled as well. 521ea15f8d77dd35ea068ee01325fb1602e9a0b7771pbos@webrtc.org // int rtp_history_ms = 1000; 522ea15f8d77dd35ea068ee01325fb1602e9a0b7771pbos@webrtc.org // receive_config_.rtp.nack.rtp_history_ms = rtp_history_ms; 523ea15f8d77dd35ea068ee01325fb1602e9a0b7771pbos@webrtc.org // send_config_.rtp.nack.rtp_history_ms = rtp_history_ms; 524ea15f8d77dd35ea068ee01325fb1602e9a0b7771pbos@webrtc.org send_config_.rtp.fec.red_payload_type = kRedPayloadType; 525ea15f8d77dd35ea068ee01325fb1602e9a0b7771pbos@webrtc.org send_config_.rtp.fec.ulpfec_payload_type = kUlpfecPayloadType; 526ea15f8d77dd35ea068ee01325fb1602e9a0b7771pbos@webrtc.org 527ea15f8d77dd35ea068ee01325fb1602e9a0b7771pbos@webrtc.org receive_config_.rtp.fec.red_payload_type = kRedPayloadType; 528ea15f8d77dd35ea068ee01325fb1602e9a0b7771pbos@webrtc.org receive_config_.rtp.fec.ulpfec_payload_type = kUlpfecPayloadType; 529ea15f8d77dd35ea068ee01325fb1602e9a0b7771pbos@webrtc.org receive_config_.renderer = &observer; 530ea15f8d77dd35ea068ee01325fb1602e9a0b7771pbos@webrtc.org 531ea15f8d77dd35ea068ee01325fb1602e9a0b7771pbos@webrtc.org CreateStreams(); 532ea15f8d77dd35ea068ee01325fb1602e9a0b7771pbos@webrtc.org CreateFrameGenerator(); 533ea15f8d77dd35ea068ee01325fb1602e9a0b7771pbos@webrtc.org StartSending(); 534ea15f8d77dd35ea068ee01325fb1602e9a0b7771pbos@webrtc.org 535ea15f8d77dd35ea068ee01325fb1602e9a0b7771pbos@webrtc.org // Wait() waits for an event triggered when NACKs have been received, NACKed 536ea15f8d77dd35ea068ee01325fb1602e9a0b7771pbos@webrtc.org // packets retransmitted and frames rendered again. 537ea15f8d77dd35ea068ee01325fb1602e9a0b7771pbos@webrtc.org EXPECT_EQ(kEventSignaled, observer.Wait()); 538ea15f8d77dd35ea068ee01325fb1602e9a0b7771pbos@webrtc.org 539ea15f8d77dd35ea068ee01325fb1602e9a0b7771pbos@webrtc.org StopSending(); 540ea15f8d77dd35ea068ee01325fb1602e9a0b7771pbos@webrtc.org 541ea15f8d77dd35ea068ee01325fb1602e9a0b7771pbos@webrtc.org observer.StopSending(); 542618a0ec1d2c17d485b7ce51cbfd282e6bae8e019pbos@webrtc.org 543618a0ec1d2c17d485b7ce51cbfd282e6bae8e019pbos@webrtc.org DestroyStreams(); 5448ce445ecc8a3fbf2a7517f71e778948f6a8e3d2fpbos@webrtc.org} 545ce8510901416e37afabb0a54c6e10bec6db63a42pbos@webrtc.org 546c71929dce136f9bc59fcc7ceb172cf74fc507ea9pbos@webrtc.org// This test drops second RTP packet with a marker bit set, makes sure it's 547c71929dce136f9bc59fcc7ceb172cf74fc507ea9pbos@webrtc.org// retransmitted and renders. Retransmission SSRCs are also checked. 548c71929dce136f9bc59fcc7ceb172cf74fc507ea9pbos@webrtc.orgvoid CallTest::DecodesRetransmittedFrame(bool retransmit_over_rtx) { 549c71929dce136f9bc59fcc7ceb172cf74fc507ea9pbos@webrtc.org static const int kDroppedFrameNumber = 2; 550c71929dce136f9bc59fcc7ceb172cf74fc507ea9pbos@webrtc.org class RetransmissionObserver : public test::RtpRtcpObserver, 551c71929dce136f9bc59fcc7ceb172cf74fc507ea9pbos@webrtc.org public I420FrameCallback { 552c71929dce136f9bc59fcc7ceb172cf74fc507ea9pbos@webrtc.org public: 553c71929dce136f9bc59fcc7ceb172cf74fc507ea9pbos@webrtc.org RetransmissionObserver(bool expect_rtx) 554c71929dce136f9bc59fcc7ceb172cf74fc507ea9pbos@webrtc.org : RtpRtcpObserver(kDefaultTimeoutMs), 555c71929dce136f9bc59fcc7ceb172cf74fc507ea9pbos@webrtc.org retransmission_ssrc_(expect_rtx ? kSendRtxSsrc : kSendSsrc), 556c71929dce136f9bc59fcc7ceb172cf74fc507ea9pbos@webrtc.org retransmission_payload_type_(expect_rtx ? kSendRtxPayloadType 557c71929dce136f9bc59fcc7ceb172cf74fc507ea9pbos@webrtc.org : kSendPayloadType), 558c71929dce136f9bc59fcc7ceb172cf74fc507ea9pbos@webrtc.org marker_bits_observed_(0), 559c71929dce136f9bc59fcc7ceb172cf74fc507ea9pbos@webrtc.org retransmitted_timestamp_(0), 560c71929dce136f9bc59fcc7ceb172cf74fc507ea9pbos@webrtc.org frame_retransmitted_(false) {} 561c71929dce136f9bc59fcc7ceb172cf74fc507ea9pbos@webrtc.org 562c71929dce136f9bc59fcc7ceb172cf74fc507ea9pbos@webrtc.org private: 563c71929dce136f9bc59fcc7ceb172cf74fc507ea9pbos@webrtc.org virtual Action OnSendRtp(const uint8_t* packet, size_t length) OVERRIDE { 564c71929dce136f9bc59fcc7ceb172cf74fc507ea9pbos@webrtc.org RTPHeader header; 565c71929dce136f9bc59fcc7ceb172cf74fc507ea9pbos@webrtc.org EXPECT_TRUE(parser_->Parse(packet, static_cast<int>(length), &header)); 566c71929dce136f9bc59fcc7ceb172cf74fc507ea9pbos@webrtc.org 567c71929dce136f9bc59fcc7ceb172cf74fc507ea9pbos@webrtc.org if (header.timestamp == retransmitted_timestamp_) { 568c71929dce136f9bc59fcc7ceb172cf74fc507ea9pbos@webrtc.org EXPECT_EQ(retransmission_ssrc_, header.ssrc); 569c71929dce136f9bc59fcc7ceb172cf74fc507ea9pbos@webrtc.org EXPECT_EQ(retransmission_payload_type_, header.payloadType); 570c71929dce136f9bc59fcc7ceb172cf74fc507ea9pbos@webrtc.org frame_retransmitted_ = true; 571c71929dce136f9bc59fcc7ceb172cf74fc507ea9pbos@webrtc.org return SEND_PACKET; 572c71929dce136f9bc59fcc7ceb172cf74fc507ea9pbos@webrtc.org } 573c71929dce136f9bc59fcc7ceb172cf74fc507ea9pbos@webrtc.org 574c71929dce136f9bc59fcc7ceb172cf74fc507ea9pbos@webrtc.org EXPECT_EQ(kSendSsrc, header.ssrc); 575c71929dce136f9bc59fcc7ceb172cf74fc507ea9pbos@webrtc.org EXPECT_EQ(kSendPayloadType, header.payloadType); 576c71929dce136f9bc59fcc7ceb172cf74fc507ea9pbos@webrtc.org 577c71929dce136f9bc59fcc7ceb172cf74fc507ea9pbos@webrtc.org // Found the second frame's final packet, drop this and expect a 578c71929dce136f9bc59fcc7ceb172cf74fc507ea9pbos@webrtc.org // retransmission. 579c71929dce136f9bc59fcc7ceb172cf74fc507ea9pbos@webrtc.org if (header.markerBit && ++marker_bits_observed_ == kDroppedFrameNumber) { 580c71929dce136f9bc59fcc7ceb172cf74fc507ea9pbos@webrtc.org retransmitted_timestamp_ = header.timestamp; 581c71929dce136f9bc59fcc7ceb172cf74fc507ea9pbos@webrtc.org return DROP_PACKET; 582c71929dce136f9bc59fcc7ceb172cf74fc507ea9pbos@webrtc.org } 583c71929dce136f9bc59fcc7ceb172cf74fc507ea9pbos@webrtc.org 584c71929dce136f9bc59fcc7ceb172cf74fc507ea9pbos@webrtc.org return SEND_PACKET; 585c71929dce136f9bc59fcc7ceb172cf74fc507ea9pbos@webrtc.org } 586c71929dce136f9bc59fcc7ceb172cf74fc507ea9pbos@webrtc.org 587c71929dce136f9bc59fcc7ceb172cf74fc507ea9pbos@webrtc.org virtual void FrameCallback(I420VideoFrame* frame) OVERRIDE { 588c476e64d056c5e342bc5b23eecd493abf6d85d7fpbos@webrtc.org CriticalSectionScoped lock(crit_.get()); 589c71929dce136f9bc59fcc7ceb172cf74fc507ea9pbos@webrtc.org if (frame->timestamp() == retransmitted_timestamp_) { 590c71929dce136f9bc59fcc7ceb172cf74fc507ea9pbos@webrtc.org EXPECT_TRUE(frame_retransmitted_); 591c71929dce136f9bc59fcc7ceb172cf74fc507ea9pbos@webrtc.org observation_complete_->Set(); 592c71929dce136f9bc59fcc7ceb172cf74fc507ea9pbos@webrtc.org } 593c71929dce136f9bc59fcc7ceb172cf74fc507ea9pbos@webrtc.org } 594c71929dce136f9bc59fcc7ceb172cf74fc507ea9pbos@webrtc.org 595c71929dce136f9bc59fcc7ceb172cf74fc507ea9pbos@webrtc.org const uint32_t retransmission_ssrc_; 596c71929dce136f9bc59fcc7ceb172cf74fc507ea9pbos@webrtc.org const int retransmission_payload_type_; 597c71929dce136f9bc59fcc7ceb172cf74fc507ea9pbos@webrtc.org int marker_bits_observed_; 598c71929dce136f9bc59fcc7ceb172cf74fc507ea9pbos@webrtc.org uint32_t retransmitted_timestamp_; 599c71929dce136f9bc59fcc7ceb172cf74fc507ea9pbos@webrtc.org bool frame_retransmitted_; 600c71929dce136f9bc59fcc7ceb172cf74fc507ea9pbos@webrtc.org } observer(retransmit_over_rtx); 601c71929dce136f9bc59fcc7ceb172cf74fc507ea9pbos@webrtc.org 602c71929dce136f9bc59fcc7ceb172cf74fc507ea9pbos@webrtc.org CreateCalls(Call::Config(observer.SendTransport()), 603c71929dce136f9bc59fcc7ceb172cf74fc507ea9pbos@webrtc.org Call::Config(observer.ReceiveTransport())); 604c71929dce136f9bc59fcc7ceb172cf74fc507ea9pbos@webrtc.org 605c71929dce136f9bc59fcc7ceb172cf74fc507ea9pbos@webrtc.org observer.SetReceivers(receiver_call_->Receiver(), sender_call_->Receiver()); 606c71929dce136f9bc59fcc7ceb172cf74fc507ea9pbos@webrtc.org 607c71929dce136f9bc59fcc7ceb172cf74fc507ea9pbos@webrtc.org CreateTestConfigs(); 608c71929dce136f9bc59fcc7ceb172cf74fc507ea9pbos@webrtc.org send_config_.rtp.nack.rtp_history_ms = 609c71929dce136f9bc59fcc7ceb172cf74fc507ea9pbos@webrtc.org receive_config_.rtp.nack.rtp_history_ms = 1000; 610c71929dce136f9bc59fcc7ceb172cf74fc507ea9pbos@webrtc.org if (retransmit_over_rtx) { 611c71929dce136f9bc59fcc7ceb172cf74fc507ea9pbos@webrtc.org send_config_.rtp.rtx.ssrcs.push_back(kSendRtxSsrc); 612c71929dce136f9bc59fcc7ceb172cf74fc507ea9pbos@webrtc.org send_config_.rtp.rtx.payload_type = kSendRtxPayloadType; 613e2a7a77646b23fb3704d267e6079e04bde493543pbos@webrtc.org int payload_type = send_config_.encoder_settings.payload_type; 614c71929dce136f9bc59fcc7ceb172cf74fc507ea9pbos@webrtc.org receive_config_.rtp.rtx[payload_type].ssrc = kSendRtxSsrc; 615c71929dce136f9bc59fcc7ceb172cf74fc507ea9pbos@webrtc.org receive_config_.rtp.rtx[payload_type].payload_type = kSendRtxPayloadType; 616c71929dce136f9bc59fcc7ceb172cf74fc507ea9pbos@webrtc.org } 617c71929dce136f9bc59fcc7ceb172cf74fc507ea9pbos@webrtc.org receive_config_.pre_render_callback = &observer; 618c71929dce136f9bc59fcc7ceb172cf74fc507ea9pbos@webrtc.org 619c71929dce136f9bc59fcc7ceb172cf74fc507ea9pbos@webrtc.org CreateStreams(); 620c71929dce136f9bc59fcc7ceb172cf74fc507ea9pbos@webrtc.org CreateFrameGenerator(); 621c71929dce136f9bc59fcc7ceb172cf74fc507ea9pbos@webrtc.org StartSending(); 622c71929dce136f9bc59fcc7ceb172cf74fc507ea9pbos@webrtc.org 623c71929dce136f9bc59fcc7ceb172cf74fc507ea9pbos@webrtc.org EXPECT_EQ(kEventSignaled, observer.Wait()) 624c71929dce136f9bc59fcc7ceb172cf74fc507ea9pbos@webrtc.org << "Timed out while waiting for retransmission to render."; 625c71929dce136f9bc59fcc7ceb172cf74fc507ea9pbos@webrtc.org 626c71929dce136f9bc59fcc7ceb172cf74fc507ea9pbos@webrtc.org StopSending(); 627c71929dce136f9bc59fcc7ceb172cf74fc507ea9pbos@webrtc.org observer.StopSending(); 628c71929dce136f9bc59fcc7ceb172cf74fc507ea9pbos@webrtc.org DestroyStreams(); 629c71929dce136f9bc59fcc7ceb172cf74fc507ea9pbos@webrtc.org} 630c71929dce136f9bc59fcc7ceb172cf74fc507ea9pbos@webrtc.org 631c71929dce136f9bc59fcc7ceb172cf74fc507ea9pbos@webrtc.orgTEST_F(CallTest, DecodesRetransmittedFrame) { 632c71929dce136f9bc59fcc7ceb172cf74fc507ea9pbos@webrtc.org DecodesRetransmittedFrame(false); 633c71929dce136f9bc59fcc7ceb172cf74fc507ea9pbos@webrtc.org} 634c71929dce136f9bc59fcc7ceb172cf74fc507ea9pbos@webrtc.org 635c71929dce136f9bc59fcc7ceb172cf74fc507ea9pbos@webrtc.orgTEST_F(CallTest, DecodesRetransmittedFrameOverRtx) { 636c71929dce136f9bc59fcc7ceb172cf74fc507ea9pbos@webrtc.org DecodesRetransmittedFrame(true); 637c71929dce136f9bc59fcc7ceb172cf74fc507ea9pbos@webrtc.org} 638c71929dce136f9bc59fcc7ceb172cf74fc507ea9pbos@webrtc.org 63963301bd03e009d309d1fdca1217f8708be610f32pbos@webrtc.orgTEST_F(CallTest, UsesFrameCallbacks) { 64063301bd03e009d309d1fdca1217f8708be610f32pbos@webrtc.org static const int kWidth = 320; 64163301bd03e009d309d1fdca1217f8708be610f32pbos@webrtc.org static const int kHeight = 240; 64263301bd03e009d309d1fdca1217f8708be610f32pbos@webrtc.org 64363301bd03e009d309d1fdca1217f8708be610f32pbos@webrtc.org class Renderer : public VideoRenderer { 64463301bd03e009d309d1fdca1217f8708be610f32pbos@webrtc.org public: 64563301bd03e009d309d1fdca1217f8708be610f32pbos@webrtc.org Renderer() : event_(EventWrapper::Create()) {} 64663301bd03e009d309d1fdca1217f8708be610f32pbos@webrtc.org 64763301bd03e009d309d1fdca1217f8708be610f32pbos@webrtc.org virtual void RenderFrame(const I420VideoFrame& video_frame, 64863301bd03e009d309d1fdca1217f8708be610f32pbos@webrtc.org int /*time_to_render_ms*/) OVERRIDE { 64963301bd03e009d309d1fdca1217f8708be610f32pbos@webrtc.org EXPECT_EQ(0, *video_frame.buffer(kYPlane)) 65063301bd03e009d309d1fdca1217f8708be610f32pbos@webrtc.org << "Rendered frame should have zero luma which is applied by the " 65163301bd03e009d309d1fdca1217f8708be610f32pbos@webrtc.org "pre-render callback."; 65263301bd03e009d309d1fdca1217f8708be610f32pbos@webrtc.org event_->Set(); 65363301bd03e009d309d1fdca1217f8708be610f32pbos@webrtc.org } 65463301bd03e009d309d1fdca1217f8708be610f32pbos@webrtc.org 65563301bd03e009d309d1fdca1217f8708be610f32pbos@webrtc.org EventTypeWrapper Wait() { return event_->Wait(kDefaultTimeoutMs); } 65663301bd03e009d309d1fdca1217f8708be610f32pbos@webrtc.org scoped_ptr<EventWrapper> event_; 65763301bd03e009d309d1fdca1217f8708be610f32pbos@webrtc.org } renderer; 65863301bd03e009d309d1fdca1217f8708be610f32pbos@webrtc.org 65963301bd03e009d309d1fdca1217f8708be610f32pbos@webrtc.org class TestFrameCallback : public I420FrameCallback { 66063301bd03e009d309d1fdca1217f8708be610f32pbos@webrtc.org public: 66163301bd03e009d309d1fdca1217f8708be610f32pbos@webrtc.org TestFrameCallback(int expected_luma_byte, int next_luma_byte) 66263301bd03e009d309d1fdca1217f8708be610f32pbos@webrtc.org : event_(EventWrapper::Create()), 66363301bd03e009d309d1fdca1217f8708be610f32pbos@webrtc.org expected_luma_byte_(expected_luma_byte), 66463301bd03e009d309d1fdca1217f8708be610f32pbos@webrtc.org next_luma_byte_(next_luma_byte) {} 66563301bd03e009d309d1fdca1217f8708be610f32pbos@webrtc.org 66663301bd03e009d309d1fdca1217f8708be610f32pbos@webrtc.org EventTypeWrapper Wait() { return event_->Wait(kDefaultTimeoutMs); } 66763301bd03e009d309d1fdca1217f8708be610f32pbos@webrtc.org 66863301bd03e009d309d1fdca1217f8708be610f32pbos@webrtc.org private: 66963301bd03e009d309d1fdca1217f8708be610f32pbos@webrtc.org virtual void FrameCallback(I420VideoFrame* frame) { 67063301bd03e009d309d1fdca1217f8708be610f32pbos@webrtc.org EXPECT_EQ(kWidth, frame->width()) 67163301bd03e009d309d1fdca1217f8708be610f32pbos@webrtc.org << "Width not as expected, callback done before resize?"; 67263301bd03e009d309d1fdca1217f8708be610f32pbos@webrtc.org EXPECT_EQ(kHeight, frame->height()) 67363301bd03e009d309d1fdca1217f8708be610f32pbos@webrtc.org << "Height not as expected, callback done before resize?"; 67463301bd03e009d309d1fdca1217f8708be610f32pbos@webrtc.org 67563301bd03e009d309d1fdca1217f8708be610f32pbos@webrtc.org // Previous luma specified, observed luma should be fairly close. 67663301bd03e009d309d1fdca1217f8708be610f32pbos@webrtc.org if (expected_luma_byte_ != -1) { 67763301bd03e009d309d1fdca1217f8708be610f32pbos@webrtc.org EXPECT_NEAR(expected_luma_byte_, *frame->buffer(kYPlane), 10); 67863301bd03e009d309d1fdca1217f8708be610f32pbos@webrtc.org } 67963301bd03e009d309d1fdca1217f8708be610f32pbos@webrtc.org 68063301bd03e009d309d1fdca1217f8708be610f32pbos@webrtc.org memset(frame->buffer(kYPlane), 68163301bd03e009d309d1fdca1217f8708be610f32pbos@webrtc.org next_luma_byte_, 68263301bd03e009d309d1fdca1217f8708be610f32pbos@webrtc.org frame->allocated_size(kYPlane)); 68363301bd03e009d309d1fdca1217f8708be610f32pbos@webrtc.org 68463301bd03e009d309d1fdca1217f8708be610f32pbos@webrtc.org event_->Set(); 68563301bd03e009d309d1fdca1217f8708be610f32pbos@webrtc.org } 68663301bd03e009d309d1fdca1217f8708be610f32pbos@webrtc.org 68763301bd03e009d309d1fdca1217f8708be610f32pbos@webrtc.org scoped_ptr<EventWrapper> event_; 68863301bd03e009d309d1fdca1217f8708be610f32pbos@webrtc.org int expected_luma_byte_; 68963301bd03e009d309d1fdca1217f8708be610f32pbos@webrtc.org int next_luma_byte_; 69063301bd03e009d309d1fdca1217f8708be610f32pbos@webrtc.org }; 69163301bd03e009d309d1fdca1217f8708be610f32pbos@webrtc.org 69263301bd03e009d309d1fdca1217f8708be610f32pbos@webrtc.org TestFrameCallback pre_encode_callback(-1, 255); // Changes luma to 255. 69363301bd03e009d309d1fdca1217f8708be610f32pbos@webrtc.org TestFrameCallback pre_render_callback(255, 0); // Changes luma from 255 to 0. 69463301bd03e009d309d1fdca1217f8708be610f32pbos@webrtc.org 69563301bd03e009d309d1fdca1217f8708be610f32pbos@webrtc.org test::DirectTransport sender_transport, receiver_transport; 69663301bd03e009d309d1fdca1217f8708be610f32pbos@webrtc.org 69763301bd03e009d309d1fdca1217f8708be610f32pbos@webrtc.org CreateCalls(Call::Config(&sender_transport), 69863301bd03e009d309d1fdca1217f8708be610f32pbos@webrtc.org Call::Config(&receiver_transport)); 69963301bd03e009d309d1fdca1217f8708be610f32pbos@webrtc.org 70063301bd03e009d309d1fdca1217f8708be610f32pbos@webrtc.org sender_transport.SetReceiver(receiver_call_->Receiver()); 70163301bd03e009d309d1fdca1217f8708be610f32pbos@webrtc.org receiver_transport.SetReceiver(sender_call_->Receiver()); 70263301bd03e009d309d1fdca1217f8708be610f32pbos@webrtc.org 70363301bd03e009d309d1fdca1217f8708be610f32pbos@webrtc.org CreateTestConfigs(); 704e2a7a77646b23fb3704d267e6079e04bde493543pbos@webrtc.org scoped_ptr<VP8Encoder> encoder(VP8Encoder::Create()); 705e2a7a77646b23fb3704d267e6079e04bde493543pbos@webrtc.org send_config_.encoder_settings.encoder = encoder.get(); 706e2a7a77646b23fb3704d267e6079e04bde493543pbos@webrtc.org send_config_.encoder_settings.payload_name = "VP8"; 707bdfcddf7091e92134143e9a2d9ccce908e43979epbos@webrtc.org ASSERT_EQ(1u, video_streams_.size()) << "Test setup error."; 708bdfcddf7091e92134143e9a2d9ccce908e43979epbos@webrtc.org video_streams_[0].width = kWidth; 709bdfcddf7091e92134143e9a2d9ccce908e43979epbos@webrtc.org video_streams_[0].height = kHeight; 71063301bd03e009d309d1fdca1217f8708be610f32pbos@webrtc.org send_config_.pre_encode_callback = &pre_encode_callback; 711e2a7a77646b23fb3704d267e6079e04bde493543pbos@webrtc.org receive_config_.codecs.clear(); 712e2a7a77646b23fb3704d267e6079e04bde493543pbos@webrtc.org VideoCodec codec = 713e2a7a77646b23fb3704d267e6079e04bde493543pbos@webrtc.org test::CreateDecoderVideoCodec(send_config_.encoder_settings); 714e2a7a77646b23fb3704d267e6079e04bde493543pbos@webrtc.org receive_config_.external_decoders.clear(); 715e2a7a77646b23fb3704d267e6079e04bde493543pbos@webrtc.org receive_config_.codecs.push_back(codec); 71663301bd03e009d309d1fdca1217f8708be610f32pbos@webrtc.org receive_config_.pre_render_callback = &pre_render_callback; 71763301bd03e009d309d1fdca1217f8708be610f32pbos@webrtc.org receive_config_.renderer = &renderer; 71863301bd03e009d309d1fdca1217f8708be610f32pbos@webrtc.org 71963301bd03e009d309d1fdca1217f8708be610f32pbos@webrtc.org CreateStreams(); 72063301bd03e009d309d1fdca1217f8708be610f32pbos@webrtc.org StartSending(); 72163301bd03e009d309d1fdca1217f8708be610f32pbos@webrtc.org 72263301bd03e009d309d1fdca1217f8708be610f32pbos@webrtc.org // Create frames that are smaller than the send width/height, this is done to 72363301bd03e009d309d1fdca1217f8708be610f32pbos@webrtc.org // check that the callbacks are done after processing video. 72463301bd03e009d309d1fdca1217f8708be610f32pbos@webrtc.org scoped_ptr<test::FrameGenerator> frame_generator( 72563301bd03e009d309d1fdca1217f8708be610f32pbos@webrtc.org test::FrameGenerator::Create(kWidth / 2, kHeight / 2)); 726c33d37ce205e22c0e090b0b285ed963686bf24dcpbos@webrtc.org send_stream_->Input()->SwapFrame(frame_generator->NextFrame()); 72763301bd03e009d309d1fdca1217f8708be610f32pbos@webrtc.org 72863301bd03e009d309d1fdca1217f8708be610f32pbos@webrtc.org EXPECT_EQ(kEventSignaled, pre_encode_callback.Wait()) 72963301bd03e009d309d1fdca1217f8708be610f32pbos@webrtc.org << "Timed out while waiting for pre-encode callback."; 73063301bd03e009d309d1fdca1217f8708be610f32pbos@webrtc.org EXPECT_EQ(kEventSignaled, pre_render_callback.Wait()) 73163301bd03e009d309d1fdca1217f8708be610f32pbos@webrtc.org << "Timed out while waiting for pre-render callback."; 73263301bd03e009d309d1fdca1217f8708be610f32pbos@webrtc.org EXPECT_EQ(kEventSignaled, renderer.Wait()) 73363301bd03e009d309d1fdca1217f8708be610f32pbos@webrtc.org << "Timed out while waiting for the frame to render."; 73463301bd03e009d309d1fdca1217f8708be610f32pbos@webrtc.org 73563301bd03e009d309d1fdca1217f8708be610f32pbos@webrtc.org StopSending(); 73663301bd03e009d309d1fdca1217f8708be610f32pbos@webrtc.org 73763301bd03e009d309d1fdca1217f8708be610f32pbos@webrtc.org sender_transport.StopSending(); 73863301bd03e009d309d1fdca1217f8708be610f32pbos@webrtc.org receiver_transport.StopSending(); 73963301bd03e009d309d1fdca1217f8708be610f32pbos@webrtc.org 74063301bd03e009d309d1fdca1217f8708be610f32pbos@webrtc.org DestroyStreams(); 74163301bd03e009d309d1fdca1217f8708be610f32pbos@webrtc.org} 74263301bd03e009d309d1fdca1217f8708be610f32pbos@webrtc.org 74328a116612e93168906d26fc69c43b10afe434c68pbos@webrtc.orgclass PliObserver : public test::RtpRtcpObserver, public VideoRenderer { 7448ce445ecc8a3fbf2a7517f71e778948f6a8e3d2fpbos@webrtc.org static const int kInverseDropProbability = 16; 745bf6d5729629fc98dbbf8a4965cec1efe93cad895pbos@webrtc.org 7468ce445ecc8a3fbf2a7517f71e778948f6a8e3d2fpbos@webrtc.org public: 74728a116612e93168906d26fc69c43b10afe434c68pbos@webrtc.org explicit PliObserver(bool nack_enabled) 74851e010182b9947c9656f9e81a6a12f64a8e21788pbos@webrtc.org : test::RtpRtcpObserver(kLongTimeoutMs), 7498ce445ecc8a3fbf2a7517f71e778948f6a8e3d2fpbos@webrtc.org nack_enabled_(nack_enabled), 7506c172c5af42b2d10e71b12ef0ed74864dce1ecfdmflodman@webrtc.org highest_dropped_timestamp_(0), 7516c172c5af42b2d10e71b12ef0ed74864dce1ecfdmflodman@webrtc.org frames_to_drop_(0), 7528ce445ecc8a3fbf2a7517f71e778948f6a8e3d2fpbos@webrtc.org received_pli_(false) {} 7538ce445ecc8a3fbf2a7517f71e778948f6a8e3d2fpbos@webrtc.org 7548ce445ecc8a3fbf2a7517f71e778948f6a8e3d2fpbos@webrtc.org virtual Action OnSendRtp(const uint8_t* packet, size_t length) OVERRIDE { 7558ce445ecc8a3fbf2a7517f71e778948f6a8e3d2fpbos@webrtc.org RTPHeader header; 756c71929dce136f9bc59fcc7ceb172cf74fc507ea9pbos@webrtc.org EXPECT_TRUE(parser_->Parse(packet, static_cast<int>(length), &header)); 7578ce445ecc8a3fbf2a7517f71e778948f6a8e3d2fpbos@webrtc.org 7586c172c5af42b2d10e71b12ef0ed74864dce1ecfdmflodman@webrtc.org // Drop all retransmitted packets to force a PLI. 7596c172c5af42b2d10e71b12ef0ed74864dce1ecfdmflodman@webrtc.org if (header.timestamp <= highest_dropped_timestamp_) 7608ce445ecc8a3fbf2a7517f71e778948f6a8e3d2fpbos@webrtc.org return DROP_PACKET; 7618ce445ecc8a3fbf2a7517f71e778948f6a8e3d2fpbos@webrtc.org 7626c172c5af42b2d10e71b12ef0ed74864dce1ecfdmflodman@webrtc.org if (frames_to_drop_ > 0) { 7636c172c5af42b2d10e71b12ef0ed74864dce1ecfdmflodman@webrtc.org highest_dropped_timestamp_ = header.timestamp; 7646c172c5af42b2d10e71b12ef0ed74864dce1ecfdmflodman@webrtc.org --frames_to_drop_; 7658ce445ecc8a3fbf2a7517f71e778948f6a8e3d2fpbos@webrtc.org return DROP_PACKET; 7668ce445ecc8a3fbf2a7517f71e778948f6a8e3d2fpbos@webrtc.org } 7678ce445ecc8a3fbf2a7517f71e778948f6a8e3d2fpbos@webrtc.org 7688ce445ecc8a3fbf2a7517f71e778948f6a8e3d2fpbos@webrtc.org return SEND_PACKET; 769ce8510901416e37afabb0a54c6e10bec6db63a42pbos@webrtc.org } 770ce8510901416e37afabb0a54c6e10bec6db63a42pbos@webrtc.org 7718ce445ecc8a3fbf2a7517f71e778948f6a8e3d2fpbos@webrtc.org virtual Action OnReceiveRtcp(const uint8_t* packet, size_t length) OVERRIDE { 7728ce445ecc8a3fbf2a7517f71e778948f6a8e3d2fpbos@webrtc.org RTCPUtility::RTCPParserV2 parser(packet, length, true); 7738ce445ecc8a3fbf2a7517f71e778948f6a8e3d2fpbos@webrtc.org EXPECT_TRUE(parser.IsValid()); 7748ce445ecc8a3fbf2a7517f71e778948f6a8e3d2fpbos@webrtc.org 7758ce445ecc8a3fbf2a7517f71e778948f6a8e3d2fpbos@webrtc.org for (RTCPUtility::RTCPPacketTypes packet_type = parser.Begin(); 7768ce445ecc8a3fbf2a7517f71e778948f6a8e3d2fpbos@webrtc.org packet_type != RTCPUtility::kRtcpNotValidCode; 7778ce445ecc8a3fbf2a7517f71e778948f6a8e3d2fpbos@webrtc.org packet_type = parser.Iterate()) { 7788ce445ecc8a3fbf2a7517f71e778948f6a8e3d2fpbos@webrtc.org if (!nack_enabled_) 7798ce445ecc8a3fbf2a7517f71e778948f6a8e3d2fpbos@webrtc.org EXPECT_NE(packet_type, RTCPUtility::kRtcpRtpfbNackCode); 7808ce445ecc8a3fbf2a7517f71e778948f6a8e3d2fpbos@webrtc.org 7818ce445ecc8a3fbf2a7517f71e778948f6a8e3d2fpbos@webrtc.org if (packet_type == RTCPUtility::kRtcpPsfbPliCode) { 7828ce445ecc8a3fbf2a7517f71e778948f6a8e3d2fpbos@webrtc.org received_pli_ = true; 7838ce445ecc8a3fbf2a7517f71e778948f6a8e3d2fpbos@webrtc.org break; 7848ce445ecc8a3fbf2a7517f71e778948f6a8e3d2fpbos@webrtc.org } 7858ce445ecc8a3fbf2a7517f71e778948f6a8e3d2fpbos@webrtc.org } 7868ce445ecc8a3fbf2a7517f71e778948f6a8e3d2fpbos@webrtc.org return SEND_PACKET; 787ce8510901416e37afabb0a54c6e10bec6db63a42pbos@webrtc.org } 788ce8510901416e37afabb0a54c6e10bec6db63a42pbos@webrtc.org 78928a116612e93168906d26fc69c43b10afe434c68pbos@webrtc.org virtual void RenderFrame(const I420VideoFrame& video_frame, 79028a116612e93168906d26fc69c43b10afe434c68pbos@webrtc.org int time_to_render_ms) OVERRIDE { 791c476e64d056c5e342bc5b23eecd493abf6d85d7fpbos@webrtc.org CriticalSectionScoped lock(crit_.get()); 7926c172c5af42b2d10e71b12ef0ed74864dce1ecfdmflodman@webrtc.org if (received_pli_ && video_frame.timestamp() > highest_dropped_timestamp_) { 79328a116612e93168906d26fc69c43b10afe434c68pbos@webrtc.org observation_complete_->Set(); 7948ce445ecc8a3fbf2a7517f71e778948f6a8e3d2fpbos@webrtc.org } 7956c172c5af42b2d10e71b12ef0ed74864dce1ecfdmflodman@webrtc.org if (!received_pli_) 7966c172c5af42b2d10e71b12ef0ed74864dce1ecfdmflodman@webrtc.org frames_to_drop_ = kPacketsToDrop; 7978ce445ecc8a3fbf2a7517f71e778948f6a8e3d2fpbos@webrtc.org } 798ce8510901416e37afabb0a54c6e10bec6db63a42pbos@webrtc.org 7998ce445ecc8a3fbf2a7517f71e778948f6a8e3d2fpbos@webrtc.org private: 8006c172c5af42b2d10e71b12ef0ed74864dce1ecfdmflodman@webrtc.org static const int kPacketsToDrop = 1; 8016c172c5af42b2d10e71b12ef0ed74864dce1ecfdmflodman@webrtc.org 8028ce445ecc8a3fbf2a7517f71e778948f6a8e3d2fpbos@webrtc.org bool nack_enabled_; 8036c172c5af42b2d10e71b12ef0ed74864dce1ecfdmflodman@webrtc.org uint32_t highest_dropped_timestamp_; 8046c172c5af42b2d10e71b12ef0ed74864dce1ecfdmflodman@webrtc.org int frames_to_drop_; 8058ce445ecc8a3fbf2a7517f71e778948f6a8e3d2fpbos@webrtc.org bool received_pli_; 8068ce445ecc8a3fbf2a7517f71e778948f6a8e3d2fpbos@webrtc.org}; 807ce8510901416e37afabb0a54c6e10bec6db63a42pbos@webrtc.org 80828a116612e93168906d26fc69c43b10afe434c68pbos@webrtc.orgvoid CallTest::ReceivesPliAndRecovers(int rtp_history_ms) { 8098ce445ecc8a3fbf2a7517f71e778948f6a8e3d2fpbos@webrtc.org PliObserver observer(rtp_history_ms > 0); 810ce8510901416e37afabb0a54c6e10bec6db63a42pbos@webrtc.org 811b5d2d165c78331b337bc372babc3a1a3e62172afpbos@webrtc.org CreateCalls(Call::Config(observer.SendTransport()), 812b5d2d165c78331b337bc372babc3a1a3e62172afpbos@webrtc.org Call::Config(observer.ReceiveTransport())); 813ce8510901416e37afabb0a54c6e10bec6db63a42pbos@webrtc.org 8148ce445ecc8a3fbf2a7517f71e778948f6a8e3d2fpbos@webrtc.org observer.SetReceivers(receiver_call_->Receiver(), sender_call_->Receiver()); 815ce8510901416e37afabb0a54c6e10bec6db63a42pbos@webrtc.org 8168ce445ecc8a3fbf2a7517f71e778948f6a8e3d2fpbos@webrtc.org CreateTestConfigs(); 8178ce445ecc8a3fbf2a7517f71e778948f6a8e3d2fpbos@webrtc.org send_config_.rtp.nack.rtp_history_ms = rtp_history_ms; 8188ce445ecc8a3fbf2a7517f71e778948f6a8e3d2fpbos@webrtc.org receive_config_.rtp.nack.rtp_history_ms = rtp_history_ms; 81928a116612e93168906d26fc69c43b10afe434c68pbos@webrtc.org receive_config_.renderer = &observer; 820ce8510901416e37afabb0a54c6e10bec6db63a42pbos@webrtc.org 8218ce445ecc8a3fbf2a7517f71e778948f6a8e3d2fpbos@webrtc.org CreateStreams(); 8228ce445ecc8a3fbf2a7517f71e778948f6a8e3d2fpbos@webrtc.org CreateFrameGenerator(); 8238ce445ecc8a3fbf2a7517f71e778948f6a8e3d2fpbos@webrtc.org StartSending(); 824ce8510901416e37afabb0a54c6e10bec6db63a42pbos@webrtc.org 8258ce445ecc8a3fbf2a7517f71e778948f6a8e3d2fpbos@webrtc.org // Wait() waits for an event triggered when Pli has been received and frames 8268ce445ecc8a3fbf2a7517f71e778948f6a8e3d2fpbos@webrtc.org // have been rendered afterwards. 827ce8510901416e37afabb0a54c6e10bec6db63a42pbos@webrtc.org EXPECT_EQ(kEventSignaled, observer.Wait()); 828ce8510901416e37afabb0a54c6e10bec6db63a42pbos@webrtc.org 8298ce445ecc8a3fbf2a7517f71e778948f6a8e3d2fpbos@webrtc.org StopSending(); 8308ce445ecc8a3fbf2a7517f71e778948f6a8e3d2fpbos@webrtc.org 831fe881f62ea79a98b997af7d6fb0346dcb68acccepbos@webrtc.org observer.StopSending(); 832618a0ec1d2c17d485b7ce51cbfd282e6bae8e019pbos@webrtc.org 833618a0ec1d2c17d485b7ce51cbfd282e6bae8e019pbos@webrtc.org DestroyStreams(); 834ce8510901416e37afabb0a54c6e10bec6db63a42pbos@webrtc.org} 835ce8510901416e37afabb0a54c6e10bec6db63a42pbos@webrtc.org 836362e3e55056af7675a4d79dc94f1c30bbbf90569pbos@webrtc.orgTEST_F(CallTest, ReceivesPliAndRecoversWithNack) { 8378ce445ecc8a3fbf2a7517f71e778948f6a8e3d2fpbos@webrtc.org ReceivesPliAndRecovers(1000); 8388ce445ecc8a3fbf2a7517f71e778948f6a8e3d2fpbos@webrtc.org} 8398ce445ecc8a3fbf2a7517f71e778948f6a8e3d2fpbos@webrtc.org 8408ce445ecc8a3fbf2a7517f71e778948f6a8e3d2fpbos@webrtc.org// TODO(pbos): Enable this when 2250 is resolved. 841362e3e55056af7675a4d79dc94f1c30bbbf90569pbos@webrtc.orgTEST_F(CallTest, DISABLED_ReceivesPliAndRecoversWithoutNack) { 8428ce445ecc8a3fbf2a7517f71e778948f6a8e3d2fpbos@webrtc.org ReceivesPliAndRecovers(0); 8438ce445ecc8a3fbf2a7517f71e778948f6a8e3d2fpbos@webrtc.org} 8448ce445ecc8a3fbf2a7517f71e778948f6a8e3d2fpbos@webrtc.org 845bc57e0f1a00227c0cec3d429fc58cc442d07b509pbos@webrtc.orgTEST_F(CallTest, UnknownRtpPacketGivesUnknownSsrcReturnCode) { 8460020858e503d18322766b76443d83bfa5db4bffbpbos@webrtc.org class PacketInputObserver : public PacketReceiver { 8470020858e503d18322766b76443d83bfa5db4bffbpbos@webrtc.org public: 8480020858e503d18322766b76443d83bfa5db4bffbpbos@webrtc.org explicit PacketInputObserver(PacketReceiver* receiver) 8490020858e503d18322766b76443d83bfa5db4bffbpbos@webrtc.org : receiver_(receiver), delivered_packet_(EventWrapper::Create()) {} 8500020858e503d18322766b76443d83bfa5db4bffbpbos@webrtc.org 85151e010182b9947c9656f9e81a6a12f64a8e21788pbos@webrtc.org EventTypeWrapper Wait() { 85251e010182b9947c9656f9e81a6a12f64a8e21788pbos@webrtc.org return delivered_packet_->Wait(kDefaultTimeoutMs); 85351e010182b9947c9656f9e81a6a12f64a8e21788pbos@webrtc.org } 8540020858e503d18322766b76443d83bfa5db4bffbpbos@webrtc.org 8550020858e503d18322766b76443d83bfa5db4bffbpbos@webrtc.org private: 856bc57e0f1a00227c0cec3d429fc58cc442d07b509pbos@webrtc.org virtual DeliveryStatus DeliverPacket(const uint8_t* packet, 857bc57e0f1a00227c0cec3d429fc58cc442d07b509pbos@webrtc.org size_t length) OVERRIDE { 8580020858e503d18322766b76443d83bfa5db4bffbpbos@webrtc.org if (RtpHeaderParser::IsRtcp(packet, static_cast<int>(length))) { 8590020858e503d18322766b76443d83bfa5db4bffbpbos@webrtc.org return receiver_->DeliverPacket(packet, length); 8600020858e503d18322766b76443d83bfa5db4bffbpbos@webrtc.org } else { 861bc57e0f1a00227c0cec3d429fc58cc442d07b509pbos@webrtc.org DeliveryStatus delivery_status = 862bc57e0f1a00227c0cec3d429fc58cc442d07b509pbos@webrtc.org receiver_->DeliverPacket(packet, length); 863bc57e0f1a00227c0cec3d429fc58cc442d07b509pbos@webrtc.org EXPECT_EQ(DELIVERY_UNKNOWN_SSRC, delivery_status); 8640020858e503d18322766b76443d83bfa5db4bffbpbos@webrtc.org delivered_packet_->Set(); 865bc57e0f1a00227c0cec3d429fc58cc442d07b509pbos@webrtc.org return delivery_status; 8660020858e503d18322766b76443d83bfa5db4bffbpbos@webrtc.org } 8670020858e503d18322766b76443d83bfa5db4bffbpbos@webrtc.org } 8680020858e503d18322766b76443d83bfa5db4bffbpbos@webrtc.org 8690020858e503d18322766b76443d83bfa5db4bffbpbos@webrtc.org PacketReceiver* receiver_; 8700020858e503d18322766b76443d83bfa5db4bffbpbos@webrtc.org scoped_ptr<EventWrapper> delivered_packet_; 8710020858e503d18322766b76443d83bfa5db4bffbpbos@webrtc.org }; 8720020858e503d18322766b76443d83bfa5db4bffbpbos@webrtc.org 8730020858e503d18322766b76443d83bfa5db4bffbpbos@webrtc.org test::DirectTransport send_transport, receive_transport; 8740020858e503d18322766b76443d83bfa5db4bffbpbos@webrtc.org 875b5d2d165c78331b337bc372babc3a1a3e62172afpbos@webrtc.org CreateCalls(Call::Config(&send_transport), Call::Config(&receive_transport)); 8760020858e503d18322766b76443d83bfa5db4bffbpbos@webrtc.org PacketInputObserver input_observer(receiver_call_->Receiver()); 8770020858e503d18322766b76443d83bfa5db4bffbpbos@webrtc.org 8780020858e503d18322766b76443d83bfa5db4bffbpbos@webrtc.org send_transport.SetReceiver(&input_observer); 8790020858e503d18322766b76443d83bfa5db4bffbpbos@webrtc.org receive_transport.SetReceiver(sender_call_->Receiver()); 8800020858e503d18322766b76443d83bfa5db4bffbpbos@webrtc.org 8810020858e503d18322766b76443d83bfa5db4bffbpbos@webrtc.org CreateTestConfigs(); 8820020858e503d18322766b76443d83bfa5db4bffbpbos@webrtc.org 8830020858e503d18322766b76443d83bfa5db4bffbpbos@webrtc.org CreateStreams(); 8840020858e503d18322766b76443d83bfa5db4bffbpbos@webrtc.org CreateFrameGenerator(); 8850020858e503d18322766b76443d83bfa5db4bffbpbos@webrtc.org StartSending(); 8860020858e503d18322766b76443d83bfa5db4bffbpbos@webrtc.org 88712a93e063c94500f8fe0a045fc381a816fdf3c69pbos@webrtc.org receiver_call_->DestroyVideoReceiveStream(receive_stream_); 8880020858e503d18322766b76443d83bfa5db4bffbpbos@webrtc.org receive_stream_ = NULL; 8890020858e503d18322766b76443d83bfa5db4bffbpbos@webrtc.org 8900020858e503d18322766b76443d83bfa5db4bffbpbos@webrtc.org // Wait() waits for a received packet. 8910020858e503d18322766b76443d83bfa5db4bffbpbos@webrtc.org EXPECT_EQ(kEventSignaled, input_observer.Wait()); 8920020858e503d18322766b76443d83bfa5db4bffbpbos@webrtc.org 8930020858e503d18322766b76443d83bfa5db4bffbpbos@webrtc.org StopSending(); 8940020858e503d18322766b76443d83bfa5db4bffbpbos@webrtc.org 8950020858e503d18322766b76443d83bfa5db4bffbpbos@webrtc.org DestroyStreams(); 8960020858e503d18322766b76443d83bfa5db4bffbpbos@webrtc.org 8970020858e503d18322766b76443d83bfa5db4bffbpbos@webrtc.org send_transport.StopSending(); 8980020858e503d18322766b76443d83bfa5db4bffbpbos@webrtc.org receive_transport.StopSending(); 8990020858e503d18322766b76443d83bfa5db4bffbpbos@webrtc.org} 900c5080a993e1be0ee14292f5fe8cd7a5b30033f5fpbos@webrtc.org 90151e010182b9947c9656f9e81a6a12f64a8e21788pbos@webrtc.orgvoid CallTest::RespectsRtcpMode(newapi::RtcpMode rtcp_mode) { 90251e010182b9947c9656f9e81a6a12f64a8e21788pbos@webrtc.org static const int kRtpHistoryMs = 1000; 90351e010182b9947c9656f9e81a6a12f64a8e21788pbos@webrtc.org static const int kNumCompoundRtcpPacketsToObserve = 10; 90451e010182b9947c9656f9e81a6a12f64a8e21788pbos@webrtc.org class RtcpModeObserver : public test::RtpRtcpObserver { 90551e010182b9947c9656f9e81a6a12f64a8e21788pbos@webrtc.org public: 906d05597a15dd2d01c8e172df86b960b7d4ac9647fpbos@webrtc.org explicit RtcpModeObserver(newapi::RtcpMode rtcp_mode) 90751e010182b9947c9656f9e81a6a12f64a8e21788pbos@webrtc.org : test::RtpRtcpObserver(kDefaultTimeoutMs), 90851e010182b9947c9656f9e81a6a12f64a8e21788pbos@webrtc.org rtcp_mode_(rtcp_mode), 90951e010182b9947c9656f9e81a6a12f64a8e21788pbos@webrtc.org sent_rtp_(0), 91051e010182b9947c9656f9e81a6a12f64a8e21788pbos@webrtc.org sent_rtcp_(0) {} 91151e010182b9947c9656f9e81a6a12f64a8e21788pbos@webrtc.org 91251e010182b9947c9656f9e81a6a12f64a8e21788pbos@webrtc.org private: 91351e010182b9947c9656f9e81a6a12f64a8e21788pbos@webrtc.org virtual Action OnSendRtp(const uint8_t* packet, size_t length) OVERRIDE { 91451e010182b9947c9656f9e81a6a12f64a8e21788pbos@webrtc.org if (++sent_rtp_ % 3 == 0) 91551e010182b9947c9656f9e81a6a12f64a8e21788pbos@webrtc.org return DROP_PACKET; 91651e010182b9947c9656f9e81a6a12f64a8e21788pbos@webrtc.org 91751e010182b9947c9656f9e81a6a12f64a8e21788pbos@webrtc.org return SEND_PACKET; 91851e010182b9947c9656f9e81a6a12f64a8e21788pbos@webrtc.org } 91951e010182b9947c9656f9e81a6a12f64a8e21788pbos@webrtc.org 92051e010182b9947c9656f9e81a6a12f64a8e21788pbos@webrtc.org virtual Action OnReceiveRtcp(const uint8_t* packet, 92151e010182b9947c9656f9e81a6a12f64a8e21788pbos@webrtc.org size_t length) OVERRIDE { 92251e010182b9947c9656f9e81a6a12f64a8e21788pbos@webrtc.org ++sent_rtcp_; 92351e010182b9947c9656f9e81a6a12f64a8e21788pbos@webrtc.org RTCPUtility::RTCPParserV2 parser(packet, length, true); 92451e010182b9947c9656f9e81a6a12f64a8e21788pbos@webrtc.org EXPECT_TRUE(parser.IsValid()); 92551e010182b9947c9656f9e81a6a12f64a8e21788pbos@webrtc.org 92651e010182b9947c9656f9e81a6a12f64a8e21788pbos@webrtc.org RTCPUtility::RTCPPacketTypes packet_type = parser.Begin(); 92751e010182b9947c9656f9e81a6a12f64a8e21788pbos@webrtc.org bool has_report_block = false; 92851e010182b9947c9656f9e81a6a12f64a8e21788pbos@webrtc.org while (packet_type != RTCPUtility::kRtcpNotValidCode) { 92951e010182b9947c9656f9e81a6a12f64a8e21788pbos@webrtc.org EXPECT_NE(RTCPUtility::kRtcpSrCode, packet_type); 93051e010182b9947c9656f9e81a6a12f64a8e21788pbos@webrtc.org if (packet_type == RTCPUtility::kRtcpRrCode) { 93151e010182b9947c9656f9e81a6a12f64a8e21788pbos@webrtc.org has_report_block = true; 93251e010182b9947c9656f9e81a6a12f64a8e21788pbos@webrtc.org break; 93351e010182b9947c9656f9e81a6a12f64a8e21788pbos@webrtc.org } 93451e010182b9947c9656f9e81a6a12f64a8e21788pbos@webrtc.org packet_type = parser.Iterate(); 93551e010182b9947c9656f9e81a6a12f64a8e21788pbos@webrtc.org } 93651e010182b9947c9656f9e81a6a12f64a8e21788pbos@webrtc.org 93751e010182b9947c9656f9e81a6a12f64a8e21788pbos@webrtc.org switch (rtcp_mode_) { 93851e010182b9947c9656f9e81a6a12f64a8e21788pbos@webrtc.org case newapi::kRtcpCompound: 93951e010182b9947c9656f9e81a6a12f64a8e21788pbos@webrtc.org if (!has_report_block) { 94051e010182b9947c9656f9e81a6a12f64a8e21788pbos@webrtc.org ADD_FAILURE() << "Received RTCP packet without receiver report for " 94151e010182b9947c9656f9e81a6a12f64a8e21788pbos@webrtc.org "kRtcpCompound."; 94251e010182b9947c9656f9e81a6a12f64a8e21788pbos@webrtc.org observation_complete_->Set(); 94351e010182b9947c9656f9e81a6a12f64a8e21788pbos@webrtc.org } 94451e010182b9947c9656f9e81a6a12f64a8e21788pbos@webrtc.org 94551e010182b9947c9656f9e81a6a12f64a8e21788pbos@webrtc.org if (sent_rtcp_ >= kNumCompoundRtcpPacketsToObserve) 94651e010182b9947c9656f9e81a6a12f64a8e21788pbos@webrtc.org observation_complete_->Set(); 94751e010182b9947c9656f9e81a6a12f64a8e21788pbos@webrtc.org 94851e010182b9947c9656f9e81a6a12f64a8e21788pbos@webrtc.org break; 94951e010182b9947c9656f9e81a6a12f64a8e21788pbos@webrtc.org case newapi::kRtcpReducedSize: 95051e010182b9947c9656f9e81a6a12f64a8e21788pbos@webrtc.org if (!has_report_block) 95151e010182b9947c9656f9e81a6a12f64a8e21788pbos@webrtc.org observation_complete_->Set(); 95251e010182b9947c9656f9e81a6a12f64a8e21788pbos@webrtc.org break; 95351e010182b9947c9656f9e81a6a12f64a8e21788pbos@webrtc.org } 95451e010182b9947c9656f9e81a6a12f64a8e21788pbos@webrtc.org 95551e010182b9947c9656f9e81a6a12f64a8e21788pbos@webrtc.org return SEND_PACKET; 95651e010182b9947c9656f9e81a6a12f64a8e21788pbos@webrtc.org } 95751e010182b9947c9656f9e81a6a12f64a8e21788pbos@webrtc.org 95851e010182b9947c9656f9e81a6a12f64a8e21788pbos@webrtc.org newapi::RtcpMode rtcp_mode_; 95951e010182b9947c9656f9e81a6a12f64a8e21788pbos@webrtc.org int sent_rtp_; 96051e010182b9947c9656f9e81a6a12f64a8e21788pbos@webrtc.org int sent_rtcp_; 96151e010182b9947c9656f9e81a6a12f64a8e21788pbos@webrtc.org } observer(rtcp_mode); 96251e010182b9947c9656f9e81a6a12f64a8e21788pbos@webrtc.org 96351e010182b9947c9656f9e81a6a12f64a8e21788pbos@webrtc.org CreateCalls(Call::Config(observer.SendTransport()), 96451e010182b9947c9656f9e81a6a12f64a8e21788pbos@webrtc.org Call::Config(observer.ReceiveTransport())); 96551e010182b9947c9656f9e81a6a12f64a8e21788pbos@webrtc.org 96651e010182b9947c9656f9e81a6a12f64a8e21788pbos@webrtc.org observer.SetReceivers(receiver_call_->Receiver(), sender_call_->Receiver()); 96751e010182b9947c9656f9e81a6a12f64a8e21788pbos@webrtc.org 96851e010182b9947c9656f9e81a6a12f64a8e21788pbos@webrtc.org CreateTestConfigs(); 96951e010182b9947c9656f9e81a6a12f64a8e21788pbos@webrtc.org send_config_.rtp.nack.rtp_history_ms = kRtpHistoryMs; 97051e010182b9947c9656f9e81a6a12f64a8e21788pbos@webrtc.org receive_config_.rtp.nack.rtp_history_ms = kRtpHistoryMs; 97151e010182b9947c9656f9e81a6a12f64a8e21788pbos@webrtc.org receive_config_.rtp.rtcp_mode = rtcp_mode; 97251e010182b9947c9656f9e81a6a12f64a8e21788pbos@webrtc.org 97351e010182b9947c9656f9e81a6a12f64a8e21788pbos@webrtc.org CreateStreams(); 97451e010182b9947c9656f9e81a6a12f64a8e21788pbos@webrtc.org CreateFrameGenerator(); 97551e010182b9947c9656f9e81a6a12f64a8e21788pbos@webrtc.org StartSending(); 97651e010182b9947c9656f9e81a6a12f64a8e21788pbos@webrtc.org 97751e010182b9947c9656f9e81a6a12f64a8e21788pbos@webrtc.org EXPECT_EQ(kEventSignaled, observer.Wait()) 97851e010182b9947c9656f9e81a6a12f64a8e21788pbos@webrtc.org << (rtcp_mode == newapi::kRtcpCompound 97951e010182b9947c9656f9e81a6a12f64a8e21788pbos@webrtc.org ? "Timed out before observing enough compound packets." 98051e010182b9947c9656f9e81a6a12f64a8e21788pbos@webrtc.org : "Timed out before receiving a non-compound RTCP packet."); 98151e010182b9947c9656f9e81a6a12f64a8e21788pbos@webrtc.org 98251e010182b9947c9656f9e81a6a12f64a8e21788pbos@webrtc.org StopSending(); 98351e010182b9947c9656f9e81a6a12f64a8e21788pbos@webrtc.org observer.StopSending(); 98451e010182b9947c9656f9e81a6a12f64a8e21788pbos@webrtc.org DestroyStreams(); 98551e010182b9947c9656f9e81a6a12f64a8e21788pbos@webrtc.org} 98651e010182b9947c9656f9e81a6a12f64a8e21788pbos@webrtc.org 98751e010182b9947c9656f9e81a6a12f64a8e21788pbos@webrtc.orgTEST_F(CallTest, UsesRtcpCompoundMode) { 98851e010182b9947c9656f9e81a6a12f64a8e21788pbos@webrtc.org RespectsRtcpMode(newapi::kRtcpCompound); 98951e010182b9947c9656f9e81a6a12f64a8e21788pbos@webrtc.org} 99051e010182b9947c9656f9e81a6a12f64a8e21788pbos@webrtc.org 99151e010182b9947c9656f9e81a6a12f64a8e21788pbos@webrtc.orgTEST_F(CallTest, UsesRtcpReducedSizeMode) { 99251e010182b9947c9656f9e81a6a12f64a8e21788pbos@webrtc.org RespectsRtcpMode(newapi::kRtcpReducedSize); 99351e010182b9947c9656f9e81a6a12f64a8e21788pbos@webrtc.org} 99451e010182b9947c9656f9e81a6a12f64a8e21788pbos@webrtc.org 995c5080a993e1be0ee14292f5fe8cd7a5b30033f5fpbos@webrtc.org// Test sets up a Call multiple senders with different resolutions and SSRCs. 996c5080a993e1be0ee14292f5fe8cd7a5b30033f5fpbos@webrtc.org// Another is set up to receive all three of these with different renderers. 997c5080a993e1be0ee14292f5fe8cd7a5b30033f5fpbos@webrtc.org// Each renderer verifies that it receives the expected resolution, and as soon 998c5080a993e1be0ee14292f5fe8cd7a5b30033f5fpbos@webrtc.org// as every renderer has received a frame, the test finishes. 999c5080a993e1be0ee14292f5fe8cd7a5b30033f5fpbos@webrtc.orgTEST_F(CallTest, SendsAndReceivesMultipleStreams) { 1000c5080a993e1be0ee14292f5fe8cd7a5b30033f5fpbos@webrtc.org static const size_t kNumStreams = 3; 1001c5080a993e1be0ee14292f5fe8cd7a5b30033f5fpbos@webrtc.org 1002c5080a993e1be0ee14292f5fe8cd7a5b30033f5fpbos@webrtc.org class VideoOutputObserver : public VideoRenderer { 1003c5080a993e1be0ee14292f5fe8cd7a5b30033f5fpbos@webrtc.org public: 10044383539b27ae877337679901c1cc9120f3a83fefpbos@webrtc.org VideoOutputObserver(test::FrameGeneratorCapturer** capturer, 10054383539b27ae877337679901c1cc9120f3a83fefpbos@webrtc.org int width, 10064383539b27ae877337679901c1cc9120f3a83fefpbos@webrtc.org int height) 10074383539b27ae877337679901c1cc9120f3a83fefpbos@webrtc.org : capturer_(capturer), 10084383539b27ae877337679901c1cc9120f3a83fefpbos@webrtc.org width_(width), 10094383539b27ae877337679901c1cc9120f3a83fefpbos@webrtc.org height_(height), 10104383539b27ae877337679901c1cc9120f3a83fefpbos@webrtc.org done_(EventWrapper::Create()) {} 1011c5080a993e1be0ee14292f5fe8cd7a5b30033f5fpbos@webrtc.org 1012c5080a993e1be0ee14292f5fe8cd7a5b30033f5fpbos@webrtc.org virtual void RenderFrame(const I420VideoFrame& video_frame, 1013c5080a993e1be0ee14292f5fe8cd7a5b30033f5fpbos@webrtc.org int time_to_render_ms) OVERRIDE { 1014c5080a993e1be0ee14292f5fe8cd7a5b30033f5fpbos@webrtc.org EXPECT_EQ(width_, video_frame.width()); 1015c5080a993e1be0ee14292f5fe8cd7a5b30033f5fpbos@webrtc.org EXPECT_EQ(height_, video_frame.height()); 10164383539b27ae877337679901c1cc9120f3a83fefpbos@webrtc.org (*capturer_)->Stop(); 1017c5080a993e1be0ee14292f5fe8cd7a5b30033f5fpbos@webrtc.org done_->Set(); 1018c5080a993e1be0ee14292f5fe8cd7a5b30033f5fpbos@webrtc.org } 1019c5080a993e1be0ee14292f5fe8cd7a5b30033f5fpbos@webrtc.org 1020e2a7a77646b23fb3704d267e6079e04bde493543pbos@webrtc.org EventTypeWrapper Wait() { return done_->Wait(kDefaultTimeoutMs); } 1021c5080a993e1be0ee14292f5fe8cd7a5b30033f5fpbos@webrtc.org 1022c5080a993e1be0ee14292f5fe8cd7a5b30033f5fpbos@webrtc.org private: 10234383539b27ae877337679901c1cc9120f3a83fefpbos@webrtc.org test::FrameGeneratorCapturer** capturer_; 1024c5080a993e1be0ee14292f5fe8cd7a5b30033f5fpbos@webrtc.org int width_; 1025c5080a993e1be0ee14292f5fe8cd7a5b30033f5fpbos@webrtc.org int height_; 1026c5080a993e1be0ee14292f5fe8cd7a5b30033f5fpbos@webrtc.org scoped_ptr<EventWrapper> done_; 1027c5080a993e1be0ee14292f5fe8cd7a5b30033f5fpbos@webrtc.org }; 1028c5080a993e1be0ee14292f5fe8cd7a5b30033f5fpbos@webrtc.org 1029c5080a993e1be0ee14292f5fe8cd7a5b30033f5fpbos@webrtc.org struct { 1030c5080a993e1be0ee14292f5fe8cd7a5b30033f5fpbos@webrtc.org uint32_t ssrc; 1031c5080a993e1be0ee14292f5fe8cd7a5b30033f5fpbos@webrtc.org int width; 1032c5080a993e1be0ee14292f5fe8cd7a5b30033f5fpbos@webrtc.org int height; 1033c5080a993e1be0ee14292f5fe8cd7a5b30033f5fpbos@webrtc.org } codec_settings[kNumStreams] = {{1, 640, 480}, {2, 320, 240}, {3, 240, 160}}; 1034c5080a993e1be0ee14292f5fe8cd7a5b30033f5fpbos@webrtc.org 1035c5080a993e1be0ee14292f5fe8cd7a5b30033f5fpbos@webrtc.org test::DirectTransport sender_transport, receiver_transport; 1036c5080a993e1be0ee14292f5fe8cd7a5b30033f5fpbos@webrtc.org scoped_ptr<Call> sender_call(Call::Create(Call::Config(&sender_transport))); 1037c5080a993e1be0ee14292f5fe8cd7a5b30033f5fpbos@webrtc.org scoped_ptr<Call> receiver_call( 1038c5080a993e1be0ee14292f5fe8cd7a5b30033f5fpbos@webrtc.org Call::Create(Call::Config(&receiver_transport))); 1039c5080a993e1be0ee14292f5fe8cd7a5b30033f5fpbos@webrtc.org sender_transport.SetReceiver(receiver_call->Receiver()); 1040c5080a993e1be0ee14292f5fe8cd7a5b30033f5fpbos@webrtc.org receiver_transport.SetReceiver(sender_call->Receiver()); 1041c5080a993e1be0ee14292f5fe8cd7a5b30033f5fpbos@webrtc.org 1042c5080a993e1be0ee14292f5fe8cd7a5b30033f5fpbos@webrtc.org VideoSendStream* send_streams[kNumStreams]; 1043c5080a993e1be0ee14292f5fe8cd7a5b30033f5fpbos@webrtc.org VideoReceiveStream* receive_streams[kNumStreams]; 1044c5080a993e1be0ee14292f5fe8cd7a5b30033f5fpbos@webrtc.org 1045c5080a993e1be0ee14292f5fe8cd7a5b30033f5fpbos@webrtc.org VideoOutputObserver* observers[kNumStreams]; 1046c5080a993e1be0ee14292f5fe8cd7a5b30033f5fpbos@webrtc.org test::FrameGeneratorCapturer* frame_generators[kNumStreams]; 1047c5080a993e1be0ee14292f5fe8cd7a5b30033f5fpbos@webrtc.org 1048e2a7a77646b23fb3704d267e6079e04bde493543pbos@webrtc.org scoped_ptr<VP8Encoder> encoders[kNumStreams]; 1049e2a7a77646b23fb3704d267e6079e04bde493543pbos@webrtc.org for (size_t i = 0; i < kNumStreams; ++i) 1050e2a7a77646b23fb3704d267e6079e04bde493543pbos@webrtc.org encoders[i].reset(VP8Encoder::Create()); 1051e2a7a77646b23fb3704d267e6079e04bde493543pbos@webrtc.org 1052c5080a993e1be0ee14292f5fe8cd7a5b30033f5fpbos@webrtc.org for (size_t i = 0; i < kNumStreams; ++i) { 1053c5080a993e1be0ee14292f5fe8cd7a5b30033f5fpbos@webrtc.org uint32_t ssrc = codec_settings[i].ssrc; 1054c5080a993e1be0ee14292f5fe8cd7a5b30033f5fpbos@webrtc.org int width = codec_settings[i].width; 1055c5080a993e1be0ee14292f5fe8cd7a5b30033f5fpbos@webrtc.org int height = codec_settings[i].height; 10564383539b27ae877337679901c1cc9120f3a83fefpbos@webrtc.org observers[i] = new VideoOutputObserver(&frame_generators[i], width, height); 1057c5080a993e1be0ee14292f5fe8cd7a5b30033f5fpbos@webrtc.org 1058e2a7a77646b23fb3704d267e6079e04bde493543pbos@webrtc.org VideoSendStream::Config send_config = sender_call->GetDefaultSendConfig(); 1059e2a7a77646b23fb3704d267e6079e04bde493543pbos@webrtc.org send_config.rtp.ssrcs.push_back(ssrc); 1060bdfcddf7091e92134143e9a2d9ccce908e43979epbos@webrtc.org send_config.encoder_settings.encoder = encoders[i].get(); 1061bdfcddf7091e92134143e9a2d9ccce908e43979epbos@webrtc.org send_config.encoder_settings.payload_name = "VP8"; 1062bdfcddf7091e92134143e9a2d9ccce908e43979epbos@webrtc.org send_config.encoder_settings.payload_type = 124; 1063bdfcddf7091e92134143e9a2d9ccce908e43979epbos@webrtc.org std::vector<VideoStream> video_streams = test::CreateVideoStreams(1); 1064bdfcddf7091e92134143e9a2d9ccce908e43979epbos@webrtc.org VideoStream* stream = &video_streams[0]; 1065e2a7a77646b23fb3704d267e6079e04bde493543pbos@webrtc.org stream->width = width; 1066e2a7a77646b23fb3704d267e6079e04bde493543pbos@webrtc.org stream->height = height; 1067e2a7a77646b23fb3704d267e6079e04bde493543pbos@webrtc.org stream->max_framerate = 5; 1068e2a7a77646b23fb3704d267e6079e04bde493543pbos@webrtc.org stream->min_bitrate_bps = stream->target_bitrate_bps = 1069e2a7a77646b23fb3704d267e6079e04bde493543pbos@webrtc.org stream->max_bitrate_bps = 100000; 1070bdfcddf7091e92134143e9a2d9ccce908e43979epbos@webrtc.org send_streams[i] = 1071bdfcddf7091e92134143e9a2d9ccce908e43979epbos@webrtc.org sender_call->CreateVideoSendStream(send_config, video_streams, NULL); 107216a058a180164c32a13f3406d35cc3ef1ad569c4pbos@webrtc.org send_streams[i]->Start(); 1073e2a7a77646b23fb3704d267e6079e04bde493543pbos@webrtc.org 1074c5080a993e1be0ee14292f5fe8cd7a5b30033f5fpbos@webrtc.org VideoReceiveStream::Config receive_config = 1075c5080a993e1be0ee14292f5fe8cd7a5b30033f5fpbos@webrtc.org receiver_call->GetDefaultReceiveConfig(); 1076c5080a993e1be0ee14292f5fe8cd7a5b30033f5fpbos@webrtc.org receive_config.renderer = observers[i]; 10774b50db1f8ce21cc7faf4f7c80b6a492dffb2a1d5pbos@webrtc.org receive_config.rtp.remote_ssrc = ssrc; 10784b50db1f8ce21cc7faf4f7c80b6a492dffb2a1d5pbos@webrtc.org receive_config.rtp.local_ssrc = kReceiverLocalSsrc; 1079e2a7a77646b23fb3704d267e6079e04bde493543pbos@webrtc.org VideoCodec codec = 1080e2a7a77646b23fb3704d267e6079e04bde493543pbos@webrtc.org test::CreateDecoderVideoCodec(send_config.encoder_settings); 1081e2a7a77646b23fb3704d267e6079e04bde493543pbos@webrtc.org receive_config.codecs.push_back(codec); 1082964d78e5c80ec8e4cbaeece5f119806b1ef9ea22pbos@webrtc.org receive_streams[i] = 1083964d78e5c80ec8e4cbaeece5f119806b1ef9ea22pbos@webrtc.org receiver_call->CreateVideoReceiveStream(receive_config); 108416a058a180164c32a13f3406d35cc3ef1ad569c4pbos@webrtc.org receive_streams[i]->Start(); 1085c5080a993e1be0ee14292f5fe8cd7a5b30033f5fpbos@webrtc.org 1086c5080a993e1be0ee14292f5fe8cd7a5b30033f5fpbos@webrtc.org frame_generators[i] = test::FrameGeneratorCapturer::Create( 1087c5080a993e1be0ee14292f5fe8cd7a5b30033f5fpbos@webrtc.org send_streams[i]->Input(), width, height, 30, Clock::GetRealTimeClock()); 1088c5080a993e1be0ee14292f5fe8cd7a5b30033f5fpbos@webrtc.org frame_generators[i]->Start(); 1089c5080a993e1be0ee14292f5fe8cd7a5b30033f5fpbos@webrtc.org } 1090c5080a993e1be0ee14292f5fe8cd7a5b30033f5fpbos@webrtc.org 1091c5080a993e1be0ee14292f5fe8cd7a5b30033f5fpbos@webrtc.org for (size_t i = 0; i < kNumStreams; ++i) { 1092e2a7a77646b23fb3704d267e6079e04bde493543pbos@webrtc.org EXPECT_EQ(kEventSignaled, observers[i]->Wait()) 1093e2a7a77646b23fb3704d267e6079e04bde493543pbos@webrtc.org << "Timed out while waiting for observer " << i << " to render."; 1094c5080a993e1be0ee14292f5fe8cd7a5b30033f5fpbos@webrtc.org } 1095c5080a993e1be0ee14292f5fe8cd7a5b30033f5fpbos@webrtc.org 1096c5080a993e1be0ee14292f5fe8cd7a5b30033f5fpbos@webrtc.org for (size_t i = 0; i < kNumStreams; ++i) { 1097c5080a993e1be0ee14292f5fe8cd7a5b30033f5fpbos@webrtc.org frame_generators[i]->Stop(); 109812a93e063c94500f8fe0a045fc381a816fdf3c69pbos@webrtc.org sender_call->DestroyVideoSendStream(send_streams[i]); 109912a93e063c94500f8fe0a045fc381a816fdf3c69pbos@webrtc.org receiver_call->DestroyVideoReceiveStream(receive_streams[i]); 1100471354f94ed73da7195e2f8e72c5a2239b9a9afbpbos@webrtc.org delete frame_generators[i]; 1101c5080a993e1be0ee14292f5fe8cd7a5b30033f5fpbos@webrtc.org delete observers[i]; 1102c5080a993e1be0ee14292f5fe8cd7a5b30033f5fpbos@webrtc.org } 1103c5080a993e1be0ee14292f5fe8cd7a5b30033f5fpbos@webrtc.org 1104c5080a993e1be0ee14292f5fe8cd7a5b30033f5fpbos@webrtc.org sender_transport.StopSending(); 1105c5080a993e1be0ee14292f5fe8cd7a5b30033f5fpbos@webrtc.org receiver_transport.StopSending(); 110646f72884ad5c4078fa324626aa69e4860e4d4ae2pbos@webrtc.org}; 1107e028410838cd976c75e379b3c2e2eb0ac52b3c99stefan@webrtc.org 11082e98d45e2455d3b48ceac1ad5457623d39802c9esprang@webrtc.orgTEST_F(CallTest, ObserversEncodedFrames) { 11092e98d45e2455d3b48ceac1ad5457623d39802c9esprang@webrtc.org class EncodedFrameTestObserver : public EncodedFrameObserver { 11102e98d45e2455d3b48ceac1ad5457623d39802c9esprang@webrtc.org public: 1111c71929dce136f9bc59fcc7ceb172cf74fc507ea9pbos@webrtc.org EncodedFrameTestObserver() 1112c71929dce136f9bc59fcc7ceb172cf74fc507ea9pbos@webrtc.org : length_(0), 1113c71929dce136f9bc59fcc7ceb172cf74fc507ea9pbos@webrtc.org frame_type_(kFrameEmpty), 1114c71929dce136f9bc59fcc7ceb172cf74fc507ea9pbos@webrtc.org called_(EventWrapper::Create()) {} 11152e98d45e2455d3b48ceac1ad5457623d39802c9esprang@webrtc.org virtual ~EncodedFrameTestObserver() {} 11162e98d45e2455d3b48ceac1ad5457623d39802c9esprang@webrtc.org 11172e98d45e2455d3b48ceac1ad5457623d39802c9esprang@webrtc.org virtual void EncodedFrameCallback(const EncodedFrame& encoded_frame) { 11182e98d45e2455d3b48ceac1ad5457623d39802c9esprang@webrtc.org frame_type_ = encoded_frame.frame_type_; 11192e98d45e2455d3b48ceac1ad5457623d39802c9esprang@webrtc.org length_ = encoded_frame.length_; 11202e98d45e2455d3b48ceac1ad5457623d39802c9esprang@webrtc.org buffer_.reset(new uint8_t[length_]); 11212e98d45e2455d3b48ceac1ad5457623d39802c9esprang@webrtc.org memcpy(buffer_.get(), encoded_frame.data_, length_); 11222e98d45e2455d3b48ceac1ad5457623d39802c9esprang@webrtc.org called_->Set(); 11232e98d45e2455d3b48ceac1ad5457623d39802c9esprang@webrtc.org } 11242e98d45e2455d3b48ceac1ad5457623d39802c9esprang@webrtc.org 1125c71929dce136f9bc59fcc7ceb172cf74fc507ea9pbos@webrtc.org EventTypeWrapper Wait() { return called_->Wait(kDefaultTimeoutMs); } 11262e98d45e2455d3b48ceac1ad5457623d39802c9esprang@webrtc.org 11272e98d45e2455d3b48ceac1ad5457623d39802c9esprang@webrtc.org void ExpectEqualFrames(const EncodedFrameTestObserver& observer) { 11282e98d45e2455d3b48ceac1ad5457623d39802c9esprang@webrtc.org ASSERT_EQ(length_, observer.length_) 11292e98d45e2455d3b48ceac1ad5457623d39802c9esprang@webrtc.org << "Observed frames are of different lengths."; 11302e98d45e2455d3b48ceac1ad5457623d39802c9esprang@webrtc.org EXPECT_EQ(frame_type_, observer.frame_type_) 11312e98d45e2455d3b48ceac1ad5457623d39802c9esprang@webrtc.org << "Observed frames have different frame types."; 11322e98d45e2455d3b48ceac1ad5457623d39802c9esprang@webrtc.org EXPECT_EQ(0, memcmp(buffer_.get(), observer.buffer_.get(), length_)) 11332e98d45e2455d3b48ceac1ad5457623d39802c9esprang@webrtc.org << "Observed encoded frames have different content."; 11342e98d45e2455d3b48ceac1ad5457623d39802c9esprang@webrtc.org } 11352e98d45e2455d3b48ceac1ad5457623d39802c9esprang@webrtc.org 11362e98d45e2455d3b48ceac1ad5457623d39802c9esprang@webrtc.org private: 11372e98d45e2455d3b48ceac1ad5457623d39802c9esprang@webrtc.org scoped_ptr<uint8_t[]> buffer_; 11382e98d45e2455d3b48ceac1ad5457623d39802c9esprang@webrtc.org size_t length_; 11392e98d45e2455d3b48ceac1ad5457623d39802c9esprang@webrtc.org FrameType frame_type_; 11402e98d45e2455d3b48ceac1ad5457623d39802c9esprang@webrtc.org scoped_ptr<EventWrapper> called_; 11412e98d45e2455d3b48ceac1ad5457623d39802c9esprang@webrtc.org }; 11422e98d45e2455d3b48ceac1ad5457623d39802c9esprang@webrtc.org 11432e98d45e2455d3b48ceac1ad5457623d39802c9esprang@webrtc.org EncodedFrameTestObserver post_encode_observer; 11442e98d45e2455d3b48ceac1ad5457623d39802c9esprang@webrtc.org EncodedFrameTestObserver pre_decode_observer; 11452e98d45e2455d3b48ceac1ad5457623d39802c9esprang@webrtc.org 11462e98d45e2455d3b48ceac1ad5457623d39802c9esprang@webrtc.org test::DirectTransport sender_transport, receiver_transport; 11472e98d45e2455d3b48ceac1ad5457623d39802c9esprang@webrtc.org 11482e98d45e2455d3b48ceac1ad5457623d39802c9esprang@webrtc.org CreateCalls(Call::Config(&sender_transport), 11492e98d45e2455d3b48ceac1ad5457623d39802c9esprang@webrtc.org Call::Config(&receiver_transport)); 11502e98d45e2455d3b48ceac1ad5457623d39802c9esprang@webrtc.org 11512e98d45e2455d3b48ceac1ad5457623d39802c9esprang@webrtc.org sender_transport.SetReceiver(receiver_call_->Receiver()); 11522e98d45e2455d3b48ceac1ad5457623d39802c9esprang@webrtc.org receiver_transport.SetReceiver(sender_call_->Receiver()); 11532e98d45e2455d3b48ceac1ad5457623d39802c9esprang@webrtc.org 11542e98d45e2455d3b48ceac1ad5457623d39802c9esprang@webrtc.org CreateTestConfigs(); 11552e98d45e2455d3b48ceac1ad5457623d39802c9esprang@webrtc.org send_config_.post_encode_callback = &post_encode_observer; 11562e98d45e2455d3b48ceac1ad5457623d39802c9esprang@webrtc.org receive_config_.pre_decode_callback = &pre_decode_observer; 11572e98d45e2455d3b48ceac1ad5457623d39802c9esprang@webrtc.org 11582e98d45e2455d3b48ceac1ad5457623d39802c9esprang@webrtc.org CreateStreams(); 11592e98d45e2455d3b48ceac1ad5457623d39802c9esprang@webrtc.org StartSending(); 11602e98d45e2455d3b48ceac1ad5457623d39802c9esprang@webrtc.org 11612e98d45e2455d3b48ceac1ad5457623d39802c9esprang@webrtc.org scoped_ptr<test::FrameGenerator> frame_generator(test::FrameGenerator::Create( 1162bdfcddf7091e92134143e9a2d9ccce908e43979epbos@webrtc.org video_streams_[0].width, video_streams_[0].height)); 1163c33d37ce205e22c0e090b0b285ed963686bf24dcpbos@webrtc.org send_stream_->Input()->SwapFrame(frame_generator->NextFrame()); 11642e98d45e2455d3b48ceac1ad5457623d39802c9esprang@webrtc.org 11652e98d45e2455d3b48ceac1ad5457623d39802c9esprang@webrtc.org EXPECT_EQ(kEventSignaled, post_encode_observer.Wait()) 11662e98d45e2455d3b48ceac1ad5457623d39802c9esprang@webrtc.org << "Timed out while waiting for send-side encoded-frame callback."; 11672e98d45e2455d3b48ceac1ad5457623d39802c9esprang@webrtc.org 11682e98d45e2455d3b48ceac1ad5457623d39802c9esprang@webrtc.org EXPECT_EQ(kEventSignaled, pre_decode_observer.Wait()) 11692e98d45e2455d3b48ceac1ad5457623d39802c9esprang@webrtc.org << "Timed out while waiting for pre-decode encoded-frame callback."; 11702e98d45e2455d3b48ceac1ad5457623d39802c9esprang@webrtc.org 11712e98d45e2455d3b48ceac1ad5457623d39802c9esprang@webrtc.org post_encode_observer.ExpectEqualFrames(pre_decode_observer); 11722e98d45e2455d3b48ceac1ad5457623d39802c9esprang@webrtc.org 11732e98d45e2455d3b48ceac1ad5457623d39802c9esprang@webrtc.org StopSending(); 11742e98d45e2455d3b48ceac1ad5457623d39802c9esprang@webrtc.org 11752e98d45e2455d3b48ceac1ad5457623d39802c9esprang@webrtc.org sender_transport.StopSending(); 11762e98d45e2455d3b48ceac1ad5457623d39802c9esprang@webrtc.org receiver_transport.StopSending(); 11772e98d45e2455d3b48ceac1ad5457623d39802c9esprang@webrtc.org 11782e98d45e2455d3b48ceac1ad5457623d39802c9esprang@webrtc.org DestroyStreams(); 11792e98d45e2455d3b48ceac1ad5457623d39802c9esprang@webrtc.org} 11807ff4089bfcce71ba2a5d21d5adc0467782a914a0mflodman@webrtc.org 11817ff4089bfcce71ba2a5d21d5adc0467782a914a0mflodman@webrtc.orgTEST_F(CallTest, ReceiveStreamSendsRemb) { 11827ff4089bfcce71ba2a5d21d5adc0467782a914a0mflodman@webrtc.org class RembObserver : public test::RtpRtcpObserver { 11837ff4089bfcce71ba2a5d21d5adc0467782a914a0mflodman@webrtc.org public: 11847ff4089bfcce71ba2a5d21d5adc0467782a914a0mflodman@webrtc.org RembObserver() : test::RtpRtcpObserver(kDefaultTimeoutMs) {} 11857ff4089bfcce71ba2a5d21d5adc0467782a914a0mflodman@webrtc.org 11867ff4089bfcce71ba2a5d21d5adc0467782a914a0mflodman@webrtc.org virtual Action OnReceiveRtcp(const uint8_t* packet, 11877ff4089bfcce71ba2a5d21d5adc0467782a914a0mflodman@webrtc.org size_t length) OVERRIDE { 11887ff4089bfcce71ba2a5d21d5adc0467782a914a0mflodman@webrtc.org RTCPUtility::RTCPParserV2 parser(packet, length, true); 11897ff4089bfcce71ba2a5d21d5adc0467782a914a0mflodman@webrtc.org EXPECT_TRUE(parser.IsValid()); 11907ff4089bfcce71ba2a5d21d5adc0467782a914a0mflodman@webrtc.org 11917ff4089bfcce71ba2a5d21d5adc0467782a914a0mflodman@webrtc.org bool received_psfb = false; 11927ff4089bfcce71ba2a5d21d5adc0467782a914a0mflodman@webrtc.org bool received_remb = false; 11937ff4089bfcce71ba2a5d21d5adc0467782a914a0mflodman@webrtc.org RTCPUtility::RTCPPacketTypes packet_type = parser.Begin(); 11947ff4089bfcce71ba2a5d21d5adc0467782a914a0mflodman@webrtc.org while (packet_type != RTCPUtility::kRtcpNotValidCode) { 11957ff4089bfcce71ba2a5d21d5adc0467782a914a0mflodman@webrtc.org if (packet_type == RTCPUtility::kRtcpPsfbRembCode) { 11967ff4089bfcce71ba2a5d21d5adc0467782a914a0mflodman@webrtc.org const RTCPUtility::RTCPPacket& packet = parser.Packet(); 11977ff4089bfcce71ba2a5d21d5adc0467782a914a0mflodman@webrtc.org EXPECT_EQ(packet.PSFBAPP.SenderSSRC, kReceiverLocalSsrc); 11987ff4089bfcce71ba2a5d21d5adc0467782a914a0mflodman@webrtc.org received_psfb = true; 11997ff4089bfcce71ba2a5d21d5adc0467782a914a0mflodman@webrtc.org } else if (packet_type == RTCPUtility::kRtcpPsfbRembItemCode) { 12007ff4089bfcce71ba2a5d21d5adc0467782a914a0mflodman@webrtc.org const RTCPUtility::RTCPPacket& packet = parser.Packet(); 12017ff4089bfcce71ba2a5d21d5adc0467782a914a0mflodman@webrtc.org EXPECT_GT(packet.REMBItem.BitRate, 0u); 12027ff4089bfcce71ba2a5d21d5adc0467782a914a0mflodman@webrtc.org EXPECT_EQ(packet.REMBItem.NumberOfSSRCs, 1u); 12037ff4089bfcce71ba2a5d21d5adc0467782a914a0mflodman@webrtc.org EXPECT_EQ(packet.REMBItem.SSRCs[0], kSendSsrc); 12047ff4089bfcce71ba2a5d21d5adc0467782a914a0mflodman@webrtc.org received_remb = true; 12057ff4089bfcce71ba2a5d21d5adc0467782a914a0mflodman@webrtc.org } 12067ff4089bfcce71ba2a5d21d5adc0467782a914a0mflodman@webrtc.org packet_type = parser.Iterate(); 12077ff4089bfcce71ba2a5d21d5adc0467782a914a0mflodman@webrtc.org } 12087ff4089bfcce71ba2a5d21d5adc0467782a914a0mflodman@webrtc.org if (received_psfb && received_remb) 12097ff4089bfcce71ba2a5d21d5adc0467782a914a0mflodman@webrtc.org observation_complete_->Set(); 12107ff4089bfcce71ba2a5d21d5adc0467782a914a0mflodman@webrtc.org return SEND_PACKET; 12117ff4089bfcce71ba2a5d21d5adc0467782a914a0mflodman@webrtc.org } 12127ff4089bfcce71ba2a5d21d5adc0467782a914a0mflodman@webrtc.org } observer; 12137ff4089bfcce71ba2a5d21d5adc0467782a914a0mflodman@webrtc.org 12147ff4089bfcce71ba2a5d21d5adc0467782a914a0mflodman@webrtc.org CreateCalls(Call::Config(observer.SendTransport()), 12157ff4089bfcce71ba2a5d21d5adc0467782a914a0mflodman@webrtc.org Call::Config(observer.ReceiveTransport())); 12167ff4089bfcce71ba2a5d21d5adc0467782a914a0mflodman@webrtc.org observer.SetReceivers(receiver_call_->Receiver(), sender_call_->Receiver()); 12177ff4089bfcce71ba2a5d21d5adc0467782a914a0mflodman@webrtc.org CreateTestConfigs(); 12187ff4089bfcce71ba2a5d21d5adc0467782a914a0mflodman@webrtc.org CreateStreams(); 12197ff4089bfcce71ba2a5d21d5adc0467782a914a0mflodman@webrtc.org CreateFrameGenerator(); 12207ff4089bfcce71ba2a5d21d5adc0467782a914a0mflodman@webrtc.org StartSending(); 12217ff4089bfcce71ba2a5d21d5adc0467782a914a0mflodman@webrtc.org 12227ff4089bfcce71ba2a5d21d5adc0467782a914a0mflodman@webrtc.org EXPECT_EQ(kEventSignaled, observer.Wait()) 12237ff4089bfcce71ba2a5d21d5adc0467782a914a0mflodman@webrtc.org << "Timed out while waiting for a receiver RTCP REMB packet to be sent."; 12247ff4089bfcce71ba2a5d21d5adc0467782a914a0mflodman@webrtc.org 12257ff4089bfcce71ba2a5d21d5adc0467782a914a0mflodman@webrtc.org StopSending(); 12267ff4089bfcce71ba2a5d21d5adc0467782a914a0mflodman@webrtc.org observer.StopSending(); 12277ff4089bfcce71ba2a5d21d5adc0467782a914a0mflodman@webrtc.org DestroyStreams(); 12287ff4089bfcce71ba2a5d21d5adc0467782a914a0mflodman@webrtc.org} 1229b4263e09399b251e5cf306b2ade0d0f768d3cb61asapersson@webrtc.org 1230b4263e09399b251e5cf306b2ade0d0f768d3cb61asapersson@webrtc.orgvoid CallTest::TestXrReceiverReferenceTimeReport(bool enable_rrtr) { 1231b4263e09399b251e5cf306b2ade0d0f768d3cb61asapersson@webrtc.org static const int kNumRtcpReportPacketsToObserve = 5; 1232b4263e09399b251e5cf306b2ade0d0f768d3cb61asapersson@webrtc.org class RtcpXrObserver : public test::RtpRtcpObserver { 1233b4263e09399b251e5cf306b2ade0d0f768d3cb61asapersson@webrtc.org public: 1234b4263e09399b251e5cf306b2ade0d0f768d3cb61asapersson@webrtc.org explicit RtcpXrObserver(bool enable_rrtr) 1235b4263e09399b251e5cf306b2ade0d0f768d3cb61asapersson@webrtc.org : test::RtpRtcpObserver(kDefaultTimeoutMs), 1236b4263e09399b251e5cf306b2ade0d0f768d3cb61asapersson@webrtc.org enable_rrtr_(enable_rrtr), 1237b4263e09399b251e5cf306b2ade0d0f768d3cb61asapersson@webrtc.org sent_rtcp_sr_(0), 1238b4263e09399b251e5cf306b2ade0d0f768d3cb61asapersson@webrtc.org sent_rtcp_rr_(0), 1239b4263e09399b251e5cf306b2ade0d0f768d3cb61asapersson@webrtc.org sent_rtcp_rrtr_(0), 1240b4263e09399b251e5cf306b2ade0d0f768d3cb61asapersson@webrtc.org sent_rtcp_dlrr_(0) {} 1241c71929dce136f9bc59fcc7ceb172cf74fc507ea9pbos@webrtc.org 1242b4263e09399b251e5cf306b2ade0d0f768d3cb61asapersson@webrtc.org private: 1243b4263e09399b251e5cf306b2ade0d0f768d3cb61asapersson@webrtc.org // Receive stream should send RR packets (and RRTR packets if enabled). 1244b4263e09399b251e5cf306b2ade0d0f768d3cb61asapersson@webrtc.org virtual Action OnReceiveRtcp(const uint8_t* packet, 1245b4263e09399b251e5cf306b2ade0d0f768d3cb61asapersson@webrtc.org size_t length) OVERRIDE { 1246b4263e09399b251e5cf306b2ade0d0f768d3cb61asapersson@webrtc.org RTCPUtility::RTCPParserV2 parser(packet, length, true); 1247b4263e09399b251e5cf306b2ade0d0f768d3cb61asapersson@webrtc.org EXPECT_TRUE(parser.IsValid()); 1248b4263e09399b251e5cf306b2ade0d0f768d3cb61asapersson@webrtc.org 1249b4263e09399b251e5cf306b2ade0d0f768d3cb61asapersson@webrtc.org RTCPUtility::RTCPPacketTypes packet_type = parser.Begin(); 1250b4263e09399b251e5cf306b2ade0d0f768d3cb61asapersson@webrtc.org while (packet_type != RTCPUtility::kRtcpNotValidCode) { 1251b4263e09399b251e5cf306b2ade0d0f768d3cb61asapersson@webrtc.org if (packet_type == RTCPUtility::kRtcpRrCode) { 1252b4263e09399b251e5cf306b2ade0d0f768d3cb61asapersson@webrtc.org ++sent_rtcp_rr_; 1253c71929dce136f9bc59fcc7ceb172cf74fc507ea9pbos@webrtc.org } else if (packet_type == 1254c71929dce136f9bc59fcc7ceb172cf74fc507ea9pbos@webrtc.org RTCPUtility::kRtcpXrReceiverReferenceTimeCode) { 1255b4263e09399b251e5cf306b2ade0d0f768d3cb61asapersson@webrtc.org ++sent_rtcp_rrtr_; 1256b4263e09399b251e5cf306b2ade0d0f768d3cb61asapersson@webrtc.org } 1257b4263e09399b251e5cf306b2ade0d0f768d3cb61asapersson@webrtc.org EXPECT_NE(packet_type, RTCPUtility::kRtcpSrCode); 1258b4263e09399b251e5cf306b2ade0d0f768d3cb61asapersson@webrtc.org EXPECT_NE(packet_type, RTCPUtility::kRtcpXrDlrrReportBlockItemCode); 1259b4263e09399b251e5cf306b2ade0d0f768d3cb61asapersson@webrtc.org packet_type = parser.Iterate(); 1260b4263e09399b251e5cf306b2ade0d0f768d3cb61asapersson@webrtc.org } 1261b4263e09399b251e5cf306b2ade0d0f768d3cb61asapersson@webrtc.org return SEND_PACKET; 1262b4263e09399b251e5cf306b2ade0d0f768d3cb61asapersson@webrtc.org } 1263b4263e09399b251e5cf306b2ade0d0f768d3cb61asapersson@webrtc.org // Send stream should send SR packets (and DLRR packets if enabled). 1264b4263e09399b251e5cf306b2ade0d0f768d3cb61asapersson@webrtc.org virtual Action OnSendRtcp(const uint8_t* packet, size_t length) { 1265b4263e09399b251e5cf306b2ade0d0f768d3cb61asapersson@webrtc.org RTCPUtility::RTCPParserV2 parser(packet, length, true); 1266b4263e09399b251e5cf306b2ade0d0f768d3cb61asapersson@webrtc.org EXPECT_TRUE(parser.IsValid()); 1267b4263e09399b251e5cf306b2ade0d0f768d3cb61asapersson@webrtc.org 1268b4263e09399b251e5cf306b2ade0d0f768d3cb61asapersson@webrtc.org RTCPUtility::RTCPPacketTypes packet_type = parser.Begin(); 1269b4263e09399b251e5cf306b2ade0d0f768d3cb61asapersson@webrtc.org while (packet_type != RTCPUtility::kRtcpNotValidCode) { 1270b4263e09399b251e5cf306b2ade0d0f768d3cb61asapersson@webrtc.org if (packet_type == RTCPUtility::kRtcpSrCode) { 1271b4263e09399b251e5cf306b2ade0d0f768d3cb61asapersson@webrtc.org ++sent_rtcp_sr_; 1272b4263e09399b251e5cf306b2ade0d0f768d3cb61asapersson@webrtc.org } else if (packet_type == RTCPUtility::kRtcpXrDlrrReportBlockItemCode) { 1273b4263e09399b251e5cf306b2ade0d0f768d3cb61asapersson@webrtc.org ++sent_rtcp_dlrr_; 1274b4263e09399b251e5cf306b2ade0d0f768d3cb61asapersson@webrtc.org } 1275b4263e09399b251e5cf306b2ade0d0f768d3cb61asapersson@webrtc.org EXPECT_NE(packet_type, RTCPUtility::kRtcpXrReceiverReferenceTimeCode); 1276b4263e09399b251e5cf306b2ade0d0f768d3cb61asapersson@webrtc.org packet_type = parser.Iterate(); 1277b4263e09399b251e5cf306b2ade0d0f768d3cb61asapersson@webrtc.org } 1278b4263e09399b251e5cf306b2ade0d0f768d3cb61asapersson@webrtc.org if (sent_rtcp_sr_ > kNumRtcpReportPacketsToObserve && 1279b4263e09399b251e5cf306b2ade0d0f768d3cb61asapersson@webrtc.org sent_rtcp_rr_ > kNumRtcpReportPacketsToObserve) { 1280b4263e09399b251e5cf306b2ade0d0f768d3cb61asapersson@webrtc.org if (enable_rrtr_) { 1281b4263e09399b251e5cf306b2ade0d0f768d3cb61asapersson@webrtc.org EXPECT_GT(sent_rtcp_rrtr_, 0); 1282b4263e09399b251e5cf306b2ade0d0f768d3cb61asapersson@webrtc.org EXPECT_GT(sent_rtcp_dlrr_, 0); 1283b4263e09399b251e5cf306b2ade0d0f768d3cb61asapersson@webrtc.org } else { 1284b4263e09399b251e5cf306b2ade0d0f768d3cb61asapersson@webrtc.org EXPECT_EQ(0, sent_rtcp_rrtr_); 1285b4263e09399b251e5cf306b2ade0d0f768d3cb61asapersson@webrtc.org EXPECT_EQ(0, sent_rtcp_dlrr_); 1286b4263e09399b251e5cf306b2ade0d0f768d3cb61asapersson@webrtc.org } 1287b4263e09399b251e5cf306b2ade0d0f768d3cb61asapersson@webrtc.org observation_complete_->Set(); 1288b4263e09399b251e5cf306b2ade0d0f768d3cb61asapersson@webrtc.org } 1289b4263e09399b251e5cf306b2ade0d0f768d3cb61asapersson@webrtc.org return SEND_PACKET; 1290b4263e09399b251e5cf306b2ade0d0f768d3cb61asapersson@webrtc.org } 1291b4263e09399b251e5cf306b2ade0d0f768d3cb61asapersson@webrtc.org bool enable_rrtr_; 1292b4263e09399b251e5cf306b2ade0d0f768d3cb61asapersson@webrtc.org int sent_rtcp_sr_; 1293b4263e09399b251e5cf306b2ade0d0f768d3cb61asapersson@webrtc.org int sent_rtcp_rr_; 1294b4263e09399b251e5cf306b2ade0d0f768d3cb61asapersson@webrtc.org int sent_rtcp_rrtr_; 1295b4263e09399b251e5cf306b2ade0d0f768d3cb61asapersson@webrtc.org int sent_rtcp_dlrr_; 1296b4263e09399b251e5cf306b2ade0d0f768d3cb61asapersson@webrtc.org } observer(enable_rrtr); 1297b4263e09399b251e5cf306b2ade0d0f768d3cb61asapersson@webrtc.org 1298b4263e09399b251e5cf306b2ade0d0f768d3cb61asapersson@webrtc.org CreateCalls(Call::Config(observer.SendTransport()), 1299b4263e09399b251e5cf306b2ade0d0f768d3cb61asapersson@webrtc.org Call::Config(observer.ReceiveTransport())); 1300c71929dce136f9bc59fcc7ceb172cf74fc507ea9pbos@webrtc.org observer.SetReceivers(receiver_call_->Receiver(), sender_call_->Receiver()); 1301b4263e09399b251e5cf306b2ade0d0f768d3cb61asapersson@webrtc.org 1302b4263e09399b251e5cf306b2ade0d0f768d3cb61asapersson@webrtc.org CreateTestConfigs(); 1303b4263e09399b251e5cf306b2ade0d0f768d3cb61asapersson@webrtc.org receive_config_.rtp.rtcp_mode = newapi::kRtcpReducedSize; 1304b4263e09399b251e5cf306b2ade0d0f768d3cb61asapersson@webrtc.org receive_config_.rtp.rtcp_xr.receiver_reference_time_report = enable_rrtr; 1305b4263e09399b251e5cf306b2ade0d0f768d3cb61asapersson@webrtc.org 1306b4263e09399b251e5cf306b2ade0d0f768d3cb61asapersson@webrtc.org CreateStreams(); 1307b4263e09399b251e5cf306b2ade0d0f768d3cb61asapersson@webrtc.org CreateFrameGenerator(); 1308b4263e09399b251e5cf306b2ade0d0f768d3cb61asapersson@webrtc.org StartSending(); 1309b4263e09399b251e5cf306b2ade0d0f768d3cb61asapersson@webrtc.org 1310b4263e09399b251e5cf306b2ade0d0f768d3cb61asapersson@webrtc.org EXPECT_EQ(kEventSignaled, observer.Wait()) 1311b4263e09399b251e5cf306b2ade0d0f768d3cb61asapersson@webrtc.org << "Timed out while waiting for RTCP SR/RR packets to be sent."; 1312b4263e09399b251e5cf306b2ade0d0f768d3cb61asapersson@webrtc.org 1313b4263e09399b251e5cf306b2ade0d0f768d3cb61asapersson@webrtc.org StopSending(); 1314b4263e09399b251e5cf306b2ade0d0f768d3cb61asapersson@webrtc.org observer.StopSending(); 1315b4263e09399b251e5cf306b2ade0d0f768d3cb61asapersson@webrtc.org DestroyStreams(); 1316b4263e09399b251e5cf306b2ade0d0f768d3cb61asapersson@webrtc.org} 1317b4263e09399b251e5cf306b2ade0d0f768d3cb61asapersson@webrtc.org 1318c8ab7215c005f95e375f6e07f2a08ab6c7431f51sprang@webrtc.orgclass StatsObserver : public test::RtpRtcpObserver, public I420FrameCallback { 1319c8ab7215c005f95e375f6e07f2a08ab6c7431f51sprang@webrtc.org public: 1320c8ab7215c005f95e375f6e07f2a08ab6c7431f51sprang@webrtc.org StatsObserver() 1321c8ab7215c005f95e375f6e07f2a08ab6c7431f51sprang@webrtc.org : test::RtpRtcpObserver(kLongTimeoutMs), 1322c8ab7215c005f95e375f6e07f2a08ab6c7431f51sprang@webrtc.org receive_stream_(NULL), 1323c8ab7215c005f95e375f6e07f2a08ab6c7431f51sprang@webrtc.org send_stream_(NULL), 1324c8ab7215c005f95e375f6e07f2a08ab6c7431f51sprang@webrtc.org expected_receive_ssrc_(), 1325c8ab7215c005f95e375f6e07f2a08ab6c7431f51sprang@webrtc.org expected_send_ssrcs_(), 1326c8ab7215c005f95e375f6e07f2a08ab6c7431f51sprang@webrtc.org check_stats_event_(EventWrapper::Create()) {} 1327c8ab7215c005f95e375f6e07f2a08ab6c7431f51sprang@webrtc.org 1328c8ab7215c005f95e375f6e07f2a08ab6c7431f51sprang@webrtc.org void SetExpectedReceiveSsrc(uint32_t ssrc) { expected_receive_ssrc_ = ssrc; } 1329c8ab7215c005f95e375f6e07f2a08ab6c7431f51sprang@webrtc.org 1330c8ab7215c005f95e375f6e07f2a08ab6c7431f51sprang@webrtc.org void SetExpectedSendSsrcs(const std::vector<uint32_t>& ssrcs) { 1331c8ab7215c005f95e375f6e07f2a08ab6c7431f51sprang@webrtc.org for (std::vector<uint32_t>::const_iterator it = ssrcs.begin(); 1332c8ab7215c005f95e375f6e07f2a08ab6c7431f51sprang@webrtc.org it != ssrcs.end(); 1333c8ab7215c005f95e375f6e07f2a08ab6c7431f51sprang@webrtc.org ++it) { 1334c8ab7215c005f95e375f6e07f2a08ab6c7431f51sprang@webrtc.org expected_send_ssrcs_.insert(*it); 1335c8ab7215c005f95e375f6e07f2a08ab6c7431f51sprang@webrtc.org } 1336c8ab7215c005f95e375f6e07f2a08ab6c7431f51sprang@webrtc.org } 1337c8ab7215c005f95e375f6e07f2a08ab6c7431f51sprang@webrtc.org 1338c8ab7215c005f95e375f6e07f2a08ab6c7431f51sprang@webrtc.org void SetExpectedCName(std::string cname) { expected_cname_ = cname; } 1339c8ab7215c005f95e375f6e07f2a08ab6c7431f51sprang@webrtc.org 1340c8ab7215c005f95e375f6e07f2a08ab6c7431f51sprang@webrtc.org void SetReceiveStream(VideoReceiveStream* stream) { 1341c8ab7215c005f95e375f6e07f2a08ab6c7431f51sprang@webrtc.org receive_stream_ = stream; 1342c8ab7215c005f95e375f6e07f2a08ab6c7431f51sprang@webrtc.org } 1343c8ab7215c005f95e375f6e07f2a08ab6c7431f51sprang@webrtc.org 1344c8ab7215c005f95e375f6e07f2a08ab6c7431f51sprang@webrtc.org void SetSendStream(VideoSendStream* stream) { send_stream_ = stream; } 1345c8ab7215c005f95e375f6e07f2a08ab6c7431f51sprang@webrtc.org 1346c8ab7215c005f95e375f6e07f2a08ab6c7431f51sprang@webrtc.org void WaitForFilledStats() { 1347c8ab7215c005f95e375f6e07f2a08ab6c7431f51sprang@webrtc.org Clock* clock = Clock::GetRealTimeClock(); 1348c8ab7215c005f95e375f6e07f2a08ab6c7431f51sprang@webrtc.org int64_t now = clock->TimeInMilliseconds(); 1349c8ab7215c005f95e375f6e07f2a08ab6c7431f51sprang@webrtc.org int64_t stop_time = now + kLongTimeoutMs; 1350c8ab7215c005f95e375f6e07f2a08ab6c7431f51sprang@webrtc.org bool receive_ok = false; 1351c8ab7215c005f95e375f6e07f2a08ab6c7431f51sprang@webrtc.org bool send_ok = false; 1352c8ab7215c005f95e375f6e07f2a08ab6c7431f51sprang@webrtc.org 1353c8ab7215c005f95e375f6e07f2a08ab6c7431f51sprang@webrtc.org while (now < stop_time) { 1354c8ab7215c005f95e375f6e07f2a08ab6c7431f51sprang@webrtc.org if (!receive_ok) 1355c8ab7215c005f95e375f6e07f2a08ab6c7431f51sprang@webrtc.org receive_ok = CheckReceiveStats(); 1356c8ab7215c005f95e375f6e07f2a08ab6c7431f51sprang@webrtc.org if (!send_ok) 1357c8ab7215c005f95e375f6e07f2a08ab6c7431f51sprang@webrtc.org send_ok = CheckSendStats(); 1358c8ab7215c005f95e375f6e07f2a08ab6c7431f51sprang@webrtc.org 1359c8ab7215c005f95e375f6e07f2a08ab6c7431f51sprang@webrtc.org if (receive_ok && send_ok) 1360c8ab7215c005f95e375f6e07f2a08ab6c7431f51sprang@webrtc.org return; 1361c8ab7215c005f95e375f6e07f2a08ab6c7431f51sprang@webrtc.org 1362c8ab7215c005f95e375f6e07f2a08ab6c7431f51sprang@webrtc.org int64_t time_until_timout_ = stop_time - now; 1363c8ab7215c005f95e375f6e07f2a08ab6c7431f51sprang@webrtc.org if (time_until_timout_ > 0) 1364c8ab7215c005f95e375f6e07f2a08ab6c7431f51sprang@webrtc.org check_stats_event_->Wait(time_until_timout_); 1365c8ab7215c005f95e375f6e07f2a08ab6c7431f51sprang@webrtc.org now = clock->TimeInMilliseconds(); 1366c8ab7215c005f95e375f6e07f2a08ab6c7431f51sprang@webrtc.org } 1367c8ab7215c005f95e375f6e07f2a08ab6c7431f51sprang@webrtc.org 1368c8ab7215c005f95e375f6e07f2a08ab6c7431f51sprang@webrtc.org ADD_FAILURE() << "Timed out waiting for filled stats."; 1369c8ab7215c005f95e375f6e07f2a08ab6c7431f51sprang@webrtc.org for (std::map<std::string, bool>::const_iterator it = 1370c8ab7215c005f95e375f6e07f2a08ab6c7431f51sprang@webrtc.org receive_stats_filled_.begin(); 1371c8ab7215c005f95e375f6e07f2a08ab6c7431f51sprang@webrtc.org it != receive_stats_filled_.end(); 1372c8ab7215c005f95e375f6e07f2a08ab6c7431f51sprang@webrtc.org ++it) { 1373c8ab7215c005f95e375f6e07f2a08ab6c7431f51sprang@webrtc.org if (!it->second) { 1374c8ab7215c005f95e375f6e07f2a08ab6c7431f51sprang@webrtc.org ADD_FAILURE() << "Missing receive stats: " << it->first; 1375c8ab7215c005f95e375f6e07f2a08ab6c7431f51sprang@webrtc.org } 1376c8ab7215c005f95e375f6e07f2a08ab6c7431f51sprang@webrtc.org } 1377c8ab7215c005f95e375f6e07f2a08ab6c7431f51sprang@webrtc.org 1378c8ab7215c005f95e375f6e07f2a08ab6c7431f51sprang@webrtc.org for (std::map<std::string, bool>::const_iterator it = 1379c8ab7215c005f95e375f6e07f2a08ab6c7431f51sprang@webrtc.org send_stats_filled_.begin(); 1380c8ab7215c005f95e375f6e07f2a08ab6c7431f51sprang@webrtc.org it != send_stats_filled_.end(); 1381c8ab7215c005f95e375f6e07f2a08ab6c7431f51sprang@webrtc.org ++it) { 1382c8ab7215c005f95e375f6e07f2a08ab6c7431f51sprang@webrtc.org if (!it->second) { 1383c8ab7215c005f95e375f6e07f2a08ab6c7431f51sprang@webrtc.org ADD_FAILURE() << "Missing send stats: " << it->first; 1384c8ab7215c005f95e375f6e07f2a08ab6c7431f51sprang@webrtc.org } 1385c8ab7215c005f95e375f6e07f2a08ab6c7431f51sprang@webrtc.org } 1386c8ab7215c005f95e375f6e07f2a08ab6c7431f51sprang@webrtc.org } 1387c8ab7215c005f95e375f6e07f2a08ab6c7431f51sprang@webrtc.org 1388c8ab7215c005f95e375f6e07f2a08ab6c7431f51sprang@webrtc.org private: 1389c8ab7215c005f95e375f6e07f2a08ab6c7431f51sprang@webrtc.org virtual Action OnSendRtp(const uint8_t* packet, size_t length) OVERRIDE { 1390c8ab7215c005f95e375f6e07f2a08ab6c7431f51sprang@webrtc.org check_stats_event_->Set(); 1391c8ab7215c005f95e375f6e07f2a08ab6c7431f51sprang@webrtc.org return SEND_PACKET; 1392c8ab7215c005f95e375f6e07f2a08ab6c7431f51sprang@webrtc.org } 1393c8ab7215c005f95e375f6e07f2a08ab6c7431f51sprang@webrtc.org 1394c8ab7215c005f95e375f6e07f2a08ab6c7431f51sprang@webrtc.org virtual Action OnSendRtcp(const uint8_t* packet, size_t length) OVERRIDE { 1395c8ab7215c005f95e375f6e07f2a08ab6c7431f51sprang@webrtc.org check_stats_event_->Set(); 1396c8ab7215c005f95e375f6e07f2a08ab6c7431f51sprang@webrtc.org return SEND_PACKET; 1397c8ab7215c005f95e375f6e07f2a08ab6c7431f51sprang@webrtc.org } 1398c8ab7215c005f95e375f6e07f2a08ab6c7431f51sprang@webrtc.org 1399c8ab7215c005f95e375f6e07f2a08ab6c7431f51sprang@webrtc.org virtual Action OnReceiveRtp(const uint8_t* packet, size_t length) OVERRIDE { 1400c8ab7215c005f95e375f6e07f2a08ab6c7431f51sprang@webrtc.org check_stats_event_->Set(); 1401c8ab7215c005f95e375f6e07f2a08ab6c7431f51sprang@webrtc.org return SEND_PACKET; 1402c8ab7215c005f95e375f6e07f2a08ab6c7431f51sprang@webrtc.org } 1403c8ab7215c005f95e375f6e07f2a08ab6c7431f51sprang@webrtc.org 1404c8ab7215c005f95e375f6e07f2a08ab6c7431f51sprang@webrtc.org virtual Action OnReceiveRtcp(const uint8_t* packet, size_t length) OVERRIDE { 1405c8ab7215c005f95e375f6e07f2a08ab6c7431f51sprang@webrtc.org check_stats_event_->Set(); 1406c8ab7215c005f95e375f6e07f2a08ab6c7431f51sprang@webrtc.org return SEND_PACKET; 1407c8ab7215c005f95e375f6e07f2a08ab6c7431f51sprang@webrtc.org } 1408c8ab7215c005f95e375f6e07f2a08ab6c7431f51sprang@webrtc.org 1409c8ab7215c005f95e375f6e07f2a08ab6c7431f51sprang@webrtc.org virtual void FrameCallback(I420VideoFrame* video_frame) OVERRIDE { 1410c8ab7215c005f95e375f6e07f2a08ab6c7431f51sprang@webrtc.org // Ensure that we have at least 5ms send side delay. 1411c8ab7215c005f95e375f6e07f2a08ab6c7431f51sprang@webrtc.org int64_t render_time = video_frame->render_time_ms(); 1412c8ab7215c005f95e375f6e07f2a08ab6c7431f51sprang@webrtc.org if (render_time > 0) 1413c8ab7215c005f95e375f6e07f2a08ab6c7431f51sprang@webrtc.org video_frame->set_render_time_ms(render_time - 5); 1414c8ab7215c005f95e375f6e07f2a08ab6c7431f51sprang@webrtc.org } 1415c8ab7215c005f95e375f6e07f2a08ab6c7431f51sprang@webrtc.org 1416c8ab7215c005f95e375f6e07f2a08ab6c7431f51sprang@webrtc.org bool CheckReceiveStats() { 1417c8ab7215c005f95e375f6e07f2a08ab6c7431f51sprang@webrtc.org assert(receive_stream_ != NULL); 1418c8ab7215c005f95e375f6e07f2a08ab6c7431f51sprang@webrtc.org VideoReceiveStream::Stats stats = receive_stream_->GetStats(); 1419c8ab7215c005f95e375f6e07f2a08ab6c7431f51sprang@webrtc.org EXPECT_EQ(expected_receive_ssrc_, stats.ssrc); 1420c8ab7215c005f95e375f6e07f2a08ab6c7431f51sprang@webrtc.org 1421c8ab7215c005f95e375f6e07f2a08ab6c7431f51sprang@webrtc.org // Make sure all fields have been populated. 1422c8ab7215c005f95e375f6e07f2a08ab6c7431f51sprang@webrtc.org 1423c8ab7215c005f95e375f6e07f2a08ab6c7431f51sprang@webrtc.org receive_stats_filled_["IncomingRate"] |= 1424c8ab7215c005f95e375f6e07f2a08ab6c7431f51sprang@webrtc.org stats.network_frame_rate != 0 || stats.bitrate_bps != 0; 1425c8ab7215c005f95e375f6e07f2a08ab6c7431f51sprang@webrtc.org 1426c8ab7215c005f95e375f6e07f2a08ab6c7431f51sprang@webrtc.org receive_stats_filled_["FrameCallback"] |= stats.decode_frame_rate != 0; 1427c8ab7215c005f95e375f6e07f2a08ab6c7431f51sprang@webrtc.org 1428c8ab7215c005f95e375f6e07f2a08ab6c7431f51sprang@webrtc.org receive_stats_filled_["FrameRendered"] |= stats.render_frame_rate != 0; 1429c8ab7215c005f95e375f6e07f2a08ab6c7431f51sprang@webrtc.org 1430c8ab7215c005f95e375f6e07f2a08ab6c7431f51sprang@webrtc.org receive_stats_filled_["StatisticsUpdated"] |= 1431c8ab7215c005f95e375f6e07f2a08ab6c7431f51sprang@webrtc.org stats.rtcp_stats.cumulative_lost != 0 || 1432c8ab7215c005f95e375f6e07f2a08ab6c7431f51sprang@webrtc.org stats.rtcp_stats.extended_max_sequence_number != 0 || 1433c8ab7215c005f95e375f6e07f2a08ab6c7431f51sprang@webrtc.org stats.rtcp_stats.fraction_lost != 0 || stats.rtcp_stats.jitter != 0; 1434c8ab7215c005f95e375f6e07f2a08ab6c7431f51sprang@webrtc.org 1435c8ab7215c005f95e375f6e07f2a08ab6c7431f51sprang@webrtc.org receive_stats_filled_["DataCountersUpdated"] |= 1436c8ab7215c005f95e375f6e07f2a08ab6c7431f51sprang@webrtc.org stats.rtp_stats.bytes != 0 || stats.rtp_stats.fec_packets != 0 || 1437c8ab7215c005f95e375f6e07f2a08ab6c7431f51sprang@webrtc.org stats.rtp_stats.header_bytes != 0 || stats.rtp_stats.packets != 0 || 1438c8ab7215c005f95e375f6e07f2a08ab6c7431f51sprang@webrtc.org stats.rtp_stats.padding_bytes != 0 || 1439c8ab7215c005f95e375f6e07f2a08ab6c7431f51sprang@webrtc.org stats.rtp_stats.retransmitted_packets != 0; 1440c8ab7215c005f95e375f6e07f2a08ab6c7431f51sprang@webrtc.org 1441c8ab7215c005f95e375f6e07f2a08ab6c7431f51sprang@webrtc.org receive_stats_filled_["CodecStats"] |= 1442c8ab7215c005f95e375f6e07f2a08ab6c7431f51sprang@webrtc.org stats.avg_delay_ms != 0 || stats.discarded_packets != 0 || 1443c8ab7215c005f95e375f6e07f2a08ab6c7431f51sprang@webrtc.org stats.key_frames != 0 || stats.delta_frames != 0; 1444c8ab7215c005f95e375f6e07f2a08ab6c7431f51sprang@webrtc.org 1445c8ab7215c005f95e375f6e07f2a08ab6c7431f51sprang@webrtc.org receive_stats_filled_["CName"] |= stats.c_name == expected_cname_; 1446c8ab7215c005f95e375f6e07f2a08ab6c7431f51sprang@webrtc.org 1447c8ab7215c005f95e375f6e07f2a08ab6c7431f51sprang@webrtc.org return AllStatsFilled(receive_stats_filled_); 1448c8ab7215c005f95e375f6e07f2a08ab6c7431f51sprang@webrtc.org } 1449c8ab7215c005f95e375f6e07f2a08ab6c7431f51sprang@webrtc.org 1450c8ab7215c005f95e375f6e07f2a08ab6c7431f51sprang@webrtc.org bool CheckSendStats() { 1451c8ab7215c005f95e375f6e07f2a08ab6c7431f51sprang@webrtc.org assert(send_stream_ != NULL); 1452c8ab7215c005f95e375f6e07f2a08ab6c7431f51sprang@webrtc.org VideoSendStream::Stats stats = send_stream_->GetStats(); 1453c8ab7215c005f95e375f6e07f2a08ab6c7431f51sprang@webrtc.org 1454c8ab7215c005f95e375f6e07f2a08ab6c7431f51sprang@webrtc.org send_stats_filled_["NumStreams"] |= 1455c8ab7215c005f95e375f6e07f2a08ab6c7431f51sprang@webrtc.org stats.substreams.size() == expected_send_ssrcs_.size(); 1456c8ab7215c005f95e375f6e07f2a08ab6c7431f51sprang@webrtc.org 1457c8ab7215c005f95e375f6e07f2a08ab6c7431f51sprang@webrtc.org send_stats_filled_["Delay"] |= 1458c8ab7215c005f95e375f6e07f2a08ab6c7431f51sprang@webrtc.org stats.avg_delay_ms != 0 || stats.max_delay_ms != 0; 1459c8ab7215c005f95e375f6e07f2a08ab6c7431f51sprang@webrtc.org 1460c8ab7215c005f95e375f6e07f2a08ab6c7431f51sprang@webrtc.org receive_stats_filled_["CName"] |= stats.c_name == expected_cname_; 1461c8ab7215c005f95e375f6e07f2a08ab6c7431f51sprang@webrtc.org 1462c8ab7215c005f95e375f6e07f2a08ab6c7431f51sprang@webrtc.org for (std::map<uint32_t, StreamStats>::const_iterator it = 1463c8ab7215c005f95e375f6e07f2a08ab6c7431f51sprang@webrtc.org stats.substreams.begin(); 1464c8ab7215c005f95e375f6e07f2a08ab6c7431f51sprang@webrtc.org it != stats.substreams.end(); 1465c8ab7215c005f95e375f6e07f2a08ab6c7431f51sprang@webrtc.org ++it) { 1466c8ab7215c005f95e375f6e07f2a08ab6c7431f51sprang@webrtc.org EXPECT_TRUE(expected_send_ssrcs_.find(it->first) != 1467c8ab7215c005f95e375f6e07f2a08ab6c7431f51sprang@webrtc.org expected_send_ssrcs_.end()); 1468c8ab7215c005f95e375f6e07f2a08ab6c7431f51sprang@webrtc.org 1469c8ab7215c005f95e375f6e07f2a08ab6c7431f51sprang@webrtc.org send_stats_filled_[CompoundKey("IncomingRate", it->first)] |= 1470c8ab7215c005f95e375f6e07f2a08ab6c7431f51sprang@webrtc.org stats.input_frame_rate != 0; 1471c8ab7215c005f95e375f6e07f2a08ab6c7431f51sprang@webrtc.org 1472c8ab7215c005f95e375f6e07f2a08ab6c7431f51sprang@webrtc.org const StreamStats& stream_stats = it->second; 1473c8ab7215c005f95e375f6e07f2a08ab6c7431f51sprang@webrtc.org 1474c8ab7215c005f95e375f6e07f2a08ab6c7431f51sprang@webrtc.org send_stats_filled_[CompoundKey("StatisticsUpdated", it->first)] |= 1475c8ab7215c005f95e375f6e07f2a08ab6c7431f51sprang@webrtc.org stream_stats.rtcp_stats.cumulative_lost != 0 || 1476c8ab7215c005f95e375f6e07f2a08ab6c7431f51sprang@webrtc.org stream_stats.rtcp_stats.extended_max_sequence_number != 0 || 1477c8ab7215c005f95e375f6e07f2a08ab6c7431f51sprang@webrtc.org stream_stats.rtcp_stats.fraction_lost != 0; 1478c8ab7215c005f95e375f6e07f2a08ab6c7431f51sprang@webrtc.org 1479c8ab7215c005f95e375f6e07f2a08ab6c7431f51sprang@webrtc.org send_stats_filled_[CompoundKey("DataCountersUpdated", it->first)] |= 1480c8ab7215c005f95e375f6e07f2a08ab6c7431f51sprang@webrtc.org stream_stats.rtp_stats.fec_packets != 0 || 1481c8ab7215c005f95e375f6e07f2a08ab6c7431f51sprang@webrtc.org stream_stats.rtp_stats.padding_bytes != 0 || 1482c8ab7215c005f95e375f6e07f2a08ab6c7431f51sprang@webrtc.org stream_stats.rtp_stats.retransmitted_packets != 0 || 1483c8ab7215c005f95e375f6e07f2a08ab6c7431f51sprang@webrtc.org stream_stats.rtp_stats.packets != 0; 1484c8ab7215c005f95e375f6e07f2a08ab6c7431f51sprang@webrtc.org 1485c8ab7215c005f95e375f6e07f2a08ab6c7431f51sprang@webrtc.org send_stats_filled_[CompoundKey("BitrateStatisticsObserver", it->first)] |= 1486c8ab7215c005f95e375f6e07f2a08ab6c7431f51sprang@webrtc.org stream_stats.bitrate_bps != 0; 1487c8ab7215c005f95e375f6e07f2a08ab6c7431f51sprang@webrtc.org 1488c8ab7215c005f95e375f6e07f2a08ab6c7431f51sprang@webrtc.org send_stats_filled_[CompoundKey("FrameCountObserver", it->first)] |= 1489c8ab7215c005f95e375f6e07f2a08ab6c7431f51sprang@webrtc.org stream_stats.delta_frames != 0 || stream_stats.key_frames != 0; 1490c8ab7215c005f95e375f6e07f2a08ab6c7431f51sprang@webrtc.org 1491c8ab7215c005f95e375f6e07f2a08ab6c7431f51sprang@webrtc.org send_stats_filled_[CompoundKey("OutgoingRate", it->first)] |= 1492c8ab7215c005f95e375f6e07f2a08ab6c7431f51sprang@webrtc.org stats.encode_frame_rate != 0; 1493c8ab7215c005f95e375f6e07f2a08ab6c7431f51sprang@webrtc.org } 1494c8ab7215c005f95e375f6e07f2a08ab6c7431f51sprang@webrtc.org 1495c8ab7215c005f95e375f6e07f2a08ab6c7431f51sprang@webrtc.org return AllStatsFilled(send_stats_filled_); 1496c8ab7215c005f95e375f6e07f2a08ab6c7431f51sprang@webrtc.org } 1497c8ab7215c005f95e375f6e07f2a08ab6c7431f51sprang@webrtc.org 1498c8ab7215c005f95e375f6e07f2a08ab6c7431f51sprang@webrtc.org std::string CompoundKey(const char* name, uint32_t ssrc) { 1499c8ab7215c005f95e375f6e07f2a08ab6c7431f51sprang@webrtc.org std::ostringstream oss; 1500c8ab7215c005f95e375f6e07f2a08ab6c7431f51sprang@webrtc.org oss << name << "_" << ssrc; 1501c8ab7215c005f95e375f6e07f2a08ab6c7431f51sprang@webrtc.org return oss.str(); 1502c8ab7215c005f95e375f6e07f2a08ab6c7431f51sprang@webrtc.org } 1503c8ab7215c005f95e375f6e07f2a08ab6c7431f51sprang@webrtc.org 1504c8ab7215c005f95e375f6e07f2a08ab6c7431f51sprang@webrtc.org bool AllStatsFilled(const std::map<std::string, bool>& stats_map) { 1505c8ab7215c005f95e375f6e07f2a08ab6c7431f51sprang@webrtc.org for (std::map<std::string, bool>::const_iterator it = stats_map.begin(); 1506c8ab7215c005f95e375f6e07f2a08ab6c7431f51sprang@webrtc.org it != stats_map.end(); 1507c8ab7215c005f95e375f6e07f2a08ab6c7431f51sprang@webrtc.org ++it) { 1508c8ab7215c005f95e375f6e07f2a08ab6c7431f51sprang@webrtc.org if (!it->second) 1509c8ab7215c005f95e375f6e07f2a08ab6c7431f51sprang@webrtc.org return false; 1510c8ab7215c005f95e375f6e07f2a08ab6c7431f51sprang@webrtc.org } 1511c8ab7215c005f95e375f6e07f2a08ab6c7431f51sprang@webrtc.org return true; 1512c8ab7215c005f95e375f6e07f2a08ab6c7431f51sprang@webrtc.org } 1513c8ab7215c005f95e375f6e07f2a08ab6c7431f51sprang@webrtc.org 1514c8ab7215c005f95e375f6e07f2a08ab6c7431f51sprang@webrtc.org VideoReceiveStream* receive_stream_; 1515c8ab7215c005f95e375f6e07f2a08ab6c7431f51sprang@webrtc.org std::map<std::string, bool> receive_stats_filled_; 1516c8ab7215c005f95e375f6e07f2a08ab6c7431f51sprang@webrtc.org 1517c8ab7215c005f95e375f6e07f2a08ab6c7431f51sprang@webrtc.org VideoSendStream* send_stream_; 1518c8ab7215c005f95e375f6e07f2a08ab6c7431f51sprang@webrtc.org std::map<std::string, bool> send_stats_filled_; 1519c8ab7215c005f95e375f6e07f2a08ab6c7431f51sprang@webrtc.org 1520c8ab7215c005f95e375f6e07f2a08ab6c7431f51sprang@webrtc.org uint32_t expected_receive_ssrc_; 1521c8ab7215c005f95e375f6e07f2a08ab6c7431f51sprang@webrtc.org std::set<uint32_t> expected_send_ssrcs_; 1522c8ab7215c005f95e375f6e07f2a08ab6c7431f51sprang@webrtc.org std::string expected_cname_; 1523c8ab7215c005f95e375f6e07f2a08ab6c7431f51sprang@webrtc.org 1524c8ab7215c005f95e375f6e07f2a08ab6c7431f51sprang@webrtc.org scoped_ptr<EventWrapper> check_stats_event_; 1525c8ab7215c005f95e375f6e07f2a08ab6c7431f51sprang@webrtc.org}; 1526c8ab7215c005f95e375f6e07f2a08ab6c7431f51sprang@webrtc.org 1527c8ab7215c005f95e375f6e07f2a08ab6c7431f51sprang@webrtc.orgTEST_F(CallTest, GetStats) { 1528c8ab7215c005f95e375f6e07f2a08ab6c7431f51sprang@webrtc.org StatsObserver observer; 1529c8ab7215c005f95e375f6e07f2a08ab6c7431f51sprang@webrtc.org 1530c8ab7215c005f95e375f6e07f2a08ab6c7431f51sprang@webrtc.org CreateCalls(Call::Config(observer.SendTransport()), 1531c8ab7215c005f95e375f6e07f2a08ab6c7431f51sprang@webrtc.org Call::Config(observer.ReceiveTransport())); 1532c8ab7215c005f95e375f6e07f2a08ab6c7431f51sprang@webrtc.org 1533c8ab7215c005f95e375f6e07f2a08ab6c7431f51sprang@webrtc.org observer.SetReceivers(receiver_call_->Receiver(), sender_call_->Receiver()); 1534c8ab7215c005f95e375f6e07f2a08ab6c7431f51sprang@webrtc.org 1535c8ab7215c005f95e375f6e07f2a08ab6c7431f51sprang@webrtc.org CreateTestConfigs(); 1536c8ab7215c005f95e375f6e07f2a08ab6c7431f51sprang@webrtc.org send_config_.pre_encode_callback = &observer; // Used to inject delay. 1537c8ab7215c005f95e375f6e07f2a08ab6c7431f51sprang@webrtc.org send_config_.rtp.c_name = "SomeCName"; 1538c8ab7215c005f95e375f6e07f2a08ab6c7431f51sprang@webrtc.org 1539c8ab7215c005f95e375f6e07f2a08ab6c7431f51sprang@webrtc.org observer.SetExpectedReceiveSsrc(receive_config_.rtp.local_ssrc); 1540c8ab7215c005f95e375f6e07f2a08ab6c7431f51sprang@webrtc.org observer.SetExpectedSendSsrcs(send_config_.rtp.ssrcs); 1541c8ab7215c005f95e375f6e07f2a08ab6c7431f51sprang@webrtc.org observer.SetExpectedCName(send_config_.rtp.c_name); 1542c8ab7215c005f95e375f6e07f2a08ab6c7431f51sprang@webrtc.org 1543c8ab7215c005f95e375f6e07f2a08ab6c7431f51sprang@webrtc.org CreateStreams(); 1544c8ab7215c005f95e375f6e07f2a08ab6c7431f51sprang@webrtc.org observer.SetReceiveStream(receive_stream_); 1545c8ab7215c005f95e375f6e07f2a08ab6c7431f51sprang@webrtc.org observer.SetSendStream(send_stream_); 1546c8ab7215c005f95e375f6e07f2a08ab6c7431f51sprang@webrtc.org CreateFrameGenerator(); 1547c8ab7215c005f95e375f6e07f2a08ab6c7431f51sprang@webrtc.org StartSending(); 1548c8ab7215c005f95e375f6e07f2a08ab6c7431f51sprang@webrtc.org 1549c8ab7215c005f95e375f6e07f2a08ab6c7431f51sprang@webrtc.org observer.WaitForFilledStats(); 1550c8ab7215c005f95e375f6e07f2a08ab6c7431f51sprang@webrtc.org 1551c8ab7215c005f95e375f6e07f2a08ab6c7431f51sprang@webrtc.org StopSending(); 1552c8ab7215c005f95e375f6e07f2a08ab6c7431f51sprang@webrtc.org observer.StopSending(); 1553c8ab7215c005f95e375f6e07f2a08ab6c7431f51sprang@webrtc.org DestroyStreams(); 1554c8ab7215c005f95e375f6e07f2a08ab6c7431f51sprang@webrtc.org} 1555c8ab7215c005f95e375f6e07f2a08ab6c7431f51sprang@webrtc.org 1556b4263e09399b251e5cf306b2ade0d0f768d3cb61asapersson@webrtc.orgTEST_F(CallTest, ReceiverReferenceTimeReportEnabled) { 1557b4263e09399b251e5cf306b2ade0d0f768d3cb61asapersson@webrtc.org TestXrReceiverReferenceTimeReport(true); 1558b4263e09399b251e5cf306b2ade0d0f768d3cb61asapersson@webrtc.org} 1559b4263e09399b251e5cf306b2ade0d0f768d3cb61asapersson@webrtc.org 1560b4263e09399b251e5cf306b2ade0d0f768d3cb61asapersson@webrtc.orgTEST_F(CallTest, ReceiverReferenceTimeReportDisabled) { 1561b4263e09399b251e5cf306b2ade0d0f768d3cb61asapersson@webrtc.org TestXrReceiverReferenceTimeReport(false); 1562b4263e09399b251e5cf306b2ade0d0f768d3cb61asapersson@webrtc.org} 15633f83f9cae99b605aee71b46839e902653baeb3f6pbos@webrtc.org 156499153baa13d2a844373be5fa45eeb5be492b3445asapersson@webrtc.orgTEST_F(CallTest, TestReceivedRtpPacketStats) { 156599153baa13d2a844373be5fa45eeb5be492b3445asapersson@webrtc.org static const size_t kNumRtpPacketsToSend = 5; 156699153baa13d2a844373be5fa45eeb5be492b3445asapersson@webrtc.org class ReceivedRtpStatsObserver : public test::RtpRtcpObserver { 156799153baa13d2a844373be5fa45eeb5be492b3445asapersson@webrtc.org public: 156899153baa13d2a844373be5fa45eeb5be492b3445asapersson@webrtc.org ReceivedRtpStatsObserver() 156999153baa13d2a844373be5fa45eeb5be492b3445asapersson@webrtc.org : test::RtpRtcpObserver(kDefaultTimeoutMs), 157099153baa13d2a844373be5fa45eeb5be492b3445asapersson@webrtc.org receive_stream_(NULL), 157199153baa13d2a844373be5fa45eeb5be492b3445asapersson@webrtc.org sent_rtp_(0) {} 157299153baa13d2a844373be5fa45eeb5be492b3445asapersson@webrtc.org 157399153baa13d2a844373be5fa45eeb5be492b3445asapersson@webrtc.org void SetReceiveStream(VideoReceiveStream* stream) { 157499153baa13d2a844373be5fa45eeb5be492b3445asapersson@webrtc.org receive_stream_ = stream; 157599153baa13d2a844373be5fa45eeb5be492b3445asapersson@webrtc.org } 157699153baa13d2a844373be5fa45eeb5be492b3445asapersson@webrtc.org 157799153baa13d2a844373be5fa45eeb5be492b3445asapersson@webrtc.org private: 157899153baa13d2a844373be5fa45eeb5be492b3445asapersson@webrtc.org virtual Action OnSendRtp(const uint8_t* packet, size_t length) OVERRIDE { 157999153baa13d2a844373be5fa45eeb5be492b3445asapersson@webrtc.org if (sent_rtp_ >= kNumRtpPacketsToSend) { 158099153baa13d2a844373be5fa45eeb5be492b3445asapersson@webrtc.org VideoReceiveStream::Stats stats = receive_stream_->GetStats(); 158199153baa13d2a844373be5fa45eeb5be492b3445asapersson@webrtc.org if (kNumRtpPacketsToSend == stats.rtp_stats.packets) { 158299153baa13d2a844373be5fa45eeb5be492b3445asapersson@webrtc.org observation_complete_->Set(); 158399153baa13d2a844373be5fa45eeb5be492b3445asapersson@webrtc.org } 158499153baa13d2a844373be5fa45eeb5be492b3445asapersson@webrtc.org return DROP_PACKET; 158599153baa13d2a844373be5fa45eeb5be492b3445asapersson@webrtc.org } 158699153baa13d2a844373be5fa45eeb5be492b3445asapersson@webrtc.org ++sent_rtp_; 158799153baa13d2a844373be5fa45eeb5be492b3445asapersson@webrtc.org return SEND_PACKET; 158899153baa13d2a844373be5fa45eeb5be492b3445asapersson@webrtc.org } 158999153baa13d2a844373be5fa45eeb5be492b3445asapersson@webrtc.org 159099153baa13d2a844373be5fa45eeb5be492b3445asapersson@webrtc.org VideoReceiveStream* receive_stream_; 159199153baa13d2a844373be5fa45eeb5be492b3445asapersson@webrtc.org uint32_t sent_rtp_; 159299153baa13d2a844373be5fa45eeb5be492b3445asapersson@webrtc.org } observer; 159399153baa13d2a844373be5fa45eeb5be492b3445asapersson@webrtc.org 159499153baa13d2a844373be5fa45eeb5be492b3445asapersson@webrtc.org CreateCalls(Call::Config(observer.SendTransport()), 159599153baa13d2a844373be5fa45eeb5be492b3445asapersson@webrtc.org Call::Config(observer.ReceiveTransport())); 159699153baa13d2a844373be5fa45eeb5be492b3445asapersson@webrtc.org observer.SetReceivers(receiver_call_->Receiver(), sender_call_->Receiver()); 159799153baa13d2a844373be5fa45eeb5be492b3445asapersson@webrtc.org 159899153baa13d2a844373be5fa45eeb5be492b3445asapersson@webrtc.org CreateTestConfigs(); 159999153baa13d2a844373be5fa45eeb5be492b3445asapersson@webrtc.org CreateStreams(); 160099153baa13d2a844373be5fa45eeb5be492b3445asapersson@webrtc.org observer.SetReceiveStream(receive_stream_); 160199153baa13d2a844373be5fa45eeb5be492b3445asapersson@webrtc.org CreateFrameGenerator(); 160299153baa13d2a844373be5fa45eeb5be492b3445asapersson@webrtc.org StartSending(); 160399153baa13d2a844373be5fa45eeb5be492b3445asapersson@webrtc.org 160499153baa13d2a844373be5fa45eeb5be492b3445asapersson@webrtc.org EXPECT_EQ(kEventSignaled, observer.Wait()) 160599153baa13d2a844373be5fa45eeb5be492b3445asapersson@webrtc.org << "Timed out while verifying number of received RTP packets."; 160699153baa13d2a844373be5fa45eeb5be492b3445asapersson@webrtc.org 160799153baa13d2a844373be5fa45eeb5be492b3445asapersson@webrtc.org StopSending(); 160899153baa13d2a844373be5fa45eeb5be492b3445asapersson@webrtc.org observer.StopSending(); 160999153baa13d2a844373be5fa45eeb5be492b3445asapersson@webrtc.org DestroyStreams(); 161099153baa13d2a844373be5fa45eeb5be492b3445asapersson@webrtc.org} 161199153baa13d2a844373be5fa45eeb5be492b3445asapersson@webrtc.org 1612ce8510901416e37afabb0a54c6e10bec6db63a42pbos@webrtc.org} // namespace webrtc 1613