diff --git a/logging/rtc_event_log/encoder/rtc_event_log_encoder_unittest.cc b/logging/rtc_event_log/encoder/rtc_event_log_encoder_unittest.cc index 6fae2d9cd6..458b5af894 100644 --- a/logging/rtc_event_log/encoder/rtc_event_log_encoder_unittest.cc +++ b/logging/rtc_event_log/encoder/rtc_event_log_encoder_unittest.cc @@ -1035,6 +1035,44 @@ TEST_P(RtcEventLogEncoderTest, RtcEventRtcpPli) { } } +TEST_P(RtcEventLogEncoderTest, RtcEventRtcpBye) { + if (force_repeated_fields_) { + return; + } + + rtc::ScopedFakeClock fake_clock; + fake_clock.SetTime(Timestamp::Millis(prng_.Rand())); + + for (auto direction : {kIncomingPacket, kOutgoingPacket}) { + std::vector events(event_count_); + std::vector timestamps_us(event_count_); + for (size_t i = 0; i < event_count_; ++i) { + timestamps_us[i] = rtc::TimeMicros(); + events[i] = gen_.NewBye(); + rtc::Buffer buffer = events[i].Build(); + if (direction == kIncomingPacket) { + history_.push_back( + std::make_unique(buffer)); + } else { + history_.push_back( + std::make_unique(buffer)); + } + fake_clock.AdvanceTime(TimeDelta::Millis(prng_.Rand(0, 1000))); + } + + std::string encoded = + encoder_->EncodeBatch(history_.begin(), history_.end()); + ASSERT_TRUE(parsed_log_.ParseString(encoded).ok()); + + const auto& byes = parsed_log_.byes(direction); + ASSERT_EQ(byes.size(), event_count_); + + for (size_t i = 0; i < event_count_; ++i) { + verifier_.VerifyLoggedBye(timestamps_us[i], events[i], byes[i]); + } + } +} + TEST_P(RtcEventLogEncoderTest, RtcEventRtcpNack) { if (force_repeated_fields_) { return; diff --git a/logging/rtc_event_log/logged_events.h b/logging/rtc_event_log/logged_events.h index 1ed21befe0..da7653d392 100644 --- a/logging/rtc_event_log/logged_events.h +++ b/logging/rtc_event_log/logged_events.h @@ -17,6 +17,7 @@ #include "api/rtp_headers.h" #include "api/units/time_delta.h" #include "api/units/timestamp.h" +#include "modules/rtp_rtcp/source/rtcp_packet/bye.h" #include "modules/rtp_rtcp/source/rtcp_packet/extended_reports.h" #include "modules/rtp_rtcp/source/rtcp_packet/fir.h" #include "modules/rtp_rtcp/source/rtcp_packet/loss_notification.h" @@ -228,6 +229,16 @@ struct LoggedRtcpPacketLossNotification { rtcp::LossNotification loss_notification; }; +struct LoggedRtcpPacketBye { + LoggedRtcpPacketBye() = default; + + int64_t log_time_us() const { return timestamp_us; } + int64_t log_time_ms() const { return timestamp_us / 1000; } + + int64_t timestamp_us; + rtcp::Bye bye; +}; + struct LoggedStartEvent { explicit LoggedStartEvent(int64_t timestamp_us) : LoggedStartEvent(timestamp_us, timestamp_us / 1000) {} diff --git a/logging/rtc_event_log/rtc_event_log_parser.cc b/logging/rtc_event_log/rtc_event_log_parser.cc index 59a722c7f3..bdc093b759 100644 --- a/logging/rtc_event_log/rtc_event_log_parser.cc +++ b/logging/rtc_event_log/rtc_event_log_parser.cc @@ -694,6 +694,7 @@ ParsedRtcEventLog::ParseStatus StoreRtcpBlocks( std::vector* nack_list, std::vector* fir_list, std::vector* pli_list, + std::vector* bye_list, std::vector* transport_feedback_list, std::vector* loss_notification_list) { rtcp::CommonHeader header; @@ -738,7 +739,13 @@ ParsedRtcEventLog::ParseStatus StoreRtcpBlocks( if (parsed_block.pli.Parse(header)) { pli_list->push_back(std::move(parsed_block)); } - } else if (header.type() == rtcp::Remb::kPacketType && + } else if (header.type() == rtcp::Bye::kPacketType) { + LoggedRtcpPacketBye parsed_block; + parsed_block.timestamp_us = timestamp_us; + if (parsed_block.bye.Parse(header)) { + bye_list->push_back(std::move(parsed_block)); + } + } else if (header.type() == rtcp::Psfb::kPacketType && header.fmt() == rtcp::Psfb::kAfbMessageType) { bool type_found = false; if (!type_found) { @@ -1182,7 +1189,7 @@ ParsedRtcEventLog::ParseStatus ParsedRtcEventLog::ParseStream( auto status = StoreRtcpBlocks( timestamp_us, packet_begin, packet_end, &incoming_sr_, &incoming_rr_, &incoming_xr_, &incoming_remb_, &incoming_nack_, &incoming_fir_, - &incoming_pli_, &incoming_transport_feedback_, + &incoming_pli_, &incoming_bye_, &incoming_transport_feedback_, &incoming_loss_notification_); RTC_RETURN_IF_ERROR(status); } @@ -1194,7 +1201,7 @@ ParsedRtcEventLog::ParseStatus ParsedRtcEventLog::ParseStream( auto status = StoreRtcpBlocks( timestamp_us, packet_begin, packet_end, &outgoing_sr_, &outgoing_rr_, &outgoing_xr_, &outgoing_remb_, &outgoing_nack_, &outgoing_fir_, - &outgoing_pli_, &outgoing_transport_feedback_, + &outgoing_pli_, &outgoing_bye_, &outgoing_transport_feedback_, &outgoing_loss_notification_); RTC_RETURN_IF_ERROR(status); } diff --git a/logging/rtc_event_log/rtc_event_log_parser.h b/logging/rtc_event_log/rtc_event_log_parser.h index d890792a39..841bbf7d05 100644 --- a/logging/rtc_event_log/rtc_event_log_parser.h +++ b/logging/rtc_event_log/rtc_event_log_parser.h @@ -603,6 +603,15 @@ class ParsedRtcEventLog { } } + const std::vector& byes( + PacketDirection direction) const { + if (direction == kIncomingPacket) { + return incoming_bye_; + } else { + return outgoing_bye_; + } + } + const std::vector& transport_feedbacks( PacketDirection direction) const { if (direction == kIncomingPacket) { @@ -849,6 +858,8 @@ class ParsedRtcEventLog { std::vector outgoing_fir_; std::vector incoming_pli_; std::vector outgoing_pli_; + std::vector incoming_bye_; + std::vector outgoing_bye_; std::vector incoming_transport_feedback_; std::vector outgoing_transport_feedback_; std::vector incoming_loss_notification_; diff --git a/logging/rtc_event_log/rtc_event_log_unittest_helper.cc b/logging/rtc_event_log/rtc_event_log_unittest_helper.cc index 2896c130f2..7ad0ad68e8 100644 --- a/logging/rtc_event_log/rtc_event_log_unittest_helper.cc +++ b/logging/rtc_event_log/rtc_event_log_unittest_helper.cc @@ -338,6 +338,19 @@ rtcp::Pli EventGenerator::NewPli() { return pli; } +rtcp::Bye EventGenerator::NewBye() { + rtcp::Bye bye; + bye.SetSenderSsrc(prng_.Rand()); + std::vector csrcs{prng_.Rand(), prng_.Rand()}; + bye.SetCsrcs(csrcs); + if (prng_.Rand(0, 2)) { + bye.SetReason("foo"); + } else { + bye.SetReason("bar"); + } + return bye; +} + rtcp::TransportFeedback EventGenerator::NewTransportFeedback() { rtcp::TransportFeedback transport_feedback; uint16_t base_seq_no = prng_.Rand(); @@ -396,6 +409,7 @@ EventGenerator::NewRtcpPacketIncoming() { kPli, kNack, kRemb, + kBye, kTransportFeedback, kNumValues }; @@ -437,6 +451,11 @@ EventGenerator::NewRtcpPacketIncoming() { rtc::Buffer buffer = remb.Build(); return std::make_unique(buffer); } + case SupportedRtcpTypes::kBye: { + rtcp::Bye bye = NewBye(); + rtc::Buffer buffer = bye.Build(); + return std::make_unique(buffer); + } case SupportedRtcpTypes::kTransportFeedback: { rtcp::TransportFeedback transport_feedback = NewTransportFeedback(); rtc::Buffer buffer = transport_feedback.Build(); @@ -459,6 +478,7 @@ EventGenerator::NewRtcpPacketOutgoing() { kPli, kNack, kRemb, + kBye, kTransportFeedback, kNumValues }; @@ -500,6 +520,11 @@ EventGenerator::NewRtcpPacketOutgoing() { rtc::Buffer buffer = remb.Build(); return std::make_unique(buffer); } + case SupportedRtcpTypes::kBye: { + rtcp::Bye bye = NewBye(); + rtc::Buffer buffer = bye.Build(); + return std::make_unique(buffer); + } case SupportedRtcpTypes::kTransportFeedback: { rtcp::TransportFeedback transport_feedback = NewTransportFeedback(); rtc::Buffer buffer = transport_feedback.Build(); @@ -1133,6 +1158,7 @@ void EventVerifier::VerifyLoggedExtendedReports( int64_t log_time_us, const rtcp::ExtendedReports& original_xr, const LoggedRtcpPacketExtendedReports& logged_xr) { + EXPECT_EQ(log_time_us, logged_xr.log_time_us()); EXPECT_EQ(original_xr.sender_ssrc(), logged_xr.xr.sender_ssrc()); EXPECT_EQ(original_xr.rrtr().has_value(), logged_xr.xr.rrtr().has_value()); @@ -1173,8 +1199,8 @@ void EventVerifier::VerifyLoggedExtendedReports( void EventVerifier::VerifyLoggedFir(int64_t log_time_us, const rtcp::Fir& original_fir, const LoggedRtcpPacketFir& logged_fir) { + EXPECT_EQ(log_time_us, logged_fir.log_time_us()); EXPECT_EQ(original_fir.sender_ssrc(), logged_fir.fir.sender_ssrc()); - const auto& original_requests = original_fir.requests(); const auto& logged_requests = logged_fir.fir.requests(); ASSERT_EQ(original_requests.size(), logged_requests.size()); @@ -1187,10 +1213,20 @@ void EventVerifier::VerifyLoggedFir(int64_t log_time_us, void EventVerifier::VerifyLoggedPli(int64_t log_time_us, const rtcp::Pli& original_pli, const LoggedRtcpPacketPli& logged_pli) { + EXPECT_EQ(log_time_us, logged_pli.log_time_us()); EXPECT_EQ(original_pli.sender_ssrc(), logged_pli.pli.sender_ssrc()); EXPECT_EQ(original_pli.media_ssrc(), logged_pli.pli.media_ssrc()); } +void EventVerifier::VerifyLoggedBye(int64_t log_time_us, + const rtcp::Bye& original_bye, + const LoggedRtcpPacketBye& logged_bye) { + EXPECT_EQ(log_time_us, logged_bye.log_time_us()); + EXPECT_EQ(original_bye.sender_ssrc(), logged_bye.bye.sender_ssrc()); + EXPECT_EQ(original_bye.csrcs(), logged_bye.bye.csrcs()); + EXPECT_EQ(original_bye.reason(), logged_bye.bye.reason()); +} + void EventVerifier::VerifyLoggedNack(int64_t log_time_us, const rtcp::Nack& original_nack, const LoggedRtcpPacketNack& logged_nack) { diff --git a/logging/rtc_event_log/rtc_event_log_unittest_helper.h b/logging/rtc_event_log/rtc_event_log_unittest_helper.h index bf9fb573c1..94cf3d5ae7 100644 --- a/logging/rtc_event_log/rtc_event_log_unittest_helper.h +++ b/logging/rtc_event_log/rtc_event_log_unittest_helper.h @@ -45,6 +45,7 @@ #include "logging/rtc_event_log/rtc_event_log_parser.h" #include "logging/rtc_event_log/rtc_stream_config.h" #include "modules/rtp_rtcp/include/rtp_header_extension_map.h" +#include "modules/rtp_rtcp/source/rtcp_packet/bye.h" #include "modules/rtp_rtcp/source/rtcp_packet/extended_reports.h" #include "modules/rtp_rtcp/source/rtcp_packet/fir.h" #include "modules/rtp_rtcp/source/rtcp_packet/loss_notification.h" @@ -93,6 +94,7 @@ class EventGenerator { rtcp::Remb NewRemb(); rtcp::Fir NewFir(); rtcp::Pli NewPli(); + rtcp::Bye NewBye(); rtcp::TransportFeedback NewTransportFeedback(); rtcp::LossNotification NewLossNotification(); @@ -275,6 +277,9 @@ class EventVerifier { void VerifyLoggedPli(int64_t log_time_us, const rtcp::Pli& original_pli, const LoggedRtcpPacketPli& logged_pli); + void VerifyLoggedBye(int64_t log_time_us, + const rtcp::Bye& original_bye, + const LoggedRtcpPacketBye& logged_bye); void VerifyLoggedNack(int64_t log_time_us, const rtcp::Nack& original_nack, const LoggedRtcpPacketNack& logged_nack); diff --git a/rtc_tools/rtc_event_log_visualizer/analyzer.cc b/rtc_tools/rtc_event_log_visualizer/analyzer.cc index a7153c6fbd..d6acda9ec3 100644 --- a/rtc_tools/rtc_event_log_visualizer/analyzer.cc +++ b/rtc_tools/rtc_event_log_visualizer/analyzer.cc @@ -445,6 +445,8 @@ void EventLogAnalyzer::CreateRtcpTypeGraph(PacketDirection direction, CreateRtcpTypeTimeSeries(parsed_log_.firs(direction), config_, "FIR", 7)); plot->AppendTimeSeries( CreateRtcpTypeTimeSeries(parsed_log_.plis(direction), config_, "PLI", 8)); + plot->AppendTimeSeries( + CreateRtcpTypeTimeSeries(parsed_log_.byes(direction), config_, "BYE", 9)); plot->SetXAxis(config_.CallBeginTimeSec(), config_.CallEndTimeSec(), "Time (s)", kLeftMargin, kRightMargin); plot->SetSuggestedYAxis(0, 1, "RTCP type", kBottomMargin, kTopMargin); @@ -456,7 +458,8 @@ void EventLogAnalyzer::CreateRtcpTypeGraph(PacketDirection direction, {5, "NACK"}, {6, "REMB"}, {7, "FIR"}, - {8, "PLI"}}); + {8, "PLI"}, + {9, "BYE"}}); } template