1a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org/*
2a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org *  Copyright (c) 2013 The WebRTC project authors. All Rights Reserved.
3a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org *
4a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org *  Use of this source code is governed by a BSD-style license
5a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org *  that can be found in the LICENSE file in the root of the source
6a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org *  tree. An additional intellectual property rights grant can be found
7a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org *  in the file PATENTS.  All contributing project authors may
8a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org *  be found in the AUTHORS file in the root of the source tree.
9a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org */
10a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org
11a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org#include "testing/gmock/include/gmock/gmock.h"
12a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org#include "testing/gtest/include/gtest/gtest.h"
13a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org#include "webrtc/modules/rtp_rtcp/interface/receive_statistics.h"
14a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org#include "webrtc/system_wrappers/interface/clock.h"
15a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org#include "webrtc/system_wrappers/interface/scoped_ptr.h"
16a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org
17a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.orgnamespace webrtc {
18a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org
19a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.orgconst int kPacketSize1 = 100;
20a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.orgconst int kPacketSize2 = 300;
21a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.orgconst uint32_t kSsrc1 = 1;
22a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.orgconst uint32_t kSsrc2 = 2;
23a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org
24a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.orgclass ReceiveStatisticsTest : public ::testing::Test {
25a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org public:
26a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org  ReceiveStatisticsTest() :
27a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org      clock_(0),
28a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org      receive_statistics_(ReceiveStatistics::Create(&clock_)) {
29a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org    memset(&header1_, 0, sizeof(header1_));
30a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org    header1_.ssrc = kSsrc1;
317d99cd47d8055ec6815f2862b75a0bdf53304199sprang@webrtc.org    header1_.sequenceNumber = 100;
32a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org    memset(&header2_, 0, sizeof(header2_));
33a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org    header2_.ssrc = kSsrc2;
347d99cd47d8055ec6815f2862b75a0bdf53304199sprang@webrtc.org    header2_.sequenceNumber = 100;
35a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org  }
36a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org
37a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org protected:
38a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org  SimulatedClock clock_;
39a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org  scoped_ptr<ReceiveStatistics> receive_statistics_;
40a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org  RTPHeader header1_;
41a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org  RTPHeader header2_;
42a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org};
43a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org
44a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.orgTEST_F(ReceiveStatisticsTest, TwoIncomingSsrcs) {
45db74c61ddfa26c23d3e392b241c983010e10b1c5stefan@webrtc.org  receive_statistics_->IncomingPacket(header1_, kPacketSize1, false);
46a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org  ++header1_.sequenceNumber;
47db74c61ddfa26c23d3e392b241c983010e10b1c5stefan@webrtc.org  receive_statistics_->IncomingPacket(header2_, kPacketSize2, false);
48a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org  ++header2_.sequenceNumber;
49a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org  clock_.AdvanceTimeMilliseconds(100);
50db74c61ddfa26c23d3e392b241c983010e10b1c5stefan@webrtc.org  receive_statistics_->IncomingPacket(header1_, kPacketSize1, false);
51a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org  ++header1_.sequenceNumber;
52db74c61ddfa26c23d3e392b241c983010e10b1c5stefan@webrtc.org  receive_statistics_->IncomingPacket(header2_, kPacketSize2, false);
53a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org  ++header2_.sequenceNumber;
54a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org
55a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org  StreamStatistician* statistician =
56a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org      receive_statistics_->GetStatistician(kSsrc1);
57a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org  ASSERT_TRUE(statistician != NULL);
58a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org  EXPECT_GT(statistician->BitrateReceived(), 0u);
59a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org  uint32_t bytes_received = 0;
60a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org  uint32_t packets_received = 0;
61a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org  statistician->GetDataCounters(&bytes_received, &packets_received);
62a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org  EXPECT_EQ(200u, bytes_received);
63a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org  EXPECT_EQ(2u, packets_received);
64a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org
65a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org  statistician =
66a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org      receive_statistics_->GetStatistician(kSsrc2);
67a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org  ASSERT_TRUE(statistician != NULL);
68a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org  EXPECT_GT(statistician->BitrateReceived(), 0u);
69a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org  statistician->GetDataCounters(&bytes_received, &packets_received);
70a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org  EXPECT_EQ(600u, bytes_received);
71a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org  EXPECT_EQ(2u, packets_received);
72a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org
73a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org  StatisticianMap statisticians = receive_statistics_->GetActiveStatisticians();
74a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org  EXPECT_EQ(2u, statisticians.size());
75a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org  // Add more incoming packets and verify that they are registered in both
76a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org  // access methods.
77db74c61ddfa26c23d3e392b241c983010e10b1c5stefan@webrtc.org  receive_statistics_->IncomingPacket(header1_, kPacketSize1, false);
78a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org  ++header1_.sequenceNumber;
79db74c61ddfa26c23d3e392b241c983010e10b1c5stefan@webrtc.org  receive_statistics_->IncomingPacket(header2_, kPacketSize2, false);
80a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org  ++header2_.sequenceNumber;
81a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org
82a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org  statisticians[kSsrc1]->GetDataCounters(&bytes_received, &packets_received);
83a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org  EXPECT_EQ(300u, bytes_received);
84a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org  EXPECT_EQ(3u, packets_received);
85a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org  statisticians[kSsrc2]->GetDataCounters(&bytes_received, &packets_received);
86a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org  EXPECT_EQ(900u, bytes_received);
87a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org  EXPECT_EQ(3u, packets_received);
88a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org
89a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org  receive_statistics_->GetStatistician(kSsrc1)->GetDataCounters(
90a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org      &bytes_received, &packets_received);
91a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org  EXPECT_EQ(300u, bytes_received);
92a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org  EXPECT_EQ(3u, packets_received);
93a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org  receive_statistics_->GetStatistician(kSsrc2)->GetDataCounters(
94a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org      &bytes_received, &packets_received);
95a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org  EXPECT_EQ(900u, bytes_received);
96a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org  EXPECT_EQ(3u, packets_received);
97a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org}
98a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org
99a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.orgTEST_F(ReceiveStatisticsTest, ActiveStatisticians) {
100db74c61ddfa26c23d3e392b241c983010e10b1c5stefan@webrtc.org  receive_statistics_->IncomingPacket(header1_, kPacketSize1, false);
101a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org  ++header1_.sequenceNumber;
102a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org  clock_.AdvanceTimeMilliseconds(1000);
103db74c61ddfa26c23d3e392b241c983010e10b1c5stefan@webrtc.org  receive_statistics_->IncomingPacket(header2_, kPacketSize2, false);
104a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org  ++header2_.sequenceNumber;
105a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org  StatisticianMap statisticians = receive_statistics_->GetActiveStatisticians();
106a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org  // Nothing should time out since only 1000 ms has passed since the first
107a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org  // packet came in.
108a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org  EXPECT_EQ(2u, statisticians.size());
109a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org
110a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org  clock_.AdvanceTimeMilliseconds(7000);
111a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org  // kSsrc1 should have timed out.
112a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org  statisticians = receive_statistics_->GetActiveStatisticians();
113a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org  EXPECT_EQ(1u, statisticians.size());
114a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org
115a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org  clock_.AdvanceTimeMilliseconds(1000);
116a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org  // kSsrc2 should have timed out.
117a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org  statisticians = receive_statistics_->GetActiveStatisticians();
118a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org  EXPECT_EQ(0u, statisticians.size());
119a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org
120db74c61ddfa26c23d3e392b241c983010e10b1c5stefan@webrtc.org  receive_statistics_->IncomingPacket(header1_, kPacketSize1, false);
121a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org  ++header1_.sequenceNumber;
122a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org  // kSsrc1 should be active again and the data counters should have survived.
123a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org  statisticians = receive_statistics_->GetActiveStatisticians();
124a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org  EXPECT_EQ(1u, statisticians.size());
125a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org  StreamStatistician* statistician =
126a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org      receive_statistics_->GetStatistician(kSsrc1);
127a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org  ASSERT_TRUE(statistician != NULL);
128a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org  uint32_t bytes_received = 0;
129a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org  uint32_t packets_received = 0;
130a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org  statistician->GetDataCounters(&bytes_received, &packets_received);
131a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org  EXPECT_EQ(200u, bytes_received);
132a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org  EXPECT_EQ(2u, packets_received);
133a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org}
1344f1f5fa55d803fc0b7f3fd4f6a25a0f84c4e3280sprang@webrtc.org
1357d99cd47d8055ec6815f2862b75a0bdf53304199sprang@webrtc.orgTEST_F(ReceiveStatisticsTest, RtcpCallbacks) {
1364f1f5fa55d803fc0b7f3fd4f6a25a0f84c4e3280sprang@webrtc.org  class TestCallback : public RtcpStatisticsCallback {
1374f1f5fa55d803fc0b7f3fd4f6a25a0f84c4e3280sprang@webrtc.org   public:
1384f1f5fa55d803fc0b7f3fd4f6a25a0f84c4e3280sprang@webrtc.org    TestCallback()
1394f1f5fa55d803fc0b7f3fd4f6a25a0f84c4e3280sprang@webrtc.org        : RtcpStatisticsCallback(), num_calls_(0), ssrc_(0), stats_() {}
1404f1f5fa55d803fc0b7f3fd4f6a25a0f84c4e3280sprang@webrtc.org    virtual ~TestCallback() {}
1414f1f5fa55d803fc0b7f3fd4f6a25a0f84c4e3280sprang@webrtc.org
1424f1f5fa55d803fc0b7f3fd4f6a25a0f84c4e3280sprang@webrtc.org    virtual void StatisticsUpdated(const RtcpStatistics& statistics,
1434f1f5fa55d803fc0b7f3fd4f6a25a0f84c4e3280sprang@webrtc.org                                   uint32_t ssrc) {
1444f1f5fa55d803fc0b7f3fd4f6a25a0f84c4e3280sprang@webrtc.org      ssrc_ = ssrc;
1454f1f5fa55d803fc0b7f3fd4f6a25a0f84c4e3280sprang@webrtc.org      stats_ = statistics;
1464f1f5fa55d803fc0b7f3fd4f6a25a0f84c4e3280sprang@webrtc.org      ++num_calls_;
1474f1f5fa55d803fc0b7f3fd4f6a25a0f84c4e3280sprang@webrtc.org    }
1484f1f5fa55d803fc0b7f3fd4f6a25a0f84c4e3280sprang@webrtc.org
1494f1f5fa55d803fc0b7f3fd4f6a25a0f84c4e3280sprang@webrtc.org    uint32_t num_calls_;
1504f1f5fa55d803fc0b7f3fd4f6a25a0f84c4e3280sprang@webrtc.org    uint32_t ssrc_;
1514f1f5fa55d803fc0b7f3fd4f6a25a0f84c4e3280sprang@webrtc.org    RtcpStatistics stats_;
1524f1f5fa55d803fc0b7f3fd4f6a25a0f84c4e3280sprang@webrtc.org  } callback;
1534f1f5fa55d803fc0b7f3fd4f6a25a0f84c4e3280sprang@webrtc.org
1544f1f5fa55d803fc0b7f3fd4f6a25a0f84c4e3280sprang@webrtc.org  receive_statistics_->RegisterRtcpStatisticsCallback(&callback);
1554f1f5fa55d803fc0b7f3fd4f6a25a0f84c4e3280sprang@webrtc.org
1564f1f5fa55d803fc0b7f3fd4f6a25a0f84c4e3280sprang@webrtc.org  // Add some arbitrary data, with loss and jitter.
1574f1f5fa55d803fc0b7f3fd4f6a25a0f84c4e3280sprang@webrtc.org  header1_.sequenceNumber = 1;
1584f1f5fa55d803fc0b7f3fd4f6a25a0f84c4e3280sprang@webrtc.org  clock_.AdvanceTimeMilliseconds(7);
1594f1f5fa55d803fc0b7f3fd4f6a25a0f84c4e3280sprang@webrtc.org  header1_.timestamp += 3;
1604f1f5fa55d803fc0b7f3fd4f6a25a0f84c4e3280sprang@webrtc.org  receive_statistics_->IncomingPacket(header1_, kPacketSize1, false);
1614f1f5fa55d803fc0b7f3fd4f6a25a0f84c4e3280sprang@webrtc.org  header1_.sequenceNumber += 2;
1624f1f5fa55d803fc0b7f3fd4f6a25a0f84c4e3280sprang@webrtc.org  clock_.AdvanceTimeMilliseconds(9);
1634f1f5fa55d803fc0b7f3fd4f6a25a0f84c4e3280sprang@webrtc.org  header1_.timestamp += 9;
1644f1f5fa55d803fc0b7f3fd4f6a25a0f84c4e3280sprang@webrtc.org  receive_statistics_->IncomingPacket(header1_, kPacketSize1, false);
1654f1f5fa55d803fc0b7f3fd4f6a25a0f84c4e3280sprang@webrtc.org  --header1_.sequenceNumber;
1664f1f5fa55d803fc0b7f3fd4f6a25a0f84c4e3280sprang@webrtc.org  clock_.AdvanceTimeMilliseconds(13);
1674f1f5fa55d803fc0b7f3fd4f6a25a0f84c4e3280sprang@webrtc.org  header1_.timestamp += 47;
1684f1f5fa55d803fc0b7f3fd4f6a25a0f84c4e3280sprang@webrtc.org  receive_statistics_->IncomingPacket(header1_, kPacketSize1, true);
1694f1f5fa55d803fc0b7f3fd4f6a25a0f84c4e3280sprang@webrtc.org  header1_.sequenceNumber += 3;
1704f1f5fa55d803fc0b7f3fd4f6a25a0f84c4e3280sprang@webrtc.org  clock_.AdvanceTimeMilliseconds(11);
1714f1f5fa55d803fc0b7f3fd4f6a25a0f84c4e3280sprang@webrtc.org  header1_.timestamp += 17;
1724f1f5fa55d803fc0b7f3fd4f6a25a0f84c4e3280sprang@webrtc.org  receive_statistics_->IncomingPacket(header1_, kPacketSize1, false);
1734f1f5fa55d803fc0b7f3fd4f6a25a0f84c4e3280sprang@webrtc.org  ++header1_.sequenceNumber;
1744f1f5fa55d803fc0b7f3fd4f6a25a0f84c4e3280sprang@webrtc.org
1754f1f5fa55d803fc0b7f3fd4f6a25a0f84c4e3280sprang@webrtc.org  EXPECT_EQ(0u, callback.num_calls_);
1764f1f5fa55d803fc0b7f3fd4f6a25a0f84c4e3280sprang@webrtc.org
1774f1f5fa55d803fc0b7f3fd4f6a25a0f84c4e3280sprang@webrtc.org  // Call GetStatistics, simulating a timed rtcp sender thread.
1784f1f5fa55d803fc0b7f3fd4f6a25a0f84c4e3280sprang@webrtc.org  RtcpStatistics statistics;
1794f1f5fa55d803fc0b7f3fd4f6a25a0f84c4e3280sprang@webrtc.org  receive_statistics_->GetStatistician(kSsrc1)
1804f1f5fa55d803fc0b7f3fd4f6a25a0f84c4e3280sprang@webrtc.org      ->GetStatistics(&statistics, true);
1814f1f5fa55d803fc0b7f3fd4f6a25a0f84c4e3280sprang@webrtc.org
1824f1f5fa55d803fc0b7f3fd4f6a25a0f84c4e3280sprang@webrtc.org  EXPECT_EQ(1u, callback.num_calls_);
1834f1f5fa55d803fc0b7f3fd4f6a25a0f84c4e3280sprang@webrtc.org  EXPECT_EQ(callback.ssrc_, kSsrc1);
1844f1f5fa55d803fc0b7f3fd4f6a25a0f84c4e3280sprang@webrtc.org  EXPECT_EQ(statistics.cumulative_lost, callback.stats_.cumulative_lost);
1854f1f5fa55d803fc0b7f3fd4f6a25a0f84c4e3280sprang@webrtc.org  EXPECT_EQ(statistics.extended_max_sequence_number,
1864f1f5fa55d803fc0b7f3fd4f6a25a0f84c4e3280sprang@webrtc.org            callback.stats_.extended_max_sequence_number);
1874f1f5fa55d803fc0b7f3fd4f6a25a0f84c4e3280sprang@webrtc.org  EXPECT_EQ(statistics.fraction_lost, callback.stats_.fraction_lost);
1884f1f5fa55d803fc0b7f3fd4f6a25a0f84c4e3280sprang@webrtc.org  EXPECT_EQ(statistics.jitter, callback.stats_.jitter);
1897d99cd47d8055ec6815f2862b75a0bdf53304199sprang@webrtc.org  EXPECT_EQ(51, statistics.fraction_lost);
1907d99cd47d8055ec6815f2862b75a0bdf53304199sprang@webrtc.org  EXPECT_EQ(1u, statistics.cumulative_lost);
1917d99cd47d8055ec6815f2862b75a0bdf53304199sprang@webrtc.org  EXPECT_EQ(5u, statistics.extended_max_sequence_number);
1927d99cd47d8055ec6815f2862b75a0bdf53304199sprang@webrtc.org  EXPECT_EQ(4u, statistics.jitter);
1934f1f5fa55d803fc0b7f3fd4f6a25a0f84c4e3280sprang@webrtc.org
1944f1f5fa55d803fc0b7f3fd4f6a25a0f84c4e3280sprang@webrtc.org  receive_statistics_->RegisterRtcpStatisticsCallback(NULL);
1954f1f5fa55d803fc0b7f3fd4f6a25a0f84c4e3280sprang@webrtc.org
1964f1f5fa55d803fc0b7f3fd4f6a25a0f84c4e3280sprang@webrtc.org  // Add some more data.
1974f1f5fa55d803fc0b7f3fd4f6a25a0f84c4e3280sprang@webrtc.org  header1_.sequenceNumber = 1;
1984f1f5fa55d803fc0b7f3fd4f6a25a0f84c4e3280sprang@webrtc.org  clock_.AdvanceTimeMilliseconds(7);
1994f1f5fa55d803fc0b7f3fd4f6a25a0f84c4e3280sprang@webrtc.org  header1_.timestamp += 3;
2004f1f5fa55d803fc0b7f3fd4f6a25a0f84c4e3280sprang@webrtc.org  receive_statistics_->IncomingPacket(header1_, kPacketSize1, false);
2014f1f5fa55d803fc0b7f3fd4f6a25a0f84c4e3280sprang@webrtc.org  header1_.sequenceNumber += 2;
2024f1f5fa55d803fc0b7f3fd4f6a25a0f84c4e3280sprang@webrtc.org  clock_.AdvanceTimeMilliseconds(9);
2034f1f5fa55d803fc0b7f3fd4f6a25a0f84c4e3280sprang@webrtc.org  header1_.timestamp += 9;
2044f1f5fa55d803fc0b7f3fd4f6a25a0f84c4e3280sprang@webrtc.org  receive_statistics_->IncomingPacket(header1_, kPacketSize1, false);
2054f1f5fa55d803fc0b7f3fd4f6a25a0f84c4e3280sprang@webrtc.org  --header1_.sequenceNumber;
2064f1f5fa55d803fc0b7f3fd4f6a25a0f84c4e3280sprang@webrtc.org  clock_.AdvanceTimeMilliseconds(13);
2074f1f5fa55d803fc0b7f3fd4f6a25a0f84c4e3280sprang@webrtc.org  header1_.timestamp += 47;
2084f1f5fa55d803fc0b7f3fd4f6a25a0f84c4e3280sprang@webrtc.org  receive_statistics_->IncomingPacket(header1_, kPacketSize1, true);
2094f1f5fa55d803fc0b7f3fd4f6a25a0f84c4e3280sprang@webrtc.org  header1_.sequenceNumber += 3;
2104f1f5fa55d803fc0b7f3fd4f6a25a0f84c4e3280sprang@webrtc.org  clock_.AdvanceTimeMilliseconds(11);
2114f1f5fa55d803fc0b7f3fd4f6a25a0f84c4e3280sprang@webrtc.org  header1_.timestamp += 17;
2124f1f5fa55d803fc0b7f3fd4f6a25a0f84c4e3280sprang@webrtc.org  receive_statistics_->IncomingPacket(header1_, kPacketSize1, false);
2134f1f5fa55d803fc0b7f3fd4f6a25a0f84c4e3280sprang@webrtc.org  ++header1_.sequenceNumber;
2144f1f5fa55d803fc0b7f3fd4f6a25a0f84c4e3280sprang@webrtc.org
2154f1f5fa55d803fc0b7f3fd4f6a25a0f84c4e3280sprang@webrtc.org  receive_statistics_->GetStatistician(kSsrc1)
2164f1f5fa55d803fc0b7f3fd4f6a25a0f84c4e3280sprang@webrtc.org      ->GetStatistics(&statistics, true);
2174f1f5fa55d803fc0b7f3fd4f6a25a0f84c4e3280sprang@webrtc.org
2184f1f5fa55d803fc0b7f3fd4f6a25a0f84c4e3280sprang@webrtc.org  // Should not have been called after deregister.
2194f1f5fa55d803fc0b7f3fd4f6a25a0f84c4e3280sprang@webrtc.org  EXPECT_EQ(1u, callback.num_calls_);
2204f1f5fa55d803fc0b7f3fd4f6a25a0f84c4e3280sprang@webrtc.org}
2217d99cd47d8055ec6815f2862b75a0bdf53304199sprang@webrtc.org
22217189d2517bd1927b286dc706d40867f0535fe6bsprang@webrtc.orgclass RtpTestCallback : public StreamDataCountersCallback {
22317189d2517bd1927b286dc706d40867f0535fe6bsprang@webrtc.org public:
22417189d2517bd1927b286dc706d40867f0535fe6bsprang@webrtc.org  RtpTestCallback()
22517189d2517bd1927b286dc706d40867f0535fe6bsprang@webrtc.org      : StreamDataCountersCallback(), num_calls_(0), ssrc_(0), stats_() {}
22617189d2517bd1927b286dc706d40867f0535fe6bsprang@webrtc.org  virtual ~RtpTestCallback() {}
2277d99cd47d8055ec6815f2862b75a0bdf53304199sprang@webrtc.org
22817189d2517bd1927b286dc706d40867f0535fe6bsprang@webrtc.org  virtual void DataCountersUpdated(const StreamDataCounters& counters,
22917189d2517bd1927b286dc706d40867f0535fe6bsprang@webrtc.org                                   uint32_t ssrc) {
23017189d2517bd1927b286dc706d40867f0535fe6bsprang@webrtc.org    ssrc_ = ssrc;
23117189d2517bd1927b286dc706d40867f0535fe6bsprang@webrtc.org    stats_ = counters;
23217189d2517bd1927b286dc706d40867f0535fe6bsprang@webrtc.org    ++num_calls_;
23317189d2517bd1927b286dc706d40867f0535fe6bsprang@webrtc.org  }
2347d99cd47d8055ec6815f2862b75a0bdf53304199sprang@webrtc.org
23517189d2517bd1927b286dc706d40867f0535fe6bsprang@webrtc.org  void ExpectMatches(uint32_t num_calls,
23617189d2517bd1927b286dc706d40867f0535fe6bsprang@webrtc.org                     uint32_t ssrc,
23717189d2517bd1927b286dc706d40867f0535fe6bsprang@webrtc.org                     uint32_t bytes,
23817189d2517bd1927b286dc706d40867f0535fe6bsprang@webrtc.org                     uint32_t padding,
23917189d2517bd1927b286dc706d40867f0535fe6bsprang@webrtc.org                     uint32_t packets,
24017189d2517bd1927b286dc706d40867f0535fe6bsprang@webrtc.org                     uint32_t retransmits,
24117189d2517bd1927b286dc706d40867f0535fe6bsprang@webrtc.org                     uint32_t fec) {
24217189d2517bd1927b286dc706d40867f0535fe6bsprang@webrtc.org    EXPECT_EQ(num_calls, num_calls_);
24317189d2517bd1927b286dc706d40867f0535fe6bsprang@webrtc.org    EXPECT_EQ(ssrc, ssrc_);
24417189d2517bd1927b286dc706d40867f0535fe6bsprang@webrtc.org    EXPECT_EQ(bytes, stats_.bytes);
24517189d2517bd1927b286dc706d40867f0535fe6bsprang@webrtc.org    EXPECT_EQ(padding, stats_.padding_bytes);
24617189d2517bd1927b286dc706d40867f0535fe6bsprang@webrtc.org    EXPECT_EQ(packets, stats_.packets);
24717189d2517bd1927b286dc706d40867f0535fe6bsprang@webrtc.org    EXPECT_EQ(retransmits, stats_.retransmitted_packets);
24817189d2517bd1927b286dc706d40867f0535fe6bsprang@webrtc.org    EXPECT_EQ(fec, stats_.fec_packets);
24917189d2517bd1927b286dc706d40867f0535fe6bsprang@webrtc.org  }
2507d99cd47d8055ec6815f2862b75a0bdf53304199sprang@webrtc.org
25117189d2517bd1927b286dc706d40867f0535fe6bsprang@webrtc.org  uint32_t num_calls_;
25217189d2517bd1927b286dc706d40867f0535fe6bsprang@webrtc.org  uint32_t ssrc_;
25317189d2517bd1927b286dc706d40867f0535fe6bsprang@webrtc.org  StreamDataCounters stats_;
25417189d2517bd1927b286dc706d40867f0535fe6bsprang@webrtc.org};
2557d99cd47d8055ec6815f2862b75a0bdf53304199sprang@webrtc.org
25617189d2517bd1927b286dc706d40867f0535fe6bsprang@webrtc.orgTEST_F(ReceiveStatisticsTest, RtpCallbacks) {
25717189d2517bd1927b286dc706d40867f0535fe6bsprang@webrtc.org  RtpTestCallback callback;
2587d99cd47d8055ec6815f2862b75a0bdf53304199sprang@webrtc.org  receive_statistics_->RegisterRtpStatisticsCallback(&callback);
2597d99cd47d8055ec6815f2862b75a0bdf53304199sprang@webrtc.org
2607d99cd47d8055ec6815f2862b75a0bdf53304199sprang@webrtc.org  const uint32_t kHeaderLength = 20;
2617d99cd47d8055ec6815f2862b75a0bdf53304199sprang@webrtc.org  const uint32_t kPaddingLength = 9;
2627d99cd47d8055ec6815f2862b75a0bdf53304199sprang@webrtc.org
2637d99cd47d8055ec6815f2862b75a0bdf53304199sprang@webrtc.org  // One packet of size kPacketSize1.
2647d99cd47d8055ec6815f2862b75a0bdf53304199sprang@webrtc.org  header1_.headerLength = kHeaderLength;
2657d99cd47d8055ec6815f2862b75a0bdf53304199sprang@webrtc.org  receive_statistics_->IncomingPacket(
2667d99cd47d8055ec6815f2862b75a0bdf53304199sprang@webrtc.org      header1_, kPacketSize1 + kHeaderLength, false);
2677d99cd47d8055ec6815f2862b75a0bdf53304199sprang@webrtc.org  callback.ExpectMatches(1, kSsrc1, kPacketSize1, 0, 1, 0, 0);
2687d99cd47d8055ec6815f2862b75a0bdf53304199sprang@webrtc.org
2697d99cd47d8055ec6815f2862b75a0bdf53304199sprang@webrtc.org  ++header1_.sequenceNumber;
2707d99cd47d8055ec6815f2862b75a0bdf53304199sprang@webrtc.org  clock_.AdvanceTimeMilliseconds(5);
2717d99cd47d8055ec6815f2862b75a0bdf53304199sprang@webrtc.org  header1_.paddingLength = 9;
2727d99cd47d8055ec6815f2862b75a0bdf53304199sprang@webrtc.org  // Another packet of size kPacketSize1 with 9 bytes padding.
2737d99cd47d8055ec6815f2862b75a0bdf53304199sprang@webrtc.org  receive_statistics_->IncomingPacket(
2747d99cd47d8055ec6815f2862b75a0bdf53304199sprang@webrtc.org      header1_, kPacketSize1 + kHeaderLength + kPaddingLength, false);
2757d99cd47d8055ec6815f2862b75a0bdf53304199sprang@webrtc.org  callback.ExpectMatches(2, kSsrc1, 2 * kPacketSize1, kPaddingLength, 2, 0, 0);
2767d99cd47d8055ec6815f2862b75a0bdf53304199sprang@webrtc.org
2777d99cd47d8055ec6815f2862b75a0bdf53304199sprang@webrtc.org  clock_.AdvanceTimeMilliseconds(5);
2787d99cd47d8055ec6815f2862b75a0bdf53304199sprang@webrtc.org  // Retransmit last packet.
2797d99cd47d8055ec6815f2862b75a0bdf53304199sprang@webrtc.org  receive_statistics_->IncomingPacket(
2807d99cd47d8055ec6815f2862b75a0bdf53304199sprang@webrtc.org      header1_, kPacketSize1 + kHeaderLength + kPaddingLength, true);
2817d99cd47d8055ec6815f2862b75a0bdf53304199sprang@webrtc.org  callback.ExpectMatches(
2827d99cd47d8055ec6815f2862b75a0bdf53304199sprang@webrtc.org      3, kSsrc1, 3 * kPacketSize1, kPaddingLength * 2, 3, 1, 0);
2837d99cd47d8055ec6815f2862b75a0bdf53304199sprang@webrtc.org
2847d99cd47d8055ec6815f2862b75a0bdf53304199sprang@webrtc.org  header1_.paddingLength = 0;
2857d99cd47d8055ec6815f2862b75a0bdf53304199sprang@webrtc.org  ++header1_.sequenceNumber;
2867d99cd47d8055ec6815f2862b75a0bdf53304199sprang@webrtc.org  clock_.AdvanceTimeMilliseconds(5);
2877d99cd47d8055ec6815f2862b75a0bdf53304199sprang@webrtc.org  // One recovered packet.
2887d99cd47d8055ec6815f2862b75a0bdf53304199sprang@webrtc.org  receive_statistics_->IncomingPacket(
2897d99cd47d8055ec6815f2862b75a0bdf53304199sprang@webrtc.org      header1_, kPacketSize1 + kHeaderLength, false);
2907d99cd47d8055ec6815f2862b75a0bdf53304199sprang@webrtc.org  receive_statistics_->FecPacketReceived(kSsrc1);
2917d99cd47d8055ec6815f2862b75a0bdf53304199sprang@webrtc.org  callback.ExpectMatches(
2927d99cd47d8055ec6815f2862b75a0bdf53304199sprang@webrtc.org      5, kSsrc1, 4 * kPacketSize1, kPaddingLength * 2, 4, 1, 1);
2937d99cd47d8055ec6815f2862b75a0bdf53304199sprang@webrtc.org
2947d99cd47d8055ec6815f2862b75a0bdf53304199sprang@webrtc.org  receive_statistics_->RegisterRtpStatisticsCallback(NULL);
2957d99cd47d8055ec6815f2862b75a0bdf53304199sprang@webrtc.org
2967d99cd47d8055ec6815f2862b75a0bdf53304199sprang@webrtc.org  // New stats, but callback should not be called.
2977d99cd47d8055ec6815f2862b75a0bdf53304199sprang@webrtc.org  ++header1_.sequenceNumber;
2987d99cd47d8055ec6815f2862b75a0bdf53304199sprang@webrtc.org  clock_.AdvanceTimeMilliseconds(5);
2997d99cd47d8055ec6815f2862b75a0bdf53304199sprang@webrtc.org  receive_statistics_->IncomingPacket(
3007d99cd47d8055ec6815f2862b75a0bdf53304199sprang@webrtc.org      header1_, kPacketSize1 + kHeaderLength, true);
3017d99cd47d8055ec6815f2862b75a0bdf53304199sprang@webrtc.org  callback.ExpectMatches(
3027d99cd47d8055ec6815f2862b75a0bdf53304199sprang@webrtc.org      5, kSsrc1, 4 * kPacketSize1, kPaddingLength * 2, 4, 1, 1);
3037d99cd47d8055ec6815f2862b75a0bdf53304199sprang@webrtc.org}
30417189d2517bd1927b286dc706d40867f0535fe6bsprang@webrtc.org
30517189d2517bd1927b286dc706d40867f0535fe6bsprang@webrtc.orgTEST_F(ReceiveStatisticsTest, RtpCallbacksFecFirst) {
30617189d2517bd1927b286dc706d40867f0535fe6bsprang@webrtc.org  RtpTestCallback callback;
30717189d2517bd1927b286dc706d40867f0535fe6bsprang@webrtc.org  receive_statistics_->RegisterRtpStatisticsCallback(&callback);
30817189d2517bd1927b286dc706d40867f0535fe6bsprang@webrtc.org
30917189d2517bd1927b286dc706d40867f0535fe6bsprang@webrtc.org  const uint32_t kHeaderLength = 20;
31017189d2517bd1927b286dc706d40867f0535fe6bsprang@webrtc.org
31117189d2517bd1927b286dc706d40867f0535fe6bsprang@webrtc.org  // If first packet is FEC, ignore it.
31217189d2517bd1927b286dc706d40867f0535fe6bsprang@webrtc.org  receive_statistics_->FecPacketReceived(kSsrc1);
31317189d2517bd1927b286dc706d40867f0535fe6bsprang@webrtc.org  EXPECT_EQ(0u, callback.num_calls_);
31417189d2517bd1927b286dc706d40867f0535fe6bsprang@webrtc.org
31517189d2517bd1927b286dc706d40867f0535fe6bsprang@webrtc.org  header1_.headerLength = kHeaderLength;
31617189d2517bd1927b286dc706d40867f0535fe6bsprang@webrtc.org  receive_statistics_->IncomingPacket(
31717189d2517bd1927b286dc706d40867f0535fe6bsprang@webrtc.org      header1_, kPacketSize1 + kHeaderLength, false);
31817189d2517bd1927b286dc706d40867f0535fe6bsprang@webrtc.org  callback.ExpectMatches(1, kSsrc1, kPacketSize1, 0, 1, 0, 0);
31917189d2517bd1927b286dc706d40867f0535fe6bsprang@webrtc.org
32017189d2517bd1927b286dc706d40867f0535fe6bsprang@webrtc.org  receive_statistics_->FecPacketReceived(kSsrc1);
32117189d2517bd1927b286dc706d40867f0535fe6bsprang@webrtc.org  callback.ExpectMatches(2, kSsrc1, kPacketSize1, 0, 1, 0, 1);
32217189d2517bd1927b286dc706d40867f0535fe6bsprang@webrtc.org}
323a20e2d4c9ae860db62de6e304bfdf517c049ec3dstefan@webrtc.org}  // namespace webrtc
324