blob: f8d92438589aed763dfa881adb8fe1d6bec44ef6 [file] [log] [blame]
mikhal@webrtc.org946d2402013-03-15 23:21:521/*
mikhal@webrtc.orgb9609752013-05-15 20:17:432* Copyright (c) 2013 The WebRTC project authors. All Rights Reserved.
3*
4* Use of this source code is governed by a BSD-style license
5* that can be found in the LICENSE file in the root of the source
6* tree. An additional intellectual property rights grant can be found
7* in the file PATENTS. All contributing project authors may
8* be found in the AUTHORS file in the root of the source tree.
9*/
mikhal@webrtc.org946d2402013-03-15 23:21:5210
11#include <algorithm>
mikhal@webrtc.orgb9609752013-05-15 20:17:4312#include <iterator>
13#include <list>
kwiberg6e27acd2016-04-27 08:19:5814#include <memory>
mikhal@webrtc.orgb9609752013-05-15 20:17:4315#include <set>
mikhal@webrtc.org946d2402013-03-15 23:21:5216
17#include "testing/gtest/include/gtest/gtest.h"
18#include "webrtc/common_types.h"
Henrik Kjellander36a14b52015-11-04 07:31:5219#include "webrtc/modules/rtp_rtcp/include/receive_statistics.h"
20#include "webrtc/modules/rtp_rtcp/include/rtp_header_parser.h"
21#include "webrtc/modules/rtp_rtcp/include/rtp_payload_registry.h"
22#include "webrtc/modules/rtp_rtcp/include/rtp_receiver.h"
23#include "webrtc/modules/rtp_rtcp/include/rtp_rtcp.h"
24#include "webrtc/modules/rtp_rtcp/include/rtp_rtcp_defines.h"
pbosd5bdda32015-09-28 16:59:3125#include "webrtc/transport.h"
mikhal@webrtc.org946d2402013-03-15 23:21:5226
danilchap090af542015-12-10 20:39:0827namespace webrtc {
mikhal@webrtc.orgb9609752013-05-15 20:17:4328
29const int kVideoNackListSize = 30;
pbos@webrtc.orgb57da652013-04-08 11:08:4130const uint32_t kTestSsrc = 3456;
31const uint16_t kTestSequenceNumber = 2345;
mikhal@webrtc.orgb9609752013-05-15 20:17:4332const uint32_t kTestNumberOfPackets = 1350;
33const int kTestNumberOfRtxPackets = 149;
34const int kNumFrames = 30;
Shao Changbin0f071712015-04-21 12:24:5035const int kPayloadType = 123;
36const int kRtxPayloadType = 98;
mikhal@webrtc.org946d2402013-03-15 23:21:5237
danilchap3bf825b2015-12-10 10:39:4038class VerifyingRtxReceiver : public NullRtpData {
mikhal@webrtc.org946d2402013-03-15 23:21:5239 public:
40 VerifyingRtxReceiver() {}
41
kjellander@webrtc.org860ac532015-03-04 12:58:3542 int32_t OnReceivedPayloadData(
pbos@webrtc.orgb57da652013-04-08 11:08:4143 const uint8_t* data,
Peter Boströmc9da01c2016-06-14 10:52:5444 size_t size,
kjellander@webrtc.org860ac532015-03-04 12:58:3545 const webrtc::WebRtcRTPHeader* rtp_header) override {
mikhal@webrtc.orgb9609752013-05-15 20:17:4346 if (!sequence_numbers_.empty())
mikhal@webrtc.org946d2402013-03-15 23:21:5247 EXPECT_EQ(kTestSsrc, rtp_header->header.ssrc);
mikhal@webrtc.org946d2402013-03-15 23:21:5248 sequence_numbers_.push_back(rtp_header->header.sequenceNumber);
49 return 0;
50 }
mikhal@webrtc.orgb9609752013-05-15 20:17:4351 std::list<uint16_t> sequence_numbers_;
mikhal@webrtc.org946d2402013-03-15 23:21:5252};
53
wu@webrtc.org7fc75bb2013-08-15 23:38:5454class TestRtpFeedback : public NullRtpFeedback {
55 public:
danilchap9bcfdee2015-12-15 10:54:4756 explicit TestRtpFeedback(RtpRtcp* rtp_rtcp) : rtp_rtcp_(rtp_rtcp) {}
wu@webrtc.org7fc75bb2013-08-15 23:38:5457 virtual ~TestRtpFeedback() {}
58
Peter Boström00a7fa42015-09-17 21:03:5759 void OnIncomingSSRCChanged(const uint32_t ssrc) override {
stefan@webrtc.orga20e2d42013-08-21 20:58:2160 rtp_rtcp_->SetRemoteSSRC(ssrc);
wu@webrtc.org7fc75bb2013-08-15 23:38:5461 }
62
63 private:
64 RtpRtcp* rtp_rtcp_;
65};
66
mikhal@webrtc.org946d2402013-03-15 23:21:5267class RtxLoopBackTransport : public webrtc::Transport {
68 public:
69 explicit RtxLoopBackTransport(uint32_t rtx_ssrc)
70 : count_(0),
71 packet_loss_(0),
mikhal@webrtc.orgb9609752013-05-15 20:17:4372 consecutive_drop_start_(0),
73 consecutive_drop_end_(0),
mikhal@webrtc.org946d2402013-03-15 23:21:5274 rtx_ssrc_(rtx_ssrc),
75 count_rtx_ssrc_(0),
wu@webrtc.org7fc75bb2013-08-15 23:38:5476 rtp_payload_registry_(NULL),
77 rtp_receiver_(NULL),
stefan@webrtc.orgdb74c612013-09-06 13:40:1178 module_(NULL) {}
mikhal@webrtc.orgb9609752013-05-15 20:17:4379
wu@webrtc.org7fc75bb2013-08-15 23:38:5480 void SetSendModule(RtpRtcp* rtpRtcpModule,
81 RTPPayloadRegistry* rtp_payload_registry,
82 RtpReceiver* receiver) {
mikhal@webrtc.org946d2402013-03-15 23:21:5283 module_ = rtpRtcpModule;
wu@webrtc.org7fc75bb2013-08-15 23:38:5484 rtp_payload_registry_ = rtp_payload_registry;
85 rtp_receiver_ = receiver;
mikhal@webrtc.org946d2402013-03-15 23:21:5286 }
mikhal@webrtc.orgb9609752013-05-15 20:17:4387
danilchap3bf825b2015-12-10 10:39:4088 void DropEveryNthPacket(int n) { packet_loss_ = n; }
mikhal@webrtc.orgb9609752013-05-15 20:17:4389
90 void DropConsecutivePackets(int start, int total) {
91 consecutive_drop_start_ = start;
92 consecutive_drop_end_ = start + total;
93 packet_loss_ = 0;
94 }
95
stefaneb16b932015-10-02 10:39:3396 bool SendRtp(const uint8_t* data,
97 size_t len,
98 const PacketOptions& options) override {
mikhal@webrtc.org946d2402013-03-15 23:21:5299 count_++;
danilchap3bf825b2015-12-10 10:39:40100 const unsigned char* ptr = static_cast<const unsigned char*>(data);
mikhal@webrtc.org946d2402013-03-15 23:21:52101 uint32_t ssrc = (ptr[8] << 24) + (ptr[9] << 16) + (ptr[10] << 8) + ptr[11];
danilchap3bf825b2015-12-10 10:39:40102 if (ssrc == rtx_ssrc_)
103 count_rtx_ssrc_++;
mikhal@webrtc.orgb9609752013-05-15 20:17:43104 uint16_t sequence_number = (ptr[2] << 8) + ptr[3];
pkasting@chromium.org0ab923a2014-11-20 22:28:14105 size_t packet_length = len;
pbos2c58add2015-11-17 01:19:34106 uint8_t restored_packet[1500];
stefan@webrtc.org6696fba2013-05-29 12:12:51107 RTPHeader header;
kwiberg6e27acd2016-04-27 08:19:58108 std::unique_ptr<RtpHeaderParser> parser(RtpHeaderParser::Create());
stefan@webrtc.orgdb74c612013-09-06 13:40:11109 if (!parser->Parse(ptr, len, &header)) {
pbosd5bdda32015-09-28 16:59:31110 return false;
mikhal@webrtc.org946d2402013-03-15 23:21:52111 }
tereliuse2c98532015-09-17 10:19:45112
113 if (!rtp_payload_registry_->IsRtx(header)) {
114 // Don't store retransmitted packets since we compare it to the list
115 // created by the receiver.
116 expected_sequence_numbers_.insert(expected_sequence_numbers_.end(),
117 sequence_number);
118 }
119 if (packet_loss_ > 0) {
120 if ((count_ % packet_loss_) == 0) {
pbosd5bdda32015-09-28 16:59:31121 return true;
tereliuse2c98532015-09-17 10:19:45122 }
123 } else if (count_ >= consecutive_drop_start_ &&
124 count_ < consecutive_drop_end_) {
pbosd5bdda32015-09-28 16:59:31125 return true;
tereliuse2c98532015-09-17 10:19:45126 }
stefan@webrtc.orgdb74c612013-09-06 13:40:11127 if (rtp_payload_registry_->IsRtx(header)) {
128 // Remove the RTX header and parse the original RTP header.
129 EXPECT_TRUE(rtp_payload_registry_->RestoreOriginalPacket(
noahric95c84b72015-10-14 18:29:49130 restored_packet, ptr, &packet_length, rtp_receiver_->SSRC(), header));
131 if (!parser->Parse(restored_packet, packet_length, &header)) {
pbosd5bdda32015-09-28 16:59:31132 return false;
stefan@webrtc.orgdb74c612013-09-06 13:40:11133 }
pbos2c58add2015-11-17 01:19:34134 ptr = restored_packet;
Shao Changbin0f071712015-04-21 12:24:50135 } else {
136 rtp_payload_registry_->SetIncomingPayloadType(header);
stefan@webrtc.orgdb74c612013-09-06 13:40:11137 }
Shao Changbin0f071712015-04-21 12:24:50138
wu@webrtc.org7fc75bb2013-08-15 23:38:54139 PayloadUnion payload_specific;
140 if (!rtp_payload_registry_->GetPayloadSpecifics(header.payloadType,
stefan@webrtc.orgdb74c612013-09-06 13:40:11141 &payload_specific)) {
pbosd5bdda32015-09-28 16:59:31142 return false;
wu@webrtc.org7fc75bb2013-08-15 23:38:54143 }
pbos2c58add2015-11-17 01:19:34144 if (!rtp_receiver_->IncomingRtpPacket(header, ptr + header.headerLength,
145 packet_length - header.headerLength,
146 payload_specific, true)) {
pbosd5bdda32015-09-28 16:59:31147 return false;
stefan@webrtc.org6696fba2013-05-29 12:12:51148 }
pbosd5bdda32015-09-28 16:59:31149 return true;
mikhal@webrtc.org946d2402013-03-15 23:21:52150 }
mikhal@webrtc.orgb9609752013-05-15 20:17:43151
pbosd5bdda32015-09-28 16:59:31152 bool SendRtcp(const uint8_t* data, size_t len) override {
153 return module_->IncomingRtcpPacket((const uint8_t*)data, len) == 0;
mikhal@webrtc.org946d2402013-03-15 23:21:52154 }
155 int count_;
156 int packet_loss_;
mikhal@webrtc.orgb9609752013-05-15 20:17:43157 int consecutive_drop_start_;
158 int consecutive_drop_end_;
mikhal@webrtc.org946d2402013-03-15 23:21:52159 uint32_t rtx_ssrc_;
160 int count_rtx_ssrc_;
wu@webrtc.org7fc75bb2013-08-15 23:38:54161 RTPPayloadRegistry* rtp_payload_registry_;
162 RtpReceiver* rtp_receiver_;
mikhal@webrtc.org946d2402013-03-15 23:21:52163 RtpRtcp* module_;
mikhal@webrtc.orgb9609752013-05-15 20:17:43164 std::set<uint16_t> expected_sequence_numbers_;
mikhal@webrtc.org946d2402013-03-15 23:21:52165};
166
stefan@webrtc.org0b5c7f12013-03-18 15:00:50167class RtpRtcpRtxNackTest : public ::testing::Test {
mikhal@webrtc.org946d2402013-03-15 23:21:52168 protected:
stefan@webrtc.org0b5c7f12013-03-18 15:00:50169 RtpRtcpRtxNackTest()
andresp@webrtc.org99681312014-04-08 11:06:12170 : rtp_payload_registry_(RTPPayloadStrategy::CreateStrategy(false)),
aluebsb78878b2016-07-08 18:01:59171 rtp_rtcp_module_(NULL),
mikhal@webrtc.org946d2402013-03-15 23:21:52172 transport_(kTestSsrc + 1),
173 receiver_(),
174 payload_data_length(sizeof(payload_data)),
aluebsb78878b2016-07-08 18:01:59175 fake_clock(123456) {}
stefan@webrtc.org0b5c7f12013-03-18 15:00:50176 ~RtpRtcpRtxNackTest() {}
mikhal@webrtc.org946d2402013-03-15 23:21:52177
kjellander@webrtc.org860ac532015-03-04 12:58:35178 void SetUp() override {
mikhal@webrtc.org946d2402013-03-15 23:21:52179 RtpRtcp::Configuration configuration;
mikhal@webrtc.org946d2402013-03-15 23:21:52180 configuration.audio = false;
181 configuration.clock = &fake_clock;
wu@webrtc.org7fc75bb2013-08-15 23:38:54182 receive_statistics_.reset(ReceiveStatistics::Create(&fake_clock));
183 configuration.receive_statistics = receive_statistics_.get();
mikhal@webrtc.org946d2402013-03-15 23:21:52184 configuration.outgoing_transport = &transport_;
185 rtp_rtcp_module_ = RtpRtcp::CreateRtpRtcp(configuration);
186
wu@webrtc.org7fc75bb2013-08-15 23:38:54187 rtp_feedback_.reset(new TestRtpFeedback(rtp_rtcp_module_));
188
189 rtp_receiver_.reset(RtpReceiver::CreateVideoReceiver(
danilchap3bf825b2015-12-10 10:39:40190 &fake_clock, &receiver_, rtp_feedback_.get(), &rtp_payload_registry_));
wu@webrtc.org7fc75bb2013-08-15 23:38:54191
stefan@webrtc.org903e7462014-06-05 08:25:29192 rtp_rtcp_module_->SetSSRC(kTestSsrc);
pbosba01e952015-10-02 09:36:56193 rtp_rtcp_module_->SetRTCPStatus(RtcpMode::kCompound);
pbos@webrtc.orgf377da92014-12-19 13:49:55194 rtp_rtcp_module_->SetStorePacketsStatus(true, 600);
mikhal@webrtc.org946d2402013-03-15 23:21:52195 EXPECT_EQ(0, rtp_rtcp_module_->SetSendingStatus(true));
pbos@webrtc.orgf377da92014-12-19 13:49:55196 rtp_rtcp_module_->SetSequenceNumber(kTestSequenceNumber);
197 rtp_rtcp_module_->SetStartTimestamp(111111);
mikhal@webrtc.org946d2402013-03-15 23:21:52198
wu@webrtc.org7fc75bb2013-08-15 23:38:54199 transport_.SetSendModule(rtp_rtcp_module_, &rtp_payload_registry_,
200 rtp_receiver_.get());
mikhal@webrtc.org946d2402013-03-15 23:21:52201
202 VideoCodec video_codec;
203 memset(&video_codec, 0, sizeof(video_codec));
Shao Changbin0f071712015-04-21 12:24:50204 video_codec.plType = kPayloadType;
mikhal@webrtc.org946d2402013-03-15 23:21:52205 memcpy(video_codec.plName, "I420", 5);
206
207 EXPECT_EQ(0, rtp_rtcp_module_->RegisterSendPayload(video_codec));
Shao Changbin0f071712015-04-21 12:24:50208 rtp_rtcp_module_->SetRtxSendPayloadType(kRtxPayloadType, kPayloadType);
danilchap3bf825b2015-12-10 10:39:40209 EXPECT_EQ(0, rtp_receiver_->RegisterReceivePayload(
210 video_codec.plName, video_codec.plType, 90000, 0,
211 video_codec.maxBitrate));
Shao Changbin0f071712015-04-21 12:24:50212 rtp_payload_registry_.SetRtxPayloadType(kRtxPayloadType, kPayloadType);
mikhal@webrtc.org946d2402013-03-15 23:21:52213
pkasting@chromium.org0ab923a2014-11-20 22:28:14214 for (size_t n = 0; n < payload_data_length; n++) {
mikhal@webrtc.org946d2402013-03-15 23:21:52215 payload_data[n] = n % 10;
216 }
217 }
218
mikhal@webrtc.orgb9609752013-05-15 20:17:43219 int BuildNackList(uint16_t* nack_list) {
220 receiver_.sequence_numbers_.sort();
221 std::list<uint16_t> missing_sequence_numbers;
danilchap3bf825b2015-12-10 10:39:40222 std::list<uint16_t>::iterator it = receiver_.sequence_numbers_.begin();
mikhal@webrtc.orgb9609752013-05-15 20:17:43223
224 while (it != receiver_.sequence_numbers_.end()) {
225 uint16_t sequence_number_1 = *it;
226 ++it;
227 if (it != receiver_.sequence_numbers_.end()) {
228 uint16_t sequence_number_2 = *it;
229 // Add all missing sequence numbers to list
danilchap3bf825b2015-12-10 10:39:40230 for (uint16_t i = sequence_number_1 + 1; i < sequence_number_2; ++i) {
mikhal@webrtc.orgb9609752013-05-15 20:17:43231 missing_sequence_numbers.push_back(i);
232 }
233 }
234 }
235 int n = 0;
236 for (it = missing_sequence_numbers.begin();
danilchap3bf825b2015-12-10 10:39:40237 it != missing_sequence_numbers.end(); ++it) {
mikhal@webrtc.orgb9609752013-05-15 20:17:43238 nack_list[n++] = (*it);
239 }
240 return n;
241 }
242
243 bool ExpectedPacketsReceived() {
244 std::list<uint16_t> received_sorted;
245 std::copy(receiver_.sequence_numbers_.begin(),
246 receiver_.sequence_numbers_.end(),
247 std::back_inserter(received_sorted));
248 received_sorted.sort();
tereliuse2c98532015-09-17 10:19:45249 return received_sorted.size() ==
250 transport_.expected_sequence_numbers_.size() &&
251 std::equal(received_sorted.begin(), received_sorted.end(),
mikhal@webrtc.orgb9609752013-05-15 20:17:43252 transport_.expected_sequence_numbers_.begin());
253 }
254
255 void RunRtxTest(RtxMode rtx_method, int loss) {
stefan@webrtc.org903e7462014-06-05 08:25:29256 rtp_payload_registry_.SetRtxSsrc(kTestSsrc + 1);
pbos@webrtc.org4b0399b2015-01-13 14:15:15257 rtp_rtcp_module_->SetRtxSendStatus(rtx_method);
stefan@webrtc.org903e7462014-06-05 08:25:29258 rtp_rtcp_module_->SetRtxSsrc(kTestSsrc + 1);
mikhal@webrtc.orgb9609752013-05-15 20:17:43259 transport_.DropEveryNthPacket(loss);
260 uint32_t timestamp = 3000;
261 uint16_t nack_list[kVideoNackListSize];
262 for (int frame = 0; frame < kNumFrames; ++frame) {
Shao Changbin0f071712015-04-21 12:24:50263 EXPECT_EQ(0, rtp_rtcp_module_->SendOutgoingData(
264 webrtc::kVideoFrameDelta, kPayloadType, timestamp,
265 timestamp / 90, payload_data, payload_data_length));
sprang@webrtc.orgbbf5cad2015-01-29 09:09:17266 // Min required delay until retransmit = 5 + RTT ms (RTT = 0).
267 fake_clock.AdvanceTimeMilliseconds(5);
mikhal@webrtc.orgb9609752013-05-15 20:17:43268 int length = BuildNackList(nack_list);
269 if (length > 0)
270 rtp_rtcp_module_->SendNACK(nack_list, length);
sprang@webrtc.orgbbf5cad2015-01-29 09:09:17271 fake_clock.AdvanceTimeMilliseconds(28); // 33ms - 5ms delay.
mikhal@webrtc.orgb9609752013-05-15 20:17:43272 rtp_rtcp_module_->Process();
273 // Prepare next frame.
274 timestamp += 3000;
275 }
276 receiver_.sequence_numbers_.sort();
277 }
278
kjellander@webrtc.org860ac532015-03-04 12:58:35279 void TearDown() override { delete rtp_rtcp_module_; }
mikhal@webrtc.org946d2402013-03-15 23:21:52280
kwiberg6e27acd2016-04-27 08:19:58281 std::unique_ptr<ReceiveStatistics> receive_statistics_;
wu@webrtc.org7fc75bb2013-08-15 23:38:54282 RTPPayloadRegistry rtp_payload_registry_;
kwiberg6e27acd2016-04-27 08:19:58283 std::unique_ptr<RtpReceiver> rtp_receiver_;
mikhal@webrtc.org946d2402013-03-15 23:21:52284 RtpRtcp* rtp_rtcp_module_;
kwiberg6e27acd2016-04-27 08:19:58285 std::unique_ptr<TestRtpFeedback> rtp_feedback_;
mikhal@webrtc.org946d2402013-03-15 23:21:52286 RtxLoopBackTransport transport_;
287 VerifyingRtxReceiver receiver_;
danilchap3bf825b2015-12-10 10:39:40288 uint8_t payload_data[65000];
pkasting@chromium.org0ab923a2014-11-20 22:28:14289 size_t payload_data_length;
mikhal@webrtc.org946d2402013-03-15 23:21:52290 SimulatedClock fake_clock;
291};
292
mikhal@webrtc.orgb9609752013-05-15 20:17:43293TEST_F(RtpRtcpRtxNackTest, LongNackList) {
294 const int kNumPacketsToDrop = 900;
295 const int kNumRequiredRtcp = 4;
pbos@webrtc.orgb57da652013-04-08 11:08:41296 uint32_t timestamp = 3000;
mikhal@webrtc.orgb9609752013-05-15 20:17:43297 uint16_t nack_list[kNumPacketsToDrop];
298 // Disable StorePackets to be able to set a larger packet history.
pbos@webrtc.orgf377da92014-12-19 13:49:55299 rtp_rtcp_module_->SetStorePacketsStatus(false, 0);
mikhal@webrtc.orgb9609752013-05-15 20:17:43300 // Enable StorePackets with a packet history of 2000 packets.
pbos@webrtc.orgf377da92014-12-19 13:49:55301 rtp_rtcp_module_->SetStorePacketsStatus(true, 2000);
mikhal@webrtc.orgb9609752013-05-15 20:17:43302 // Drop 900 packets from the second one so that we get a NACK list which is
303 // big enough to require 4 RTCP packets to be fully transmitted to the sender.
304 transport_.DropConsecutivePackets(2, kNumPacketsToDrop);
305 // Send 30 frames which at the default size is roughly what we need to get
306 // enough packets.
307 for (int frame = 0; frame < kNumFrames; ++frame) {
Shao Changbin0f071712015-04-21 12:24:50308 EXPECT_EQ(0, rtp_rtcp_module_->SendOutgoingData(
309 webrtc::kVideoFrameDelta, kPayloadType, timestamp,
310 timestamp / 90, payload_data, payload_data_length));
mikhal@webrtc.org946d2402013-03-15 23:21:52311 // Prepare next frame.
312 timestamp += 3000;
mikhal@webrtc.orgb9609752013-05-15 20:17:43313 fake_clock.AdvanceTimeMilliseconds(33);
314 rtp_rtcp_module_->Process();
mikhal@webrtc.org946d2402013-03-15 23:21:52315 }
mikhal@webrtc.orgb9609752013-05-15 20:17:43316 EXPECT_FALSE(transport_.expected_sequence_numbers_.empty());
317 EXPECT_FALSE(receiver_.sequence_numbers_.empty());
318 size_t last_receive_count = receiver_.sequence_numbers_.size();
319 int length = BuildNackList(nack_list);
320 for (int i = 0; i < kNumRequiredRtcp - 1; ++i) {
321 rtp_rtcp_module_->SendNACK(nack_list, length);
322 EXPECT_GT(receiver_.sequence_numbers_.size(), last_receive_count);
323 last_receive_count = receiver_.sequence_numbers_.size();
324 EXPECT_FALSE(ExpectedPacketsReceived());
325 }
326 rtp_rtcp_module_->SendNACK(nack_list, length);
327 EXPECT_GT(receiver_.sequence_numbers_.size(), last_receive_count);
328 EXPECT_TRUE(ExpectedPacketsReceived());
mikhal@webrtc.org946d2402013-03-15 23:21:52329}
330
mikhal@webrtc.orgb9609752013-05-15 20:17:43331TEST_F(RtpRtcpRtxNackTest, RtxNack) {
332 RunRtxTest(kRtxRetransmitted, 10);
mikhal@webrtc.org946d2402013-03-15 23:21:52333 EXPECT_EQ(kTestSequenceNumber, *(receiver_.sequence_numbers_.begin()));
334 EXPECT_EQ(kTestSequenceNumber + kTestNumberOfPackets - 1,
danilchap3bf825b2015-12-10 10:39:40335 *(receiver_.sequence_numbers_.rbegin()));
mikhal@webrtc.org946d2402013-03-15 23:21:52336 EXPECT_EQ(kTestNumberOfPackets, receiver_.sequence_numbers_.size());
337 EXPECT_EQ(kTestNumberOfRtxPackets, transport_.count_rtx_ssrc_);
mikhal@webrtc.orgb9609752013-05-15 20:17:43338 EXPECT_TRUE(ExpectedPacketsReceived());
mikhal@webrtc.org946d2402013-03-15 23:21:52339}
danilchap090af542015-12-10 20:39:08340
341} // namespace webrtc