Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(747)

Unified Diff: webrtc/video/end_to_end_tests.cc

Issue 1406193002: Transport sequence number should be set also for retransmissions. (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: Fixed race in setup of unit test Created 5 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « webrtc/modules/rtp_rtcp/source/rtp_sender.cc ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: webrtc/video/end_to_end_tests.cc
diff --git a/webrtc/video/end_to_end_tests.cc b/webrtc/video/end_to_end_tests.cc
index 305dcb0aaf8f3029c2f0d254fcbd83388265ac38..01f132ff27f4eb5dfaeb0f9fc4e5bc4326dcca7e 100644
--- a/webrtc/video/end_to_end_tests.cc
+++ b/webrtc/video/end_to_end_tests.cc
@@ -20,6 +20,7 @@
#include "webrtc/call.h"
#include "webrtc/call/transport_adapter.h"
#include "webrtc/frame_callback.h"
+#include "webrtc/modules/rtp_rtcp/source/byte_io.h"
#include "webrtc/modules/rtp_rtcp/source/rtcp_utility.h"
#include "webrtc/modules/video_coding/codecs/vp8/include/vp8.h"
#include "webrtc/modules/video_coding/codecs/vp9/include/vp9.h"
@@ -1335,19 +1336,20 @@ TEST_F(EndToEndTest, SendsAndReceivesMultipleStreams) {
}
TEST_F(EndToEndTest, AssignsTransportSequenceNumbers) {
- // TODO(sprang): Extend this to verify received values once send-side BWE
- // is in place.
-
static const int kExtensionId = 5;
class RtpExtensionHeaderObserver : public test::DirectTransport {
public:
- RtpExtensionHeaderObserver()
+ RtpExtensionHeaderObserver(const uint32_t& first_media_ssrc,
+ const std::map<uint32_t, uint32_t>& ssrc_map)
: done_(EventWrapper::Create()),
parser_(RtpHeaderParser::Create()),
- last_seq_(0),
+ first_media_ssrc_(first_media_ssrc),
+ rtx_to_media_ssrcs_(ssrc_map),
padding_observed_(false),
- rtx_padding_observed_(false) {
+ rtx_padding_observed_(false),
+ retransmit_observed_(false),
+ started_(false) {
parser_->RegisterRtpHeaderExtension(kRtpExtensionTransportSequenceNumber,
kExtensionId);
}
@@ -1356,54 +1358,110 @@ TEST_F(EndToEndTest, AssignsTransportSequenceNumbers) {
bool SendRtp(const uint8_t* data,
size_t length,
const PacketOptions& options) override {
- if (IsDone())
- return false;
+ {
+ rtc::CritScope cs(&lock_);
- RTPHeader header;
- EXPECT_TRUE(parser_->Parse(data, length, &header));
- if (header.extension.hasTransportSequenceNumber) {
- EXPECT_EQ(options.packet_id,
- header.extension.transportSequenceNumber);
- if (!streams_observed_.empty()) {
- EXPECT_EQ(static_cast<uint16_t>(last_seq_ + 1),
+ if (IsDone())
+ return false;
+
+ if (started_) {
+ RTPHeader header;
+ EXPECT_TRUE(parser_->Parse(data, length, &header));
+ bool drop_packet = false;
+
+ EXPECT_TRUE(header.extension.hasTransportSequenceNumber);
+ EXPECT_EQ(options.packet_id,
header.extension.transportSequenceNumber);
- }
- last_seq_ = header.extension.transportSequenceNumber;
-
- size_t payload_length =
- length - (header.headerLength + header.paddingLength);
- if (payload_length == 0) {
- padding_observed_ = true;
- } else if (header.payloadType == kSendRtxPayloadType) {
- rtx_padding_observed_ = true;
- } else {
- streams_observed_.insert(header.ssrc);
- }
+ if (!streams_observed_.empty()) {
+ // Unwrap packet id and verify uniqueness.
+ int64_t packet_id = unwrapper_.Unwrap(options.packet_id);
+ EXPECT_TRUE(received_packed_ids_.insert(packet_id).second);
+ }
- if (IsDone())
- done_->Set();
+ // Drop (up to) every 17th packet, so we get retransmits.
+ // Only drop media, and not on the first stream (otherwise it will be
+ // hard to distinguish from padding, which is always sent on the first
+ // stream).
+ if (header.payloadType != kSendRtxPayloadType &&
+ header.ssrc != first_media_ssrc_ &&
+ header.extension.transportSequenceNumber % 17 == 0) {
+ dropped_seq_[header.ssrc].insert(header.sequenceNumber);
+ drop_packet = true;
+ }
+
+ size_t payload_length =
+ length - (header.headerLength + header.paddingLength);
+ if (payload_length == 0) {
+ padding_observed_ = true;
+ } else if (header.payloadType == kSendRtxPayloadType) {
+ uint16_t original_sequence_number =
+ ByteReader<uint16_t>::ReadBigEndian(&data[header.headerLength]);
+ uint32_t original_ssrc =
+ rtx_to_media_ssrcs_.find(header.ssrc)->second;
+ std::set<uint16_t>* seq_no_map = &dropped_seq_[original_ssrc];
+ auto it = seq_no_map->find(original_sequence_number);
+ if (it != seq_no_map->end()) {
+ retransmit_observed_ = true;
+ seq_no_map->erase(it);
+ } else {
+ rtx_padding_observed_ = true;
+ }
+ } else {
+ streams_observed_.insert(header.ssrc);
+ }
+
+ if (IsDone())
+ done_->Set();
+
+ if (drop_packet)
+ return true;
+ }
}
+
return test::DirectTransport::SendRtp(data, length, options);
}
bool IsDone() {
- return streams_observed_.size() == MultiStreamTest::kNumStreams &&
- padding_observed_ && rtx_padding_observed_;
+ bool observed_types_ok =
+ streams_observed_.size() == MultiStreamTest::kNumStreams &&
+ padding_observed_ && retransmit_observed_ && rtx_padding_observed_;
+ if (!observed_types_ok)
+ return false;
+ // We should not have any gaps in the sequence number range.
+ size_t seqno_range =
+ *received_packed_ids_.rbegin() - *received_packed_ids_.begin() + 1;
+ return seqno_range == received_packed_ids_.size();
}
- EventTypeWrapper Wait() { return done_->Wait(kDefaultTimeoutMs); }
+ EventTypeWrapper Wait() {
+ {
+ // Can't be sure until this point that rtx_to_media_ssrcs_ etc have
+ // been initialized and are OK to read.
+ rtc::CritScope cs(&lock_);
+ started_ = true;
+ }
+ return done_->Wait(kDefaultTimeoutMs);
+ }
+ rtc::CriticalSection lock_;
rtc::scoped_ptr<EventWrapper> done_;
rtc::scoped_ptr<RtpHeaderParser> parser_;
- uint16_t last_seq_;
+ SequenceNumberUnwrapper unwrapper_;
+ std::set<int64_t> received_packed_ids_;
std::set<uint32_t> streams_observed_;
+ std::map<uint32_t, std::set<uint16_t>> dropped_seq_;
+ const uint32_t& first_media_ssrc_;
+ const std::map<uint32_t, uint32_t>& rtx_to_media_ssrcs_;
bool padding_observed_;
bool rtx_padding_observed_;
+ bool retransmit_observed_;
+ bool started_;
};
class TransportSequenceNumberTester : public MultiStreamTest {
public:
- TransportSequenceNumberTester() : observer_(nullptr) {}
+ TransportSequenceNumberTester()
+ : first_media_ssrc_(0), observer_(nullptr) {}
virtual ~TransportSequenceNumberTester() {}
protected:
@@ -1431,24 +1489,33 @@ TEST_F(EndToEndTest, AssignsTransportSequenceNumbers) {
// Configure RTX for redundant payload padding.
send_config->rtp.nack.rtp_history_ms = kNackRtpHistoryMs;
- send_config->rtp.rtx.ssrcs.push_back(kSendRtxSsrcs[0]);
+ send_config->rtp.rtx.ssrcs.push_back(kSendRtxSsrcs[stream_index]);
send_config->rtp.rtx.payload_type = kSendRtxPayloadType;
+ rtx_to_media_ssrcs_[kSendRtxSsrcs[stream_index]] =
+ send_config->rtp.ssrcs[0];
+
+ if (stream_index == 0)
+ first_media_ssrc_ = send_config->rtp.ssrcs[0];
}
void UpdateReceiveConfig(
size_t stream_index,
VideoReceiveStream::Config* receive_config) override {
+ receive_config->rtp.nack.rtp_history_ms = kNackRtpHistoryMs;
receive_config->rtp.extensions.clear();
receive_config->rtp.extensions.push_back(
RtpExtension(RtpExtension::kTransportSequenceNumber, kExtensionId));
}
virtual test::DirectTransport* CreateSendTransport() {
- observer_ = new RtpExtensionHeaderObserver();
+ observer_ = new RtpExtensionHeaderObserver(first_media_ssrc_,
+ rtx_to_media_ssrcs_);
return observer_;
}
private:
+ uint32_t first_media_ssrc_;
+ std::map<uint32_t, uint32_t> rtx_to_media_ssrcs_;
RtpExtensionHeaderObserver* observer_;
} tester;
« no previous file with comments | « webrtc/modules/rtp_rtcp/source/rtp_sender.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698