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 d036474c13d3888e606f38dc0034990ff61061ae..3724d4779f6c213a611c23aa9113c8c4240d6c02 100644 |
--- a/webrtc/video/end_to_end_tests.cc |
+++ b/webrtc/video/end_to_end_tests.cc |
@@ -9,6 +9,7 @@ |
*/ |
#include <algorithm> |
#include <map> |
+#include <set> |
#include <sstream> |
#include <string> |
@@ -2930,7 +2931,7 @@ TEST_F(EndToEndTest, DISABLED_RedundantPayloadsTransmittedOnAllSsrcs) { |
void EndToEndTest::TestRtpStatePreservation(bool use_rtx) { |
static const uint32_t kMaxSequenceNumberGap = 100; |
- static const uint64_t kMaxTimestampGap = kDefaultTimeoutMs * 90; |
+ static const uint32_t kMaxTimestampGap = kDefaultTimeoutMs * 90; |
class RtpSequenceObserver : public test::RtpRtcpObserver { |
public: |
explicit RtpSequenceObserver(bool use_rtx) |
@@ -2945,19 +2946,38 @@ void EndToEndTest::TestRtpStatePreservation(bool use_rtx) { |
void ResetExpectedSsrcs(size_t num_expected_ssrcs) { |
rtc::CritScope lock(&crit_); |
- ssrc_observed_.clear(); |
+ ssrc_observed_rtp_.clear(); |
+ ssrc_observed_rtcp_sr_.clear(); |
ssrcs_to_observe_ = num_expected_ssrcs; |
} |
private: |
+ void ValidateTimestampGap(uint32_t ssrc, uint32_t timestamp) { |
pbos-webrtc
2016/01/28 10:25:06
Can you use TimeDiff or TimeIsBetween in webrtc/ba
danilchap
2016/01/28 10:44:09
Thanks, that makes test more clear what is checked
|
+ auto find_timestamp = last_observed_timestamp_.find(ssrc); |
+ if (find_timestamp == last_observed_timestamp_.end()) { |
+ last_observed_timestamp_[ssrc] = timestamp; |
+ } else { |
+ // Use unsigned operation to automagicaly manage roll-over. |
+ uint32_t timestamp_gap = timestamp - find_timestamp->second; |
+ if (timestamp_gap >= 0x80000000) { // negative - negate. |
+ timestamp_gap = (0xffffffff - timestamp_gap) + 1; |
+ } |
+ // It is normal for the gap to be negative: RTCP with current time |
+ // can be sent just before RTP with capture time. |
+ EXPECT_LE(timestamp_gap, kMaxTimestampGap) |
+ << "Gap in timestamps (" |
+ << find_timestamp->second |
+ << " -> " << timestamp << ") too large for SSRC: " << ssrc << "."; |
+ find_timestamp->second = timestamp; |
+ } |
+ } |
+ |
Action OnSendRtp(const uint8_t* packet, size_t length) override { |
RTPHeader header; |
EXPECT_TRUE(parser_->Parse(packet, length, &header)); |
const uint32_t ssrc = header.ssrc; |
const uint16_t sequence_number = header.sequenceNumber; |
const uint32_t timestamp = header.timestamp; |
- const bool only_padding = |
- header.headerLength + header.paddingLength == length; |
EXPECT_TRUE(configured_ssrcs_[ssrc]) |
<< "Received SSRC that wasn't configured: " << ssrc; |
@@ -2966,7 +2986,6 @@ void EndToEndTest::TestRtpStatePreservation(bool use_rtx) { |
last_observed_sequence_number_.find(header.ssrc); |
if (it == last_observed_sequence_number_.end()) { |
last_observed_sequence_number_[ssrc] = sequence_number; |
- last_observed_timestamp_[ssrc] = timestamp; |
} else { |
// Verify sequence numbers are reasonably close. |
uint32_t extended_sequence_number = sequence_number; |
@@ -2980,35 +2999,35 @@ void EndToEndTest::TestRtpStatePreservation(bool use_rtx) { |
<< last_observed_sequence_number_[ssrc] << " -> " << sequence_number |
<< ") too large for SSRC: " << ssrc << "."; |
last_observed_sequence_number_[ssrc] = sequence_number; |
- |
- // TODO(pbos): Remove this check if we ever have monotonically |
- // increasing timestamps. Right now padding packets add a delta which |
- // can cause reordering between padding packets and regular packets, |
- // hence we drop padding-only packets to not flake. |
- if (only_padding) { |
- // Verify that timestamps are reasonably close. |
- uint64_t extended_timestamp = timestamp; |
- // Check for roll-over. |
- if (timestamp < last_observed_timestamp_[ssrc]) |
- extended_timestamp += static_cast<uint64_t>(0xFFFFFFFFu) + 1; |
- EXPECT_LE(extended_timestamp - last_observed_timestamp_[ssrc], |
- kMaxTimestampGap) |
- << "Gap in timestamps (" << last_observed_timestamp_[ssrc] |
- << " -> " << timestamp << ") too large for SSRC: " << ssrc << "."; |
- } |
- last_observed_timestamp_[ssrc] = timestamp; |
} |
+ ValidateTimestampGap(ssrc, timestamp); |
rtc::CritScope lock(&crit_); |
- // Wait for media packets on all ssrcs. |
- if (!ssrc_observed_[ssrc] && !only_padding) { |
- ssrc_observed_[ssrc] = true; |
- if (--ssrcs_to_observe_ == 0) |
- observation_complete_.Set(); |
+ ssrc_observed_rtp_.insert(ssrc); |
+ if (ssrc_observed_rtcp_sr_.size() >= ssrcs_to_observe_ && |
+ ssrc_observed_rtp_.size() >= ssrcs_to_observe_) { |
+ observation_complete_.Set(); |
} |
return SEND_PACKET; |
} |
+ Action OnSendRtcp(const uint8_t* packet, size_t length) override { |
+ test::RtcpPacketParser rtcp_parser; |
+ rtcp_parser.Parse(packet, length); |
+ if (rtcp_parser.sender_report()->num_packets() > 0) { |
+ uint32_t ssrc = rtcp_parser.sender_report()->Ssrc(); |
+ uint32_t rtcp_timestamp = rtcp_parser.sender_report()->RtpTimestamp(); |
+ ValidateTimestampGap(ssrc, rtcp_timestamp); |
+ |
+ rtc::CritScope lock(&crit_); |
+ ssrc_observed_rtcp_sr_.insert(ssrc); |
+ if (ssrc_observed_rtcp_sr_.size() >= ssrcs_to_observe_ && |
+ ssrc_observed_rtp_.size() >= ssrcs_to_observe_) { |
+ observation_complete_.Set(); |
+ } |
+ } |
+ return SEND_PACKET; |
+ } |
std::map<uint32_t, uint16_t> last_observed_sequence_number_; |
std::map<uint32_t, uint32_t> last_observed_timestamp_; |
@@ -3016,7 +3035,8 @@ void EndToEndTest::TestRtpStatePreservation(bool use_rtx) { |
rtc::CriticalSection crit_; |
size_t ssrcs_to_observe_ GUARDED_BY(crit_); |
- std::map<uint32_t, bool> ssrc_observed_ GUARDED_BY(crit_); |
+ std::set<uint32_t> ssrc_observed_rtp_ GUARDED_BY(crit_); |
+ std::set<uint32_t> ssrc_observed_rtcp_sr_ GUARDED_BY(crit_); |
} observer(use_rtx); |
CreateCalls(Call::Config(), Call::Config()); |