Support GenericPacketReceived/Sent/AckReceived event logs.

This change does not include receive_timestamps for ACKs, because there is 1 problem.
That problem will be resolved in a separate change.

I am getting receive_timestamp errors that have to do with delta compression with optional fields.
Two failure modes that I noticed:
1) the base event does not have the timestamp: it crashes with length validation
# Check failed: base <= MaxUnsignedValueOfBitWidth(params_.value_width_bits()) (1820716 vs. 131071)
2) all events are null, it crashes with assert that X events were expected, but no events were deserialized.


Bug: webrtc:9719
Change-Id: I5d1bbb95dfd15ca7321667aad5e4d89c085e9c06
Reviewed-on: https://webrtc-review.googlesource.com/c/122360
Commit-Queue: Peter Slatala <psla@webrtc.org>
Reviewed-by: Björn Terelius <terelius@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#26668}
This commit is contained in:
Piotr (Peter) Slatala
2019-02-13 07:49:30 -08:00
committed by Commit Bot
parent 975a899ad0
commit 5e2aad1c95
17 changed files with 838 additions and 21 deletions

View File

@ -347,6 +347,10 @@ if (rtc_enable_protobuf) {
"//third_party/abseil-cpp/absl/memory",
"//third_party/abseil-cpp/absl/types:optional",
]
if (!build_with_chromium && is_clang) {
suppressed_configs += [ "//build/config/clang:find_bad_constructs" ]
}
}
if (rtc_include_tests) {
@ -369,6 +373,7 @@ if (rtc_enable_protobuf) {
":ice_log",
":rtc_event_audio",
":rtc_event_bwe",
":rtc_event_generic_packet_events",
":rtc_event_log2_proto",
":rtc_event_log_api",
":rtc_event_log_impl_base",

View File

@ -867,6 +867,9 @@ std::string RtcEventLogEncoderNewFormat::EncodeBatch(
EncodeVideoSendStreamConfig(video_send_stream_configs, &event_stream);
EncodeIceCandidatePairConfig(ice_candidate_configs, &event_stream);
EncodeIceCandidatePairEvent(ice_candidate_events, &event_stream);
EncodeGenericPacketsReceived(generic_packets_received, &event_stream);
EncodeGenericPacketsSent(generic_packets_sent, &event_stream);
EncodeGenericAcksReceived(generic_acks_received, &event_stream);
} // Deallocate the temporary vectors.
return event_stream.SerializeAsString();
@ -1326,6 +1329,212 @@ void RtcEventLogEncoderNewFormat::EncodeRtpPacketIncoming(
}
}
void RtcEventLogEncoderNewFormat::EncodeGenericPacketsSent(
rtc::ArrayView<const RtcEventGenericPacketSent*> batch,
rtclog2::EventStream* event_stream) {
if (batch.empty()) {
return;
}
const RtcEventGenericPacketSent* const base_event = batch[0];
rtclog2::GenericPacketSent* proto_batch =
event_stream->add_generic_packets_sent();
proto_batch->set_timestamp_ms(base_event->timestamp_ms());
proto_batch->set_packet_number(base_event->packet_number());
proto_batch->set_overhead_length(base_event->overhead_length());
proto_batch->set_payload_length(base_event->payload_length());
proto_batch->set_padding_length(base_event->padding_length());
// Delta encoding
proto_batch->set_number_of_deltas(batch.size() - 1);
std::vector<absl::optional<uint64_t>> values(batch.size() - 1);
std::string encoded_deltas;
if (batch.size() == 1) {
return;
}
// timestamp_ms
for (size_t i = 0; i < values.size(); ++i) {
const RtcEventGenericPacketSent* event = batch[i + 1];
values[i] = ToUnsigned(event->timestamp_ms());
}
encoded_deltas = EncodeDeltas(ToUnsigned(base_event->timestamp_ms()), values);
if (!encoded_deltas.empty()) {
proto_batch->set_timestamp_ms_deltas(encoded_deltas);
}
// packet_number
for (size_t i = 0; i < values.size(); ++i) {
const RtcEventGenericPacketSent* event = batch[i + 1];
values[i] = ToUnsigned(event->packet_number());
}
encoded_deltas =
EncodeDeltas(ToUnsigned(base_event->packet_number()), values);
if (!encoded_deltas.empty()) {
proto_batch->set_packet_number_deltas(encoded_deltas);
}
// overhead_length
for (size_t i = 0; i < values.size(); ++i) {
const RtcEventGenericPacketSent* event = batch[i + 1];
values[i] = event->overhead_length();
}
encoded_deltas = EncodeDeltas(base_event->overhead_length(), values);
if (!encoded_deltas.empty()) {
proto_batch->set_overhead_length_deltas(encoded_deltas);
}
// payload_length
for (size_t i = 0; i < values.size(); ++i) {
const RtcEventGenericPacketSent* event = batch[i + 1];
values[i] = event->payload_length();
}
encoded_deltas = EncodeDeltas(base_event->payload_length(), values);
if (!encoded_deltas.empty()) {
proto_batch->set_payload_length_deltas(encoded_deltas);
}
// padding_length
for (size_t i = 0; i < values.size(); ++i) {
const RtcEventGenericPacketSent* event = batch[i + 1];
values[i] = event->padding_length();
}
encoded_deltas = EncodeDeltas(base_event->padding_length(), values);
if (!encoded_deltas.empty()) {
proto_batch->set_padding_length_deltas(encoded_deltas);
}
}
void RtcEventLogEncoderNewFormat::EncodeGenericPacketsReceived(
rtc::ArrayView<const RtcEventGenericPacketReceived*> batch,
rtclog2::EventStream* event_stream) {
if (batch.empty()) {
return;
}
const RtcEventGenericPacketReceived* const base_event = batch[0];
rtclog2::GenericPacketReceived* proto_batch =
event_stream->add_generic_packets_received();
proto_batch->set_timestamp_ms(base_event->timestamp_ms());
proto_batch->set_packet_number(base_event->packet_number());
proto_batch->set_packet_length(base_event->packet_length());
// Delta encoding
proto_batch->set_number_of_deltas(batch.size() - 1);
std::vector<absl::optional<uint64_t>> values(batch.size() - 1);
std::string encoded_deltas;
if (batch.size() == 1) {
return;
}
// timestamp_ms
for (size_t i = 0; i < values.size(); ++i) {
const RtcEventGenericPacketReceived* event = batch[i + 1];
values[i] = ToUnsigned(event->timestamp_ms());
}
encoded_deltas = EncodeDeltas(ToUnsigned(base_event->timestamp_ms()), values);
if (!encoded_deltas.empty()) {
proto_batch->set_timestamp_ms_deltas(encoded_deltas);
}
// packet_number
for (size_t i = 0; i < values.size(); ++i) {
const RtcEventGenericPacketReceived* event = batch[i + 1];
values[i] = ToUnsigned(event->packet_number());
}
encoded_deltas =
EncodeDeltas(ToUnsigned(base_event->packet_number()), values);
if (!encoded_deltas.empty()) {
proto_batch->set_packet_number_deltas(encoded_deltas);
}
// packet_length
for (size_t i = 0; i < values.size(); ++i) {
const RtcEventGenericPacketReceived* event = batch[i + 1];
values[i] = event->packet_length();
}
encoded_deltas = EncodeDeltas(base_event->packet_length(), values);
if (!encoded_deltas.empty()) {
proto_batch->set_packet_length_deltas(encoded_deltas);
}
}
void RtcEventLogEncoderNewFormat::EncodeGenericAcksReceived(
rtc::ArrayView<const RtcEventGenericAckReceived*> batch,
rtclog2::EventStream* event_stream) {
if (batch.empty()) {
return;
}
const RtcEventGenericAckReceived* const base_event = batch[0];
rtclog2::GenericAckReceived* proto_batch =
event_stream->add_generic_acks_received();
proto_batch->set_timestamp_ms(base_event->timestamp_ms());
proto_batch->set_packet_number(base_event->packet_number());
proto_batch->set_acked_packet_number(base_event->acked_packet_number());
absl::optional<uint64_t> base_receive_timestamp;
if (base_event->receive_acked_packet_time_ms()) {
int64_t receive_acked_packet_time_ms =
base_event->receive_acked_packet_time_ms().value();
base_receive_timestamp = ToUnsigned(receive_acked_packet_time_ms);
proto_batch->set_receive_acked_packet_time_ms(receive_acked_packet_time_ms);
}
// Delta encoding
proto_batch->set_number_of_deltas(batch.size() - 1);
std::vector<absl::optional<uint64_t>> values(batch.size() - 1);
std::string encoded_deltas;
if (batch.size() == 1) {
return;
}
// timestamp_ms
for (size_t i = 0; i < values.size(); ++i) {
const RtcEventGenericAckReceived* event = batch[i + 1];
values[i] = ToUnsigned(event->timestamp_ms());
}
encoded_deltas = EncodeDeltas(ToUnsigned(base_event->timestamp_ms()), values);
if (!encoded_deltas.empty()) {
proto_batch->set_timestamp_ms_deltas(encoded_deltas);
}
// packet_number
for (size_t i = 0; i < values.size(); ++i) {
const RtcEventGenericAckReceived* event = batch[i + 1];
values[i] = ToUnsigned(event->packet_number());
}
encoded_deltas =
EncodeDeltas(ToUnsigned(base_event->packet_number()), values);
if (!encoded_deltas.empty()) {
proto_batch->set_packet_number_deltas(encoded_deltas);
}
// acked packet number
for (size_t i = 0; i < values.size(); ++i) {
const RtcEventGenericAckReceived* event = batch[i + 1];
values[i] = ToUnsigned(event->acked_packet_number());
}
encoded_deltas =
EncodeDeltas(ToUnsigned(base_event->acked_packet_number()), values);
if (!encoded_deltas.empty()) {
proto_batch->set_acked_packet_number_deltas(encoded_deltas);
}
// receive timestamp
for (size_t i = 0; i < values.size(); ++i) {
const RtcEventGenericAckReceived* event = batch[i + 1];
if (event->receive_acked_packet_time_ms()) {
values[i] = ToUnsigned(event->receive_acked_packet_time_ms().value());
} else {
values[i] = absl::nullopt;
}
}
encoded_deltas = EncodeDeltas(base_receive_timestamp, values);
if (!encoded_deltas.empty()) {
proto_batch->set_receive_acked_packet_time_ms_deltas(encoded_deltas);
}
}
void RtcEventLogEncoderNewFormat::EncodeRtpPacketOutgoing(
const std::map<uint32_t, std::vector<const RtcEventRtpPacketOutgoing*>>&
batch,

View File

@ -49,6 +49,9 @@ class RtcEventVideoSendStreamConfig;
class RtcEventIceCandidatePairConfig;
class RtcEventIceCandidatePair;
class RtpPacket;
class RtcEventGenericAckReceived;
class RtcEventGenericPacketReceived;
class RtcEventGenericPacketSent;
class RtcEventLogEncoderNewFormat final : public RtcEventLogEncoder {
public:
@ -116,6 +119,15 @@ class RtcEventLogEncoderNewFormat final : public RtcEventLogEncoder {
const std::map<uint32_t, std::vector<const RtcEventRtpPacketOutgoing*>>&
batch,
rtclog2::EventStream* event_stream);
void EncodeGenericAcksReceived(
rtc::ArrayView<const RtcEventGenericAckReceived*> batch,
rtclog2::EventStream* event_stream);
void EncodeGenericPacketsReceived(
rtc::ArrayView<const RtcEventGenericPacketReceived*> batch,
rtclog2::EventStream* event_stream);
void EncodeGenericPacketsSent(
rtc::ArrayView<const RtcEventGenericPacketSent*> batch,
rtclog2::EventStream* event_stream);
void EncodeVideoRecvStreamConfig(
rtc::ArrayView<const RtcEventVideoReceiveStreamConfig*> batch,
rtclog2::EventStream* event_stream);

View File

@ -463,6 +463,77 @@ TEST_P(RtcEventLogEncoderTest, RtcEventBweUpdateLossBased) {
}
}
TEST_P(RtcEventLogEncoderTest, RtcEventGenericPacketReceived) {
if (!new_encoding_) {
return;
}
std::vector<std::unique_ptr<RtcEventGenericPacketReceived>> events(
event_count_);
for (size_t i = 0; i < event_count_; ++i) {
events[i] = (i == 0 || !force_repeated_fields_)
? gen_.NewGenericPacketReceived()
: events[0]->Copy();
history_.push_back(events[i]->Copy());
}
std::string encoded = encoder_->EncodeBatch(history_.begin(), history_.end());
ASSERT_TRUE(parsed_log_.ParseString(encoded));
const auto& packets_received = parsed_log_.generic_packets_received();
ASSERT_EQ(packets_received.size(), event_count_);
for (size_t i = 0; i < event_count_; ++i) {
verifier_.VerifyLoggedGenericPacketReceived(*events[i],
packets_received[i]);
}
}
TEST_P(RtcEventLogEncoderTest, RtcEventGenericPacketSent) {
if (!new_encoding_) {
return;
}
std::vector<std::unique_ptr<RtcEventGenericPacketSent>> events(event_count_);
for (size_t i = 0; i < event_count_; ++i) {
events[i] = (i == 0 || !force_repeated_fields_)
? gen_.NewGenericPacketSent()
: events[0]->Copy();
history_.push_back(events[i]->Copy());
}
std::string encoded = encoder_->EncodeBatch(history_.begin(), history_.end());
ASSERT_TRUE(parsed_log_.ParseString(encoded));
const auto& packets_sent = parsed_log_.generic_packets_sent();
ASSERT_EQ(packets_sent.size(), event_count_);
for (size_t i = 0; i < event_count_; ++i) {
verifier_.VerifyLoggedGenericPacketSent(*events[i], packets_sent[i]);
}
}
TEST_P(RtcEventLogEncoderTest, RtcEventGenericAcksReceived) {
if (!new_encoding_) {
return;
}
std::vector<std::unique_ptr<RtcEventGenericAckReceived>> events(event_count_);
for (size_t i = 0; i < event_count_; ++i) {
events[i] = (i == 0 || !force_repeated_fields_)
? gen_.NewGenericAckReceived()
: events[0]->Copy();
history_.push_back(events[i]->Copy());
}
std::string encoded = encoder_->EncodeBatch(history_.begin(), history_.end());
ASSERT_TRUE(parsed_log_.ParseString(encoded));
const auto& decoded_events = parsed_log_.generic_acks_received();
ASSERT_EQ(decoded_events.size(), event_count_);
for (size_t i = 0; i < event_count_; ++i) {
verifier_.VerifyLoggedGenericAckReceived(*events[i], decoded_events[i]);
}
}
TEST_P(RtcEventLogEncoderTest, RtcEventDtlsTransportState) {
std::vector<std::unique_ptr<RtcEventDtlsTransportState>> events(event_count_);
for (size_t i = 0; i < event_count_; ++i) {

View File

@ -13,16 +13,17 @@
#include <vector>
namespace webrtc {
std::vector<std::unique_ptr<RtcEventGenericAckReceived>>
RtcEventGenericAckReceived::CreateLogs(
int64_t packet_number,
const std::vector<AckedPacket> acked_packets) {
const std::vector<AckedPacket>& acked_packets) {
std::vector<std::unique_ptr<RtcEventGenericAckReceived>> result;
int64_t time_us = rtc::TimeMicros();
for (const AckedPacket& packet : acked_packets) {
result.push_back(absl::WrapUnique(new RtcEventGenericAckReceived(
time_us, packet_number, packet.packet_number,
packet.receive_timestamp_ms)));
packet.receive_acked_packet_time_ms)));
}
return result;
}
@ -31,11 +32,19 @@ RtcEventGenericAckReceived::RtcEventGenericAckReceived(
int64_t timestamp_us,
int64_t packet_number,
int64_t acked_packet_number,
absl::optional<int64_t> receive_timestamp_ms)
absl::optional<int64_t> receive_acked_packet_time_ms)
: RtcEvent(timestamp_us),
packet_number_(packet_number),
acked_packet_number_(acked_packet_number),
receive_timestamp_ms_(receive_timestamp_ms) {}
receive_acked_packet_time_ms_(receive_acked_packet_time_ms) {}
std::unique_ptr<RtcEventGenericAckReceived> RtcEventGenericAckReceived::Copy()
const {
return absl::WrapUnique(new RtcEventGenericAckReceived(*this));
}
RtcEventGenericAckReceived::RtcEventGenericAckReceived(
const RtcEventGenericAckReceived& packet) = default;
RtcEventGenericAckReceived::~RtcEventGenericAckReceived() = default;

View File

@ -24,7 +24,7 @@ struct AckedPacket {
// The time where the packet was received. Not every ACK will
// include the receive timestamp.
absl::optional<int64_t> receive_timestamp_ms;
absl::optional<int64_t> receive_acked_packet_time_ms;
};
class RtcEventGenericAckReceived final : public RtcEvent {
@ -33,11 +33,12 @@ class RtcEventGenericAckReceived final : public RtcEvent {
// the same timestamp.
static std::vector<std::unique_ptr<RtcEventGenericAckReceived>> CreateLogs(
int64_t packet_number,
const std::vector<AckedPacket> acked_packets);
const std::vector<AckedPacket>& acked_packets);
RtcEventGenericAckReceived(const RtcEventGenericAckReceived& packet);
~RtcEventGenericAckReceived() override;
std::unique_ptr<RtcEventGenericAckReceived> Copy() const;
Type GetType() const override;
bool IsConfigEvent() const override;
@ -48,24 +49,32 @@ class RtcEventGenericAckReceived final : public RtcEvent {
// An identifier of the acked packet.
int64_t acked_packet_number() const { return acked_packet_number_; }
// Collection of the received acks with their timestamps.
const absl::optional<int64_t> receive_timestamp_ms() const {
return receive_timestamp_ms_;
// Timestamp when the |acked_packet_number| was received by the remote side.
absl::optional<int64_t> receive_timestamp_ms() const {
return receive_acked_packet_time_ms_;
}
absl::optional<int64_t> receive_acked_packet_time_ms() const {
return receive_acked_packet_time_ms_;
}
private:
RtcEventGenericAckReceived(const RtcEventGenericAckReceived& packet);
// When the ack is received, |packet_number| identifies the packet which
// contained an ack for |acked_packet_number|, and contains the
// |receive_timestamp_ms| on which the |acked_packet_number| was received on
// the remote side. The |receive_timestamp_ms| may be null.
RtcEventGenericAckReceived(int64_t timestamp_us,
int64_t packet_number,
int64_t acked_packet_number,
absl::optional<int64_t> receive_timestamp_ms);
// |receive_acked_packet_time_ms| on which the |acked_packet_number| was
// received on the remote side. The |receive_acked_packet_time_ms| may be
// null.
RtcEventGenericAckReceived(
int64_t timestamp_us,
int64_t packet_number,
int64_t acked_packet_number,
absl::optional<int64_t> receive_acked_packet_time_ms);
const int64_t packet_number_;
const int64_t acked_packet_number_;
const absl::optional<int64_t> receive_timestamp_ms_;
const absl::optional<int64_t> receive_acked_packet_time_ms_;
};
} // namespace webrtc

View File

@ -17,8 +17,15 @@ RtcEventGenericPacketReceived::RtcEventGenericPacketReceived(
size_t packet_length)
: packet_number_(packet_number), packet_length_(packet_length) {}
RtcEventGenericPacketReceived::RtcEventGenericPacketReceived(
const RtcEventGenericPacketReceived& packet) = default;
RtcEventGenericPacketReceived::~RtcEventGenericPacketReceived() = default;
std::unique_ptr<RtcEventGenericPacketReceived>
RtcEventGenericPacketReceived::Copy() const {
return absl::WrapUnique(new RtcEventGenericPacketReceived(*this));
}
RtcEvent::Type RtcEventGenericPacketReceived::GetType() const {
return RtcEvent::Type::GenericPacketReceived;
}

View File

@ -11,6 +11,8 @@
#ifndef LOGGING_RTC_EVENT_LOG_EVENTS_RTC_EVENT_GENERIC_PACKET_RECEIVED_H_
#define LOGGING_RTC_EVENT_LOG_EVENTS_RTC_EVENT_GENERIC_PACKET_RECEIVED_H_
#include <memory>
#include "logging/rtc_event_log/events/rtc_event.h"
namespace webrtc {
@ -18,9 +20,10 @@ namespace webrtc {
class RtcEventGenericPacketReceived final : public RtcEvent {
public:
RtcEventGenericPacketReceived(int64_t packet_number, size_t packet_length);
RtcEventGenericPacketReceived(const RtcEventGenericPacketReceived& packet);
~RtcEventGenericPacketReceived() override;
std::unique_ptr<RtcEventGenericPacketReceived> Copy() const;
Type GetType() const override;
bool IsConfigEvent() const override;
@ -33,6 +36,8 @@ class RtcEventGenericPacketReceived final : public RtcEvent {
size_t packet_length() const { return packet_length_; }
private:
RtcEventGenericPacketReceived(const RtcEventGenericPacketReceived& packet);
const int64_t packet_number_;
const size_t packet_length_;
};

View File

@ -21,8 +21,16 @@ RtcEventGenericPacketSent::RtcEventGenericPacketSent(int64_t packet_number,
payload_length_(payload_length),
padding_length_(padding_length) {}
RtcEventGenericPacketSent::RtcEventGenericPacketSent(
const RtcEventGenericPacketSent& packet) = default;
RtcEventGenericPacketSent::~RtcEventGenericPacketSent() = default;
std::unique_ptr<RtcEventGenericPacketSent> RtcEventGenericPacketSent::Copy()
const {
return absl::WrapUnique(new RtcEventGenericPacketSent(*this));
}
RtcEvent::Type RtcEventGenericPacketSent::GetType() const {
return RtcEvent::Type::GenericPacketSent;
}

View File

@ -11,6 +11,8 @@
#ifndef LOGGING_RTC_EVENT_LOG_EVENTS_RTC_EVENT_GENERIC_PACKET_SENT_H_
#define LOGGING_RTC_EVENT_LOG_EVENTS_RTC_EVENT_GENERIC_PACKET_SENT_H_
#include <memory>
#include "logging/rtc_event_log/events/rtc_event.h"
namespace webrtc {
@ -21,9 +23,10 @@ class RtcEventGenericPacketSent final : public RtcEvent {
size_t overhead_length,
size_t payload_length,
size_t padding_length);
RtcEventGenericPacketSent(const RtcEventGenericPacketSent& packet);
~RtcEventGenericPacketSent() override;
std::unique_ptr<RtcEventGenericPacketSent> Copy() const;
Type GetType() const override;
bool IsConfigEvent() const override;
@ -48,6 +51,8 @@ class RtcEventGenericPacketSent final : public RtcEvent {
size_t padding_length() const { return padding_length_; }
private:
RtcEventGenericPacketSent(const RtcEventGenericPacketSent& packet);
const int64_t packet_number_;
const size_t overhead_length_;
const size_t payload_length_;

View File

@ -522,5 +522,65 @@ struct LoggedIceEvent {
LoggedIceEventType event_type;
};
struct LoggedGenericPacketSent {
LoggedGenericPacketSent() = default;
LoggedGenericPacketSent(int64_t timestamp_us,
int64_t packet_number,
size_t overhead_length,
size_t payload_length,
size_t padding_length)
: timestamp_us(timestamp_us),
packet_number(packet_number),
overhead_length(overhead_length),
payload_length(payload_length),
padding_length(padding_length) {}
int64_t log_time_us() const { return timestamp_us; }
int64_t log_time_ms() const { return timestamp_us / 1000; }
int64_t timestamp_us;
int64_t packet_number;
size_t overhead_length;
size_t payload_length;
size_t padding_length;
};
struct LoggedGenericPacketReceived {
LoggedGenericPacketReceived() = default;
LoggedGenericPacketReceived(int64_t timestamp_us,
int64_t packet_number,
int packet_length)
: timestamp_us(timestamp_us),
packet_number(packet_number),
packet_length(packet_length) {}
int64_t log_time_us() const { return timestamp_us; }
int64_t log_time_ms() const { return timestamp_us / 1000; }
int64_t timestamp_us;
int64_t packet_number;
int packet_length;
};
struct LoggedGenericAckReceived {
LoggedGenericAckReceived() = default;
LoggedGenericAckReceived(int64_t timestamp_us,
int64_t packet_number,
int64_t acked_packet_number,
absl::optional<int64_t> receive_acked_packet_time_ms)
: timestamp_us(timestamp_us),
packet_number(packet_number),
acked_packet_number(acked_packet_number),
receive_acked_packet_time_ms(receive_acked_packet_time_ms) {}
int64_t log_time_us() const { return timestamp_us; }
int64_t log_time_ms() const { return timestamp_us / 1000; }
int64_t timestamp_us;
int64_t packet_number;
int64_t acked_packet_number;
absl::optional<int64_t> receive_acked_packet_time_ms;
};
} // namespace webrtc
#endif // LOGGING_RTC_EVENT_LOG_LOGGED_EVENTS_H_

View File

@ -34,6 +34,9 @@ message EventStream {
repeated IceCandidatePairEvent ice_candidate_events = 26;
repeated DtlsTransportStateEvent dtls_transport_state_events = 27;
repeated DtlsWritableState dtls_writable_states = 28;
repeated GenericPacketSent generic_packets_sent = 29;
repeated GenericPacketReceived generic_packets_received = 30;
repeated GenericAckReceived generic_acks_received = 31;
repeated AudioRecvStreamConfig audio_recv_stream_configs = 101;
repeated AudioSendStreamConfig audio_send_stream_configs = 102;
@ -46,6 +49,56 @@ message Event {
// TODO(terelius): Do we want to preserve the old Event definition here?
}
message GenericPacketReceived {
// All fields are required.
optional int64 timestamp_ms = 1;
optional int64 packet_number = 2;
// Length of the packet in bytes.
optional int32 packet_length = 3;
// Provided if there are deltas in the batch.
optional uint32 number_of_deltas = 16;
optional bytes timestamp_ms_deltas = 17;
optional bytes packet_number_deltas = 18;
optional bytes packet_length_deltas = 19;
}
message GenericPacketSent {
// All fields are required. All lengths in bytes.
optional int64 timestamp_ms = 1;
optional int64 packet_number = 2;
// overhead+payload+padding length = packet_length in bytes.
optional int32 overhead_length = 3;
optional int32 payload_length = 4;
optional int32 padding_length = 5;
optional uint32 number_of_deltas = 16;
optional bytes timestamp_ms_deltas = 17;
optional bytes packet_number_deltas = 18;
optional bytes overhead_length_deltas = 19;
optional bytes payload_length_deltas = 20;
optional bytes padding_length_deltas = 21;
}
message GenericAckReceived {
optional int64 timestamp_ms = 1;
// ID of the received packet.
optional int64 packet_number = 2;
// ID of the packet that was acked.
optional int64 acked_packet_number = 3;
// Timestamp in ms when the packet was received by the other side.
optional int64 receive_acked_packet_time_ms = 4;
optional uint32 number_of_deltas = 16;
optional bytes timestamp_ms_deltas = 17;
optional bytes packet_number_deltas = 18;
optional bytes acked_packet_number_deltas = 19;
optional bytes receive_acked_packet_time_ms_deltas = 20;
}
message IncomingRtpPackets {
// required
optional int64 timestamp_ms = 1;

View File

@ -1134,6 +1134,9 @@ bool ParsedRtcEventLog::ParseStream(
}
StoreFirstAndLastTimestamp(incoming_rtcp_packets());
StoreFirstAndLastTimestamp(outgoing_rtcp_packets());
StoreFirstAndLastTimestamp(generic_packets_sent_);
StoreFirstAndLastTimestamp(generic_packets_received_);
StoreFirstAndLastTimestamp(generic_acks_received_);
return success;
}
@ -2079,7 +2082,10 @@ void ParsedRtcEventLog::StoreParsedNewFormatEvent(
stream.audio_recv_stream_configs_size() +
stream.audio_send_stream_configs_size() +
stream.video_recv_stream_configs_size() +
stream.video_send_stream_configs_size(),
stream.video_send_stream_configs_size() +
stream.generic_packets_sent_size() +
stream.generic_packets_received_size() +
stream.generic_acks_received_size(),
1u);
if (stream.incoming_rtp_packets_size() == 1) {
@ -2126,6 +2132,12 @@ void ParsedRtcEventLog::StoreParsedNewFormatEvent(
StoreVideoRecvConfig(stream.video_recv_stream_configs(0));
} else if (stream.video_send_stream_configs_size() == 1) {
StoreVideoSendConfig(stream.video_send_stream_configs(0));
} else if (stream.generic_packets_received_size() == 1) {
StoreGenericPacketReceivedEvent(stream.generic_packets_received(0));
} else if (stream.generic_packets_sent_size() == 1) {
StoreGenericPacketSentEvent(stream.generic_packets_sent(0));
} else if (stream.generic_acks_received_size() == 1) {
StoreGenericAckReceivedEvent(stream.generic_acks_received(0));
} else {
RTC_NOTREACHED();
}
@ -2398,6 +2410,190 @@ void ParsedRtcEventLog::StoreBweProbeFailureEvent(
// TODO(terelius): Should we delta encode this event type?
}
void ParsedRtcEventLog::StoreGenericAckReceivedEvent(
const rtclog2::GenericAckReceived& proto) {
RTC_CHECK(proto.has_timestamp_ms());
RTC_CHECK(proto.has_packet_number());
RTC_CHECK(proto.has_acked_packet_number());
// receive_acked_packet_time_ms is optional.
absl::optional<int64_t> base_receive_acked_packet_time_ms;
if (proto.has_receive_acked_packet_time_ms()) {
base_receive_acked_packet_time_ms = proto.receive_acked_packet_time_ms();
}
generic_acks_received_.push_back(
{proto.timestamp_ms() * 1000, proto.packet_number(),
proto.acked_packet_number(), base_receive_acked_packet_time_ms});
const size_t number_of_deltas =
proto.has_number_of_deltas() ? proto.number_of_deltas() : 0u;
if (number_of_deltas == 0) {
return;
}
// timestamp_ms
std::vector<absl::optional<uint64_t>> timestamp_ms_values =
DecodeDeltas(proto.timestamp_ms_deltas(),
ToUnsigned(proto.timestamp_ms()), number_of_deltas);
RTC_CHECK_EQ(timestamp_ms_values.size(), number_of_deltas);
// packet_number
std::vector<absl::optional<uint64_t>> packet_number_values =
DecodeDeltas(proto.packet_number_deltas(),
ToUnsigned(proto.packet_number()), number_of_deltas);
RTC_CHECK_EQ(packet_number_values.size(), number_of_deltas);
// acked_packet_number
std::vector<absl::optional<uint64_t>> acked_packet_number_values =
DecodeDeltas(proto.acked_packet_number_deltas(),
ToUnsigned(proto.acked_packet_number()), number_of_deltas);
RTC_CHECK_EQ(acked_packet_number_values.size(), number_of_deltas);
// optional receive_acked_packet_time_ms
const absl::optional<uint64_t> unsigned_receive_acked_packet_time_ms_base =
proto.has_receive_acked_packet_time_ms()
? absl::optional<uint64_t>(
ToUnsigned(proto.receive_acked_packet_time_ms()))
: absl::optional<uint64_t>();
std::vector<absl::optional<uint64_t>> receive_acked_packet_time_ms_values =
DecodeDeltas(proto.receive_acked_packet_time_ms_deltas(),
unsigned_receive_acked_packet_time_ms_base,
number_of_deltas);
RTC_CHECK_EQ(receive_acked_packet_time_ms_values.size(), number_of_deltas);
for (size_t i = 0; i < number_of_deltas; i++) {
int64_t timestamp_ms;
RTC_CHECK(ToSigned(timestamp_ms_values[i].value(), &timestamp_ms));
int64_t packet_number;
RTC_CHECK(ToSigned(packet_number_values[i].value(), &packet_number));
int64_t acked_packet_number;
RTC_CHECK(
ToSigned(acked_packet_number_values[i].value(), &acked_packet_number));
absl::optional<int64_t> receive_acked_packet_time_ms;
if (receive_acked_packet_time_ms_values[i].has_value()) {
int64_t value;
RTC_CHECK(
ToSigned(receive_acked_packet_time_ms_values[i].value(), &value));
receive_acked_packet_time_ms = value;
}
generic_acks_received_.push_back({timestamp_ms * 1000, packet_number,
acked_packet_number,
receive_acked_packet_time_ms});
}
}
void ParsedRtcEventLog::StoreGenericPacketSentEvent(
const rtclog2::GenericPacketSent& proto) {
RTC_CHECK(proto.has_timestamp_ms());
// Base event
RTC_CHECK(proto.has_packet_number());
RTC_CHECK(proto.has_overhead_length());
RTC_CHECK(proto.has_payload_length());
RTC_CHECK(proto.has_padding_length());
generic_packets_sent_.push_back(
{proto.timestamp_ms() * 1000, proto.packet_number(),
static_cast<size_t>(proto.overhead_length()),
static_cast<size_t>(proto.payload_length()),
static_cast<size_t>(proto.padding_length())});
const size_t number_of_deltas =
proto.has_number_of_deltas() ? proto.number_of_deltas() : 0u;
if (number_of_deltas == 0) {
return;
}
// timestamp_ms
std::vector<absl::optional<uint64_t>> timestamp_ms_values =
DecodeDeltas(proto.timestamp_ms_deltas(),
ToUnsigned(proto.timestamp_ms()), number_of_deltas);
RTC_CHECK_EQ(timestamp_ms_values.size(), number_of_deltas);
// packet_number
std::vector<absl::optional<uint64_t>> packet_number_values =
DecodeDeltas(proto.packet_number_deltas(),
ToUnsigned(proto.packet_number()), number_of_deltas);
RTC_CHECK_EQ(packet_number_values.size(), number_of_deltas);
std::vector<absl::optional<uint64_t>> overhead_length_values =
DecodeDeltas(proto.overhead_length_deltas(), proto.overhead_length(),
number_of_deltas);
RTC_CHECK_EQ(overhead_length_values.size(), number_of_deltas);
std::vector<absl::optional<uint64_t>> payload_length_values =
DecodeDeltas(proto.payload_length_deltas(),
ToUnsigned(proto.payload_length()), number_of_deltas);
RTC_CHECK_EQ(payload_length_values.size(), number_of_deltas);
std::vector<absl::optional<uint64_t>> padding_length_values =
DecodeDeltas(proto.padding_length_deltas(),
ToUnsigned(proto.padding_length()), number_of_deltas);
RTC_CHECK_EQ(padding_length_values.size(), number_of_deltas);
for (size_t i = 0; i < number_of_deltas; i++) {
int64_t timestamp_ms;
RTC_CHECK(ToSigned(timestamp_ms_values[i].value(), &timestamp_ms));
int64_t packet_number;
RTC_CHECK(ToSigned(packet_number_values[i].value(), &packet_number));
RTC_CHECK(overhead_length_values[i].has_value());
RTC_CHECK(payload_length_values[i].has_value());
RTC_CHECK(padding_length_values[i].has_value());
generic_packets_sent_.push_back(
{timestamp_ms * 1000, packet_number,
static_cast<size_t>(overhead_length_values[i].value()),
static_cast<size_t>(payload_length_values[i].value()),
static_cast<size_t>(padding_length_values[i].value())});
}
}
void ParsedRtcEventLog::StoreGenericPacketReceivedEvent(
const rtclog2::GenericPacketReceived& proto) {
RTC_CHECK(proto.has_timestamp_ms());
// Base event
RTC_CHECK(proto.has_packet_number());
RTC_CHECK(proto.has_packet_length());
generic_packets_received_.push_back({proto.timestamp_ms() * 1000,
proto.packet_number(),
proto.packet_length()});
const size_t number_of_deltas =
proto.has_number_of_deltas() ? proto.number_of_deltas() : 0u;
if (number_of_deltas == 0) {
return;
}
// timestamp_ms
std::vector<absl::optional<uint64_t>> timestamp_ms_values =
DecodeDeltas(proto.timestamp_ms_deltas(),
ToUnsigned(proto.timestamp_ms()), number_of_deltas);
RTC_CHECK_EQ(timestamp_ms_values.size(), number_of_deltas);
// packet_number
std::vector<absl::optional<uint64_t>> packet_number_values =
DecodeDeltas(proto.packet_number_deltas(),
ToUnsigned(proto.packet_number()), number_of_deltas);
RTC_CHECK_EQ(packet_number_values.size(), number_of_deltas);
std::vector<absl::optional<uint64_t>> packet_length_values = DecodeDeltas(
proto.packet_length_deltas(), proto.packet_length(), number_of_deltas);
RTC_CHECK_EQ(packet_length_values.size(), number_of_deltas);
for (size_t i = 0; i < number_of_deltas; i++) {
int64_t timestamp_ms;
RTC_CHECK(ToSigned(timestamp_ms_values[i].value(), &timestamp_ms));
int64_t packet_number;
RTC_CHECK(ToSigned(packet_number_values[i].value(), &packet_number));
int32_t packet_length;
RTC_CHECK(ToSigned(packet_length_values[i].value(), &packet_length));
generic_packets_received_.push_back(
{timestamp_ms * 1000, packet_number, packet_length});
}
}
void ParsedRtcEventLog::StoreAudioNetworkAdaptationEvent(
const rtclog2::AudioNetworkAdaptations& proto) {
RTC_CHECK(proto.has_timestamp_ms());

View File

@ -470,6 +470,17 @@ class ParsedRtcEventLog {
}
}
const std::vector<LoggedGenericPacketReceived>& generic_packets_received() {
return generic_packets_received_;
}
const std::vector<LoggedGenericPacketSent>& generic_packets_sent() {
return generic_packets_sent_;
}
const std::vector<LoggedGenericAckReceived>& generic_acks_received() {
return generic_acks_received_;
}
int64_t first_timestamp() const { return first_timestamp_; }
int64_t last_timestamp() const { return last_timestamp_; }
@ -578,6 +589,10 @@ class ParsedRtcEventLog {
void StoreAudioSendConfig(const rtclog2::AudioSendStreamConfig& proto);
void StoreVideoRecvConfig(const rtclog2::VideoRecvStreamConfig& proto);
void StoreVideoSendConfig(const rtclog2::VideoSendStreamConfig& proto);
void StoreGenericPacketReceivedEvent(
const rtclog2::GenericPacketReceived& proto);
void StoreGenericPacketSentEvent(const rtclog2::GenericPacketSent& proto);
void StoreGenericAckReceivedEvent(const rtclog2::GenericAckReceived& proto);
// End of new parsing functions.
struct Stream {
@ -678,6 +693,10 @@ class ParsedRtcEventLog {
std::vector<LoggedVideoRecvConfig> video_recv_configs_;
std::vector<LoggedVideoSendConfig> video_send_configs_;
std::vector<LoggedGenericPacketReceived> generic_packets_received_;
std::vector<LoggedGenericPacketSent> generic_packets_sent_;
std::vector<LoggedGenericAckReceived> generic_acks_received_;
uint8_t last_incoming_rtcp_packet_[IP_PACKET_SIZE];
uint8_t last_incoming_rtcp_packet_length_;

View File

@ -26,6 +26,9 @@
#include "logging/rtc_event_log/events/rtc_event_bwe_update_loss_based.h"
#include "logging/rtc_event_log/events/rtc_event_dtls_transport_state.h"
#include "logging/rtc_event_log/events/rtc_event_dtls_writable_state.h"
#include "logging/rtc_event_log/events/rtc_event_generic_ack_received.h"
#include "logging/rtc_event_log/events/rtc_event_generic_packet_received.h"
#include "logging/rtc_event_log/events/rtc_event_generic_packet_sent.h"
#include "logging/rtc_event_log/events/rtc_event_probe_cluster_created.h"
#include "logging/rtc_event_log/events/rtc_event_probe_result_failure.h"
#include "logging/rtc_event_log/events/rtc_event_probe_result_success.h"
@ -73,13 +76,18 @@ struct EventCounts {
size_t outgoing_rtp_packets = 0;
size_t incoming_rtcp_packets = 0;
size_t outgoing_rtcp_packets = 0;
size_t generic_packets_sent = 0;
size_t generic_packets_received = 0;
size_t generic_acks_received = 0;
size_t total_nonconfig_events() const {
return alr_states + audio_playouts + ana_configs + bwe_loss_events +
bwe_delay_events + dtls_transport_states + dtls_writable_states +
probe_creations + probe_successes + probe_failures + ice_configs +
ice_events + incoming_rtp_packets + outgoing_rtp_packets +
incoming_rtcp_packets + outgoing_rtcp_packets;
incoming_rtcp_packets + outgoing_rtcp_packets +
generic_packets_sent + generic_packets_received +
generic_acks_received;
}
size_t total_config_events() const {
@ -120,6 +128,10 @@ class RtcEventLogSession
void WriteLog(EventCounts count, size_t num_events_before_log_start);
void ReadAndVerifyLog();
bool IsNewFormat() {
return encoding_type_ == RtcEventLog::EncodingType::NewFormat;
}
private:
void WriteAudioRecvConfigs(size_t audio_recv_streams, RtcEventLog* event_log);
void WriteAudioSendConfigs(size_t audio_send_streams, RtcEventLog* event_log);
@ -163,6 +175,11 @@ class RtcEventLogSession
outgoing_rtp_map_; // Groups outgoing RTP by SSRC.
std::vector<std::unique_ptr<RtcEventRtcpPacketIncoming>> incoming_rtcp_list_;
std::vector<std::unique_ptr<RtcEventRtcpPacketOutgoing>> outgoing_rtcp_list_;
std::vector<std::unique_ptr<RtcEventGenericPacketSent>> generic_packets_sent_;
std::vector<std::unique_ptr<RtcEventGenericPacketReceived>>
generic_packets_received_;
std::vector<std::unique_ptr<RtcEventGenericAckReceived>>
generic_acks_received_;
int64_t start_time_us_;
int64_t utc_start_time_us_;
@ -471,6 +488,33 @@ void RtcEventLogSession::WriteLog(EventCounts count,
}
selection -= count.outgoing_rtcp_packets;
if (selection < count.generic_packets_sent) {
auto event = gen_.NewGenericPacketSent();
generic_packets_sent_.push_back(event->Copy());
event_log->Log(std::move(event));
count.generic_packets_sent--;
continue;
}
selection -= count.generic_packets_sent;
if (selection < count.generic_packets_received) {
auto event = gen_.NewGenericPacketReceived();
generic_packets_received_.push_back(event->Copy());
event_log->Log(std::move(event));
count.generic_packets_received--;
continue;
}
selection -= count.generic_packets_received;
if (selection < count.generic_acks_received) {
auto event = gen_.NewGenericAckReceived();
generic_acks_received_.push_back(event->Copy());
event_log->Log(std::move(event));
count.generic_acks_received--;
continue;
}
selection -= count.generic_acks_received;
RTC_NOTREACHED();
}
@ -648,6 +692,28 @@ void RtcEventLogSession::ReadAndVerifyLog() {
parsed_video_send_configs[i]);
}
auto& parsed_generic_packets_received = parsed_log.generic_packets_received();
ASSERT_EQ(parsed_generic_packets_received.size(),
generic_packets_received_.size());
for (size_t i = 0; i < parsed_generic_packets_received.size(); i++) {
verifier_.VerifyLoggedGenericPacketReceived(
*generic_packets_received_[i], parsed_generic_packets_received[i]);
}
auto& parsed_generic_packets_sent = parsed_log.generic_packets_sent();
ASSERT_EQ(parsed_generic_packets_sent.size(), generic_packets_sent_.size());
for (size_t i = 0; i < parsed_generic_packets_sent.size(); i++) {
verifier_.VerifyLoggedGenericPacketSent(*generic_packets_sent_[i],
parsed_generic_packets_sent[i]);
}
auto& parsed_generic_acks_received = parsed_log.generic_acks_received();
ASSERT_EQ(parsed_generic_acks_received.size(), generic_acks_received_.size());
for (size_t i = 0; i < parsed_generic_acks_received.size(); i++) {
verifier_.VerifyLoggedGenericAckReceived(*generic_acks_received_[i],
parsed_generic_acks_received[i]);
}
EXPECT_EQ(first_timestamp_ms_, parsed_log.first_timestamp() / 1000);
EXPECT_EQ(last_timestamp_ms_, parsed_log.last_timestamp() / 1000);
@ -679,6 +745,11 @@ TEST_P(RtcEventLogSession, StartLoggingFromBeginning) {
count.outgoing_rtp_packets = 100;
count.incoming_rtcp_packets = 20;
count.outgoing_rtcp_packets = 20;
if (IsNewFormat()) {
count.generic_packets_sent = 100;
count.generic_packets_received = 100;
count.generic_acks_received = 20;
}
WriteLog(count, 0);
ReadAndVerifyLog();
@ -706,6 +777,11 @@ TEST_P(RtcEventLogSession, StartLoggingInTheMiddle) {
count.outgoing_rtp_packets = 500;
count.incoming_rtcp_packets = 50;
count.outgoing_rtcp_packets = 50;
if (IsNewFormat()) {
count.generic_packets_sent = 500;
count.generic_packets_received = 500;
count.generic_acks_received = 50;
}
WriteLog(count, 500);
ReadAndVerifyLog();

View File

@ -397,6 +397,28 @@ EventGenerator::NewRtcpPacketOutgoing() {
}
}
std::unique_ptr<RtcEventGenericPacketSent>
EventGenerator::NewGenericPacketSent() {
return absl::make_unique<RtcEventGenericPacketSent>(
sent_packet_number_++, prng_.Rand(40, 50), prng_.Rand(0, 150),
prng_.Rand(0, 1000));
}
std::unique_ptr<RtcEventGenericPacketReceived>
EventGenerator::NewGenericPacketReceived() {
return absl::make_unique<RtcEventGenericPacketReceived>(
received_packet_number_++, prng_.Rand(40, 250));
}
std::unique_ptr<RtcEventGenericAckReceived>
EventGenerator::NewGenericAckReceived() {
absl::optional<int64_t> receive_timestamp = absl::nullopt;
if (prng_.Rand(0, 2) > 0) {
receive_timestamp = prng_.Rand(0, 100000);
}
AckedPacket packet = {prng_.Rand(40, 250), receive_timestamp};
return std::move(RtcEventGenericAckReceived::CreateLogs(
received_packet_number_++, std::vector<AckedPacket>{packet})[0]);
}
void EventGenerator::RandomizeRtpPacket(
size_t payload_size,
size_t padding_size,
@ -857,6 +879,36 @@ void EventVerifier::VerifyLoggedRtpPacketOutgoing(
VerifyLoggedRtpHeader(original_event.header(), logged_event.rtp.header);
}
void EventVerifier::VerifyLoggedGenericPacketSent(
const RtcEventGenericPacketSent& original_event,
const LoggedGenericPacketSent& logged_event) const {
EXPECT_EQ(original_event.timestamp_ms(), logged_event.log_time_ms());
EXPECT_EQ(original_event.packet_number(), logged_event.packet_number);
EXPECT_EQ(original_event.overhead_length(), logged_event.overhead_length);
EXPECT_EQ(original_event.payload_length(), logged_event.payload_length);
EXPECT_EQ(original_event.padding_length(), logged_event.padding_length);
}
void EventVerifier::VerifyLoggedGenericPacketReceived(
const RtcEventGenericPacketReceived& original_event,
const LoggedGenericPacketReceived& logged_event) const {
EXPECT_EQ(original_event.timestamp_ms(), logged_event.log_time_ms());
EXPECT_EQ(original_event.packet_number(), logged_event.packet_number);
EXPECT_EQ(static_cast<int>(original_event.packet_length()),
logged_event.packet_length);
}
void EventVerifier::VerifyLoggedGenericAckReceived(
const RtcEventGenericAckReceived& original_event,
const LoggedGenericAckReceived& logged_event) const {
EXPECT_EQ(original_event.timestamp_ms(), logged_event.log_time_ms());
EXPECT_EQ(original_event.packet_number(), logged_event.packet_number);
EXPECT_EQ(original_event.acked_packet_number(),
logged_event.acked_packet_number);
EXPECT_EQ(original_event.receive_acked_packet_time_ms(),
logged_event.receive_acked_packet_time_ms);
}
void EventVerifier::VerifyLoggedRtcpPacketIncoming(
const RtcEventRtcpPacketIncoming& original_event,
const LoggedRtcpPacketIncoming& logged_event) const {

View File

@ -24,6 +24,9 @@
#include "logging/rtc_event_log/events/rtc_event_bwe_update_loss_based.h"
#include "logging/rtc_event_log/events/rtc_event_dtls_transport_state.h"
#include "logging/rtc_event_log/events/rtc_event_dtls_writable_state.h"
#include "logging/rtc_event_log/events/rtc_event_generic_ack_received.h"
#include "logging/rtc_event_log/events/rtc_event_generic_packet_received.h"
#include "logging/rtc_event_log/events/rtc_event_generic_packet_sent.h"
#include "logging/rtc_event_log/events/rtc_event_ice_candidate_pair.h"
#include "logging/rtc_event_log/events/rtc_event_ice_candidate_pair_config.h"
#include "logging/rtc_event_log/events/rtc_event_probe_cluster_created.h"
@ -81,6 +84,10 @@ class EventGenerator {
std::unique_ptr<RtcEventRtcpPacketOutgoing> NewRtcpPacketOutgoing();
std::unique_ptr<RtcEventGenericPacketSent> NewGenericPacketSent();
std::unique_ptr<RtcEventGenericPacketReceived> NewGenericPacketReceived();
std::unique_ptr<RtcEventGenericAckReceived> NewGenericAckReceived();
rtcp::SenderReport NewSenderReport();
rtcp::ReceiverReport NewReceiverReport();
rtcp::Nack NewNack();
@ -133,6 +140,8 @@ class EventGenerator {
private:
rtcp::ReportBlock NewReportBlock();
int sent_packet_number_ = 0;
int received_packet_number_ = 0;
Random prng_;
};
@ -197,6 +206,18 @@ class EventVerifier {
const RtcEventRtpPacketOutgoing& original_event,
const LoggedRtpPacketOutgoing& logged_event) const;
void VerifyLoggedGenericPacketSent(
const RtcEventGenericPacketSent& original_event,
const LoggedGenericPacketSent& logged_event) const;
void VerifyLoggedGenericPacketReceived(
const RtcEventGenericPacketReceived& original_event,
const LoggedGenericPacketReceived& logged_event) const;
void VerifyLoggedGenericAckReceived(
const RtcEventGenericAckReceived& original_event,
const LoggedGenericAckReceived& logged_event) const;
template <typename EventType, typename ParsedType>
void VerifyLoggedRtpPacket(const EventType& original_event,
const ParsedType& logged_event) {