blob: 17601dd9669b2b06476bb0ef5103ea7ce0d418bf [file] [log] [blame]
mikhal@webrtc.orgbda7f302013-03-15 23:21:52 +00001/*
Yves Gerey665174f2018-06-19 15:03:05 +02002 * 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.orgbda7f302013-03-15 23:21:52 +000010
mikhal@webrtc.org6cfa3902013-05-15 20:17:43 +000011#include <iterator>
12#include <list>
kwiberg84be5112016-04-27 01:19:58 -070013#include <memory>
mikhal@webrtc.org6cfa3902013-05-15 20:17:43 +000014#include <set>
mikhal@webrtc.orgbda7f302013-03-15 23:21:52 +000015
Steve Anton91c26062019-03-28 10:56:11 -070016#include "absl/algorithm/container.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020017#include "api/call/transport.h"
Niels Möller5fe95102019-03-04 16:49:25 +010018#include "api/transport/field_trial_based_config.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020019#include "call/rtp_stream_receiver_controller.h"
20#include "call/rtx_receive_stream.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020021#include "modules/rtp_rtcp/include/receive_statistics.h"
22#include "modules/rtp_rtcp/include/rtp_rtcp.h"
23#include "modules/rtp_rtcp/include/rtp_rtcp_defines.h"
Niels Möller5fe95102019-03-04 16:49:25 +010024#include "modules/rtp_rtcp/source/playout_delay_oracle.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020025#include "modules/rtp_rtcp/source/rtp_packet_received.h"
Niels Möller5fe95102019-03-04 16:49:25 +010026#include "modules/rtp_rtcp/source/rtp_sender_video.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020027#include "rtc_base/rate_limiter.h"
28#include "test/gtest.h"
mikhal@webrtc.orgbda7f302013-03-15 23:21:52 +000029
danilchap6a6f0892015-12-10 12:39:08 -080030namespace webrtc {
mikhal@webrtc.org6cfa3902013-05-15 20:17:43 +000031
32const int kVideoNackListSize = 30;
pbos@webrtc.org2f446732013-04-08 11:08:41 +000033const uint32_t kTestSsrc = 3456;
nissef54573b2017-09-13 07:13:57 -070034const uint32_t kTestRtxSsrc = kTestSsrc + 1;
pbos@webrtc.org2f446732013-04-08 11:08:41 +000035const uint16_t kTestSequenceNumber = 2345;
mikhal@webrtc.org6cfa3902013-05-15 20:17:43 +000036const uint32_t kTestNumberOfPackets = 1350;
37const int kTestNumberOfRtxPackets = 149;
38const int kNumFrames = 30;
Shao Changbine62202f2015-04-21 20:24:50 +080039const int kPayloadType = 123;
40const int kRtxPayloadType = 98;
sprangcd349d92016-07-13 09:11:28 -070041const int64_t kMaxRttMs = 1000;
mikhal@webrtc.orgbda7f302013-03-15 23:21:52 +000042
nissef54573b2017-09-13 07:13:57 -070043class VerifyingMediaStream : public RtpPacketSinkInterface {
mikhal@webrtc.orgbda7f302013-03-15 23:21:52 +000044 public:
nissef54573b2017-09-13 07:13:57 -070045 VerifyingMediaStream() {}
mikhal@webrtc.orgbda7f302013-03-15 23:21:52 +000046
nissef54573b2017-09-13 07:13:57 -070047 void OnRtpPacket(const RtpPacketReceived& packet) override {
mikhal@webrtc.org6cfa3902013-05-15 20:17:43 +000048 if (!sequence_numbers_.empty())
nissef54573b2017-09-13 07:13:57 -070049 EXPECT_EQ(kTestSsrc, packet.Ssrc());
50
51 sequence_numbers_.push_back(packet.SequenceNumber());
mikhal@webrtc.orgbda7f302013-03-15 23:21:52 +000052 }
mikhal@webrtc.org6cfa3902013-05-15 20:17:43 +000053 std::list<uint16_t> sequence_numbers_;
mikhal@webrtc.orgbda7f302013-03-15 23:21:52 +000054};
55
56class RtxLoopBackTransport : public webrtc::Transport {
57 public:
58 explicit RtxLoopBackTransport(uint32_t rtx_ssrc)
59 : count_(0),
60 packet_loss_(0),
mikhal@webrtc.org6cfa3902013-05-15 20:17:43 +000061 consecutive_drop_start_(0),
62 consecutive_drop_end_(0),
mikhal@webrtc.orgbda7f302013-03-15 23:21:52 +000063 rtx_ssrc_(rtx_ssrc),
64 count_rtx_ssrc_(0),
stefan@webrtc.org7bb8f022013-09-06 13:40:11 +000065 module_(NULL) {}
mikhal@webrtc.org6cfa3902013-05-15 20:17:43 +000066
Yves Gerey665174f2018-06-19 15:03:05 +020067 void SetSendModule(RtpRtcp* rtpRtcpModule) { module_ = rtpRtcpModule; }
mikhal@webrtc.org6cfa3902013-05-15 20:17:43 +000068
danilchap162abd32015-12-10 02:39:40 -080069 void DropEveryNthPacket(int n) { packet_loss_ = n; }
mikhal@webrtc.org6cfa3902013-05-15 20:17:43 +000070
71 void DropConsecutivePackets(int start, int total) {
72 consecutive_drop_start_ = start;
73 consecutive_drop_end_ = start + total;
74 packet_loss_ = 0;
75 }
76
stefan1d8a5062015-10-02 03:39:33 -070077 bool SendRtp(const uint8_t* data,
78 size_t len,
79 const PacketOptions& options) override {
mikhal@webrtc.orgbda7f302013-03-15 23:21:52 +000080 count_++;
nissef54573b2017-09-13 07:13:57 -070081 RtpPacketReceived packet;
82 if (!packet.Parse(data, len))
nissea6468532017-09-08 05:00:54 -070083 return false;
nissef54573b2017-09-13 07:13:57 -070084 if (packet.Ssrc() == rtx_ssrc_) {
85 count_rtx_ssrc_++;
86 } else {
87 // For non-RTX packets only.
tereliuse64fbce2015-09-17 03:19:45 -070088 expected_sequence_numbers_.insert(expected_sequence_numbers_.end(),
nissef54573b2017-09-13 07:13:57 -070089 packet.SequenceNumber());
tereliuse64fbce2015-09-17 03:19:45 -070090 }
91 if (packet_loss_ > 0) {
92 if ((count_ % packet_loss_) == 0) {
pbos2d566682015-09-28 09:59:31 -070093 return true;
tereliuse64fbce2015-09-17 03:19:45 -070094 }
95 } else if (count_ >= consecutive_drop_start_ &&
96 count_ < consecutive_drop_end_) {
pbos2d566682015-09-28 09:59:31 -070097 return true;
tereliuse64fbce2015-09-17 03:19:45 -070098 }
nissef54573b2017-09-13 07:13:57 -070099 EXPECT_TRUE(stream_receiver_controller_.OnRtpPacket(packet));
pbos2d566682015-09-28 09:59:31 -0700100 return true;
mikhal@webrtc.orgbda7f302013-03-15 23:21:52 +0000101 }
mikhal@webrtc.org6cfa3902013-05-15 20:17:43 +0000102
pbos2d566682015-09-28 09:59:31 -0700103 bool SendRtcp(const uint8_t* data, size_t len) override {
nisse479d3d72017-09-13 07:53:37 -0700104 module_->IncomingRtcpPacket((const uint8_t*)data, len);
105 return true;
mikhal@webrtc.orgbda7f302013-03-15 23:21:52 +0000106 }
107 int count_;
108 int packet_loss_;
mikhal@webrtc.org6cfa3902013-05-15 20:17:43 +0000109 int consecutive_drop_start_;
110 int consecutive_drop_end_;
mikhal@webrtc.orgbda7f302013-03-15 23:21:52 +0000111 uint32_t rtx_ssrc_;
112 int count_rtx_ssrc_;
113 RtpRtcp* module_;
nissef54573b2017-09-13 07:13:57 -0700114 RtpStreamReceiverController stream_receiver_controller_;
mikhal@webrtc.org6cfa3902013-05-15 20:17:43 +0000115 std::set<uint16_t> expected_sequence_numbers_;
mikhal@webrtc.orgbda7f302013-03-15 23:21:52 +0000116};
117
stefan@webrtc.org41211462013-03-18 15:00:50 +0000118class RtpRtcpRtxNackTest : public ::testing::Test {
mikhal@webrtc.orgbda7f302013-03-15 23:21:52 +0000119 protected:
stefan@webrtc.org41211462013-03-18 15:00:50 +0000120 RtpRtcpRtxNackTest()
magjedf3feeff2016-11-25 06:40:25 -0800121 : rtp_rtcp_module_(nullptr),
nissef54573b2017-09-13 07:13:57 -0700122 transport_(kTestRtxSsrc),
Yves Gerey665174f2018-06-19 15:03:05 +0200123 rtx_stream_(&media_stream_, rtx_associated_payload_types_, kTestSsrc),
sprangcd349d92016-07-13 09:11:28 -0700124 fake_clock(123456),
Erik Språng737336d2016-07-29 12:59:36 +0200125 retransmission_rate_limiter_(&fake_clock, kMaxRttMs) {}
Danil Chapovalovdd7e2842018-03-09 15:37:03 +0000126 ~RtpRtcpRtxNackTest() override {}
mikhal@webrtc.orgbda7f302013-03-15 23:21:52 +0000127
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000128 void SetUp() override {
mikhal@webrtc.orgbda7f302013-03-15 23:21:52 +0000129 RtpRtcp::Configuration configuration;
mikhal@webrtc.orgbda7f302013-03-15 23:21:52 +0000130 configuration.audio = false;
131 configuration.clock = &fake_clock;
Niels Möller0d210ee2019-08-07 16:16:45 +0200132 receive_statistics_ = ReceiveStatistics::Create(&fake_clock);
wu@webrtc.org822fbd82013-08-15 23:38:54 +0000133 configuration.receive_statistics = receive_statistics_.get();
mikhal@webrtc.orgbda7f302013-03-15 23:21:52 +0000134 configuration.outgoing_transport = &transport_;
Erik Språng737336d2016-07-29 12:59:36 +0200135 configuration.retransmission_rate_limiter = &retransmission_rate_limiter_;
Erik Språng54d5d2c2019-08-20 17:22:36 +0200136 configuration.local_media_ssrc = kTestSsrc;
Erik Språng6841d252019-10-15 14:29:11 +0200137 configuration.rtx_send_ssrc = kTestRtxSsrc;
Danil Chapovalovc44f6cc2019-03-06 11:31:09 +0100138 rtp_rtcp_module_ = RtpRtcp::Create(configuration);
Erik Språngdc34a252019-10-04 15:17:29 +0200139 FieldTrialBasedConfig field_trials;
140 RTPSenderVideo::Config video_config;
141 video_config.clock = &fake_clock;
142 video_config.rtp_sender = rtp_rtcp_module_->RtpSender();
143 video_config.playout_delay_oracle = &playout_delay_oracle_;
144 video_config.field_trials = &field_trials;
145 rtp_sender_video_ = std::make_unique<RTPSenderVideo>(video_config);
pbosda903ea2015-10-02 02:36:56 -0700146 rtp_rtcp_module_->SetRTCPStatus(RtcpMode::kCompound);
pbos@webrtc.orgd16e8392014-12-19 13:49:55 +0000147 rtp_rtcp_module_->SetStorePacketsStatus(true, 600);
mikhal@webrtc.orgbda7f302013-03-15 23:21:52 +0000148 EXPECT_EQ(0, rtp_rtcp_module_->SetSendingStatus(true));
pbos@webrtc.orgd16e8392014-12-19 13:49:55 +0000149 rtp_rtcp_module_->SetSequenceNumber(kTestSequenceNumber);
150 rtp_rtcp_module_->SetStartTimestamp(111111);
mikhal@webrtc.orgbda7f302013-03-15 23:21:52 +0000151
nissef54573b2017-09-13 07:13:57 -0700152 // Used for NACK processing.
153 // TODO(nisse): Unclear on which side? It's confusing to use a
154 // single rtp_rtcp module for both send and receive side.
155 rtp_rtcp_module_->SetRemoteSSRC(kTestSsrc);
mikhal@webrtc.orgbda7f302013-03-15 23:21:52 +0000156
Shao Changbine62202f2015-04-21 20:24:50 +0800157 rtp_rtcp_module_->SetRtxSendPayloadType(kRtxPayloadType, kPayloadType);
Niels Möller5fe95102019-03-04 16:49:25 +0100158 transport_.SetSendModule(rtp_rtcp_module_.get());
nissef54573b2017-09-13 07:13:57 -0700159 media_receiver_ = transport_.stream_receiver_controller_.CreateReceiver(
160 kTestSsrc, &media_stream_);
mikhal@webrtc.orgbda7f302013-03-15 23:21:52 +0000161
Danil Chapovalov51bf2002019-10-11 10:53:27 +0200162 for (size_t n = 0; n < sizeof(payload_data); n++) {
mikhal@webrtc.orgbda7f302013-03-15 23:21:52 +0000163 payload_data[n] = n % 10;
164 }
165 }
166
mikhal@webrtc.org6cfa3902013-05-15 20:17:43 +0000167 int BuildNackList(uint16_t* nack_list) {
nissef54573b2017-09-13 07:13:57 -0700168 media_stream_.sequence_numbers_.sort();
mikhal@webrtc.org6cfa3902013-05-15 20:17:43 +0000169 std::list<uint16_t> missing_sequence_numbers;
nissef54573b2017-09-13 07:13:57 -0700170 std::list<uint16_t>::iterator it = media_stream_.sequence_numbers_.begin();
mikhal@webrtc.org6cfa3902013-05-15 20:17:43 +0000171
nissef54573b2017-09-13 07:13:57 -0700172 while (it != media_stream_.sequence_numbers_.end()) {
mikhal@webrtc.org6cfa3902013-05-15 20:17:43 +0000173 uint16_t sequence_number_1 = *it;
174 ++it;
nissef54573b2017-09-13 07:13:57 -0700175 if (it != media_stream_.sequence_numbers_.end()) {
mikhal@webrtc.org6cfa3902013-05-15 20:17:43 +0000176 uint16_t sequence_number_2 = *it;
177 // Add all missing sequence numbers to list
danilchap162abd32015-12-10 02:39:40 -0800178 for (uint16_t i = sequence_number_1 + 1; i < sequence_number_2; ++i) {
mikhal@webrtc.org6cfa3902013-05-15 20:17:43 +0000179 missing_sequence_numbers.push_back(i);
180 }
181 }
182 }
183 int n = 0;
184 for (it = missing_sequence_numbers.begin();
danilchap162abd32015-12-10 02:39:40 -0800185 it != missing_sequence_numbers.end(); ++it) {
mikhal@webrtc.org6cfa3902013-05-15 20:17:43 +0000186 nack_list[n++] = (*it);
187 }
188 return n;
189 }
190
191 bool ExpectedPacketsReceived() {
192 std::list<uint16_t> received_sorted;
Steve Anton91c26062019-03-28 10:56:11 -0700193 absl::c_copy(media_stream_.sequence_numbers_,
194 std::back_inserter(received_sorted));
mikhal@webrtc.org6cfa3902013-05-15 20:17:43 +0000195 received_sorted.sort();
Steve Anton91c26062019-03-28 10:56:11 -0700196 return absl::c_equal(received_sorted,
197 transport_.expected_sequence_numbers_);
mikhal@webrtc.org6cfa3902013-05-15 20:17:43 +0000198 }
199
200 void RunRtxTest(RtxMode rtx_method, int loss) {
nissef54573b2017-09-13 07:13:57 -0700201 rtx_receiver_ = transport_.stream_receiver_controller_.CreateReceiver(
202 kTestRtxSsrc, &rtx_stream_);
pbos@webrtc.org0b0c2412015-01-13 14:15:15 +0000203 rtp_rtcp_module_->SetRtxSendStatus(rtx_method);
mikhal@webrtc.org6cfa3902013-05-15 20:17:43 +0000204 transport_.DropEveryNthPacket(loss);
205 uint32_t timestamp = 3000;
206 uint16_t nack_list[kVideoNackListSize];
207 for (int frame = 0; frame < kNumFrames; ++frame) {
Sami Kalliomäki426a80c2018-08-08 11:37:59 +0200208 RTPVideoHeader video_header;
Niels Möller5fe95102019-03-04 16:49:25 +0100209 EXPECT_TRUE(rtp_rtcp_module_->OnSendingRtpFrame(timestamp, timestamp / 90,
210 kPayloadType, false));
Danil Chapovalov51bf2002019-10-11 10:53:27 +0200211 video_header.frame_type = VideoFrameType::kVideoFrameDelta;
Niels Möller5fe95102019-03-04 16:49:25 +0100212 EXPECT_TRUE(rtp_sender_video_->SendVideo(
Danil Chapovalov51bf2002019-10-11 10:53:27 +0200213 kPayloadType, VideoCodecType::kVideoCodecGeneric, timestamp,
214 timestamp / 90, payload_data, nullptr, video_header, 0));
sprang@webrtc.org43c88392015-01-29 09:09:17 +0000215 // Min required delay until retransmit = 5 + RTT ms (RTT = 0).
216 fake_clock.AdvanceTimeMilliseconds(5);
mikhal@webrtc.org6cfa3902013-05-15 20:17:43 +0000217 int length = BuildNackList(nack_list);
218 if (length > 0)
219 rtp_rtcp_module_->SendNACK(nack_list, length);
sprang@webrtc.org43c88392015-01-29 09:09:17 +0000220 fake_clock.AdvanceTimeMilliseconds(28); // 33ms - 5ms delay.
mikhal@webrtc.org6cfa3902013-05-15 20:17:43 +0000221 rtp_rtcp_module_->Process();
222 // Prepare next frame.
223 timestamp += 3000;
224 }
nissef54573b2017-09-13 07:13:57 -0700225 media_stream_.sequence_numbers_.sort();
mikhal@webrtc.org6cfa3902013-05-15 20:17:43 +0000226 }
227
kwiberg84be5112016-04-27 01:19:58 -0700228 std::unique_ptr<ReceiveStatistics> receive_statistics_;
Niels Möller5fe95102019-03-04 16:49:25 +0100229 std::unique_ptr<RtpRtcp> rtp_rtcp_module_;
230 PlayoutDelayOracle playout_delay_oracle_;
231 std::unique_ptr<RTPSenderVideo> rtp_sender_video_;
mikhal@webrtc.orgbda7f302013-03-15 23:21:52 +0000232 RtxLoopBackTransport transport_;
Yves Gerey665174f2018-06-19 15:03:05 +0200233 const std::map<int, int> rtx_associated_payload_types_ = {
234 {kRtxPayloadType, kPayloadType}};
nissef54573b2017-09-13 07:13:57 -0700235 VerifyingMediaStream media_stream_;
236 RtxReceiveStream rtx_stream_;
danilchap162abd32015-12-10 02:39:40 -0800237 uint8_t payload_data[65000];
mikhal@webrtc.orgbda7f302013-03-15 23:21:52 +0000238 SimulatedClock fake_clock;
Erik Språng737336d2016-07-29 12:59:36 +0200239 RateLimiter retransmission_rate_limiter_;
nissef54573b2017-09-13 07:13:57 -0700240 std::unique_ptr<RtpStreamReceiverInterface> media_receiver_;
241 std::unique_ptr<RtpStreamReceiverInterface> rtx_receiver_;
mikhal@webrtc.orgbda7f302013-03-15 23:21:52 +0000242};
243
mikhal@webrtc.org6cfa3902013-05-15 20:17:43 +0000244TEST_F(RtpRtcpRtxNackTest, LongNackList) {
245 const int kNumPacketsToDrop = 900;
246 const int kNumRequiredRtcp = 4;
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000247 uint32_t timestamp = 3000;
mikhal@webrtc.org6cfa3902013-05-15 20:17:43 +0000248 uint16_t nack_list[kNumPacketsToDrop];
249 // Disable StorePackets to be able to set a larger packet history.
pbos@webrtc.orgd16e8392014-12-19 13:49:55 +0000250 rtp_rtcp_module_->SetStorePacketsStatus(false, 0);
mikhal@webrtc.org6cfa3902013-05-15 20:17:43 +0000251 // Enable StorePackets with a packet history of 2000 packets.
pbos@webrtc.orgd16e8392014-12-19 13:49:55 +0000252 rtp_rtcp_module_->SetStorePacketsStatus(true, 2000);
mikhal@webrtc.org6cfa3902013-05-15 20:17:43 +0000253 // Drop 900 packets from the second one so that we get a NACK list which is
254 // big enough to require 4 RTCP packets to be fully transmitted to the sender.
255 transport_.DropConsecutivePackets(2, kNumPacketsToDrop);
256 // Send 30 frames which at the default size is roughly what we need to get
257 // enough packets.
258 for (int frame = 0; frame < kNumFrames; ++frame) {
Sami Kalliomäki426a80c2018-08-08 11:37:59 +0200259 RTPVideoHeader video_header;
Niels Möller5fe95102019-03-04 16:49:25 +0100260 EXPECT_TRUE(rtp_rtcp_module_->OnSendingRtpFrame(timestamp, timestamp / 90,
261 kPayloadType, false));
Danil Chapovalov51bf2002019-10-11 10:53:27 +0200262 video_header.frame_type = VideoFrameType::kVideoFrameDelta;
Niels Möller5fe95102019-03-04 16:49:25 +0100263 EXPECT_TRUE(rtp_sender_video_->SendVideo(
Danil Chapovalov51bf2002019-10-11 10:53:27 +0200264 kPayloadType, VideoCodecType::kVideoCodecGeneric, timestamp,
265 timestamp / 90, payload_data, nullptr, video_header, 0));
mikhal@webrtc.orgbda7f302013-03-15 23:21:52 +0000266 // Prepare next frame.
267 timestamp += 3000;
mikhal@webrtc.org6cfa3902013-05-15 20:17:43 +0000268 fake_clock.AdvanceTimeMilliseconds(33);
269 rtp_rtcp_module_->Process();
mikhal@webrtc.orgbda7f302013-03-15 23:21:52 +0000270 }
mikhal@webrtc.org6cfa3902013-05-15 20:17:43 +0000271 EXPECT_FALSE(transport_.expected_sequence_numbers_.empty());
nissef54573b2017-09-13 07:13:57 -0700272 EXPECT_FALSE(media_stream_.sequence_numbers_.empty());
273 size_t last_receive_count = media_stream_.sequence_numbers_.size();
mikhal@webrtc.org6cfa3902013-05-15 20:17:43 +0000274 int length = BuildNackList(nack_list);
275 for (int i = 0; i < kNumRequiredRtcp - 1; ++i) {
276 rtp_rtcp_module_->SendNACK(nack_list, length);
nissef54573b2017-09-13 07:13:57 -0700277 EXPECT_GT(media_stream_.sequence_numbers_.size(), last_receive_count);
278 last_receive_count = media_stream_.sequence_numbers_.size();
mikhal@webrtc.org6cfa3902013-05-15 20:17:43 +0000279 EXPECT_FALSE(ExpectedPacketsReceived());
280 }
281 rtp_rtcp_module_->SendNACK(nack_list, length);
nissef54573b2017-09-13 07:13:57 -0700282 EXPECT_GT(media_stream_.sequence_numbers_.size(), last_receive_count);
mikhal@webrtc.org6cfa3902013-05-15 20:17:43 +0000283 EXPECT_TRUE(ExpectedPacketsReceived());
mikhal@webrtc.orgbda7f302013-03-15 23:21:52 +0000284}
285
mikhal@webrtc.org6cfa3902013-05-15 20:17:43 +0000286TEST_F(RtpRtcpRtxNackTest, RtxNack) {
287 RunRtxTest(kRtxRetransmitted, 10);
nissef54573b2017-09-13 07:13:57 -0700288 EXPECT_EQ(kTestSequenceNumber, *(media_stream_.sequence_numbers_.begin()));
mikhal@webrtc.orgbda7f302013-03-15 23:21:52 +0000289 EXPECT_EQ(kTestSequenceNumber + kTestNumberOfPackets - 1,
nissef54573b2017-09-13 07:13:57 -0700290 *(media_stream_.sequence_numbers_.rbegin()));
291 EXPECT_EQ(kTestNumberOfPackets, media_stream_.sequence_numbers_.size());
mikhal@webrtc.orgbda7f302013-03-15 23:21:52 +0000292 EXPECT_EQ(kTestNumberOfRtxPackets, transport_.count_rtx_ssrc_);
mikhal@webrtc.org6cfa3902013-05-15 20:17:43 +0000293 EXPECT_TRUE(ExpectedPacketsReceived());
mikhal@webrtc.orgbda7f302013-03-15 23:21:52 +0000294}
danilchap6a6f0892015-12-10 12:39:08 -0800295
296} // namespace webrtc