Add RTC event logging of LossNotification RTCP messages
Bug: webrtc:10226 Change-Id: Ib65970a8f13cd64529f3101993d40887168e313e Reviewed-on: https://webrtc-review.googlesource.com/c/118933 Commit-Queue: Elad Alon <eladalon@webrtc.org> Reviewed-by: Björn Terelius <terelius@webrtc.org> Cr-Commit-Position: refs/heads/master@{#26391}
This commit is contained in:
@ -859,6 +859,46 @@ TEST_P(RtcEventLogEncoderTest, RtcEventRtcpTransportFeedback) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_P(RtcEventLogEncoderTest, RtcEventRtcpLossNotification) {
|
||||||
|
if (force_repeated_fields_) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
rtc::ScopedFakeClock fake_clock;
|
||||||
|
fake_clock.SetTimeMicros(static_cast<int64_t>(prng_.Rand<uint32_t>()) * 1000);
|
||||||
|
|
||||||
|
for (auto direction : {kIncomingPacket, kOutgoingPacket}) {
|
||||||
|
std::vector<rtcp::LossNotification> events;
|
||||||
|
events.reserve(event_count_);
|
||||||
|
std::vector<int64_t> timestamps_us(event_count_);
|
||||||
|
for (size_t i = 0; i < event_count_; ++i) {
|
||||||
|
timestamps_us[i] = rtc::TimeMicros();
|
||||||
|
events.emplace_back(gen_.NewLossNotification());
|
||||||
|
rtc::Buffer buffer = events[i].Build();
|
||||||
|
if (direction == kIncomingPacket) {
|
||||||
|
history_.push_back(
|
||||||
|
absl::make_unique<RtcEventRtcpPacketIncoming>(buffer));
|
||||||
|
} else {
|
||||||
|
history_.push_back(
|
||||||
|
absl::make_unique<RtcEventRtcpPacketOutgoing>(buffer));
|
||||||
|
}
|
||||||
|
fake_clock.AdvanceTimeMicros(prng_.Rand(0, 1000) * 1000);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string encoded =
|
||||||
|
encoder_->EncodeBatch(history_.begin(), history_.end());
|
||||||
|
ASSERT_TRUE(parsed_log_.ParseString(encoded));
|
||||||
|
|
||||||
|
const auto& loss_notifications = parsed_log_.loss_notifications(direction);
|
||||||
|
ASSERT_EQ(loss_notifications.size(), event_count_);
|
||||||
|
|
||||||
|
for (size_t i = 0; i < event_count_; ++i) {
|
||||||
|
verifier_.VerifyLoggedLossNotification(timestamps_us[i], events[i],
|
||||||
|
loss_notifications[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
TEST_P(RtcEventLogEncoderTest, RtcEventRtpPacketIncoming) {
|
TEST_P(RtcEventLogEncoderTest, RtcEventRtpPacketIncoming) {
|
||||||
TestRtpPackets<RtcEventRtpPacketIncoming, LoggedRtpPacketIncoming>();
|
TestRtpPackets<RtcEventRtpPacketIncoming, LoggedRtpPacketIncoming>();
|
||||||
}
|
}
|
||||||
|
@ -25,6 +25,7 @@
|
|||||||
#include "logging/rtc_event_log/rtc_stream_config.h"
|
#include "logging/rtc_event_log/rtc_stream_config.h"
|
||||||
#include "modules/audio_coding/audio_network_adaptor/include/audio_network_adaptor_config.h"
|
#include "modules/audio_coding/audio_network_adaptor/include/audio_network_adaptor_config.h"
|
||||||
#include "modules/remote_bitrate_estimator/include/bwe_defines.h"
|
#include "modules/remote_bitrate_estimator/include/bwe_defines.h"
|
||||||
|
#include "modules/rtp_rtcp/source/rtcp_packet/loss_notification.h"
|
||||||
#include "modules/rtp_rtcp/source/rtcp_packet/nack.h"
|
#include "modules/rtp_rtcp/source/rtcp_packet/nack.h"
|
||||||
#include "modules/rtp_rtcp/source/rtcp_packet/receiver_report.h"
|
#include "modules/rtp_rtcp/source/rtcp_packet/receiver_report.h"
|
||||||
#include "modules/rtp_rtcp/source/rtcp_packet/remb.h"
|
#include "modules/rtp_rtcp/source/rtcp_packet/remb.h"
|
||||||
@ -345,8 +346,6 @@ struct LoggedRtcpPacketRemb {
|
|||||||
rtcp::Remb remb;
|
rtcp::Remb remb;
|
||||||
};
|
};
|
||||||
|
|
||||||
// TODO(eladalon): Add LossNotification.
|
|
||||||
|
|
||||||
struct LoggedRtcpPacketNack {
|
struct LoggedRtcpPacketNack {
|
||||||
LoggedRtcpPacketNack() = default;
|
LoggedRtcpPacketNack() = default;
|
||||||
LoggedRtcpPacketNack(int64_t timestamp_us, const rtcp::Nack& nack)
|
LoggedRtcpPacketNack(int64_t timestamp_us, const rtcp::Nack& nack)
|
||||||
@ -373,6 +372,20 @@ struct LoggedRtcpPacketTransportFeedback {
|
|||||||
rtcp::TransportFeedback transport_feedback;
|
rtcp::TransportFeedback transport_feedback;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct LoggedRtcpPacketLossNotification {
|
||||||
|
LoggedRtcpPacketLossNotification() = default;
|
||||||
|
LoggedRtcpPacketLossNotification(
|
||||||
|
int64_t timestamp_us,
|
||||||
|
const rtcp::LossNotification& loss_notification)
|
||||||
|
: timestamp_us(timestamp_us), loss_notification(loss_notification) {}
|
||||||
|
|
||||||
|
int64_t log_time_us() const { return timestamp_us; }
|
||||||
|
int64_t log_time_ms() const { return timestamp_us / 1000; }
|
||||||
|
|
||||||
|
int64_t timestamp_us;
|
||||||
|
rtcp::LossNotification loss_notification;
|
||||||
|
};
|
||||||
|
|
||||||
struct LoggedStartEvent {
|
struct LoggedStartEvent {
|
||||||
explicit LoggedStartEvent(int64_t timestamp_us)
|
explicit LoggedStartEvent(int64_t timestamp_us)
|
||||||
: LoggedStartEvent(timestamp_us, timestamp_us / 1000) {}
|
: LoggedStartEvent(timestamp_us, timestamp_us / 1000) {}
|
||||||
|
@ -782,7 +782,8 @@ void StoreRtcpBlocks(
|
|||||||
std::vector<LoggedRtcpPacketSenderReport>* sr_list,
|
std::vector<LoggedRtcpPacketSenderReport>* sr_list,
|
||||||
std::vector<LoggedRtcpPacketReceiverReport>* rr_list,
|
std::vector<LoggedRtcpPacketReceiverReport>* rr_list,
|
||||||
std::vector<LoggedRtcpPacketRemb>* remb_list,
|
std::vector<LoggedRtcpPacketRemb>* remb_list,
|
||||||
std::vector<LoggedRtcpPacketNack>* nack_list) {
|
std::vector<LoggedRtcpPacketNack>* nack_list,
|
||||||
|
std::vector<LoggedRtcpPacketLossNotification>* loss_notification_list) {
|
||||||
rtcp::CommonHeader header;
|
rtcp::CommonHeader header;
|
||||||
for (const uint8_t* block = packet_begin; block < packet_end;
|
for (const uint8_t* block = packet_begin; block < packet_end;
|
||||||
block = header.NextPacket()) {
|
block = header.NextPacket()) {
|
||||||
@ -807,10 +808,22 @@ void StoreRtcpBlocks(
|
|||||||
}
|
}
|
||||||
} else if (header.type() == rtcp::Remb::kPacketType &&
|
} else if (header.type() == rtcp::Remb::kPacketType &&
|
||||||
header.fmt() == rtcp::Remb::kFeedbackMessageType) {
|
header.fmt() == rtcp::Remb::kFeedbackMessageType) {
|
||||||
LoggedRtcpPacketRemb parsed_block;
|
bool type_found = false;
|
||||||
parsed_block.timestamp_us = timestamp_us;
|
if (!type_found) {
|
||||||
if (parsed_block.remb.Parse(header)) {
|
LoggedRtcpPacketRemb parsed_block;
|
||||||
remb_list->push_back(std::move(parsed_block));
|
parsed_block.timestamp_us = timestamp_us;
|
||||||
|
if (parsed_block.remb.Parse(header)) {
|
||||||
|
remb_list->push_back(std::move(parsed_block));
|
||||||
|
type_found = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!type_found) {
|
||||||
|
LoggedRtcpPacketLossNotification parsed_block;
|
||||||
|
parsed_block.timestamp_us = timestamp_us;
|
||||||
|
if (parsed_block.loss_notification.Parse(header)) {
|
||||||
|
loss_notification_list->push_back(std::move(parsed_block));
|
||||||
|
type_found = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else if (header.type() == rtcp::Nack::kPacketType &&
|
} else if (header.type() == rtcp::Nack::kPacketType &&
|
||||||
header.fmt() == rtcp::Nack::kFeedbackMessageType) {
|
header.fmt() == rtcp::Nack::kFeedbackMessageType) {
|
||||||
@ -937,6 +950,8 @@ void ParsedRtcEventLog::Clear() {
|
|||||||
outgoing_remb_.clear();
|
outgoing_remb_.clear();
|
||||||
incoming_transport_feedback_.clear();
|
incoming_transport_feedback_.clear();
|
||||||
outgoing_transport_feedback_.clear();
|
outgoing_transport_feedback_.clear();
|
||||||
|
incoming_loss_notification_.clear();
|
||||||
|
outgoing_loss_notification_.clear();
|
||||||
|
|
||||||
start_log_events_.clear();
|
start_log_events_.clear();
|
||||||
stop_log_events_.clear();
|
stop_log_events_.clear();
|
||||||
@ -1046,7 +1061,8 @@ bool ParsedRtcEventLog::ParseStream(
|
|||||||
const uint8_t* packet_end = packet_begin + incoming.rtcp.raw_data.size();
|
const uint8_t* packet_end = packet_begin + incoming.rtcp.raw_data.size();
|
||||||
StoreRtcpBlocks(timestamp_us, packet_begin, packet_end,
|
StoreRtcpBlocks(timestamp_us, packet_begin, packet_end,
|
||||||
&incoming_transport_feedback_, &incoming_sr_, &incoming_rr_,
|
&incoming_transport_feedback_, &incoming_sr_, &incoming_rr_,
|
||||||
&incoming_remb_, &incoming_nack_);
|
&incoming_remb_, &incoming_nack_,
|
||||||
|
&incoming_loss_notification_);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const auto& outgoing : outgoing_rtcp_packets_) {
|
for (const auto& outgoing : outgoing_rtcp_packets_) {
|
||||||
@ -1055,7 +1071,8 @@ bool ParsedRtcEventLog::ParseStream(
|
|||||||
const uint8_t* packet_end = packet_begin + outgoing.rtcp.raw_data.size();
|
const uint8_t* packet_end = packet_begin + outgoing.rtcp.raw_data.size();
|
||||||
StoreRtcpBlocks(timestamp_us, packet_begin, packet_end,
|
StoreRtcpBlocks(timestamp_us, packet_begin, packet_end,
|
||||||
&outgoing_transport_feedback_, &outgoing_sr_, &outgoing_rr_,
|
&outgoing_transport_feedback_, &outgoing_sr_, &outgoing_rr_,
|
||||||
&outgoing_remb_, &outgoing_nack_);
|
&outgoing_remb_, &outgoing_nack_,
|
||||||
|
&outgoing_loss_notification_);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Store first and last timestamp events that might happen before the call is
|
// Store first and last timestamp events that might happen before the call is
|
||||||
|
@ -461,6 +461,15 @@ class ParsedRtcEventLog {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const std::vector<LoggedRtcpPacketLossNotification>& loss_notifications(
|
||||||
|
PacketDirection direction) {
|
||||||
|
if (direction == kIncomingPacket) {
|
||||||
|
return incoming_loss_notification_;
|
||||||
|
} else {
|
||||||
|
return outgoing_loss_notification_;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int64_t first_timestamp() const { return first_timestamp_; }
|
int64_t first_timestamp() const { return first_timestamp_; }
|
||||||
int64_t last_timestamp() const { return last_timestamp_; }
|
int64_t last_timestamp() const { return last_timestamp_; }
|
||||||
|
|
||||||
@ -635,6 +644,8 @@ class ParsedRtcEventLog {
|
|||||||
std::vector<LoggedRtcpPacketRemb> outgoing_remb_;
|
std::vector<LoggedRtcpPacketRemb> outgoing_remb_;
|
||||||
std::vector<LoggedRtcpPacketTransportFeedback> incoming_transport_feedback_;
|
std::vector<LoggedRtcpPacketTransportFeedback> incoming_transport_feedback_;
|
||||||
std::vector<LoggedRtcpPacketTransportFeedback> outgoing_transport_feedback_;
|
std::vector<LoggedRtcpPacketTransportFeedback> outgoing_transport_feedback_;
|
||||||
|
std::vector<LoggedRtcpPacketLossNotification> incoming_loss_notification_;
|
||||||
|
std::vector<LoggedRtcpPacketLossNotification> outgoing_loss_notification_;
|
||||||
|
|
||||||
std::vector<LoggedStartEvent> start_log_events_;
|
std::vector<LoggedStartEvent> start_log_events_;
|
||||||
std::vector<LoggedStopEvent> stop_log_events_;
|
std::vector<LoggedStopEvent> stop_log_events_;
|
||||||
|
@ -296,6 +296,17 @@ rtcp::Remb EventGenerator::NewRemb() {
|
|||||||
return remb;
|
return remb;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
rtcp::LossNotification EventGenerator::NewLossNotification() {
|
||||||
|
rtcp::LossNotification loss_notification;
|
||||||
|
const uint16_t last_decoded = prng_.Rand<uint16_t>();
|
||||||
|
const uint16_t last_received =
|
||||||
|
last_decoded + (prng_.Rand<uint16_t>() & 0x7fff);
|
||||||
|
const bool decodability_flag = prng_.Rand<bool>();
|
||||||
|
EXPECT_TRUE(
|
||||||
|
loss_notification.Set(last_decoded, last_received, decodability_flag));
|
||||||
|
return loss_notification;
|
||||||
|
}
|
||||||
|
|
||||||
std::unique_ptr<RtcEventRtcpPacketIncoming>
|
std::unique_ptr<RtcEventRtcpPacketIncoming>
|
||||||
EventGenerator::NewRtcpPacketIncoming() {
|
EventGenerator::NewRtcpPacketIncoming() {
|
||||||
enum class SupportedRtcpTypes {
|
enum class SupportedRtcpTypes {
|
||||||
@ -957,6 +968,19 @@ void EventVerifier::VerifyLoggedRemb(int64_t log_time_us,
|
|||||||
EXPECT_EQ(original_remb.bitrate_bps(), logged_remb.remb.bitrate_bps());
|
EXPECT_EQ(original_remb.bitrate_bps(), logged_remb.remb.bitrate_bps());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void EventVerifier::VerifyLoggedLossNotification(
|
||||||
|
int64_t log_time_us,
|
||||||
|
const rtcp::LossNotification& original_loss_notification,
|
||||||
|
const LoggedRtcpPacketLossNotification& logged_loss_notification) {
|
||||||
|
EXPECT_EQ(log_time_us, logged_loss_notification.log_time_us());
|
||||||
|
EXPECT_EQ(original_loss_notification.last_decoded(),
|
||||||
|
logged_loss_notification.loss_notification.last_decoded());
|
||||||
|
EXPECT_EQ(original_loss_notification.last_received(),
|
||||||
|
logged_loss_notification.loss_notification.last_received());
|
||||||
|
EXPECT_EQ(original_loss_notification.decodability_flag(),
|
||||||
|
logged_loss_notification.loss_notification.decodability_flag());
|
||||||
|
}
|
||||||
|
|
||||||
void EventVerifier::VerifyLoggedStartEvent(
|
void EventVerifier::VerifyLoggedStartEvent(
|
||||||
int64_t start_time_us,
|
int64_t start_time_us,
|
||||||
int64_t utc_start_time_us,
|
int64_t utc_start_time_us,
|
||||||
|
@ -38,6 +38,7 @@
|
|||||||
#include "logging/rtc_event_log/rtc_event_log_parser.h"
|
#include "logging/rtc_event_log/rtc_event_log_parser.h"
|
||||||
#include "logging/rtc_event_log/rtc_stream_config.h"
|
#include "logging/rtc_event_log/rtc_stream_config.h"
|
||||||
#include "modules/rtp_rtcp/include/rtp_header_extension_map.h"
|
#include "modules/rtp_rtcp/include/rtp_header_extension_map.h"
|
||||||
|
#include "modules/rtp_rtcp/source/rtcp_packet/loss_notification.h"
|
||||||
#include "modules/rtp_rtcp/source/rtcp_packet/receiver_report.h"
|
#include "modules/rtp_rtcp/source/rtcp_packet/receiver_report.h"
|
||||||
#include "modules/rtp_rtcp/source/rtcp_packet/report_block.h"
|
#include "modules/rtp_rtcp/source/rtcp_packet/report_block.h"
|
||||||
#include "modules/rtp_rtcp/source/rtcp_packet/sender_report.h"
|
#include "modules/rtp_rtcp/source/rtcp_packet/sender_report.h"
|
||||||
@ -85,6 +86,7 @@ class EventGenerator {
|
|||||||
rtcp::Nack NewNack();
|
rtcp::Nack NewNack();
|
||||||
rtcp::TransportFeedback NewTransportFeedback();
|
rtcp::TransportFeedback NewTransportFeedback();
|
||||||
rtcp::Remb NewRemb();
|
rtcp::Remb NewRemb();
|
||||||
|
rtcp::LossNotification NewLossNotification();
|
||||||
|
|
||||||
// |all_configured_exts| determines whether the RTP packet exhibits all
|
// |all_configured_exts| determines whether the RTP packet exhibits all
|
||||||
// configured extensions, or a random subset thereof.
|
// configured extensions, or a random subset thereof.
|
||||||
@ -240,6 +242,10 @@ class EventVerifier {
|
|||||||
void VerifyLoggedRemb(int64_t log_time_us,
|
void VerifyLoggedRemb(int64_t log_time_us,
|
||||||
const rtcp::Remb& original_remb,
|
const rtcp::Remb& original_remb,
|
||||||
const LoggedRtcpPacketRemb& logged_remb);
|
const LoggedRtcpPacketRemb& logged_remb);
|
||||||
|
void VerifyLoggedLossNotification(
|
||||||
|
int64_t log_time_us,
|
||||||
|
const rtcp::LossNotification& original_loss_notification,
|
||||||
|
const LoggedRtcpPacketLossNotification& logged_loss_notification);
|
||||||
|
|
||||||
void VerifyLoggedStartEvent(int64_t start_time_us,
|
void VerifyLoggedStartEvent(int64_t start_time_us,
|
||||||
int64_t utc_start_time_us,
|
int64_t utc_start_time_us,
|
||||||
|
Reference in New Issue
Block a user