OLD | NEW |
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 Loading... |
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 Loading... |
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 |
OLD | NEW |