2013-10-23 13:58:31 +00:00
|
|
|
/*
|
|
|
|
|
* Copyright (c) 2013 The WebRTC project authors. All Rights Reserved.
|
|
|
|
|
*
|
|
|
|
|
* Use of this source code is governed by a BSD-style license
|
|
|
|
|
* that can be found in the LICENSE file in the root of the source
|
|
|
|
|
* tree. An additional intellectual property rights grant can be found
|
|
|
|
|
* in the file PATENTS. All contributing project authors may
|
|
|
|
|
* be found in the AUTHORS file in the root of the source tree.
|
|
|
|
|
*/
|
|
|
|
|
|
2015-12-10 05:05:27 -08:00
|
|
|
#include <map>
|
2016-04-27 01:19:58 -07:00
|
|
|
#include <memory>
|
2015-12-10 05:05:27 -08:00
|
|
|
#include <set>
|
|
|
|
|
|
2019-03-04 16:49:25 +01:00
|
|
|
#include "absl/memory/memory.h"
|
|
|
|
|
#include "api/transport/field_trial_based_config.h"
|
2018-06-08 14:03:44 +02:00
|
|
|
#include "api/video_codecs/video_codec.h"
|
2017-09-15 06:47:31 +02:00
|
|
|
#include "modules/rtp_rtcp/include/rtp_header_parser.h"
|
|
|
|
|
#include "modules/rtp_rtcp/include/rtp_rtcp_defines.h"
|
2019-03-04 16:49:25 +01:00
|
|
|
#include "modules/rtp_rtcp/source/playout_delay_oracle.h"
|
2017-09-15 06:47:31 +02:00
|
|
|
#include "modules/rtp_rtcp/source/rtcp_packet.h"
|
|
|
|
|
#include "modules/rtp_rtcp/source/rtcp_packet/nack.h"
|
2018-09-14 08:26:32 +02:00
|
|
|
#include "modules/rtp_rtcp/source/rtp_packet_received.h"
|
2017-09-15 06:47:31 +02:00
|
|
|
#include "modules/rtp_rtcp/source/rtp_rtcp_impl.h"
|
2019-03-06 16:47:29 +01:00
|
|
|
#include "modules/rtp_rtcp/source/rtp_sender_video.h"
|
2017-09-15 06:47:31 +02:00
|
|
|
#include "rtc_base/rate_limiter.h"
|
|
|
|
|
#include "test/gmock.h"
|
|
|
|
|
#include "test/gtest.h"
|
|
|
|
|
#include "test/rtcp_packet_parser.h"
|
2014-06-17 17:32:05 +00:00
|
|
|
|
|
|
|
|
using ::testing::_;
|
2014-10-29 12:42:30 +00:00
|
|
|
using ::testing::ElementsAre;
|
2014-06-17 17:32:05 +00:00
|
|
|
using ::testing::NiceMock;
|
|
|
|
|
using ::testing::Return;
|
|
|
|
|
using ::testing::SaveArg;
|
2013-10-23 13:58:31 +00:00
|
|
|
|
|
|
|
|
namespace webrtc {
|
|
|
|
|
namespace {
|
2014-01-24 13:23:49 +00:00
|
|
|
const uint32_t kSenderSsrc = 0x12345;
|
|
|
|
|
const uint32_t kReceiverSsrc = 0x23456;
|
2015-01-12 21:51:21 +00:00
|
|
|
const int64_t kOneWayNetworkDelayMs = 100;
|
2014-08-04 11:59:42 +00:00
|
|
|
const uint8_t kBaseLayerTid = 0;
|
|
|
|
|
const uint8_t kHigherLayerTid = 1;
|
|
|
|
|
const uint16_t kSequenceNumber = 100;
|
2013-10-23 13:58:31 +00:00
|
|
|
|
2013-11-20 12:46:11 +00:00
|
|
|
class RtcpRttStatsTestImpl : public RtcpRttStats {
|
2013-10-31 12:14:34 +00:00
|
|
|
public:
|
|
|
|
|
RtcpRttStatsTestImpl() : rtt_ms_(0) {}
|
2018-03-09 15:37:03 +00:00
|
|
|
~RtcpRttStatsTestImpl() override = default;
|
2013-10-31 12:14:34 +00:00
|
|
|
|
2015-03-04 12:58:35 +00:00
|
|
|
void OnRttUpdate(int64_t rtt_ms) override { rtt_ms_ = rtt_ms; }
|
|
|
|
|
int64_t LastProcessedRtt() const override { return rtt_ms_; }
|
2015-01-12 21:51:21 +00:00
|
|
|
int64_t rtt_ms_;
|
2013-10-31 12:14:34 +00:00
|
|
|
};
|
|
|
|
|
|
2018-11-13 10:08:33 +01:00
|
|
|
class SendTransport : public Transport {
|
2013-10-23 13:58:31 +00:00
|
|
|
public:
|
2014-08-04 11:59:42 +00:00
|
|
|
SendTransport()
|
2017-07-06 04:38:06 -07:00
|
|
|
: receiver_(nullptr),
|
|
|
|
|
clock_(nullptr),
|
2014-08-04 11:59:42 +00:00
|
|
|
delay_ms_(0),
|
2017-07-06 04:38:06 -07:00
|
|
|
rtp_packets_sent_(0),
|
2019-03-04 18:59:32 +01:00
|
|
|
rtcp_packets_sent_(0) {}
|
2013-10-23 13:58:31 +00:00
|
|
|
|
2014-01-24 13:23:49 +00:00
|
|
|
void SetRtpRtcpModule(ModuleRtpRtcpImpl* receiver) { receiver_ = receiver; }
|
2015-01-12 21:51:21 +00:00
|
|
|
void SimulateNetworkDelay(int64_t delay_ms, SimulatedClock* clock) {
|
2013-10-23 13:58:31 +00:00
|
|
|
clock_ = clock;
|
|
|
|
|
delay_ms_ = delay_ms;
|
|
|
|
|
}
|
2015-10-02 03:39:33 -07:00
|
|
|
bool SendRtp(const uint8_t* data,
|
|
|
|
|
size_t len,
|
|
|
|
|
const PacketOptions& options) override {
|
2014-08-04 11:59:42 +00:00
|
|
|
RTPHeader header;
|
2016-04-27 01:19:58 -07:00
|
|
|
std::unique_ptr<RtpHeaderParser> parser(RtpHeaderParser::Create());
|
Use size_t more consistently for packet/payload lengths.
See design doc at https://docs.google.com/a/chromium.org/document/d/1I6nmE9D_BmCY-IoV6MDPY2V6WYpEI-dg2apWXTfZyUI/edit?usp=sharing for more information.
This CL was reviewed and approved in pieces in the following CLs:
https://webrtc-codereview.appspot.com/24209004/
https://webrtc-codereview.appspot.com/24229004/
https://webrtc-codereview.appspot.com/24259004/
https://webrtc-codereview.appspot.com/25109004/
https://webrtc-codereview.appspot.com/26099004/
https://webrtc-codereview.appspot.com/27069004/
https://webrtc-codereview.appspot.com/27969004/
https://webrtc-codereview.appspot.com/27989004/
https://webrtc-codereview.appspot.com/29009004/
https://webrtc-codereview.appspot.com/30929004/
https://webrtc-codereview.appspot.com/30939004/
https://webrtc-codereview.appspot.com/31999004/
Committing as TBR to the original reviewers.
BUG=chromium:81439
TEST=none
TBR=pthatcher,henrik.lundin,tina.legrand,stefan,tkchin,glaznev,kjellander,perkj,mflodman,henrika,asapersson,niklas.enbom
Review URL: https://webrtc-codereview.appspot.com/23129004
git-svn-id: http://webrtc.googlecode.com/svn/trunk@7726 4adac7df-926f-26a2-2b94-8c16560cd09d
2014-11-20 22:28:14 +00:00
|
|
|
EXPECT_TRUE(parser->Parse(static_cast<const uint8_t*>(data), len, &header));
|
2014-08-04 11:59:42 +00:00
|
|
|
++rtp_packets_sent_;
|
|
|
|
|
last_rtp_header_ = header;
|
2015-09-28 09:59:31 -07:00
|
|
|
return true;
|
2013-10-23 13:58:31 +00:00
|
|
|
}
|
2015-09-28 09:59:31 -07:00
|
|
|
bool SendRtcp(const uint8_t* data, size_t len) override {
|
2014-10-29 12:42:30 +00:00
|
|
|
test::RtcpPacketParser parser;
|
2016-09-02 18:29:10 +02:00
|
|
|
parser.Parse(data, len);
|
|
|
|
|
last_nack_list_ = parser.nack()->packet_ids();
|
2014-10-29 12:42:30 +00:00
|
|
|
|
2013-10-23 13:58:31 +00:00
|
|
|
if (clock_) {
|
|
|
|
|
clock_->AdvanceTimeMilliseconds(delay_ms_);
|
|
|
|
|
}
|
2016-09-02 18:29:10 +02:00
|
|
|
EXPECT_TRUE(receiver_);
|
2017-09-13 07:53:37 -07:00
|
|
|
receiver_->IncomingRtcpPacket(data, len);
|
2018-01-31 22:08:26 -08:00
|
|
|
++rtcp_packets_sent_;
|
2015-09-28 09:59:31 -07:00
|
|
|
return true;
|
2013-10-23 13:58:31 +00:00
|
|
|
}
|
2018-01-31 22:08:26 -08:00
|
|
|
size_t NumRtcpSent() { return rtcp_packets_sent_; }
|
2014-01-24 13:23:49 +00:00
|
|
|
ModuleRtpRtcpImpl* receiver_;
|
2013-10-23 13:58:31 +00:00
|
|
|
SimulatedClock* clock_;
|
2015-01-12 21:51:21 +00:00
|
|
|
int64_t delay_ms_;
|
2014-08-04 11:59:42 +00:00
|
|
|
int rtp_packets_sent_;
|
2018-01-31 22:08:26 -08:00
|
|
|
size_t rtcp_packets_sent_;
|
2014-08-04 11:59:42 +00:00
|
|
|
RTPHeader last_rtp_header_;
|
2014-10-29 12:42:30 +00:00
|
|
|
std::vector<uint16_t> last_nack_list_;
|
2014-01-24 13:23:49 +00:00
|
|
|
};
|
|
|
|
|
|
2015-02-19 12:47:00 +00:00
|
|
|
class RtpRtcpModule : public RtcpPacketTypeCounterObserver {
|
2014-01-24 13:23:49 +00:00
|
|
|
public:
|
2015-12-15 02:54:47 -08:00
|
|
|
explicit RtpRtcpModule(SimulatedClock* clock)
|
2016-07-13 09:11:28 -07:00
|
|
|
: receive_statistics_(ReceiveStatistics::Create(clock)),
|
|
|
|
|
remote_ssrc_(0),
|
2017-07-06 04:38:06 -07:00
|
|
|
clock_(clock) {
|
|
|
|
|
CreateModuleImpl();
|
2014-01-24 13:23:49 +00:00
|
|
|
transport_.SimulateNetworkDelay(kOneWayNetworkDelayMs, clock);
|
|
|
|
|
}
|
2014-02-19 11:59:02 +00:00
|
|
|
|
|
|
|
|
RtcpPacketTypeCounter packets_sent_;
|
|
|
|
|
RtcpPacketTypeCounter packets_received_;
|
2016-04-27 01:19:58 -07:00
|
|
|
std::unique_ptr<ReceiveStatistics> receive_statistics_;
|
2014-01-24 13:23:49 +00:00
|
|
|
SendTransport transport_;
|
|
|
|
|
RtcpRttStatsTestImpl rtt_stats_;
|
2016-04-27 01:19:58 -07:00
|
|
|
std::unique_ptr<ModuleRtpRtcpImpl> impl_;
|
2015-02-19 12:47:00 +00:00
|
|
|
uint32_t remote_ssrc_;
|
2018-11-15 16:44:37 -08:00
|
|
|
int rtcp_report_interval_ms_ = 0;
|
2015-02-19 12:47:00 +00:00
|
|
|
|
|
|
|
|
void SetRemoteSsrc(uint32_t ssrc) {
|
|
|
|
|
remote_ssrc_ = ssrc;
|
|
|
|
|
impl_->SetRemoteSSRC(ssrc);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void RtcpPacketTypesCounterUpdated(
|
|
|
|
|
uint32_t ssrc,
|
|
|
|
|
const RtcpPacketTypeCounter& packet_counter) override {
|
|
|
|
|
counter_map_[ssrc] = packet_counter;
|
|
|
|
|
}
|
2014-02-19 11:59:02 +00:00
|
|
|
|
|
|
|
|
RtcpPacketTypeCounter RtcpSent() {
|
2015-02-19 12:47:00 +00:00
|
|
|
// RTCP counters for remote SSRC.
|
|
|
|
|
return counter_map_[remote_ssrc_];
|
2014-02-19 11:59:02 +00:00
|
|
|
}
|
2015-02-19 12:47:00 +00:00
|
|
|
|
2014-02-19 11:59:02 +00:00
|
|
|
RtcpPacketTypeCounter RtcpReceived() {
|
2015-02-19 12:47:00 +00:00
|
|
|
// Received RTCP stats for (own) local SSRC.
|
|
|
|
|
return counter_map_[impl_->SSRC()];
|
2014-02-19 11:59:02 +00:00
|
|
|
}
|
2014-08-04 11:59:42 +00:00
|
|
|
int RtpSent() { return transport_.rtp_packets_sent_; }
|
|
|
|
|
uint16_t LastRtpSequenceNumber() {
|
|
|
|
|
return transport_.last_rtp_header_.sequenceNumber;
|
|
|
|
|
}
|
2014-10-29 12:42:30 +00:00
|
|
|
std::vector<uint16_t> LastNackListSent() {
|
|
|
|
|
return transport_.last_nack_list_;
|
|
|
|
|
}
|
2018-11-15 16:44:37 -08:00
|
|
|
void SetRtcpReportIntervalAndReset(int rtcp_report_interval_ms) {
|
|
|
|
|
rtcp_report_interval_ms_ = rtcp_report_interval_ms;
|
2018-01-31 22:08:26 -08:00
|
|
|
CreateModuleImpl();
|
|
|
|
|
}
|
2015-02-19 12:47:00 +00:00
|
|
|
|
|
|
|
|
private:
|
2017-07-06 04:38:06 -07:00
|
|
|
void CreateModuleImpl() {
|
|
|
|
|
RtpRtcp::Configuration config;
|
|
|
|
|
config.audio = false;
|
|
|
|
|
config.clock = clock_;
|
|
|
|
|
config.outgoing_transport = &transport_;
|
|
|
|
|
config.receive_statistics = receive_statistics_.get();
|
|
|
|
|
config.rtcp_packet_type_counter_observer = this;
|
|
|
|
|
config.rtt_stats = &rtt_stats_;
|
2018-11-15 16:44:37 -08:00
|
|
|
config.rtcp_report_interval_ms = rtcp_report_interval_ms_;
|
2017-07-06 04:38:06 -07:00
|
|
|
|
|
|
|
|
impl_.reset(new ModuleRtpRtcpImpl(config));
|
|
|
|
|
impl_->SetRTCPStatus(RtcpMode::kCompound);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
SimulatedClock* const clock_;
|
2015-02-19 12:47:00 +00:00
|
|
|
std::map<uint32_t, RtcpPacketTypeCounter> counter_map_;
|
2013-10-23 13:58:31 +00:00
|
|
|
};
|
|
|
|
|
} // namespace
|
|
|
|
|
|
|
|
|
|
class RtpRtcpImplTest : public ::testing::Test {
|
|
|
|
|
protected:
|
|
|
|
|
RtpRtcpImplTest()
|
2017-07-06 04:38:06 -07:00
|
|
|
: clock_(133590000000000), sender_(&clock_), receiver_(&clock_) {}
|
|
|
|
|
|
|
|
|
|
void SetUp() override {
|
2014-01-24 13:23:49 +00:00
|
|
|
// Send module.
|
Reland of Delete class SSRCDatabase, and its global ssrc registry. (patchset #1 id:1 of https://codereview.webrtc.org/2700413002/ )
Reason for revert:
Intend to fix perf problem and reland.
Original issue's description:
> Revert of Delete class SSRCDatabase, and its global ssrc registry. (patchset #20 id:370001 of https://codereview.webrtc.org/2644303002/ )
>
> Reason for revert:
> Breaks webrtc_perf_tests reliably:
> https://build.chromium.org/p/client.webrtc.perf/builders/Android32%20Tests%20%28L%20Nexus5%29/builds/1780
> https://build.chromium.org/p/client.webrtc.perf/builders/Android32%20Tests%20%28L%20Nexus4%29/builds/178
>
> We're actively working on getting a quick version of webrtc_perf_tests up on the trybots again to prevent breakages like this: https://bugs.chromium.org/p/webrtc/issues/detail?id=7101
>
> Original issue's description:
> > Delete class SSRCDatabase, and its global ssrc registry,
> > and the method RTPSender::GenerateNewSSRC.
> >
> > It's now mandatory for higher layers to call SetSSRC, RTPSender
> > no longer allocates any ssrc by default.
> >
> > BUG=webrtc:4306,webrtc:6887
> >
> > Review-Url: https://codereview.webrtc.org/2644303002
> > Cr-Commit-Position: refs/heads/master@{#16670}
> > Committed: https://chromium.googlesource.com/external/webrtc/+/b78d4d13835f628e722a57abae2bf06ba3655921
>
> TBR=solenberg@webrtc.org,stefan@webrtc.org,danilchap@webrtc.org,ivoc@webrtc.org,nisse@webrtc.org
> NOTRY=True
> BUG=webrtc:4306,webrtc:6887
>
> Review-Url: https://codereview.webrtc.org/2700413002
> Cr-Commit-Position: refs/heads/master@{#16693}
> Committed: https://chromium.googlesource.com/external/webrtc/+/b5848ecbf5f7b310108546ec6b858fe93452f58e
TBR=solenberg@webrtc.org,stefan@webrtc.org,danilchap@webrtc.org,ivoc@webrtc.org,kjellander@webrtc.org,kjellander@google.com
# Not skipping CQ checks because original CL landed more than 1 days ago.
BUG=webrtc:4306,webrtc:6887
Review-Url: https://codereview.webrtc.org/2702203002
Cr-Commit-Position: refs/heads/master@{#16737}
2017-02-21 03:40:24 -08:00
|
|
|
sender_.impl_->SetSSRC(kSenderSsrc);
|
2014-01-24 13:23:49 +00:00
|
|
|
EXPECT_EQ(0, sender_.impl_->SetSendingStatus(true));
|
2014-12-19 13:49:55 +00:00
|
|
|
sender_.impl_->SetSendingMediaStatus(true);
|
2015-02-19 12:47:00 +00:00
|
|
|
sender_.SetRemoteSsrc(kReceiverSsrc);
|
2014-08-04 11:59:42 +00:00
|
|
|
sender_.impl_->SetSequenceNumber(kSequenceNumber);
|
|
|
|
|
sender_.impl_->SetStorePacketsStatus(true, 100);
|
|
|
|
|
|
2019-03-04 16:49:25 +01:00
|
|
|
sender_video_ = absl::make_unique<RTPSenderVideo>(
|
|
|
|
|
&clock_, sender_.impl_->RtpSender(), nullptr, &playout_delay_oracle_,
|
2019-05-24 13:50:56 +02:00
|
|
|
nullptr, false, false, FieldTrialBasedConfig());
|
2019-03-04 16:49:25 +01:00
|
|
|
|
2014-08-04 11:59:42 +00:00
|
|
|
memset(&codec_, 0, sizeof(VideoCodec));
|
|
|
|
|
codec_.plType = 100;
|
|
|
|
|
codec_.width = 320;
|
|
|
|
|
codec_.height = 180;
|
2019-05-23 13:21:12 +02:00
|
|
|
sender_video_->RegisterPayloadType(codec_.plType, "VP8",
|
|
|
|
|
/*raw_payload=*/false);
|
2014-08-04 11:59:42 +00:00
|
|
|
|
2014-01-24 13:23:49 +00:00
|
|
|
// Receive module.
|
|
|
|
|
EXPECT_EQ(0, receiver_.impl_->SetSendingStatus(false));
|
2014-12-19 13:49:55 +00:00
|
|
|
receiver_.impl_->SetSendingMediaStatus(false);
|
2014-06-05 08:25:29 +00:00
|
|
|
receiver_.impl_->SetSSRC(kReceiverSsrc);
|
2015-02-19 12:47:00 +00:00
|
|
|
receiver_.SetRemoteSsrc(kSenderSsrc);
|
2014-01-24 13:23:49 +00:00
|
|
|
// Transport settings.
|
|
|
|
|
sender_.transport_.SetRtpRtcpModule(receiver_.impl_.get());
|
|
|
|
|
receiver_.transport_.SetRtpRtcpModule(sender_.impl_.get());
|
2013-10-23 13:58:31 +00:00
|
|
|
}
|
2017-07-06 04:38:06 -07:00
|
|
|
|
2013-10-23 13:58:31 +00:00
|
|
|
SimulatedClock clock_;
|
2014-01-24 13:23:49 +00:00
|
|
|
RtpRtcpModule sender_;
|
2019-03-04 16:49:25 +01:00
|
|
|
PlayoutDelayOracle playout_delay_oracle_;
|
|
|
|
|
std::unique_ptr<RTPSenderVideo> sender_video_;
|
2014-01-24 13:23:49 +00:00
|
|
|
RtpRtcpModule receiver_;
|
2014-08-04 11:59:42 +00:00
|
|
|
VideoCodec codec_;
|
|
|
|
|
|
2019-03-04 16:49:25 +01:00
|
|
|
void SendFrame(const RtpRtcpModule* module,
|
|
|
|
|
RTPSenderVideo* sender,
|
|
|
|
|
uint8_t tid) {
|
2014-08-04 11:59:42 +00:00
|
|
|
RTPVideoHeaderVP8 vp8_header = {};
|
|
|
|
|
vp8_header.temporalIdx = tid;
|
2017-01-10 04:21:35 -08:00
|
|
|
RTPVideoHeader rtp_video_header;
|
|
|
|
|
rtp_video_header.width = codec_.width;
|
|
|
|
|
rtp_video_header.height = codec_.height;
|
|
|
|
|
rtp_video_header.rotation = kVideoRotation_0;
|
2017-04-11 10:34:31 -07:00
|
|
|
rtp_video_header.content_type = VideoContentType::UNSPECIFIED;
|
2017-01-10 04:21:35 -08:00
|
|
|
rtp_video_header.playout_delay = {-1, -1};
|
|
|
|
|
rtp_video_header.is_first_packet_in_frame = true;
|
|
|
|
|
rtp_video_header.simulcastIdx = 0;
|
2018-06-04 11:14:38 +02:00
|
|
|
rtp_video_header.codec = kVideoCodecVP8;
|
Reland "Remove RTPVideoHeader::vp8() accessors."
This reverts commit 1811c04f22a26da3ed2832373a5c92a9786420c3.
Reason for revert: Downstream projects fixed.
Original change's description:
> Revert "Remove RTPVideoHeader::vp8() accessors."
>
> This reverts commit af7afc66427b0e9109e7d492f2805d63d239b914.
>
> Reason for revert: Break downstream projects.
>
> Original change's description:
> > Remove RTPVideoHeader::vp8() accessors.
> >
> > Bug: none
> > Change-Id: Ia7d65148fb36a8f26647bee8a876ce7217ff8a68
> > Reviewed-on: https://webrtc-review.googlesource.com/93321
> > Reviewed-by: Niels Moller <nisse@webrtc.org>
> > Reviewed-by: Stefan Holmer <stefan@webrtc.org>
> > Reviewed-by: Danil Chapovalov <danilchap@webrtc.org>
> > Commit-Queue: Philip Eliasson <philipel@webrtc.org>
> > Cr-Commit-Position: refs/heads/master@{#24626}
>
> TBR=danilchap@webrtc.org,nisse@webrtc.org,sprang@webrtc.org,stefan@webrtc.org,philipel@webrtc.org,holmer@google.com
>
> Change-Id: I3f7f19c0ea810c0fd988c59e6556bbea9b756b33
> No-Presubmit: true
> No-Tree-Checks: true
> No-Try: true
> Bug: none
> Reviewed-on: https://webrtc-review.googlesource.com/98864
> Reviewed-by: Philip Eliasson <philipel@webrtc.org>
> Commit-Queue: Philip Eliasson <philipel@webrtc.org>
> Cr-Commit-Position: refs/heads/master@{#24628}
TBR=danilchap@webrtc.org,nisse@webrtc.org,sprang@webrtc.org,stefan@webrtc.org,philipel@webrtc.org,holmer@google.com
Change-Id: I9246f36e638108ae4fc46c1ae4559c8205d50fc1
No-Presubmit: true
No-Tree-Checks: true
No-Try: true
Bug: none
Reviewed-on: https://webrtc-review.googlesource.com/98841
Reviewed-by: Philip Eliasson <philipel@webrtc.org>
Commit-Queue: Philip Eliasson <philipel@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#24629}
2018-09-07 13:03:55 +00:00
|
|
|
rtp_video_header.video_type_header = vp8_header;
|
2017-06-19 07:18:55 -07:00
|
|
|
rtp_video_header.video_timing = {0u, 0u, 0u, 0u, 0u, 0u, false};
|
2014-08-04 11:59:42 +00:00
|
|
|
|
|
|
|
|
const uint8_t payload[100] = {0};
|
2019-03-04 16:49:25 +01:00
|
|
|
EXPECT_TRUE(module->impl_->OnSendingRtpFrame(0, 0, codec_.plType, true));
|
2019-03-21 15:43:58 +01:00
|
|
|
EXPECT_TRUE(sender->SendVideo(VideoFrameType::kVideoFrameKey, codec_.plType,
|
|
|
|
|
0, 0, payload, sizeof(payload), nullptr,
|
|
|
|
|
&rtp_video_header, 0));
|
2014-08-04 11:59:42 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void IncomingRtcpNack(const RtpRtcpModule* module, uint16_t sequence_number) {
|
2014-12-08 13:29:02 +00:00
|
|
|
bool sender = module->impl_->SSRC() == kSenderSsrc;
|
2014-08-04 11:59:42 +00:00
|
|
|
rtcp::Nack nack;
|
|
|
|
|
uint16_t list[1];
|
|
|
|
|
list[0] = sequence_number;
|
|
|
|
|
const uint16_t kListLength = sizeof(list) / sizeof(list[0]);
|
2016-09-27 09:27:47 -07:00
|
|
|
nack.SetSenderSsrc(sender ? kReceiverSsrc : kSenderSsrc);
|
|
|
|
|
nack.SetMediaSsrc(sender ? kSenderSsrc : kReceiverSsrc);
|
|
|
|
|
nack.SetPacketIds(list, kListLength);
|
2016-02-17 03:11:42 -08:00
|
|
|
rtc::Buffer packet = nack.Build();
|
2017-09-13 07:53:37 -07:00
|
|
|
module->impl_->IncomingRtcpPacket(packet.data(), packet.size());
|
2014-08-04 11:59:42 +00:00
|
|
|
}
|
2013-10-23 13:58:31 +00:00
|
|
|
};
|
|
|
|
|
|
2019-01-25 14:02:49 +01:00
|
|
|
TEST_F(RtpRtcpImplTest, RetransmitsAllLayers) {
|
2014-08-04 11:59:42 +00:00
|
|
|
// Send frames.
|
|
|
|
|
EXPECT_EQ(0, sender_.RtpSent());
|
2019-03-04 16:49:25 +01:00
|
|
|
SendFrame(&sender_, sender_video_.get(), kBaseLayerTid); // kSequenceNumber
|
|
|
|
|
SendFrame(&sender_, sender_video_.get(),
|
|
|
|
|
kHigherLayerTid); // kSequenceNumber + 1
|
|
|
|
|
SendFrame(&sender_, sender_video_.get(),
|
|
|
|
|
kNoTemporalIdx); // kSequenceNumber + 2
|
2014-08-04 11:59:42 +00:00
|
|
|
EXPECT_EQ(3, sender_.RtpSent());
|
|
|
|
|
EXPECT_EQ(kSequenceNumber + 2, sender_.LastRtpSequenceNumber());
|
|
|
|
|
|
2015-01-29 09:09:17 +00:00
|
|
|
// Min required delay until retransmit = 5 + RTT ms (RTT = 0).
|
|
|
|
|
clock_.AdvanceTimeMilliseconds(5);
|
|
|
|
|
|
2014-08-04 11:59:42 +00:00
|
|
|
// Frame with kBaseLayerTid re-sent.
|
|
|
|
|
IncomingRtcpNack(&sender_, kSequenceNumber);
|
|
|
|
|
EXPECT_EQ(4, sender_.RtpSent());
|
|
|
|
|
EXPECT_EQ(kSequenceNumber, sender_.LastRtpSequenceNumber());
|
|
|
|
|
// Frame with kHigherLayerTid re-sent.
|
|
|
|
|
IncomingRtcpNack(&sender_, kSequenceNumber + 1);
|
|
|
|
|
EXPECT_EQ(5, sender_.RtpSent());
|
|
|
|
|
EXPECT_EQ(kSequenceNumber + 1, sender_.LastRtpSequenceNumber());
|
|
|
|
|
// Frame with kNoTemporalIdx re-sent.
|
|
|
|
|
IncomingRtcpNack(&sender_, kSequenceNumber + 2);
|
|
|
|
|
EXPECT_EQ(6, sender_.RtpSent());
|
|
|
|
|
EXPECT_EQ(kSequenceNumber + 2, sender_.LastRtpSequenceNumber());
|
|
|
|
|
}
|
|
|
|
|
|
2013-10-23 13:58:31 +00:00
|
|
|
TEST_F(RtpRtcpImplTest, Rtt) {
|
2018-09-14 08:26:32 +02:00
|
|
|
RtpPacketReceived packet;
|
|
|
|
|
packet.SetTimestamp(1);
|
|
|
|
|
packet.SetSequenceNumber(123);
|
|
|
|
|
packet.SetSsrc(kSenderSsrc);
|
|
|
|
|
packet.AllocatePayload(100 - 12);
|
|
|
|
|
receiver_.receive_statistics_->OnRtpPacket(packet);
|
2013-10-23 13:58:31 +00:00
|
|
|
|
2016-07-20 15:26:59 +02:00
|
|
|
// Send Frame before sending an SR.
|
2019-03-04 16:49:25 +01:00
|
|
|
SendFrame(&sender_, sender_video_.get(), kBaseLayerTid);
|
2016-07-20 15:26:59 +02:00
|
|
|
// Sender module should send an SR.
|
2014-01-24 13:23:49 +00:00
|
|
|
EXPECT_EQ(0, sender_.impl_->SendRTCP(kRtcpReport));
|
2013-10-23 13:58:31 +00:00
|
|
|
|
2014-01-24 13:23:49 +00:00
|
|
|
// Receiver module should send a RR with a response to the last received SR.
|
2013-10-23 13:58:31 +00:00
|
|
|
clock_.AdvanceTimeMilliseconds(1000);
|
2014-01-24 13:23:49 +00:00
|
|
|
EXPECT_EQ(0, receiver_.impl_->SendRTCP(kRtcpReport));
|
2013-10-23 13:58:31 +00:00
|
|
|
|
|
|
|
|
// Verify RTT.
|
2015-01-12 21:51:21 +00:00
|
|
|
int64_t rtt;
|
|
|
|
|
int64_t avg_rtt;
|
|
|
|
|
int64_t min_rtt;
|
|
|
|
|
int64_t max_rtt;
|
2014-01-24 13:23:49 +00:00
|
|
|
EXPECT_EQ(
|
|
|
|
|
0, sender_.impl_->RTT(kReceiverSsrc, &rtt, &avg_rtt, &min_rtt, &max_rtt));
|
2016-02-22 18:59:36 +01:00
|
|
|
EXPECT_NEAR(2 * kOneWayNetworkDelayMs, rtt, 1);
|
|
|
|
|
EXPECT_NEAR(2 * kOneWayNetworkDelayMs, avg_rtt, 1);
|
|
|
|
|
EXPECT_NEAR(2 * kOneWayNetworkDelayMs, min_rtt, 1);
|
|
|
|
|
EXPECT_NEAR(2 * kOneWayNetworkDelayMs, max_rtt, 1);
|
2013-10-23 13:58:31 +00:00
|
|
|
|
|
|
|
|
// No RTT from other ssrc.
|
2014-01-24 13:23:49 +00:00
|
|
|
EXPECT_EQ(-1, sender_.impl_->RTT(kReceiverSsrc + 1, &rtt, &avg_rtt, &min_rtt,
|
|
|
|
|
&max_rtt));
|
2013-12-16 14:40:36 +00:00
|
|
|
|
|
|
|
|
// Verify RTT from rtt_stats config.
|
2015-01-12 21:51:21 +00:00
|
|
|
EXPECT_EQ(0, sender_.rtt_stats_.LastProcessedRtt());
|
|
|
|
|
EXPECT_EQ(0, sender_.impl_->rtt_ms());
|
2014-01-24 13:23:49 +00:00
|
|
|
sender_.impl_->Process();
|
2016-02-22 18:59:36 +01:00
|
|
|
EXPECT_NEAR(2 * kOneWayNetworkDelayMs, sender_.rtt_stats_.LastProcessedRtt(),
|
|
|
|
|
1);
|
|
|
|
|
EXPECT_NEAR(2 * kOneWayNetworkDelayMs, sender_.impl_->rtt_ms(), 1);
|
2013-10-23 13:58:31 +00:00
|
|
|
}
|
|
|
|
|
|
2013-11-21 08:57:04 +00:00
|
|
|
TEST_F(RtpRtcpImplTest, SetRtcpXrRrtrStatus) {
|
2014-01-24 13:23:49 +00:00
|
|
|
EXPECT_FALSE(receiver_.impl_->RtcpXrRrtrStatus());
|
|
|
|
|
receiver_.impl_->SetRtcpXrRrtrStatus(true);
|
|
|
|
|
EXPECT_TRUE(receiver_.impl_->RtcpXrRrtrStatus());
|
2013-11-21 08:57:04 +00:00
|
|
|
}
|
|
|
|
|
|
2013-10-31 12:14:34 +00:00
|
|
|
TEST_F(RtpRtcpImplTest, RttForReceiverOnly) {
|
2014-01-24 13:23:49 +00:00
|
|
|
receiver_.impl_->SetRtcpXrRrtrStatus(true);
|
2013-10-31 12:14:34 +00:00
|
|
|
|
2014-01-24 13:23:49 +00:00
|
|
|
// Receiver module should send a Receiver time reference report (RTRR).
|
|
|
|
|
EXPECT_EQ(0, receiver_.impl_->SendRTCP(kRtcpReport));
|
2013-10-31 12:14:34 +00:00
|
|
|
|
2014-01-24 13:23:49 +00:00
|
|
|
// Sender module should send a response to the last received RTRR (DLRR).
|
2013-10-31 12:14:34 +00:00
|
|
|
clock_.AdvanceTimeMilliseconds(1000);
|
2016-07-20 15:26:59 +02:00
|
|
|
// Send Frame before sending a SR.
|
2019-03-04 16:49:25 +01:00
|
|
|
SendFrame(&sender_, sender_video_.get(), kBaseLayerTid);
|
2014-01-24 13:23:49 +00:00
|
|
|
EXPECT_EQ(0, sender_.impl_->SendRTCP(kRtcpReport));
|
2013-10-31 12:14:34 +00:00
|
|
|
|
|
|
|
|
// Verify RTT.
|
2015-01-12 21:51:21 +00:00
|
|
|
EXPECT_EQ(0, receiver_.rtt_stats_.LastProcessedRtt());
|
|
|
|
|
EXPECT_EQ(0, receiver_.impl_->rtt_ms());
|
2014-01-24 13:23:49 +00:00
|
|
|
receiver_.impl_->Process();
|
2016-02-22 18:59:36 +01:00
|
|
|
EXPECT_NEAR(2 * kOneWayNetworkDelayMs,
|
|
|
|
|
receiver_.rtt_stats_.LastProcessedRtt(), 1);
|
|
|
|
|
EXPECT_NEAR(2 * kOneWayNetworkDelayMs, receiver_.impl_->rtt_ms(), 1);
|
2013-10-31 12:14:34 +00:00
|
|
|
}
|
2014-02-19 11:59:02 +00:00
|
|
|
|
2015-12-10 10:10:44 +01:00
|
|
|
TEST_F(RtpRtcpImplTest, NoSrBeforeMedia) {
|
|
|
|
|
// Ignore fake transport delays in this test.
|
|
|
|
|
sender_.transport_.SimulateNetworkDelay(0, &clock_);
|
|
|
|
|
receiver_.transport_.SimulateNetworkDelay(0, &clock_);
|
|
|
|
|
|
|
|
|
|
sender_.impl_->Process();
|
|
|
|
|
EXPECT_EQ(-1, sender_.RtcpSent().first_packet_time_ms);
|
|
|
|
|
|
|
|
|
|
// Verify no SR is sent before media has been sent, RR should still be sent
|
|
|
|
|
// from the receiving module though.
|
|
|
|
|
clock_.AdvanceTimeMilliseconds(2000);
|
|
|
|
|
int64_t current_time = clock_.TimeInMilliseconds();
|
|
|
|
|
sender_.impl_->Process();
|
|
|
|
|
receiver_.impl_->Process();
|
|
|
|
|
EXPECT_EQ(-1, sender_.RtcpSent().first_packet_time_ms);
|
|
|
|
|
EXPECT_EQ(receiver_.RtcpSent().first_packet_time_ms, current_time);
|
|
|
|
|
|
2019-03-04 16:49:25 +01:00
|
|
|
SendFrame(&sender_, sender_video_.get(), kBaseLayerTid);
|
2015-12-10 10:10:44 +01:00
|
|
|
EXPECT_EQ(sender_.RtcpSent().first_packet_time_ms, current_time);
|
|
|
|
|
}
|
|
|
|
|
|
2014-02-19 11:59:02 +00:00
|
|
|
TEST_F(RtpRtcpImplTest, RtcpPacketTypeCounter_Nack) {
|
2014-12-16 12:03:11 +00:00
|
|
|
EXPECT_EQ(-1, receiver_.RtcpSent().first_packet_time_ms);
|
|
|
|
|
EXPECT_EQ(-1, sender_.RtcpReceived().first_packet_time_ms);
|
2014-02-19 11:59:02 +00:00
|
|
|
EXPECT_EQ(0U, sender_.RtcpReceived().nack_packets);
|
|
|
|
|
EXPECT_EQ(0U, receiver_.RtcpSent().nack_packets);
|
2014-12-16 12:03:11 +00:00
|
|
|
|
2014-02-19 11:59:02 +00:00
|
|
|
// Receive module sends a NACK.
|
|
|
|
|
const uint16_t kNackLength = 1;
|
|
|
|
|
uint16_t nack_list[kNackLength] = {123};
|
|
|
|
|
EXPECT_EQ(0, receiver_.impl_->SendNACK(nack_list, kNackLength));
|
|
|
|
|
EXPECT_EQ(1U, receiver_.RtcpSent().nack_packets);
|
2014-12-16 12:03:11 +00:00
|
|
|
EXPECT_GT(receiver_.RtcpSent().first_packet_time_ms, -1);
|
2014-02-19 11:59:02 +00:00
|
|
|
|
|
|
|
|
// Send module receives the NACK.
|
|
|
|
|
EXPECT_EQ(1U, sender_.RtcpReceived().nack_packets);
|
2014-12-16 12:03:11 +00:00
|
|
|
EXPECT_GT(sender_.RtcpReceived().first_packet_time_ms, -1);
|
2014-02-19 11:59:02 +00:00
|
|
|
}
|
|
|
|
|
|
2014-12-16 12:03:11 +00:00
|
|
|
TEST_F(RtpRtcpImplTest, AddStreamDataCounters) {
|
|
|
|
|
StreamDataCounters rtp;
|
|
|
|
|
const int64_t kStartTimeMs = 1;
|
|
|
|
|
rtp.first_packet_time_ms = kStartTimeMs;
|
2015-01-22 09:39:59 +00:00
|
|
|
rtp.transmitted.packets = 1;
|
|
|
|
|
rtp.transmitted.payload_bytes = 1;
|
|
|
|
|
rtp.transmitted.header_bytes = 2;
|
|
|
|
|
rtp.transmitted.padding_bytes = 3;
|
|
|
|
|
EXPECT_EQ(rtp.transmitted.TotalBytes(), rtp.transmitted.payload_bytes +
|
|
|
|
|
rtp.transmitted.header_bytes +
|
|
|
|
|
rtp.transmitted.padding_bytes);
|
2014-12-16 12:03:11 +00:00
|
|
|
|
|
|
|
|
StreamDataCounters rtp2;
|
|
|
|
|
rtp2.first_packet_time_ms = -1;
|
2015-01-22 09:39:59 +00:00
|
|
|
rtp2.transmitted.packets = 10;
|
|
|
|
|
rtp2.transmitted.payload_bytes = 10;
|
|
|
|
|
rtp2.retransmitted.header_bytes = 4;
|
|
|
|
|
rtp2.retransmitted.payload_bytes = 5;
|
|
|
|
|
rtp2.retransmitted.padding_bytes = 6;
|
|
|
|
|
rtp2.retransmitted.packets = 7;
|
|
|
|
|
rtp2.fec.packets = 8;
|
2014-12-16 12:03:11 +00:00
|
|
|
|
|
|
|
|
StreamDataCounters sum = rtp;
|
|
|
|
|
sum.Add(rtp2);
|
|
|
|
|
EXPECT_EQ(kStartTimeMs, sum.first_packet_time_ms);
|
2015-01-22 09:39:59 +00:00
|
|
|
EXPECT_EQ(11U, sum.transmitted.packets);
|
|
|
|
|
EXPECT_EQ(11U, sum.transmitted.payload_bytes);
|
|
|
|
|
EXPECT_EQ(2U, sum.transmitted.header_bytes);
|
|
|
|
|
EXPECT_EQ(3U, sum.transmitted.padding_bytes);
|
|
|
|
|
EXPECT_EQ(4U, sum.retransmitted.header_bytes);
|
|
|
|
|
EXPECT_EQ(5U, sum.retransmitted.payload_bytes);
|
|
|
|
|
EXPECT_EQ(6U, sum.retransmitted.padding_bytes);
|
|
|
|
|
EXPECT_EQ(7U, sum.retransmitted.packets);
|
|
|
|
|
EXPECT_EQ(8U, sum.fec.packets);
|
|
|
|
|
EXPECT_EQ(sum.transmitted.TotalBytes(),
|
|
|
|
|
rtp.transmitted.TotalBytes() + rtp2.transmitted.TotalBytes());
|
2014-12-16 12:03:11 +00:00
|
|
|
|
|
|
|
|
StreamDataCounters rtp3;
|
|
|
|
|
rtp3.first_packet_time_ms = kStartTimeMs + 10;
|
|
|
|
|
sum.Add(rtp3);
|
|
|
|
|
EXPECT_EQ(kStartTimeMs, sum.first_packet_time_ms); // Holds oldest time.
|
|
|
|
|
}
|
|
|
|
|
|
2014-12-08 13:29:02 +00:00
|
|
|
TEST_F(RtpRtcpImplTest, SendsInitialNackList) {
|
|
|
|
|
// Send module sends a NACK.
|
|
|
|
|
const uint16_t kNackLength = 1;
|
|
|
|
|
uint16_t nack_list[kNackLength] = {123};
|
|
|
|
|
EXPECT_EQ(0U, sender_.RtcpSent().nack_packets);
|
2016-07-20 15:26:59 +02:00
|
|
|
// Send Frame before sending a compound RTCP that starts with SR.
|
2019-03-04 16:49:25 +01:00
|
|
|
SendFrame(&sender_, sender_video_.get(), kBaseLayerTid);
|
2014-12-08 13:29:02 +00:00
|
|
|
EXPECT_EQ(0, sender_.impl_->SendNACK(nack_list, kNackLength));
|
|
|
|
|
EXPECT_EQ(1U, sender_.RtcpSent().nack_packets);
|
|
|
|
|
EXPECT_THAT(sender_.LastNackListSent(), ElementsAre(123));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TEST_F(RtpRtcpImplTest, SendsExtendedNackList) {
|
|
|
|
|
// Send module sends a NACK.
|
|
|
|
|
const uint16_t kNackLength = 1;
|
|
|
|
|
uint16_t nack_list[kNackLength] = {123};
|
|
|
|
|
EXPECT_EQ(0U, sender_.RtcpSent().nack_packets);
|
2016-07-20 15:26:59 +02:00
|
|
|
// Send Frame before sending a compound RTCP that starts with SR.
|
2019-03-04 16:49:25 +01:00
|
|
|
SendFrame(&sender_, sender_video_.get(), kBaseLayerTid);
|
2014-12-08 13:29:02 +00:00
|
|
|
EXPECT_EQ(0, sender_.impl_->SendNACK(nack_list, kNackLength));
|
|
|
|
|
EXPECT_EQ(1U, sender_.RtcpSent().nack_packets);
|
|
|
|
|
EXPECT_THAT(sender_.LastNackListSent(), ElementsAre(123));
|
|
|
|
|
|
|
|
|
|
// Same list not re-send.
|
|
|
|
|
EXPECT_EQ(0, sender_.impl_->SendNACK(nack_list, kNackLength));
|
|
|
|
|
EXPECT_EQ(1U, sender_.RtcpSent().nack_packets);
|
|
|
|
|
EXPECT_THAT(sender_.LastNackListSent(), ElementsAre(123));
|
|
|
|
|
|
|
|
|
|
// Only extended list sent.
|
|
|
|
|
const uint16_t kNackExtLength = 2;
|
|
|
|
|
uint16_t nack_list_ext[kNackExtLength] = {123, 124};
|
|
|
|
|
EXPECT_EQ(0, sender_.impl_->SendNACK(nack_list_ext, kNackExtLength));
|
|
|
|
|
EXPECT_EQ(2U, sender_.RtcpSent().nack_packets);
|
|
|
|
|
EXPECT_THAT(sender_.LastNackListSent(), ElementsAre(124));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TEST_F(RtpRtcpImplTest, ReSendsNackListAfterRttMs) {
|
|
|
|
|
sender_.transport_.SimulateNetworkDelay(0, &clock_);
|
|
|
|
|
// Send module sends a NACK.
|
|
|
|
|
const uint16_t kNackLength = 2;
|
|
|
|
|
uint16_t nack_list[kNackLength] = {123, 125};
|
|
|
|
|
EXPECT_EQ(0U, sender_.RtcpSent().nack_packets);
|
2016-07-20 15:26:59 +02:00
|
|
|
// Send Frame before sending a compound RTCP that starts with SR.
|
2019-03-04 16:49:25 +01:00
|
|
|
SendFrame(&sender_, sender_video_.get(), kBaseLayerTid);
|
2014-12-08 13:29:02 +00:00
|
|
|
EXPECT_EQ(0, sender_.impl_->SendNACK(nack_list, kNackLength));
|
|
|
|
|
EXPECT_EQ(1U, sender_.RtcpSent().nack_packets);
|
|
|
|
|
EXPECT_THAT(sender_.LastNackListSent(), ElementsAre(123, 125));
|
|
|
|
|
|
|
|
|
|
// Same list not re-send, rtt interval has not passed.
|
|
|
|
|
const int kStartupRttMs = 100;
|
|
|
|
|
clock_.AdvanceTimeMilliseconds(kStartupRttMs);
|
|
|
|
|
EXPECT_EQ(0, sender_.impl_->SendNACK(nack_list, kNackLength));
|
|
|
|
|
EXPECT_EQ(1U, sender_.RtcpSent().nack_packets);
|
|
|
|
|
|
|
|
|
|
// Rtt interval passed, full list sent.
|
|
|
|
|
clock_.AdvanceTimeMilliseconds(1);
|
|
|
|
|
EXPECT_EQ(0, sender_.impl_->SendNACK(nack_list, kNackLength));
|
|
|
|
|
EXPECT_EQ(2U, sender_.RtcpSent().nack_packets);
|
|
|
|
|
EXPECT_THAT(sender_.LastNackListSent(), ElementsAre(123, 125));
|
|
|
|
|
}
|
|
|
|
|
|
2014-10-29 12:42:30 +00:00
|
|
|
TEST_F(RtpRtcpImplTest, UniqueNackRequests) {
|
|
|
|
|
receiver_.transport_.SimulateNetworkDelay(0, &clock_);
|
|
|
|
|
EXPECT_EQ(0U, receiver_.RtcpSent().nack_packets);
|
|
|
|
|
EXPECT_EQ(0U, receiver_.RtcpSent().nack_requests);
|
|
|
|
|
EXPECT_EQ(0U, receiver_.RtcpSent().unique_nack_requests);
|
|
|
|
|
EXPECT_EQ(0, receiver_.RtcpSent().UniqueNackRequestsInPercent());
|
|
|
|
|
|
|
|
|
|
// Receive module sends NACK request.
|
|
|
|
|
const uint16_t kNackLength = 4;
|
|
|
|
|
uint16_t nack_list[kNackLength] = {10, 11, 13, 18};
|
|
|
|
|
EXPECT_EQ(0, receiver_.impl_->SendNACK(nack_list, kNackLength));
|
|
|
|
|
EXPECT_EQ(1U, receiver_.RtcpSent().nack_packets);
|
|
|
|
|
EXPECT_EQ(4U, receiver_.RtcpSent().nack_requests);
|
|
|
|
|
EXPECT_EQ(4U, receiver_.RtcpSent().unique_nack_requests);
|
|
|
|
|
EXPECT_THAT(receiver_.LastNackListSent(), ElementsAre(10, 11, 13, 18));
|
|
|
|
|
|
|
|
|
|
// Send module receives the request.
|
|
|
|
|
EXPECT_EQ(1U, sender_.RtcpReceived().nack_packets);
|
|
|
|
|
EXPECT_EQ(4U, sender_.RtcpReceived().nack_requests);
|
|
|
|
|
EXPECT_EQ(4U, sender_.RtcpReceived().unique_nack_requests);
|
|
|
|
|
EXPECT_EQ(100, sender_.RtcpReceived().UniqueNackRequestsInPercent());
|
|
|
|
|
|
|
|
|
|
// Receive module sends new request with duplicated packets.
|
|
|
|
|
const int kStartupRttMs = 100;
|
|
|
|
|
clock_.AdvanceTimeMilliseconds(kStartupRttMs + 1);
|
|
|
|
|
const uint16_t kNackLength2 = 4;
|
|
|
|
|
uint16_t nack_list2[kNackLength2] = {11, 18, 20, 21};
|
|
|
|
|
EXPECT_EQ(0, receiver_.impl_->SendNACK(nack_list2, kNackLength2));
|
|
|
|
|
EXPECT_EQ(2U, receiver_.RtcpSent().nack_packets);
|
|
|
|
|
EXPECT_EQ(8U, receiver_.RtcpSent().nack_requests);
|
|
|
|
|
EXPECT_EQ(6U, receiver_.RtcpSent().unique_nack_requests);
|
|
|
|
|
EXPECT_THAT(receiver_.LastNackListSent(), ElementsAre(11, 18, 20, 21));
|
|
|
|
|
|
|
|
|
|
// Send module receives the request.
|
|
|
|
|
EXPECT_EQ(2U, sender_.RtcpReceived().nack_packets);
|
|
|
|
|
EXPECT_EQ(8U, sender_.RtcpReceived().nack_requests);
|
|
|
|
|
EXPECT_EQ(6U, sender_.RtcpReceived().unique_nack_requests);
|
|
|
|
|
EXPECT_EQ(75, sender_.RtcpReceived().UniqueNackRequestsInPercent());
|
|
|
|
|
}
|
2017-07-06 04:38:06 -07:00
|
|
|
|
2018-01-31 22:08:26 -08:00
|
|
|
TEST_F(RtpRtcpImplTest, ConfigurableRtcpReportInterval) {
|
|
|
|
|
const int kVideoReportInterval = 3000;
|
|
|
|
|
|
|
|
|
|
// Recreate sender impl with new configuration, and redo setup.
|
2018-11-15 16:44:37 -08:00
|
|
|
sender_.SetRtcpReportIntervalAndReset(kVideoReportInterval);
|
2018-01-31 22:08:26 -08:00
|
|
|
SetUp();
|
|
|
|
|
|
2019-03-04 16:49:25 +01:00
|
|
|
SendFrame(&sender_, sender_video_.get(), kBaseLayerTid);
|
2018-01-31 22:08:26 -08:00
|
|
|
|
|
|
|
|
// Initial state
|
|
|
|
|
sender_.impl_->Process();
|
|
|
|
|
EXPECT_EQ(sender_.RtcpSent().first_packet_time_ms, -1);
|
|
|
|
|
EXPECT_EQ(0u, sender_.transport_.NumRtcpSent());
|
|
|
|
|
|
|
|
|
|
// Move ahead to the last ms before a rtcp is expected, no action.
|
|
|
|
|
clock_.AdvanceTimeMilliseconds(kVideoReportInterval / 2 - 1);
|
|
|
|
|
sender_.impl_->Process();
|
|
|
|
|
EXPECT_EQ(sender_.RtcpSent().first_packet_time_ms, -1);
|
|
|
|
|
EXPECT_EQ(sender_.transport_.NumRtcpSent(), 0u);
|
|
|
|
|
|
|
|
|
|
// Move ahead to the first rtcp. Send RTCP.
|
|
|
|
|
clock_.AdvanceTimeMilliseconds(1);
|
|
|
|
|
sender_.impl_->Process();
|
|
|
|
|
EXPECT_GT(sender_.RtcpSent().first_packet_time_ms, -1);
|
|
|
|
|
EXPECT_EQ(sender_.transport_.NumRtcpSent(), 1u);
|
|
|
|
|
|
2019-03-04 16:49:25 +01:00
|
|
|
SendFrame(&sender_, sender_video_.get(), kBaseLayerTid);
|
2018-01-31 22:08:26 -08:00
|
|
|
|
|
|
|
|
// Move ahead to the last possible second before second rtcp is expected.
|
|
|
|
|
clock_.AdvanceTimeMilliseconds(kVideoReportInterval * 1 / 2 - 1);
|
|
|
|
|
sender_.impl_->Process();
|
|
|
|
|
EXPECT_EQ(sender_.transport_.NumRtcpSent(), 1u);
|
|
|
|
|
|
|
|
|
|
// Move ahead into the range of second rtcp, the second rtcp may be sent.
|
|
|
|
|
clock_.AdvanceTimeMilliseconds(1);
|
|
|
|
|
sender_.impl_->Process();
|
|
|
|
|
EXPECT_GE(sender_.transport_.NumRtcpSent(), 1u);
|
|
|
|
|
|
|
|
|
|
clock_.AdvanceTimeMilliseconds(kVideoReportInterval / 2);
|
|
|
|
|
sender_.impl_->Process();
|
|
|
|
|
EXPECT_GE(sender_.transport_.NumRtcpSent(), 1u);
|
|
|
|
|
|
|
|
|
|
// Move out the range of second rtcp, the second rtcp must have been sent.
|
|
|
|
|
clock_.AdvanceTimeMilliseconds(kVideoReportInterval / 2);
|
|
|
|
|
sender_.impl_->Process();
|
|
|
|
|
EXPECT_EQ(sender_.transport_.NumRtcpSent(), 2u);
|
|
|
|
|
}
|
|
|
|
|
|
2013-10-23 13:58:31 +00:00
|
|
|
} // namespace webrtc
|