diff --git a/api/rtp_receiver_interface.cc b/api/rtp_receiver_interface.cc index 52f72df45d..efa7f1b8c1 100644 --- a/api/rtp_receiver_interface.cc +++ b/api/rtp_receiver_interface.cc @@ -12,12 +12,24 @@ namespace webrtc { +RtpSource::RtpSource(int64_t timestamp_ms, + uint32_t source_id, + RtpSourceType source_type, + absl::optional audio_level, + uint32_t rtp_timestamp) + : timestamp_ms_(timestamp_ms), + source_id_(source_id), + source_type_(source_type), + audio_level_(audio_level), + rtp_timestamp_(rtp_timestamp) {} + RtpSource::RtpSource(int64_t timestamp_ms, uint32_t source_id, RtpSourceType source_type) : timestamp_ms_(timestamp_ms), source_id_(source_id), - source_type_(source_type) {} + source_type_(source_type), + rtp_timestamp_(0) {} RtpSource::RtpSource(int64_t timestamp_ms, uint32_t source_id, @@ -26,7 +38,8 @@ RtpSource::RtpSource(int64_t timestamp_ms, : timestamp_ms_(timestamp_ms), source_id_(source_id), source_type_(source_type), - audio_level_(audio_level) {} + audio_level_(audio_level), + rtp_timestamp_(0) {} RtpSource::RtpSource(const RtpSource&) = default; RtpSource& RtpSource::operator=(const RtpSource&) = default; diff --git a/api/rtp_receiver_interface.h b/api/rtp_receiver_interface.h index 3934215cce..f79bf8f50a 100644 --- a/api/rtp_receiver_interface.h +++ b/api/rtp_receiver_interface.h @@ -24,6 +24,7 @@ #include "api/proxy.h" #include "api/rtp_parameters.h" #include "api/scoped_refptr.h" +#include "rtc_base/deprecation.h" #include "rtc_base/ref_count.h" namespace webrtc { @@ -36,13 +37,23 @@ enum class RtpSourceType { class RtpSource { public: RtpSource() = delete; - RtpSource(int64_t timestamp_ms, - uint32_t source_id, - RtpSourceType source_type); + RtpSource(int64_t timestamp_ms, uint32_t source_id, RtpSourceType source_type, - uint8_t audio_level); + absl::optional audio_level, + uint32_t rtp_timestamp); + + // DEPRECATED: Will be removed after 2019-07-31. + RTC_DEPRECATED RtpSource(int64_t timestamp_ms, + uint32_t source_id, + RtpSourceType source_type); + // DEPRECATED: Will be removed after 2019-07-31. + RTC_DEPRECATED RtpSource(int64_t timestamp_ms, + uint32_t source_id, + RtpSourceType source_type, + uint8_t audio_level); + RtpSource(const RtpSource&); RtpSource& operator=(const RtpSource&); ~RtpSource(); @@ -64,9 +75,12 @@ class RtpSource { audio_level_ = level; } + uint32_t rtp_timestamp() const { return rtp_timestamp_; } + bool operator==(const RtpSource& o) const { return timestamp_ms_ == o.timestamp_ms() && source_id_ == o.source_id() && - source_type_ == o.source_type() && audio_level_ == o.audio_level_; + source_type_ == o.source_type() && audio_level_ == o.audio_level_ && + rtp_timestamp_ == o.rtp_timestamp(); } private: @@ -74,6 +88,7 @@ class RtpSource { uint32_t source_id_; RtpSourceType source_type_; absl::optional audio_level_; + uint32_t rtp_timestamp_; }; class RtpReceiverObserverInterface { diff --git a/audio/channel_receive.cc b/audio/channel_receive.cc index 85a029d877..5f59275027 100644 --- a/audio/channel_receive.cc +++ b/audio/channel_receive.cc @@ -564,9 +564,10 @@ std::vector ChannelReceive::GetSources() const { sources = contributing_sources_.GetSources(now_ms); if (last_received_rtp_system_time_ms_ >= now_ms - ContributingSources::kHistoryMs) { + RTC_DCHECK(last_received_rtp_timestamp_.has_value()); sources.emplace_back(*last_received_rtp_system_time_ms_, remote_ssrc_, - RtpSourceType::SSRC); - sources.back().set_audio_level(last_received_rtp_audio_level_); + RtpSourceType::SSRC, last_received_rtp_audio_level_, + *last_received_rtp_timestamp_); } } return sources; @@ -599,7 +600,8 @@ void ChannelReceive::OnRtpPacket(const RtpPacketReceived& packet) { std::vector csrcs = packet.Csrcs(); contributing_sources_.Update( now_ms, csrcs, - has_audio_level ? absl::optional(audio_level) : absl::nullopt); + has_audio_level ? absl::optional(audio_level) : absl::nullopt, + packet.Timestamp()); } // Store playout timestamp for the received RTP packet diff --git a/modules/rtp_rtcp/source/contributing_sources.cc b/modules/rtp_rtcp/source/contributing_sources.cc index 64dc443e29..88274ff191 100644 --- a/modules/rtp_rtcp/source/contributing_sources.cc +++ b/modules/rtp_rtcp/source/contributing_sources.cc @@ -26,8 +26,9 @@ ContributingSources::~ContributingSources() = default; void ContributingSources::Update(int64_t now_ms, rtc::ArrayView csrcs, - absl::optional audio_level) { - Entry entry = { now_ms, audio_level }; + absl::optional audio_level, + uint32_t rtp_timestamp) { + Entry entry = {now_ms, audio_level, rtp_timestamp}; for (uint32_t csrc : csrcs) { active_csrcs_[csrc] = entry; } @@ -47,14 +48,9 @@ std::vector ContributingSources::GetSources(int64_t now_ms) const { std::vector sources; for (auto& record : active_csrcs_) { if (record.second.last_seen_ms >= now_ms - kHistoryMs) { - if (record.second.audio_level.has_value()) { - sources.emplace_back(record.second.last_seen_ms, record.first, - RtpSourceType::CSRC, - *record.second.audio_level); - } else { - sources.emplace_back(record.second.last_seen_ms, record.first, - RtpSourceType::CSRC); - } + sources.emplace_back(record.second.last_seen_ms, record.first, + RtpSourceType::CSRC, record.second.audio_level, + record.second.rtp_timestamp); } } @@ -76,7 +72,10 @@ void ContributingSources::DeleteOldEntries(int64_t now_ms) { ContributingSources::Entry::Entry() = default; ContributingSources::Entry::Entry(int64_t timestamp_ms, - absl::optional audio_level_arg) - : last_seen_ms(timestamp_ms), audio_level(audio_level_arg) {} + absl::optional audio_level_arg, + uint32_t rtp_timestamp) + : last_seen_ms(timestamp_ms), + audio_level(audio_level_arg), + rtp_timestamp(rtp_timestamp) {} } // namespace webrtc diff --git a/modules/rtp_rtcp/source/contributing_sources.h b/modules/rtp_rtcp/source/contributing_sources.h index 81bf725715..67e8967922 100644 --- a/modules/rtp_rtcp/source/contributing_sources.h +++ b/modules/rtp_rtcp/source/contributing_sources.h @@ -32,8 +32,10 @@ class ContributingSources { ContributingSources(); ~ContributingSources(); - void Update(int64_t now_ms, rtc::ArrayView csrcs, - absl::optional audio_level); + void Update(int64_t now_ms, + rtc::ArrayView csrcs, + absl::optional audio_level, + uint32_t rtp_timestamp); // Returns contributing sources seen the last 10 s. std::vector GetSources(int64_t now_ms) const; @@ -41,10 +43,13 @@ class ContributingSources { private: struct Entry { Entry(); - Entry(int64_t timestamp_ms, absl::optional audio_level); + Entry(int64_t timestamp_ms, + absl::optional audio_level, + uint32_t rtp_timestamp); int64_t last_seen_ms; absl::optional audio_level; + uint32_t rtp_timestamp; }; void DeleteOldEntries(int64_t now_ms); diff --git a/modules/rtp_rtcp/source/contributing_sources_unittest.cc b/modules/rtp_rtcp/source/contributing_sources_unittest.cc index 38d25cebc9..acf8a90bab 100644 --- a/modules/rtp_rtcp/source/contributing_sources_unittest.cc +++ b/modules/rtp_rtcp/source/contributing_sources_unittest.cc @@ -23,6 +23,9 @@ using ::testing::UnorderedElementsAre; constexpr uint32_t kCsrc1 = 111; constexpr uint32_t kCsrc2 = 222; constexpr uint32_t kCsrc3 = 333; +constexpr uint32_t kRtpTimestamp1 = 314; +constexpr uint32_t kRtpTimestamp2 = 315; +constexpr uint32_t kRtpTimestamp3 = 316; } // namespace @@ -30,11 +33,13 @@ TEST(ContributingSourcesTest, RecordSources) { ContributingSources csrcs; constexpr uint32_t kCsrcs[] = {kCsrc1, kCsrc2}; constexpr int64_t kTime1 = 10; - csrcs.Update(kTime1, kCsrcs, absl::nullopt); + csrcs.Update(kTime1, kCsrcs, absl::nullopt, kRtpTimestamp1); EXPECT_THAT( csrcs.GetSources(kTime1), - UnorderedElementsAre(RtpSource(kTime1, kCsrc1, RtpSourceType::CSRC), - RtpSource(kTime1, kCsrc2, RtpSourceType::CSRC))); + UnorderedElementsAre(RtpSource(kTime1, kCsrc1, RtpSourceType::CSRC, + absl::nullopt, kRtpTimestamp1), + RtpSource(kTime1, kCsrc2, RtpSourceType::CSRC, + absl::nullopt, kRtpTimestamp1))); } TEST(ContributingSourcesTest, UpdateSources) { @@ -45,17 +50,22 @@ TEST(ContributingSourcesTest, UpdateSources) { constexpr uint32_t kCsrcs2[] = {kCsrc2, kCsrc3}; constexpr int64_t kTime1 = 10; constexpr int64_t kTime2 = kTime1 + 5 * rtc::kNumMillisecsPerSec; - csrcs.Update(kTime1, kCsrcs1, absl::nullopt); + csrcs.Update(kTime1, kCsrcs1, absl::nullopt, kRtpTimestamp1); EXPECT_THAT( csrcs.GetSources(kTime1), - UnorderedElementsAre(RtpSource(kTime1, kCsrc1, RtpSourceType::CSRC), - RtpSource(kTime1, kCsrc2, RtpSourceType::CSRC))); - csrcs.Update(kTime2, kCsrcs2, absl::nullopt); + UnorderedElementsAre(RtpSource(kTime1, kCsrc1, RtpSourceType::CSRC, + absl::nullopt, kRtpTimestamp1), + RtpSource(kTime1, kCsrc2, RtpSourceType::CSRC, + absl::nullopt, kRtpTimestamp1))); + csrcs.Update(kTime2, kCsrcs2, absl::nullopt, kRtpTimestamp2); EXPECT_THAT( csrcs.GetSources(kTime2), - UnorderedElementsAre(RtpSource(kTime1, kCsrc1, RtpSourceType::CSRC), - RtpSource(kTime2, kCsrc2, RtpSourceType::CSRC), - RtpSource(kTime2, kCsrc3, RtpSourceType::CSRC))); + UnorderedElementsAre(RtpSource(kTime1, kCsrc1, RtpSourceType::CSRC, + absl::nullopt, kRtpTimestamp1), + RtpSource(kTime2, kCsrc2, RtpSourceType::CSRC, + absl::nullopt, kRtpTimestamp2), + RtpSource(kTime2, kCsrc3, RtpSourceType::CSRC, + absl::nullopt, kRtpTimestamp2))); } TEST(ContributingSourcesTest, ReturnRecentOnly) { @@ -65,16 +75,20 @@ TEST(ContributingSourcesTest, ReturnRecentOnly) { constexpr int64_t kTime1 = 10; constexpr int64_t kTime2 = kTime1 + 5 * rtc::kNumMillisecsPerSec; constexpr int64_t kTime3 = kTime1 + 12 * rtc::kNumMillisecsPerSec; - csrcs.Update(kTime1, kCsrcs1, absl::nullopt); + csrcs.Update(kTime1, kCsrcs1, absl::nullopt, kRtpTimestamp1); EXPECT_THAT( csrcs.GetSources(kTime1), - UnorderedElementsAre(RtpSource(kTime1, kCsrc1, RtpSourceType::CSRC), - RtpSource(kTime1, kCsrc2, RtpSourceType::CSRC))); - csrcs.Update(kTime2, kCsrcs2, absl::nullopt); + UnorderedElementsAre(RtpSource(kTime1, kCsrc1, RtpSourceType::CSRC, + absl::nullopt, kRtpTimestamp1), + RtpSource(kTime1, kCsrc2, RtpSourceType::CSRC, + absl::nullopt, kRtpTimestamp1))); + csrcs.Update(kTime2, kCsrcs2, absl::nullopt, kRtpTimestamp2); EXPECT_THAT( csrcs.GetSources(kTime3), - UnorderedElementsAre(RtpSource(kTime2, kCsrc2, RtpSourceType::CSRC), - RtpSource(kTime2, kCsrc3, RtpSourceType::CSRC))); + UnorderedElementsAre(RtpSource(kTime2, kCsrc2, RtpSourceType::CSRC, + absl::nullopt, kRtpTimestamp2), + RtpSource(kTime2, kCsrc3, RtpSourceType::CSRC, + absl::nullopt, kRtpTimestamp2))); } TEST(ContributingSourcesTest, PurgeOldSources) { @@ -84,46 +98,58 @@ TEST(ContributingSourcesTest, PurgeOldSources) { constexpr int64_t kTime1 = 10; constexpr int64_t kTime2 = kTime1 + 10 * rtc::kNumMillisecsPerSec; constexpr int64_t kTime3 = kTime1 + 20 * rtc::kNumMillisecsPerSec; - csrcs.Update(kTime1, kCsrcs1, absl::nullopt); + csrcs.Update(kTime1, kCsrcs1, absl::nullopt, kRtpTimestamp1); EXPECT_THAT( csrcs.GetSources(kTime2), - UnorderedElementsAre(RtpSource(kTime1, kCsrc1, RtpSourceType::CSRC), - RtpSource(kTime1, kCsrc2, RtpSourceType::CSRC))); - csrcs.Update(kTime2, kCsrcs2, absl::nullopt); + UnorderedElementsAre(RtpSource(kTime1, kCsrc1, RtpSourceType::CSRC, + absl::nullopt, kRtpTimestamp1), + RtpSource(kTime1, kCsrc2, RtpSourceType::CSRC, + absl::nullopt, kRtpTimestamp1))); + csrcs.Update(kTime2, kCsrcs2, absl::nullopt, kRtpTimestamp2); EXPECT_THAT( csrcs.GetSources(kTime2), - UnorderedElementsAre(RtpSource(kTime1, kCsrc1, RtpSourceType::CSRC), - RtpSource(kTime2, kCsrc2, RtpSourceType::CSRC), - RtpSource(kTime2, kCsrc3, RtpSourceType::CSRC))); - csrcs.Update(kTime3, kCsrcs2, absl::nullopt); + UnorderedElementsAre(RtpSource(kTime1, kCsrc1, RtpSourceType::CSRC, + absl::nullopt, kRtpTimestamp1), + RtpSource(kTime2, kCsrc2, RtpSourceType::CSRC, + absl::nullopt, kRtpTimestamp2), + RtpSource(kTime2, kCsrc3, RtpSourceType::CSRC, + absl::nullopt, kRtpTimestamp2))); + csrcs.Update(kTime3, kCsrcs2, absl::nullopt, kRtpTimestamp3); EXPECT_THAT( csrcs.GetSources(kTime3), - UnorderedElementsAre(RtpSource(kTime3, kCsrc2, RtpSourceType::CSRC), - RtpSource(kTime3, kCsrc3, RtpSourceType::CSRC))); + UnorderedElementsAre(RtpSource(kTime3, kCsrc2, RtpSourceType::CSRC, + absl::nullopt, kRtpTimestamp3), + RtpSource(kTime3, kCsrc3, RtpSourceType::CSRC, + absl::nullopt, kRtpTimestamp3))); // Query at an earlier time; check that old sources really have been purged // and don't reappear. EXPECT_THAT( csrcs.GetSources(kTime2), - UnorderedElementsAre(RtpSource(kTime3, kCsrc2, RtpSourceType::CSRC), - RtpSource(kTime3, kCsrc3, RtpSourceType::CSRC))); + UnorderedElementsAre(RtpSource(kTime3, kCsrc2, RtpSourceType::CSRC, + absl::nullopt, kRtpTimestamp3), + RtpSource(kTime3, kCsrc3, RtpSourceType::CSRC, + absl::nullopt, kRtpTimestamp3))); } TEST(ContributingSourcesTest, AudioLevel) { ContributingSources csrcs; constexpr uint32_t kCsrcs[] = {kCsrc1, kCsrc2}; constexpr int64_t kTime1 = 10; - csrcs.Update(kTime1, kCsrcs, 47); + csrcs.Update(kTime1, kCsrcs, 47, kRtpTimestamp1); EXPECT_THAT( csrcs.GetSources(kTime1), - UnorderedElementsAre(RtpSource(kTime1, kCsrc1, RtpSourceType::CSRC, 47), - RtpSource(kTime1, kCsrc2, RtpSourceType::CSRC, 47))); + UnorderedElementsAre( + RtpSource(kTime1, kCsrc1, RtpSourceType::CSRC, 47, kRtpTimestamp1), + RtpSource(kTime1, kCsrc2, RtpSourceType::CSRC, 47, kRtpTimestamp1))); constexpr uint32_t kCsrcsSubset[] = {kCsrc1}; - csrcs.Update(kTime1 + 1, kCsrcsSubset, absl::nullopt); + csrcs.Update(kTime1 + 1, kCsrcsSubset, absl::nullopt, kRtpTimestamp2); EXPECT_THAT( csrcs.GetSources(kTime1 + 1), - UnorderedElementsAre(RtpSource(kTime1 + 1, kCsrc1, RtpSourceType::CSRC), - RtpSource(kTime1, kCsrc2, RtpSourceType::CSRC, 47))); + UnorderedElementsAre( + RtpSource(kTime1 + 1, kCsrc1, RtpSourceType::CSRC, absl::nullopt, + kRtpTimestamp2), + RtpSource(kTime1, kCsrc2, RtpSourceType::CSRC, 47, kRtpTimestamp1))); } } // namespace webrtc diff --git a/video/rtp_video_stream_receiver.cc b/video/rtp_video_stream_receiver.cc index 305b8bd898..edced5d6b2 100644 --- a/video/rtp_video_stream_receiver.cc +++ b/video/rtp_video_stream_receiver.cc @@ -326,7 +326,8 @@ void RtpVideoStreamReceiver::OnRtpPacket(const RtpPacketReceived& packet) { std::vector csrcs = packet.Csrcs(); contributing_sources_.Update(now_ms, csrcs, - /* audio level */ absl::nullopt); + /* audio level */ absl::nullopt, + packet.Timestamp()); } // Periodically log the RTP header of incoming packets. if (now_ms - last_packet_log_ms_ > kPacketLogIntervalMs) { @@ -781,8 +782,11 @@ std::vector RtpVideoStreamReceiver::GetSources() const { sources = contributing_sources_.GetSources(now_ms); if (last_received_rtp_system_time_ms_ >= now_ms - ContributingSources::kHistoryMs) { + RTC_DCHECK(last_received_rtp_timestamp_.has_value()); sources.emplace_back(*last_received_rtp_system_time_ms_, - config_.rtp.remote_ssrc, RtpSourceType::SSRC); + config_.rtp.remote_ssrc, RtpSourceType::SSRC, + /* audio_level */ absl::nullopt, + *last_received_rtp_timestamp_); } } return sources;