Index: webrtc/modules/rtp_rtcp/source/nack_rtx_unittest.cc |
diff --git a/webrtc/modules/rtp_rtcp/source/nack_rtx_unittest.cc b/webrtc/modules/rtp_rtcp/source/nack_rtx_unittest.cc |
index 1a68726b4a6720fa1db145165abdc68696ac75bd..32c9d5b9e80819c118535733110f5ff40846bc13 100644 |
--- a/webrtc/modules/rtp_rtcp/source/nack_rtx_unittest.cc |
+++ b/webrtc/modules/rtp_rtcp/source/nack_rtx_unittest.cc |
@@ -15,13 +15,13 @@ |
#include <set> |
#include "webrtc/api/call/transport.h" |
-#include "webrtc/call/rtp_stream_receiver_controller.h" |
-#include "webrtc/call/rtx_receive_stream.h" |
#include "webrtc/common_types.h" |
#include "webrtc/modules/rtp_rtcp/include/receive_statistics.h" |
+#include "webrtc/modules/rtp_rtcp/include/rtp_header_parser.h" |
+#include "webrtc/modules/rtp_rtcp/include/rtp_payload_registry.h" |
+#include "webrtc/modules/rtp_rtcp/include/rtp_receiver.h" |
#include "webrtc/modules/rtp_rtcp/include/rtp_rtcp.h" |
#include "webrtc/modules/rtp_rtcp/include/rtp_rtcp_defines.h" |
-#include "webrtc/modules/rtp_rtcp/source/rtp_packet_received.h" |
#include "webrtc/rtc_base/rate_limiter.h" |
#include "webrtc/test/gtest.h" |
@@ -29,7 +29,6 @@ |
const int kVideoNackListSize = 30; |
const uint32_t kTestSsrc = 3456; |
-const uint32_t kTestRtxSsrc = kTestSsrc + 1; |
const uint16_t kTestSequenceNumber = 2345; |
const uint32_t kTestNumberOfPackets = 1350; |
const int kTestNumberOfRtxPackets = 149; |
@@ -38,17 +37,33 @@ |
const int kRtxPayloadType = 98; |
const int64_t kMaxRttMs = 1000; |
-class VerifyingMediaStream : public RtpPacketSinkInterface { |
+class VerifyingRtxReceiver : public RtpData { |
public: |
- VerifyingMediaStream() {} |
- |
- void OnRtpPacket(const RtpPacketReceived& packet) override { |
+ VerifyingRtxReceiver() {} |
+ |
+ int32_t OnReceivedPayloadData( |
+ const uint8_t* data, |
+ size_t size, |
+ const webrtc::WebRtcRTPHeader* rtp_header) override { |
if (!sequence_numbers_.empty()) |
- EXPECT_EQ(kTestSsrc, packet.Ssrc()); |
- |
- sequence_numbers_.push_back(packet.SequenceNumber()); |
+ EXPECT_EQ(kTestSsrc, rtp_header->header.ssrc); |
+ sequence_numbers_.push_back(rtp_header->header.sequenceNumber); |
+ return 0; |
} |
std::list<uint16_t> sequence_numbers_; |
+}; |
+ |
+class TestRtpFeedback : public NullRtpFeedback { |
+ public: |
+ explicit TestRtpFeedback(RtpRtcp* rtp_rtcp) : rtp_rtcp_(rtp_rtcp) {} |
+ virtual ~TestRtpFeedback() {} |
+ |
+ void OnIncomingSSRCChanged(uint32_t ssrc) override { |
+ rtp_rtcp_->SetRemoteSSRC(ssrc); |
+ } |
+ |
+ private: |
+ RtpRtcp* rtp_rtcp_; |
}; |
class RtxLoopBackTransport : public webrtc::Transport { |
@@ -60,10 +75,16 @@ |
consecutive_drop_end_(0), |
rtx_ssrc_(rtx_ssrc), |
count_rtx_ssrc_(0), |
+ rtp_payload_registry_(NULL), |
+ rtp_receiver_(NULL), |
module_(NULL) {} |
- void SetSendModule(RtpRtcp* rtpRtcpModule) { |
+ void SetSendModule(RtpRtcp* rtpRtcpModule, |
+ RTPPayloadRegistry* rtp_payload_registry, |
+ RtpReceiver* receiver) { |
module_ = rtpRtcpModule; |
+ rtp_payload_registry_ = rtp_payload_registry; |
+ rtp_receiver_ = receiver; |
} |
void DropEveryNthPacket(int n) { packet_loss_ = n; } |
@@ -78,15 +99,24 @@ |
size_t len, |
const PacketOptions& options) override { |
count_++; |
- RtpPacketReceived packet; |
- if (!packet.Parse(data, len)) |
+ const unsigned char* ptr = static_cast<const unsigned char*>(data); |
+ uint32_t ssrc = (ptr[8] << 24) + (ptr[9] << 16) + (ptr[10] << 8) + ptr[11]; |
+ if (ssrc == rtx_ssrc_) |
+ count_rtx_ssrc_++; |
+ uint16_t sequence_number = (ptr[2] << 8) + ptr[3]; |
+ size_t packet_length = len; |
+ uint8_t restored_packet[1500]; |
+ RTPHeader header; |
+ std::unique_ptr<RtpHeaderParser> parser(RtpHeaderParser::Create()); |
+ if (!parser->Parse(ptr, len, &header)) { |
return false; |
- if (packet.Ssrc() == rtx_ssrc_) { |
- count_rtx_ssrc_++; |
- } else { |
- // For non-RTX packets only. |
+ } |
+ |
+ if (!rtp_payload_registry_->IsRtx(header)) { |
+ // Don't store retransmitted packets since we compare it to the list |
+ // created by the receiver. |
expected_sequence_numbers_.insert(expected_sequence_numbers_.end(), |
- packet.SequenceNumber()); |
+ sequence_number); |
} |
if (packet_loss_ > 0) { |
if ((count_ % packet_loss_) == 0) { |
@@ -96,7 +126,28 @@ |
count_ < consecutive_drop_end_) { |
return true; |
} |
- EXPECT_TRUE(stream_receiver_controller_.OnRtpPacket(packet)); |
+ if (rtp_payload_registry_->IsRtx(header)) { |
+ // Remove the RTX header and parse the original RTP header. |
+ EXPECT_TRUE(rtp_payload_registry_->RestoreOriginalPacket( |
+ restored_packet, ptr, &packet_length, rtp_receiver_->SSRC(), header)); |
+ if (!parser->Parse(restored_packet, packet_length, &header)) { |
+ return false; |
+ } |
+ ptr = restored_packet; |
+ } else { |
+ rtp_payload_registry_->SetIncomingPayloadType(header); |
+ } |
+ |
+ PayloadUnion payload_specific; |
+ if (!rtp_payload_registry_->GetPayloadSpecifics(header.payloadType, |
+ &payload_specific)) { |
+ return false; |
+ } |
+ if (!rtp_receiver_->IncomingRtpPacket(header, ptr + header.headerLength, |
+ packet_length - header.headerLength, |
+ payload_specific, true)) { |
+ return false; |
+ } |
return true; |
} |
@@ -109,8 +160,9 @@ |
int consecutive_drop_end_; |
uint32_t rtx_ssrc_; |
int count_rtx_ssrc_; |
+ RTPPayloadRegistry* rtp_payload_registry_; |
+ RtpReceiver* rtp_receiver_; |
RtpRtcp* module_; |
- RtpStreamReceiverController stream_receiver_controller_; |
std::set<uint16_t> expected_sequence_numbers_; |
}; |
@@ -118,10 +170,8 @@ |
protected: |
RtpRtcpRtxNackTest() |
: rtp_rtcp_module_(nullptr), |
- transport_(kTestRtxSsrc), |
- rtx_stream_(&media_stream_, |
- rtx_associated_payload_types_, |
- kTestSsrc), |
+ transport_(kTestSsrc + 1), |
+ receiver_(), |
payload_data_length(sizeof(payload_data)), |
fake_clock(123456), |
retransmission_rate_limiter_(&fake_clock, kMaxRttMs) {} |
@@ -137,6 +187,11 @@ |
configuration.retransmission_rate_limiter = &retransmission_rate_limiter_; |
rtp_rtcp_module_ = RtpRtcp::CreateRtpRtcp(configuration); |
+ rtp_feedback_.reset(new TestRtpFeedback(rtp_rtcp_module_)); |
+ |
+ rtp_receiver_.reset(RtpReceiver::CreateVideoReceiver( |
+ &fake_clock, &receiver_, rtp_feedback_.get(), &rtp_payload_registry_)); |
+ |
rtp_rtcp_module_->SetSSRC(kTestSsrc); |
rtp_rtcp_module_->SetRTCPStatus(RtcpMode::kCompound); |
rtp_rtcp_module_->SetStorePacketsStatus(true, 600); |
@@ -144,16 +199,18 @@ |
rtp_rtcp_module_->SetSequenceNumber(kTestSequenceNumber); |
rtp_rtcp_module_->SetStartTimestamp(111111); |
- // Used for NACK processing. |
- // TODO(nisse): Unclear on which side? It's confusing to use a |
- // single rtp_rtcp module for both send and receive side. |
- rtp_rtcp_module_->SetRemoteSSRC(kTestSsrc); |
- |
- rtp_rtcp_module_->RegisterVideoSendPayload(kPayloadType, "video"); |
+ transport_.SetSendModule(rtp_rtcp_module_, &rtp_payload_registry_, |
+ rtp_receiver_.get()); |
+ |
+ VideoCodec video_codec; |
+ memset(&video_codec, 0, sizeof(video_codec)); |
+ video_codec.plType = kPayloadType; |
+ memcpy(video_codec.plName, "I420", 5); |
+ |
+ EXPECT_EQ(0, rtp_rtcp_module_->RegisterSendPayload(video_codec)); |
rtp_rtcp_module_->SetRtxSendPayloadType(kRtxPayloadType, kPayloadType); |
- transport_.SetSendModule(rtp_rtcp_module_); |
- media_receiver_ = transport_.stream_receiver_controller_.CreateReceiver( |
- kTestSsrc, &media_stream_); |
+ EXPECT_EQ(0, rtp_payload_registry_.RegisterReceivePayload(video_codec)); |
+ rtp_payload_registry_.SetRtxPayloadType(kRtxPayloadType, kPayloadType); |
for (size_t n = 0; n < payload_data_length; n++) { |
payload_data[n] = n % 10; |
@@ -161,14 +218,14 @@ |
} |
int BuildNackList(uint16_t* nack_list) { |
- media_stream_.sequence_numbers_.sort(); |
+ receiver_.sequence_numbers_.sort(); |
std::list<uint16_t> missing_sequence_numbers; |
- std::list<uint16_t>::iterator it = media_stream_.sequence_numbers_.begin(); |
- |
- while (it != media_stream_.sequence_numbers_.end()) { |
+ std::list<uint16_t>::iterator it = receiver_.sequence_numbers_.begin(); |
+ |
+ while (it != receiver_.sequence_numbers_.end()) { |
uint16_t sequence_number_1 = *it; |
++it; |
- if (it != media_stream_.sequence_numbers_.end()) { |
+ if (it != receiver_.sequence_numbers_.end()) { |
uint16_t sequence_number_2 = *it; |
// Add all missing sequence numbers to list |
for (uint16_t i = sequence_number_1 + 1; i < sequence_number_2; ++i) { |
@@ -186,8 +243,8 @@ |
bool ExpectedPacketsReceived() { |
std::list<uint16_t> received_sorted; |
- std::copy(media_stream_.sequence_numbers_.begin(), |
- media_stream_.sequence_numbers_.end(), |
+ std::copy(receiver_.sequence_numbers_.begin(), |
+ receiver_.sequence_numbers_.end(), |
std::back_inserter(received_sorted)); |
received_sorted.sort(); |
return received_sorted.size() == |
@@ -197,10 +254,9 @@ |
} |
void RunRtxTest(RtxMode rtx_method, int loss) { |
- rtx_receiver_ = transport_.stream_receiver_controller_.CreateReceiver( |
- kTestRtxSsrc, &rtx_stream_); |
+ rtp_payload_registry_.SetRtxSsrc(kTestSsrc + 1); |
rtp_rtcp_module_->SetRtxSendStatus(rtx_method); |
- rtp_rtcp_module_->SetRtxSsrc(kTestRtxSsrc); |
+ rtp_rtcp_module_->SetRtxSsrc(kTestSsrc + 1); |
transport_.DropEveryNthPacket(loss); |
uint32_t timestamp = 3000; |
uint16_t nack_list[kVideoNackListSize]; |
@@ -218,24 +274,22 @@ |
// Prepare next frame. |
timestamp += 3000; |
} |
- media_stream_.sequence_numbers_.sort(); |
+ receiver_.sequence_numbers_.sort(); |
} |
void TearDown() override { delete rtp_rtcp_module_; } |
std::unique_ptr<ReceiveStatistics> receive_statistics_; |
+ RTPPayloadRegistry rtp_payload_registry_; |
+ std::unique_ptr<RtpReceiver> rtp_receiver_; |
RtpRtcp* rtp_rtcp_module_; |
+ std::unique_ptr<TestRtpFeedback> rtp_feedback_; |
RtxLoopBackTransport transport_; |
- const std::map<int, int> rtx_associated_payload_types_ = |
- {{kRtxPayloadType, kPayloadType}}; |
- VerifyingMediaStream media_stream_; |
- RtxReceiveStream rtx_stream_; |
+ VerifyingRtxReceiver receiver_; |
uint8_t payload_data[65000]; |
size_t payload_data_length; |
SimulatedClock fake_clock; |
RateLimiter retransmission_rate_limiter_; |
- std::unique_ptr<RtpStreamReceiverInterface> media_receiver_; |
- std::unique_ptr<RtpStreamReceiverInterface> rtx_receiver_; |
}; |
TEST_F(RtpRtcpRtxNackTest, LongNackList) { |
@@ -262,26 +316,26 @@ |
rtp_rtcp_module_->Process(); |
} |
EXPECT_FALSE(transport_.expected_sequence_numbers_.empty()); |
- EXPECT_FALSE(media_stream_.sequence_numbers_.empty()); |
- size_t last_receive_count = media_stream_.sequence_numbers_.size(); |
+ EXPECT_FALSE(receiver_.sequence_numbers_.empty()); |
+ size_t last_receive_count = receiver_.sequence_numbers_.size(); |
int length = BuildNackList(nack_list); |
for (int i = 0; i < kNumRequiredRtcp - 1; ++i) { |
rtp_rtcp_module_->SendNACK(nack_list, length); |
- EXPECT_GT(media_stream_.sequence_numbers_.size(), last_receive_count); |
- last_receive_count = media_stream_.sequence_numbers_.size(); |
+ EXPECT_GT(receiver_.sequence_numbers_.size(), last_receive_count); |
+ last_receive_count = receiver_.sequence_numbers_.size(); |
EXPECT_FALSE(ExpectedPacketsReceived()); |
} |
rtp_rtcp_module_->SendNACK(nack_list, length); |
- EXPECT_GT(media_stream_.sequence_numbers_.size(), last_receive_count); |
+ EXPECT_GT(receiver_.sequence_numbers_.size(), last_receive_count); |
EXPECT_TRUE(ExpectedPacketsReceived()); |
} |
TEST_F(RtpRtcpRtxNackTest, RtxNack) { |
RunRtxTest(kRtxRetransmitted, 10); |
- EXPECT_EQ(kTestSequenceNumber, *(media_stream_.sequence_numbers_.begin())); |
+ EXPECT_EQ(kTestSequenceNumber, *(receiver_.sequence_numbers_.begin())); |
EXPECT_EQ(kTestSequenceNumber + kTestNumberOfPackets - 1, |
- *(media_stream_.sequence_numbers_.rbegin())); |
- EXPECT_EQ(kTestNumberOfPackets, media_stream_.sequence_numbers_.size()); |
+ *(receiver_.sequence_numbers_.rbegin())); |
+ EXPECT_EQ(kTestNumberOfPackets, receiver_.sequence_numbers_.size()); |
EXPECT_EQ(kTestNumberOfRtxPackets, transport_.count_rtx_ssrc_); |
EXPECT_TRUE(ExpectedPacketsReceived()); |
} |