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

Side by Side 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 unified diff | Download patch
« no previous file with comments | « webrtc/modules/rtp_rtcp/source/rtp_sender.cc ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright (c) 2013 The WebRTC project authors. All Rights Reserved. 2 * Copyright (c) 2013 The WebRTC project authors. All Rights Reserved.
3 * 3 *
4 * Use of this source code is governed by a BSD-style license 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 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 6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may 7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree. 8 * be found in the AUTHORS file in the root of the source tree.
9 */ 9 */
10 #include <algorithm> 10 #include <algorithm>
11 #include <map> 11 #include <map>
12 #include <sstream> 12 #include <sstream>
13 #include <string> 13 #include <string>
14 14
15 #include "testing/gtest/include/gtest/gtest.h" 15 #include "testing/gtest/include/gtest/gtest.h"
16 16
17 #include "webrtc/base/checks.h" 17 #include "webrtc/base/checks.h"
18 #include "webrtc/base/event.h" 18 #include "webrtc/base/event.h"
19 #include "webrtc/base/scoped_ptr.h" 19 #include "webrtc/base/scoped_ptr.h"
20 #include "webrtc/call.h" 20 #include "webrtc/call.h"
21 #include "webrtc/call/transport_adapter.h" 21 #include "webrtc/call/transport_adapter.h"
22 #include "webrtc/frame_callback.h" 22 #include "webrtc/frame_callback.h"
23 #include "webrtc/modules/rtp_rtcp/source/byte_io.h"
23 #include "webrtc/modules/rtp_rtcp/source/rtcp_utility.h" 24 #include "webrtc/modules/rtp_rtcp/source/rtcp_utility.h"
24 #include "webrtc/modules/video_coding/codecs/vp8/include/vp8.h" 25 #include "webrtc/modules/video_coding/codecs/vp8/include/vp8.h"
25 #include "webrtc/modules/video_coding/codecs/vp9/include/vp9.h" 26 #include "webrtc/modules/video_coding/codecs/vp9/include/vp9.h"
26 #include "webrtc/modules/video_coding/main/interface/video_coding_defines.h" 27 #include "webrtc/modules/video_coding/main/interface/video_coding_defines.h"
27 #include "webrtc/system_wrappers/interface/critical_section_wrapper.h" 28 #include "webrtc/system_wrappers/interface/critical_section_wrapper.h"
28 #include "webrtc/system_wrappers/interface/event_wrapper.h" 29 #include "webrtc/system_wrappers/interface/event_wrapper.h"
29 #include "webrtc/system_wrappers/interface/metrics.h" 30 #include "webrtc/system_wrappers/interface/metrics.h"
30 #include "webrtc/system_wrappers/interface/sleep.h" 31 #include "webrtc/system_wrappers/interface/sleep.h"
31 #include "webrtc/test/call_test.h" 32 #include "webrtc/test/call_test.h"
32 #include "webrtc/test/direct_transport.h" 33 #include "webrtc/test/direct_transport.h"
(...skipping 1295 matching lines...) Expand 10 before | Expand all | Expand 10 after
1328 } 1329 }
1329 1330
1330 private: 1331 private:
1331 rtc::scoped_ptr<VideoOutputObserver> observers_[kNumStreams]; 1332 rtc::scoped_ptr<VideoOutputObserver> observers_[kNumStreams];
1332 } tester; 1333 } tester;
1333 1334
1334 tester.RunTest(); 1335 tester.RunTest();
1335 } 1336 }
1336 1337
1337 TEST_F(EndToEndTest, AssignsTransportSequenceNumbers) { 1338 TEST_F(EndToEndTest, AssignsTransportSequenceNumbers) {
1338 // TODO(sprang): Extend this to verify received values once send-side BWE
1339 // is in place.
1340
1341 static const int kExtensionId = 5; 1339 static const int kExtensionId = 5;
1342 1340
1343 class RtpExtensionHeaderObserver : public test::DirectTransport { 1341 class RtpExtensionHeaderObserver : public test::DirectTransport {
1344 public: 1342 public:
1345 RtpExtensionHeaderObserver() 1343 RtpExtensionHeaderObserver(const uint32_t& first_media_ssrc,
1344 const std::map<uint32_t, uint32_t>& ssrc_map)
1346 : done_(EventWrapper::Create()), 1345 : done_(EventWrapper::Create()),
1347 parser_(RtpHeaderParser::Create()), 1346 parser_(RtpHeaderParser::Create()),
1348 last_seq_(0), 1347 first_media_ssrc_(first_media_ssrc),
1348 rtx_to_media_ssrcs_(ssrc_map),
1349 padding_observed_(false), 1349 padding_observed_(false),
1350 rtx_padding_observed_(false) { 1350 rtx_padding_observed_(false),
1351 retransmit_observed_(false),
1352 started_(false) {
1351 parser_->RegisterRtpHeaderExtension(kRtpExtensionTransportSequenceNumber, 1353 parser_->RegisterRtpHeaderExtension(kRtpExtensionTransportSequenceNumber,
1352 kExtensionId); 1354 kExtensionId);
1353 } 1355 }
1354 virtual ~RtpExtensionHeaderObserver() {} 1356 virtual ~RtpExtensionHeaderObserver() {}
1355 1357
1356 bool SendRtp(const uint8_t* data, 1358 bool SendRtp(const uint8_t* data,
1357 size_t length, 1359 size_t length,
1358 const PacketOptions& options) override { 1360 const PacketOptions& options) override {
1359 if (IsDone()) 1361 {
1360 return false; 1362 rtc::CritScope cs(&lock_);
1361
1362 RTPHeader header;
1363 EXPECT_TRUE(parser_->Parse(data, length, &header));
1364 if (header.extension.hasTransportSequenceNumber) {
1365 EXPECT_EQ(options.packet_id,
1366 header.extension.transportSequenceNumber);
1367 if (!streams_observed_.empty()) {
1368 EXPECT_EQ(static_cast<uint16_t>(last_seq_ + 1),
1369 header.extension.transportSequenceNumber);
1370 }
1371 last_seq_ = header.extension.transportSequenceNumber;
1372
1373 size_t payload_length =
1374 length - (header.headerLength + header.paddingLength);
1375 if (payload_length == 0) {
1376 padding_observed_ = true;
1377 } else if (header.payloadType == kSendRtxPayloadType) {
1378 rtx_padding_observed_ = true;
1379 } else {
1380 streams_observed_.insert(header.ssrc);
1381 }
1382 1363
1383 if (IsDone()) 1364 if (IsDone())
1384 done_->Set(); 1365 return false;
1366
1367 if (started_) {
1368 RTPHeader header;
1369 EXPECT_TRUE(parser_->Parse(data, length, &header));
1370 bool drop_packet = false;
1371
1372 EXPECT_TRUE(header.extension.hasTransportSequenceNumber);
1373 EXPECT_EQ(options.packet_id,
1374 header.extension.transportSequenceNumber);
1375 if (!streams_observed_.empty()) {
1376 // Unwrap packet id and verify uniqueness.
1377 int64_t packet_id = unwrapper_.Unwrap(options.packet_id);
1378 EXPECT_TRUE(received_packed_ids_.insert(packet_id).second);
1379 }
1380
1381 // Drop (up to) every 17th packet, so we get retransmits.
1382 // Only drop media, and not on the first stream (otherwise it will be
1383 // hard to distinguish from padding, which is always sent on the first
1384 // stream).
1385 if (header.payloadType != kSendRtxPayloadType &&
1386 header.ssrc != first_media_ssrc_ &&
1387 header.extension.transportSequenceNumber % 17 == 0) {
1388 dropped_seq_[header.ssrc].insert(header.sequenceNumber);
1389 drop_packet = true;
1390 }
1391
1392 size_t payload_length =
1393 length - (header.headerLength + header.paddingLength);
1394 if (payload_length == 0) {
1395 padding_observed_ = true;
1396 } else if (header.payloadType == kSendRtxPayloadType) {
1397 uint16_t original_sequence_number =
1398 ByteReader<uint16_t>::ReadBigEndian(&data[header.headerLength]);
1399 uint32_t original_ssrc =
1400 rtx_to_media_ssrcs_.find(header.ssrc)->second;
1401 std::set<uint16_t>* seq_no_map = &dropped_seq_[original_ssrc];
1402 auto it = seq_no_map->find(original_sequence_number);
1403 if (it != seq_no_map->end()) {
1404 retransmit_observed_ = true;
1405 seq_no_map->erase(it);
1406 } else {
1407 rtx_padding_observed_ = true;
1408 }
1409 } else {
1410 streams_observed_.insert(header.ssrc);
1411 }
1412
1413 if (IsDone())
1414 done_->Set();
1415
1416 if (drop_packet)
1417 return true;
1418 }
1385 } 1419 }
1420
1386 return test::DirectTransport::SendRtp(data, length, options); 1421 return test::DirectTransport::SendRtp(data, length, options);
1387 } 1422 }
1388 1423
1389 bool IsDone() { 1424 bool IsDone() {
1390 return streams_observed_.size() == MultiStreamTest::kNumStreams && 1425 bool observed_types_ok =
1391 padding_observed_ && rtx_padding_observed_; 1426 streams_observed_.size() == MultiStreamTest::kNumStreams &&
1427 padding_observed_ && retransmit_observed_ && rtx_padding_observed_;
1428 if (!observed_types_ok)
1429 return false;
1430 // We should not have any gaps in the sequence number range.
1431 size_t seqno_range =
1432 *received_packed_ids_.rbegin() - *received_packed_ids_.begin() + 1;
1433 return seqno_range == received_packed_ids_.size();
1392 } 1434 }
1393 1435
1394 EventTypeWrapper Wait() { return done_->Wait(kDefaultTimeoutMs); } 1436 EventTypeWrapper Wait() {
1437 {
1438 // Can't be sure until this point that rtx_to_media_ssrcs_ etc have
1439 // been initialized and are OK to read.
1440 rtc::CritScope cs(&lock_);
1441 started_ = true;
1442 }
1443 return done_->Wait(kDefaultTimeoutMs);
1444 }
1395 1445
1446 rtc::CriticalSection lock_;
1396 rtc::scoped_ptr<EventWrapper> done_; 1447 rtc::scoped_ptr<EventWrapper> done_;
1397 rtc::scoped_ptr<RtpHeaderParser> parser_; 1448 rtc::scoped_ptr<RtpHeaderParser> parser_;
1398 uint16_t last_seq_; 1449 SequenceNumberUnwrapper unwrapper_;
1450 std::set<int64_t> received_packed_ids_;
1399 std::set<uint32_t> streams_observed_; 1451 std::set<uint32_t> streams_observed_;
1452 std::map<uint32_t, std::set<uint16_t>> dropped_seq_;
1453 const uint32_t& first_media_ssrc_;
1454 const std::map<uint32_t, uint32_t>& rtx_to_media_ssrcs_;
1400 bool padding_observed_; 1455 bool padding_observed_;
1401 bool rtx_padding_observed_; 1456 bool rtx_padding_observed_;
1457 bool retransmit_observed_;
1458 bool started_;
1402 }; 1459 };
1403 1460
1404 class TransportSequenceNumberTester : public MultiStreamTest { 1461 class TransportSequenceNumberTester : public MultiStreamTest {
1405 public: 1462 public:
1406 TransportSequenceNumberTester() : observer_(nullptr) {} 1463 TransportSequenceNumberTester()
1464 : first_media_ssrc_(0), observer_(nullptr) {}
1407 virtual ~TransportSequenceNumberTester() {} 1465 virtual ~TransportSequenceNumberTester() {}
1408 1466
1409 protected: 1467 protected:
1410 void Wait() override { 1468 void Wait() override {
1411 RTC_DCHECK(observer_ != nullptr); 1469 RTC_DCHECK(observer_ != nullptr);
1412 EXPECT_EQ(EventTypeWrapper::kEventSignaled, observer_->Wait()); 1470 EXPECT_EQ(EventTypeWrapper::kEventSignaled, observer_->Wait());
1413 } 1471 }
1414 1472
1415 void UpdateSendConfig( 1473 void UpdateSendConfig(
1416 size_t stream_index, 1474 size_t stream_index,
1417 VideoSendStream::Config* send_config, 1475 VideoSendStream::Config* send_config,
1418 VideoEncoderConfig* encoder_config, 1476 VideoEncoderConfig* encoder_config,
1419 test::FrameGeneratorCapturer** frame_generator) override { 1477 test::FrameGeneratorCapturer** frame_generator) override {
1420 send_config->rtp.extensions.clear(); 1478 send_config->rtp.extensions.clear();
1421 send_config->rtp.extensions.push_back( 1479 send_config->rtp.extensions.push_back(
1422 RtpExtension(RtpExtension::kTransportSequenceNumber, kExtensionId)); 1480 RtpExtension(RtpExtension::kTransportSequenceNumber, kExtensionId));
1423 1481
1424 // Force some padding to be sent. 1482 // Force some padding to be sent.
1425 const int kPaddingBitrateBps = 50000; 1483 const int kPaddingBitrateBps = 50000;
1426 int total_target_bitrate = 0; 1484 int total_target_bitrate = 0;
1427 for (const VideoStream& stream : encoder_config->streams) 1485 for (const VideoStream& stream : encoder_config->streams)
1428 total_target_bitrate += stream.target_bitrate_bps; 1486 total_target_bitrate += stream.target_bitrate_bps;
1429 encoder_config->min_transmit_bitrate_bps = 1487 encoder_config->min_transmit_bitrate_bps =
1430 total_target_bitrate + kPaddingBitrateBps; 1488 total_target_bitrate + kPaddingBitrateBps;
1431 1489
1432 // Configure RTX for redundant payload padding. 1490 // Configure RTX for redundant payload padding.
1433 send_config->rtp.nack.rtp_history_ms = kNackRtpHistoryMs; 1491 send_config->rtp.nack.rtp_history_ms = kNackRtpHistoryMs;
1434 send_config->rtp.rtx.ssrcs.push_back(kSendRtxSsrcs[0]); 1492 send_config->rtp.rtx.ssrcs.push_back(kSendRtxSsrcs[stream_index]);
1435 send_config->rtp.rtx.payload_type = kSendRtxPayloadType; 1493 send_config->rtp.rtx.payload_type = kSendRtxPayloadType;
1494 rtx_to_media_ssrcs_[kSendRtxSsrcs[stream_index]] =
1495 send_config->rtp.ssrcs[0];
1496
1497 if (stream_index == 0)
1498 first_media_ssrc_ = send_config->rtp.ssrcs[0];
1436 } 1499 }
1437 1500
1438 void UpdateReceiveConfig( 1501 void UpdateReceiveConfig(
1439 size_t stream_index, 1502 size_t stream_index,
1440 VideoReceiveStream::Config* receive_config) override { 1503 VideoReceiveStream::Config* receive_config) override {
1504 receive_config->rtp.nack.rtp_history_ms = kNackRtpHistoryMs;
1441 receive_config->rtp.extensions.clear(); 1505 receive_config->rtp.extensions.clear();
1442 receive_config->rtp.extensions.push_back( 1506 receive_config->rtp.extensions.push_back(
1443 RtpExtension(RtpExtension::kTransportSequenceNumber, kExtensionId)); 1507 RtpExtension(RtpExtension::kTransportSequenceNumber, kExtensionId));
1444 } 1508 }
1445 1509
1446 virtual test::DirectTransport* CreateSendTransport() { 1510 virtual test::DirectTransport* CreateSendTransport() {
1447 observer_ = new RtpExtensionHeaderObserver(); 1511 observer_ = new RtpExtensionHeaderObserver(first_media_ssrc_,
1512 rtx_to_media_ssrcs_);
1448 return observer_; 1513 return observer_;
1449 } 1514 }
1450 1515
1451 private: 1516 private:
1517 uint32_t first_media_ssrc_;
1518 std::map<uint32_t, uint32_t> rtx_to_media_ssrcs_;
1452 RtpExtensionHeaderObserver* observer_; 1519 RtpExtensionHeaderObserver* observer_;
1453 } tester; 1520 } tester;
1454 1521
1455 tester.RunTest(); 1522 tester.RunTest();
1456 } 1523 }
1457 1524
1458 TEST_F(EndToEndTest, ReceivesTransportFeedback) { 1525 TEST_F(EndToEndTest, ReceivesTransportFeedback) {
1459 static const int kExtensionId = 5; 1526 static const int kExtensionId = 5;
1460 1527
1461 class TransportFeedbackObserver : public test::DirectTransport { 1528 class TransportFeedbackObserver : public test::DirectTransport {
(...skipping 1669 matching lines...) Expand 10 before | Expand all | Expand 10 after
3131 EXPECT_TRUE(default_receive_config.rtp.rtx.empty()) 3198 EXPECT_TRUE(default_receive_config.rtp.rtx.empty())
3132 << "Enabling RTX requires rtpmap: rtx negotiation."; 3199 << "Enabling RTX requires rtpmap: rtx negotiation.";
3133 EXPECT_TRUE(default_receive_config.rtp.extensions.empty()) 3200 EXPECT_TRUE(default_receive_config.rtp.extensions.empty())
3134 << "Enabling RTP extensions require negotiation."; 3201 << "Enabling RTP extensions require negotiation.";
3135 3202
3136 VerifyEmptyNackConfig(default_receive_config.rtp.nack); 3203 VerifyEmptyNackConfig(default_receive_config.rtp.nack);
3137 VerifyEmptyFecConfig(default_receive_config.rtp.fec); 3204 VerifyEmptyFecConfig(default_receive_config.rtp.fec);
3138 } 3205 }
3139 3206
3140 } // namespace webrtc 3207 } // namespace webrtc
OLDNEW
« 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