1286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org/* 2286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org * Copyright (c) 2013 The WebRTC project authors. All Rights Reserved. 3286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org * 4286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org * Use of this source code is governed by a BSD-style license 5286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org * that can be found in the LICENSE file in the root of the source 6286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org * tree. An additional intellectual property rights grant can be found 7286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org * in the file PATENTS. All contributing project authors may 8286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org * be found in the AUTHORS file in the root of the source tree. 9286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org */ 10286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org 11286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org#include "testing/gmock/include/gmock/gmock.h" 12286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org#include "testing/gtest/include/gtest/gtest.h" 1300b8f6b3643332cce1ee711715f7fbb824d793cakwiberg@webrtc.org#include "webrtc/base/scoped_ptr.h" 14ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander#include "webrtc/modules/rtp_rtcp/include/receive_statistics.h" 1598f53510b222f71fdd8b799b2f33737ceeb28c61Henrik Kjellander#include "webrtc/system_wrappers/include/clock.h" 16286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org 17286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.orgnamespace webrtc { 18286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org 194591fbd09f9cb6e83433c49a12dd8524c2806502pkasting@chromium.orgconst size_t kPacketSize1 = 100; 204591fbd09f9cb6e83433c49a12dd8524c2806502pkasting@chromium.orgconst size_t kPacketSize2 = 300; 21286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.orgconst uint32_t kSsrc1 = 1; 22286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.orgconst uint32_t kSsrc2 = 2; 23286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org 24286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.orgclass ReceiveStatisticsTest : public ::testing::Test { 25286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org public: 26286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org ReceiveStatisticsTest() : 27286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org clock_(0), 28286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org receive_statistics_(ReceiveStatistics::Create(&clock_)) { 29286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org memset(&header1_, 0, sizeof(header1_)); 30286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org header1_.ssrc = kSsrc1; 310e93257cee79c0d19ddaef1f14ba750bf469a084sprang@webrtc.org header1_.sequenceNumber = 100; 32286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org memset(&header2_, 0, sizeof(header2_)); 33286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org header2_.ssrc = kSsrc2; 340e93257cee79c0d19ddaef1f14ba750bf469a084sprang@webrtc.org header2_.sequenceNumber = 100; 35286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org } 36286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org 37286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org protected: 38286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org SimulatedClock clock_; 3900b8f6b3643332cce1ee711715f7fbb824d793cakwiberg@webrtc.org rtc::scoped_ptr<ReceiveStatistics> receive_statistics_; 40286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org RTPHeader header1_; 41286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org RTPHeader header2_; 42286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org}; 43286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org 44286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.orgTEST_F(ReceiveStatisticsTest, TwoIncomingSsrcs) { 457bb8f02274ecbfa1f7ef134d708369a369a78c83stefan@webrtc.org receive_statistics_->IncomingPacket(header1_, kPacketSize1, false); 46286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org ++header1_.sequenceNumber; 477bb8f02274ecbfa1f7ef134d708369a369a78c83stefan@webrtc.org receive_statistics_->IncomingPacket(header2_, kPacketSize2, false); 48286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org ++header2_.sequenceNumber; 49286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org clock_.AdvanceTimeMilliseconds(100); 507bb8f02274ecbfa1f7ef134d708369a369a78c83stefan@webrtc.org receive_statistics_->IncomingPacket(header1_, kPacketSize1, false); 51286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org ++header1_.sequenceNumber; 527bb8f02274ecbfa1f7ef134d708369a369a78c83stefan@webrtc.org receive_statistics_->IncomingPacket(header2_, kPacketSize2, false); 53286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org ++header2_.sequenceNumber; 54286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org 55286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org StreamStatistician* statistician = 56286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org receive_statistics_->GetStatistician(kSsrc1); 57286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org ASSERT_TRUE(statistician != NULL); 58286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org EXPECT_GT(statistician->BitrateReceived(), 0u); 594591fbd09f9cb6e83433c49a12dd8524c2806502pkasting@chromium.org size_t bytes_received = 0; 60286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org uint32_t packets_received = 0; 61286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org statistician->GetDataCounters(&bytes_received, &packets_received); 62286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org EXPECT_EQ(200u, bytes_received); 63286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org EXPECT_EQ(2u, packets_received); 64286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org 65286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org statistician = 66286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org receive_statistics_->GetStatistician(kSsrc2); 67286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org ASSERT_TRUE(statistician != NULL); 68286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org EXPECT_GT(statistician->BitrateReceived(), 0u); 69286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org statistician->GetDataCounters(&bytes_received, &packets_received); 70286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org EXPECT_EQ(600u, bytes_received); 71286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org EXPECT_EQ(2u, packets_received); 72286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org 73286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org StatisticianMap statisticians = receive_statistics_->GetActiveStatisticians(); 74286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org EXPECT_EQ(2u, statisticians.size()); 75286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org // Add more incoming packets and verify that they are registered in both 76286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org // access methods. 777bb8f02274ecbfa1f7ef134d708369a369a78c83stefan@webrtc.org receive_statistics_->IncomingPacket(header1_, kPacketSize1, false); 78286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org ++header1_.sequenceNumber; 797bb8f02274ecbfa1f7ef134d708369a369a78c83stefan@webrtc.org receive_statistics_->IncomingPacket(header2_, kPacketSize2, false); 80286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org ++header2_.sequenceNumber; 81286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org 82286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org statisticians[kSsrc1]->GetDataCounters(&bytes_received, &packets_received); 83286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org EXPECT_EQ(300u, bytes_received); 84286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org EXPECT_EQ(3u, packets_received); 85286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org statisticians[kSsrc2]->GetDataCounters(&bytes_received, &packets_received); 86286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org EXPECT_EQ(900u, bytes_received); 87286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org EXPECT_EQ(3u, packets_received); 88286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org 89286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org receive_statistics_->GetStatistician(kSsrc1)->GetDataCounters( 90286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org &bytes_received, &packets_received); 91286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org EXPECT_EQ(300u, bytes_received); 92286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org EXPECT_EQ(3u, packets_received); 93286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org receive_statistics_->GetStatistician(kSsrc2)->GetDataCounters( 94286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org &bytes_received, &packets_received); 95286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org EXPECT_EQ(900u, bytes_received); 96286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org EXPECT_EQ(3u, packets_received); 97286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org} 98286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org 99286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.orgTEST_F(ReceiveStatisticsTest, ActiveStatisticians) { 1007bb8f02274ecbfa1f7ef134d708369a369a78c83stefan@webrtc.org receive_statistics_->IncomingPacket(header1_, kPacketSize1, false); 101286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org ++header1_.sequenceNumber; 102286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org clock_.AdvanceTimeMilliseconds(1000); 1037bb8f02274ecbfa1f7ef134d708369a369a78c83stefan@webrtc.org receive_statistics_->IncomingPacket(header2_, kPacketSize2, false); 104286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org ++header2_.sequenceNumber; 105286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org StatisticianMap statisticians = receive_statistics_->GetActiveStatisticians(); 106286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org // Nothing should time out since only 1000 ms has passed since the first 107286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org // packet came in. 108286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org EXPECT_EQ(2u, statisticians.size()); 109286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org 110286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org clock_.AdvanceTimeMilliseconds(7000); 111286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org // kSsrc1 should have timed out. 112286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org statisticians = receive_statistics_->GetActiveStatisticians(); 113286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org EXPECT_EQ(1u, statisticians.size()); 114286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org 115286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org clock_.AdvanceTimeMilliseconds(1000); 116286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org // kSsrc2 should have timed out. 117286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org statisticians = receive_statistics_->GetActiveStatisticians(); 118286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org EXPECT_EQ(0u, statisticians.size()); 119286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org 1207bb8f02274ecbfa1f7ef134d708369a369a78c83stefan@webrtc.org receive_statistics_->IncomingPacket(header1_, kPacketSize1, false); 121286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org ++header1_.sequenceNumber; 122286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org // kSsrc1 should be active again and the data counters should have survived. 123286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org statisticians = receive_statistics_->GetActiveStatisticians(); 124286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org EXPECT_EQ(1u, statisticians.size()); 125286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org StreamStatistician* statistician = 126286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org receive_statistics_->GetStatistician(kSsrc1); 127286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org ASSERT_TRUE(statistician != NULL); 1284591fbd09f9cb6e83433c49a12dd8524c2806502pkasting@chromium.org size_t bytes_received = 0; 129286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org uint32_t packets_received = 0; 130286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org statistician->GetDataCounters(&bytes_received, &packets_received); 131286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org EXPECT_EQ(200u, bytes_received); 132286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org EXPECT_EQ(2u, packets_received); 133286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org} 13454ae4ffb9e235a9742e2b11298327e02d870571csprang@webrtc.org 13597d0489058ae7a983f7306f32cfd49a2356c6488asapersson@webrtc.orgTEST_F(ReceiveStatisticsTest, GetReceiveStreamDataCounters) { 13697d0489058ae7a983f7306f32cfd49a2356c6488asapersson@webrtc.org receive_statistics_->IncomingPacket(header1_, kPacketSize1, false); 13797d0489058ae7a983f7306f32cfd49a2356c6488asapersson@webrtc.org StreamStatistician* statistician = 13897d0489058ae7a983f7306f32cfd49a2356c6488asapersson@webrtc.org receive_statistics_->GetStatistician(kSsrc1); 13997d0489058ae7a983f7306f32cfd49a2356c6488asapersson@webrtc.org ASSERT_TRUE(statistician != NULL); 14097d0489058ae7a983f7306f32cfd49a2356c6488asapersson@webrtc.org 14197d0489058ae7a983f7306f32cfd49a2356c6488asapersson@webrtc.org StreamDataCounters counters; 14297d0489058ae7a983f7306f32cfd49a2356c6488asapersson@webrtc.org statistician->GetReceiveStreamDataCounters(&counters); 143d08d389ce836238030ec31e45c5f9a5535e0855fasapersson@webrtc.org EXPECT_GT(counters.first_packet_time_ms, -1); 144cfd82dfc1156f6610388bec0ebbdeacaf47e9719asapersson@webrtc.org EXPECT_EQ(1u, counters.transmitted.packets); 14597d0489058ae7a983f7306f32cfd49a2356c6488asapersson@webrtc.org 14697d0489058ae7a983f7306f32cfd49a2356c6488asapersson@webrtc.org receive_statistics_->IncomingPacket(header1_, kPacketSize1, false); 14797d0489058ae7a983f7306f32cfd49a2356c6488asapersson@webrtc.org statistician->GetReceiveStreamDataCounters(&counters); 148d08d389ce836238030ec31e45c5f9a5535e0855fasapersson@webrtc.org EXPECT_GT(counters.first_packet_time_ms, -1); 149cfd82dfc1156f6610388bec0ebbdeacaf47e9719asapersson@webrtc.org EXPECT_EQ(2u, counters.transmitted.packets); 15097d0489058ae7a983f7306f32cfd49a2356c6488asapersson@webrtc.org} 15197d0489058ae7a983f7306f32cfd49a2356c6488asapersson@webrtc.org 1520e93257cee79c0d19ddaef1f14ba750bf469a084sprang@webrtc.orgTEST_F(ReceiveStatisticsTest, RtcpCallbacks) { 15354ae4ffb9e235a9742e2b11298327e02d870571csprang@webrtc.org class TestCallback : public RtcpStatisticsCallback { 15454ae4ffb9e235a9742e2b11298327e02d870571csprang@webrtc.org public: 15554ae4ffb9e235a9742e2b11298327e02d870571csprang@webrtc.org TestCallback() 15654ae4ffb9e235a9742e2b11298327e02d870571csprang@webrtc.org : RtcpStatisticsCallback(), num_calls_(0), ssrc_(0), stats_() {} 15754ae4ffb9e235a9742e2b11298327e02d870571csprang@webrtc.org virtual ~TestCallback() {} 15854ae4ffb9e235a9742e2b11298327e02d870571csprang@webrtc.org 15954ae4ffb9e235a9742e2b11298327e02d870571csprang@webrtc.org virtual void StatisticsUpdated(const RtcpStatistics& statistics, 16054ae4ffb9e235a9742e2b11298327e02d870571csprang@webrtc.org uint32_t ssrc) { 16154ae4ffb9e235a9742e2b11298327e02d870571csprang@webrtc.org ssrc_ = ssrc; 16254ae4ffb9e235a9742e2b11298327e02d870571csprang@webrtc.org stats_ = statistics; 16354ae4ffb9e235a9742e2b11298327e02d870571csprang@webrtc.org ++num_calls_; 16454ae4ffb9e235a9742e2b11298327e02d870571csprang@webrtc.org } 16554ae4ffb9e235a9742e2b11298327e02d870571csprang@webrtc.org 16614665ff7d4024d07e58622f498b23fd980001871kjellander@webrtc.org void CNameChanged(const char* cname, uint32_t ssrc) override {} 167ce4e9a356200170abcdd44ff2af95f87a6781b8epbos@webrtc.org 16854ae4ffb9e235a9742e2b11298327e02d870571csprang@webrtc.org uint32_t num_calls_; 16954ae4ffb9e235a9742e2b11298327e02d870571csprang@webrtc.org uint32_t ssrc_; 17054ae4ffb9e235a9742e2b11298327e02d870571csprang@webrtc.org RtcpStatistics stats_; 17154ae4ffb9e235a9742e2b11298327e02d870571csprang@webrtc.org } callback; 17254ae4ffb9e235a9742e2b11298327e02d870571csprang@webrtc.org 17354ae4ffb9e235a9742e2b11298327e02d870571csprang@webrtc.org receive_statistics_->RegisterRtcpStatisticsCallback(&callback); 17454ae4ffb9e235a9742e2b11298327e02d870571csprang@webrtc.org 17554ae4ffb9e235a9742e2b11298327e02d870571csprang@webrtc.org // Add some arbitrary data, with loss and jitter. 17654ae4ffb9e235a9742e2b11298327e02d870571csprang@webrtc.org header1_.sequenceNumber = 1; 17754ae4ffb9e235a9742e2b11298327e02d870571csprang@webrtc.org clock_.AdvanceTimeMilliseconds(7); 17854ae4ffb9e235a9742e2b11298327e02d870571csprang@webrtc.org header1_.timestamp += 3; 17954ae4ffb9e235a9742e2b11298327e02d870571csprang@webrtc.org receive_statistics_->IncomingPacket(header1_, kPacketSize1, false); 18054ae4ffb9e235a9742e2b11298327e02d870571csprang@webrtc.org header1_.sequenceNumber += 2; 18154ae4ffb9e235a9742e2b11298327e02d870571csprang@webrtc.org clock_.AdvanceTimeMilliseconds(9); 18254ae4ffb9e235a9742e2b11298327e02d870571csprang@webrtc.org header1_.timestamp += 9; 18354ae4ffb9e235a9742e2b11298327e02d870571csprang@webrtc.org receive_statistics_->IncomingPacket(header1_, kPacketSize1, false); 18454ae4ffb9e235a9742e2b11298327e02d870571csprang@webrtc.org --header1_.sequenceNumber; 18554ae4ffb9e235a9742e2b11298327e02d870571csprang@webrtc.org clock_.AdvanceTimeMilliseconds(13); 18654ae4ffb9e235a9742e2b11298327e02d870571csprang@webrtc.org header1_.timestamp += 47; 18754ae4ffb9e235a9742e2b11298327e02d870571csprang@webrtc.org receive_statistics_->IncomingPacket(header1_, kPacketSize1, true); 18854ae4ffb9e235a9742e2b11298327e02d870571csprang@webrtc.org header1_.sequenceNumber += 3; 18954ae4ffb9e235a9742e2b11298327e02d870571csprang@webrtc.org clock_.AdvanceTimeMilliseconds(11); 19054ae4ffb9e235a9742e2b11298327e02d870571csprang@webrtc.org header1_.timestamp += 17; 19154ae4ffb9e235a9742e2b11298327e02d870571csprang@webrtc.org receive_statistics_->IncomingPacket(header1_, kPacketSize1, false); 19254ae4ffb9e235a9742e2b11298327e02d870571csprang@webrtc.org ++header1_.sequenceNumber; 19354ae4ffb9e235a9742e2b11298327e02d870571csprang@webrtc.org 19454ae4ffb9e235a9742e2b11298327e02d870571csprang@webrtc.org EXPECT_EQ(0u, callback.num_calls_); 19554ae4ffb9e235a9742e2b11298327e02d870571csprang@webrtc.org 19654ae4ffb9e235a9742e2b11298327e02d870571csprang@webrtc.org // Call GetStatistics, simulating a timed rtcp sender thread. 19754ae4ffb9e235a9742e2b11298327e02d870571csprang@webrtc.org RtcpStatistics statistics; 19854ae4ffb9e235a9742e2b11298327e02d870571csprang@webrtc.org receive_statistics_->GetStatistician(kSsrc1) 19954ae4ffb9e235a9742e2b11298327e02d870571csprang@webrtc.org ->GetStatistics(&statistics, true); 20054ae4ffb9e235a9742e2b11298327e02d870571csprang@webrtc.org 20154ae4ffb9e235a9742e2b11298327e02d870571csprang@webrtc.org EXPECT_EQ(1u, callback.num_calls_); 20254ae4ffb9e235a9742e2b11298327e02d870571csprang@webrtc.org EXPECT_EQ(callback.ssrc_, kSsrc1); 20354ae4ffb9e235a9742e2b11298327e02d870571csprang@webrtc.org EXPECT_EQ(statistics.cumulative_lost, callback.stats_.cumulative_lost); 20454ae4ffb9e235a9742e2b11298327e02d870571csprang@webrtc.org EXPECT_EQ(statistics.extended_max_sequence_number, 20554ae4ffb9e235a9742e2b11298327e02d870571csprang@webrtc.org callback.stats_.extended_max_sequence_number); 20654ae4ffb9e235a9742e2b11298327e02d870571csprang@webrtc.org EXPECT_EQ(statistics.fraction_lost, callback.stats_.fraction_lost); 20754ae4ffb9e235a9742e2b11298327e02d870571csprang@webrtc.org EXPECT_EQ(statistics.jitter, callback.stats_.jitter); 2080e93257cee79c0d19ddaef1f14ba750bf469a084sprang@webrtc.org EXPECT_EQ(51, statistics.fraction_lost); 2090e93257cee79c0d19ddaef1f14ba750bf469a084sprang@webrtc.org EXPECT_EQ(1u, statistics.cumulative_lost); 2100e93257cee79c0d19ddaef1f14ba750bf469a084sprang@webrtc.org EXPECT_EQ(5u, statistics.extended_max_sequence_number); 2110e93257cee79c0d19ddaef1f14ba750bf469a084sprang@webrtc.org EXPECT_EQ(4u, statistics.jitter); 21254ae4ffb9e235a9742e2b11298327e02d870571csprang@webrtc.org 21354ae4ffb9e235a9742e2b11298327e02d870571csprang@webrtc.org receive_statistics_->RegisterRtcpStatisticsCallback(NULL); 21454ae4ffb9e235a9742e2b11298327e02d870571csprang@webrtc.org 21554ae4ffb9e235a9742e2b11298327e02d870571csprang@webrtc.org // Add some more data. 21654ae4ffb9e235a9742e2b11298327e02d870571csprang@webrtc.org header1_.sequenceNumber = 1; 21754ae4ffb9e235a9742e2b11298327e02d870571csprang@webrtc.org clock_.AdvanceTimeMilliseconds(7); 21854ae4ffb9e235a9742e2b11298327e02d870571csprang@webrtc.org header1_.timestamp += 3; 21954ae4ffb9e235a9742e2b11298327e02d870571csprang@webrtc.org receive_statistics_->IncomingPacket(header1_, kPacketSize1, false); 22054ae4ffb9e235a9742e2b11298327e02d870571csprang@webrtc.org header1_.sequenceNumber += 2; 22154ae4ffb9e235a9742e2b11298327e02d870571csprang@webrtc.org clock_.AdvanceTimeMilliseconds(9); 22254ae4ffb9e235a9742e2b11298327e02d870571csprang@webrtc.org header1_.timestamp += 9; 22354ae4ffb9e235a9742e2b11298327e02d870571csprang@webrtc.org receive_statistics_->IncomingPacket(header1_, kPacketSize1, false); 22454ae4ffb9e235a9742e2b11298327e02d870571csprang@webrtc.org --header1_.sequenceNumber; 22554ae4ffb9e235a9742e2b11298327e02d870571csprang@webrtc.org clock_.AdvanceTimeMilliseconds(13); 22654ae4ffb9e235a9742e2b11298327e02d870571csprang@webrtc.org header1_.timestamp += 47; 22754ae4ffb9e235a9742e2b11298327e02d870571csprang@webrtc.org receive_statistics_->IncomingPacket(header1_, kPacketSize1, true); 22854ae4ffb9e235a9742e2b11298327e02d870571csprang@webrtc.org header1_.sequenceNumber += 3; 22954ae4ffb9e235a9742e2b11298327e02d870571csprang@webrtc.org clock_.AdvanceTimeMilliseconds(11); 23054ae4ffb9e235a9742e2b11298327e02d870571csprang@webrtc.org header1_.timestamp += 17; 23154ae4ffb9e235a9742e2b11298327e02d870571csprang@webrtc.org receive_statistics_->IncomingPacket(header1_, kPacketSize1, false); 23254ae4ffb9e235a9742e2b11298327e02d870571csprang@webrtc.org ++header1_.sequenceNumber; 23354ae4ffb9e235a9742e2b11298327e02d870571csprang@webrtc.org 23454ae4ffb9e235a9742e2b11298327e02d870571csprang@webrtc.org receive_statistics_->GetStatistician(kSsrc1) 23554ae4ffb9e235a9742e2b11298327e02d870571csprang@webrtc.org ->GetStatistics(&statistics, true); 23654ae4ffb9e235a9742e2b11298327e02d870571csprang@webrtc.org 23754ae4ffb9e235a9742e2b11298327e02d870571csprang@webrtc.org // Should not have been called after deregister. 23854ae4ffb9e235a9742e2b11298327e02d870571csprang@webrtc.org EXPECT_EQ(1u, callback.num_calls_); 23954ae4ffb9e235a9742e2b11298327e02d870571csprang@webrtc.org} 2400e93257cee79c0d19ddaef1f14ba750bf469a084sprang@webrtc.org 241c30e9e230065ddde4cc439d9ba430273413e70d7sprang@webrtc.orgclass RtpTestCallback : public StreamDataCountersCallback { 242c30e9e230065ddde4cc439d9ba430273413e70d7sprang@webrtc.org public: 243c30e9e230065ddde4cc439d9ba430273413e70d7sprang@webrtc.org RtpTestCallback() 244c30e9e230065ddde4cc439d9ba430273413e70d7sprang@webrtc.org : StreamDataCountersCallback(), num_calls_(0), ssrc_(0), stats_() {} 245c30e9e230065ddde4cc439d9ba430273413e70d7sprang@webrtc.org virtual ~RtpTestCallback() {} 2460e93257cee79c0d19ddaef1f14ba750bf469a084sprang@webrtc.org 247c30e9e230065ddde4cc439d9ba430273413e70d7sprang@webrtc.org virtual void DataCountersUpdated(const StreamDataCounters& counters, 248c30e9e230065ddde4cc439d9ba430273413e70d7sprang@webrtc.org uint32_t ssrc) { 249c30e9e230065ddde4cc439d9ba430273413e70d7sprang@webrtc.org ssrc_ = ssrc; 250c30e9e230065ddde4cc439d9ba430273413e70d7sprang@webrtc.org stats_ = counters; 251c30e9e230065ddde4cc439d9ba430273413e70d7sprang@webrtc.org ++num_calls_; 252c30e9e230065ddde4cc439d9ba430273413e70d7sprang@webrtc.org } 2530e93257cee79c0d19ddaef1f14ba750bf469a084sprang@webrtc.org 2544414939954fd908b6490ce1bb88271e161219aa3asapersson@webrtc.org void MatchPacketCounter(const RtpPacketCounter& expected, 2554414939954fd908b6490ce1bb88271e161219aa3asapersson@webrtc.org const RtpPacketCounter& actual) { 2564414939954fd908b6490ce1bb88271e161219aa3asapersson@webrtc.org EXPECT_EQ(expected.payload_bytes, actual.payload_bytes); 2574414939954fd908b6490ce1bb88271e161219aa3asapersson@webrtc.org EXPECT_EQ(expected.header_bytes, actual.header_bytes); 2584414939954fd908b6490ce1bb88271e161219aa3asapersson@webrtc.org EXPECT_EQ(expected.padding_bytes, actual.padding_bytes); 2594414939954fd908b6490ce1bb88271e161219aa3asapersson@webrtc.org EXPECT_EQ(expected.packets, actual.packets); 2604414939954fd908b6490ce1bb88271e161219aa3asapersson@webrtc.org } 2614414939954fd908b6490ce1bb88271e161219aa3asapersson@webrtc.org 26297d0489058ae7a983f7306f32cfd49a2356c6488asapersson@webrtc.org void Matches(uint32_t num_calls, 26397d0489058ae7a983f7306f32cfd49a2356c6488asapersson@webrtc.org uint32_t ssrc, 26497d0489058ae7a983f7306f32cfd49a2356c6488asapersson@webrtc.org const StreamDataCounters& expected) { 265c30e9e230065ddde4cc439d9ba430273413e70d7sprang@webrtc.org EXPECT_EQ(num_calls, num_calls_); 266c30e9e230065ddde4cc439d9ba430273413e70d7sprang@webrtc.org EXPECT_EQ(ssrc, ssrc_); 2674414939954fd908b6490ce1bb88271e161219aa3asapersson@webrtc.org MatchPacketCounter(expected.transmitted, stats_.transmitted); 2684414939954fd908b6490ce1bb88271e161219aa3asapersson@webrtc.org MatchPacketCounter(expected.retransmitted, stats_.retransmitted); 2694414939954fd908b6490ce1bb88271e161219aa3asapersson@webrtc.org MatchPacketCounter(expected.fec, stats_.fec); 270c30e9e230065ddde4cc439d9ba430273413e70d7sprang@webrtc.org } 2710e93257cee79c0d19ddaef1f14ba750bf469a084sprang@webrtc.org 272c30e9e230065ddde4cc439d9ba430273413e70d7sprang@webrtc.org uint32_t num_calls_; 273c30e9e230065ddde4cc439d9ba430273413e70d7sprang@webrtc.org uint32_t ssrc_; 274c30e9e230065ddde4cc439d9ba430273413e70d7sprang@webrtc.org StreamDataCounters stats_; 275c30e9e230065ddde4cc439d9ba430273413e70d7sprang@webrtc.org}; 2760e93257cee79c0d19ddaef1f14ba750bf469a084sprang@webrtc.org 277c30e9e230065ddde4cc439d9ba430273413e70d7sprang@webrtc.orgTEST_F(ReceiveStatisticsTest, RtpCallbacks) { 278c30e9e230065ddde4cc439d9ba430273413e70d7sprang@webrtc.org RtpTestCallback callback; 2790e93257cee79c0d19ddaef1f14ba750bf469a084sprang@webrtc.org receive_statistics_->RegisterRtpStatisticsCallback(&callback); 2800e93257cee79c0d19ddaef1f14ba750bf469a084sprang@webrtc.org 2814591fbd09f9cb6e83433c49a12dd8524c2806502pkasting@chromium.org const size_t kHeaderLength = 20; 2824591fbd09f9cb6e83433c49a12dd8524c2806502pkasting@chromium.org const size_t kPaddingLength = 9; 2830e93257cee79c0d19ddaef1f14ba750bf469a084sprang@webrtc.org 2840e93257cee79c0d19ddaef1f14ba750bf469a084sprang@webrtc.org // One packet of size kPacketSize1. 2850e93257cee79c0d19ddaef1f14ba750bf469a084sprang@webrtc.org header1_.headerLength = kHeaderLength; 2860e93257cee79c0d19ddaef1f14ba750bf469a084sprang@webrtc.org receive_statistics_->IncomingPacket( 2870e93257cee79c0d19ddaef1f14ba750bf469a084sprang@webrtc.org header1_, kPacketSize1 + kHeaderLength, false); 28897d0489058ae7a983f7306f32cfd49a2356c6488asapersson@webrtc.org StreamDataCounters expected; 289cfd82dfc1156f6610388bec0ebbdeacaf47e9719asapersson@webrtc.org expected.transmitted.payload_bytes = kPacketSize1; 290cfd82dfc1156f6610388bec0ebbdeacaf47e9719asapersson@webrtc.org expected.transmitted.header_bytes = kHeaderLength; 291cfd82dfc1156f6610388bec0ebbdeacaf47e9719asapersson@webrtc.org expected.transmitted.padding_bytes = 0; 292cfd82dfc1156f6610388bec0ebbdeacaf47e9719asapersson@webrtc.org expected.transmitted.packets = 1; 293cfd82dfc1156f6610388bec0ebbdeacaf47e9719asapersson@webrtc.org expected.retransmitted.payload_bytes = 0; 294cfd82dfc1156f6610388bec0ebbdeacaf47e9719asapersson@webrtc.org expected.retransmitted.header_bytes = 0; 295cfd82dfc1156f6610388bec0ebbdeacaf47e9719asapersson@webrtc.org expected.retransmitted.padding_bytes = 0; 296cfd82dfc1156f6610388bec0ebbdeacaf47e9719asapersson@webrtc.org expected.retransmitted.packets = 0; 297cfd82dfc1156f6610388bec0ebbdeacaf47e9719asapersson@webrtc.org expected.fec.packets = 0; 29897d0489058ae7a983f7306f32cfd49a2356c6488asapersson@webrtc.org callback.Matches(1, kSsrc1, expected); 2990e93257cee79c0d19ddaef1f14ba750bf469a084sprang@webrtc.org 3000e93257cee79c0d19ddaef1f14ba750bf469a084sprang@webrtc.org ++header1_.sequenceNumber; 3010e93257cee79c0d19ddaef1f14ba750bf469a084sprang@webrtc.org clock_.AdvanceTimeMilliseconds(5); 3020e93257cee79c0d19ddaef1f14ba750bf469a084sprang@webrtc.org header1_.paddingLength = 9; 3030e93257cee79c0d19ddaef1f14ba750bf469a084sprang@webrtc.org // Another packet of size kPacketSize1 with 9 bytes padding. 3040e93257cee79c0d19ddaef1f14ba750bf469a084sprang@webrtc.org receive_statistics_->IncomingPacket( 3050e93257cee79c0d19ddaef1f14ba750bf469a084sprang@webrtc.org header1_, kPacketSize1 + kHeaderLength + kPaddingLength, false); 306cfd82dfc1156f6610388bec0ebbdeacaf47e9719asapersson@webrtc.org expected.transmitted.payload_bytes = kPacketSize1 * 2; 307cfd82dfc1156f6610388bec0ebbdeacaf47e9719asapersson@webrtc.org expected.transmitted.header_bytes = kHeaderLength * 2; 308cfd82dfc1156f6610388bec0ebbdeacaf47e9719asapersson@webrtc.org expected.transmitted.padding_bytes = kPaddingLength; 309cfd82dfc1156f6610388bec0ebbdeacaf47e9719asapersson@webrtc.org expected.transmitted.packets = 2; 31097d0489058ae7a983f7306f32cfd49a2356c6488asapersson@webrtc.org callback.Matches(2, kSsrc1, expected); 3110e93257cee79c0d19ddaef1f14ba750bf469a084sprang@webrtc.org 3120e93257cee79c0d19ddaef1f14ba750bf469a084sprang@webrtc.org clock_.AdvanceTimeMilliseconds(5); 3130e93257cee79c0d19ddaef1f14ba750bf469a084sprang@webrtc.org // Retransmit last packet. 3140e93257cee79c0d19ddaef1f14ba750bf469a084sprang@webrtc.org receive_statistics_->IncomingPacket( 3150e93257cee79c0d19ddaef1f14ba750bf469a084sprang@webrtc.org header1_, kPacketSize1 + kHeaderLength + kPaddingLength, true); 316cfd82dfc1156f6610388bec0ebbdeacaf47e9719asapersson@webrtc.org expected.transmitted.payload_bytes = kPacketSize1 * 3; 317cfd82dfc1156f6610388bec0ebbdeacaf47e9719asapersson@webrtc.org expected.transmitted.header_bytes = kHeaderLength * 3; 318cfd82dfc1156f6610388bec0ebbdeacaf47e9719asapersson@webrtc.org expected.transmitted.padding_bytes = kPaddingLength * 2; 319cfd82dfc1156f6610388bec0ebbdeacaf47e9719asapersson@webrtc.org expected.transmitted.packets = 3; 320cfd82dfc1156f6610388bec0ebbdeacaf47e9719asapersson@webrtc.org expected.retransmitted.payload_bytes = kPacketSize1; 321cfd82dfc1156f6610388bec0ebbdeacaf47e9719asapersson@webrtc.org expected.retransmitted.header_bytes = kHeaderLength; 322cfd82dfc1156f6610388bec0ebbdeacaf47e9719asapersson@webrtc.org expected.retransmitted.padding_bytes = kPaddingLength; 323cfd82dfc1156f6610388bec0ebbdeacaf47e9719asapersson@webrtc.org expected.retransmitted.packets = 1; 32497d0489058ae7a983f7306f32cfd49a2356c6488asapersson@webrtc.org callback.Matches(3, kSsrc1, expected); 3250e93257cee79c0d19ddaef1f14ba750bf469a084sprang@webrtc.org 3260e93257cee79c0d19ddaef1f14ba750bf469a084sprang@webrtc.org header1_.paddingLength = 0; 3270e93257cee79c0d19ddaef1f14ba750bf469a084sprang@webrtc.org ++header1_.sequenceNumber; 3280e93257cee79c0d19ddaef1f14ba750bf469a084sprang@webrtc.org clock_.AdvanceTimeMilliseconds(5); 329273fbbb921e61273c3d83eb494d0a68db7834d3dasapersson@webrtc.org // One FEC packet. 3300e93257cee79c0d19ddaef1f14ba750bf469a084sprang@webrtc.org receive_statistics_->IncomingPacket( 3310e93257cee79c0d19ddaef1f14ba750bf469a084sprang@webrtc.org header1_, kPacketSize1 + kHeaderLength, false); 332273fbbb921e61273c3d83eb494d0a68db7834d3dasapersson@webrtc.org receive_statistics_->FecPacketReceived(header1_, 333273fbbb921e61273c3d83eb494d0a68db7834d3dasapersson@webrtc.org kPacketSize1 + kHeaderLength); 334cfd82dfc1156f6610388bec0ebbdeacaf47e9719asapersson@webrtc.org expected.transmitted.payload_bytes = kPacketSize1 * 4; 335cfd82dfc1156f6610388bec0ebbdeacaf47e9719asapersson@webrtc.org expected.transmitted.header_bytes = kHeaderLength * 4; 336cfd82dfc1156f6610388bec0ebbdeacaf47e9719asapersson@webrtc.org expected.transmitted.packets = 4; 337273fbbb921e61273c3d83eb494d0a68db7834d3dasapersson@webrtc.org expected.fec.payload_bytes = kPacketSize1; 338273fbbb921e61273c3d83eb494d0a68db7834d3dasapersson@webrtc.org expected.fec.header_bytes = kHeaderLength; 339cfd82dfc1156f6610388bec0ebbdeacaf47e9719asapersson@webrtc.org expected.fec.packets = 1; 34097d0489058ae7a983f7306f32cfd49a2356c6488asapersson@webrtc.org callback.Matches(5, kSsrc1, expected); 3410e93257cee79c0d19ddaef1f14ba750bf469a084sprang@webrtc.org 3420e93257cee79c0d19ddaef1f14ba750bf469a084sprang@webrtc.org receive_statistics_->RegisterRtpStatisticsCallback(NULL); 3430e93257cee79c0d19ddaef1f14ba750bf469a084sprang@webrtc.org 3440e93257cee79c0d19ddaef1f14ba750bf469a084sprang@webrtc.org // New stats, but callback should not be called. 3450e93257cee79c0d19ddaef1f14ba750bf469a084sprang@webrtc.org ++header1_.sequenceNumber; 3460e93257cee79c0d19ddaef1f14ba750bf469a084sprang@webrtc.org clock_.AdvanceTimeMilliseconds(5); 3470e93257cee79c0d19ddaef1f14ba750bf469a084sprang@webrtc.org receive_statistics_->IncomingPacket( 3480e93257cee79c0d19ddaef1f14ba750bf469a084sprang@webrtc.org header1_, kPacketSize1 + kHeaderLength, true); 34997d0489058ae7a983f7306f32cfd49a2356c6488asapersson@webrtc.org callback.Matches(5, kSsrc1, expected); 3500e93257cee79c0d19ddaef1f14ba750bf469a084sprang@webrtc.org} 351c30e9e230065ddde4cc439d9ba430273413e70d7sprang@webrtc.org 352c30e9e230065ddde4cc439d9ba430273413e70d7sprang@webrtc.orgTEST_F(ReceiveStatisticsTest, RtpCallbacksFecFirst) { 353c30e9e230065ddde4cc439d9ba430273413e70d7sprang@webrtc.org RtpTestCallback callback; 354c30e9e230065ddde4cc439d9ba430273413e70d7sprang@webrtc.org receive_statistics_->RegisterRtpStatisticsCallback(&callback); 355c30e9e230065ddde4cc439d9ba430273413e70d7sprang@webrtc.org 356c30e9e230065ddde4cc439d9ba430273413e70d7sprang@webrtc.org const uint32_t kHeaderLength = 20; 357273fbbb921e61273c3d83eb494d0a68db7834d3dasapersson@webrtc.org header1_.headerLength = kHeaderLength; 358c30e9e230065ddde4cc439d9ba430273413e70d7sprang@webrtc.org 359c30e9e230065ddde4cc439d9ba430273413e70d7sprang@webrtc.org // If first packet is FEC, ignore it. 360273fbbb921e61273c3d83eb494d0a68db7834d3dasapersson@webrtc.org receive_statistics_->FecPacketReceived(header1_, 361273fbbb921e61273c3d83eb494d0a68db7834d3dasapersson@webrtc.org kPacketSize1 + kHeaderLength); 362c30e9e230065ddde4cc439d9ba430273413e70d7sprang@webrtc.org EXPECT_EQ(0u, callback.num_calls_); 363c30e9e230065ddde4cc439d9ba430273413e70d7sprang@webrtc.org 364c30e9e230065ddde4cc439d9ba430273413e70d7sprang@webrtc.org receive_statistics_->IncomingPacket( 365c30e9e230065ddde4cc439d9ba430273413e70d7sprang@webrtc.org header1_, kPacketSize1 + kHeaderLength, false); 36697d0489058ae7a983f7306f32cfd49a2356c6488asapersson@webrtc.org StreamDataCounters expected; 367cfd82dfc1156f6610388bec0ebbdeacaf47e9719asapersson@webrtc.org expected.transmitted.payload_bytes = kPacketSize1; 368cfd82dfc1156f6610388bec0ebbdeacaf47e9719asapersson@webrtc.org expected.transmitted.header_bytes = kHeaderLength; 369cfd82dfc1156f6610388bec0ebbdeacaf47e9719asapersson@webrtc.org expected.transmitted.padding_bytes = 0; 370cfd82dfc1156f6610388bec0ebbdeacaf47e9719asapersson@webrtc.org expected.transmitted.packets = 1; 371cfd82dfc1156f6610388bec0ebbdeacaf47e9719asapersson@webrtc.org expected.fec.packets = 0; 37297d0489058ae7a983f7306f32cfd49a2356c6488asapersson@webrtc.org callback.Matches(1, kSsrc1, expected); 373c30e9e230065ddde4cc439d9ba430273413e70d7sprang@webrtc.org 374273fbbb921e61273c3d83eb494d0a68db7834d3dasapersson@webrtc.org receive_statistics_->FecPacketReceived(header1_, 375273fbbb921e61273c3d83eb494d0a68db7834d3dasapersson@webrtc.org kPacketSize1 + kHeaderLength); 376273fbbb921e61273c3d83eb494d0a68db7834d3dasapersson@webrtc.org expected.fec.payload_bytes = kPacketSize1; 377273fbbb921e61273c3d83eb494d0a68db7834d3dasapersson@webrtc.org expected.fec.header_bytes = kHeaderLength; 378cfd82dfc1156f6610388bec0ebbdeacaf47e9719asapersson@webrtc.org expected.fec.packets = 1; 37997d0489058ae7a983f7306f32cfd49a2356c6488asapersson@webrtc.org callback.Matches(2, kSsrc1, expected); 380c30e9e230065ddde4cc439d9ba430273413e70d7sprang@webrtc.org} 381286fe0b04d97205ac84688bbe613d5749192b2d1stefan@webrtc.org} // namespace webrtc 382