webrtc/logging/rtc_event_log/rtc_event_log_unittest_helper.cc
Bjorn Terelius d932fba3bc Track padding and header size in log event.
Padding size and header size are not part of the header, but we still
want to log them. Add the values as separate fields to the log events.

Bug: webrtc:8111
Change-Id: I8dfa2ccafe679f96b8911b538a8512b0170bc642
Reviewed-on: https://webrtc-review.googlesource.com/c/106321
Commit-Queue: Björn Terelius <terelius@webrtc.org>
Reviewed-by: Elad Alon <eladalon@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#25237}
2018-10-17 15:52:17 +00:00

782 lines
31 KiB
C++

/*
* Copyright (c) 2016 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#include "logging/rtc_event_log/rtc_event_log_unittest_helper.h"
#include <string.h> // memcmp
#include <limits>
#include <memory>
#include <numeric>
#include <string>
#include <utility>
#include <vector>
#include "absl/types/optional.h"
#include "modules/audio_coding/audio_network_adaptor/include/audio_network_adaptor.h"
#include "modules/remote_bitrate_estimator/include/bwe_defines.h"
#include "modules/rtp_rtcp/include/rtp_cvo.h"
#include "modules/rtp_rtcp/source/rtp_header_extensions.h"
#include "modules/rtp_rtcp/source/rtp_packet_received.h"
#include "modules/rtp_rtcp/source/rtp_packet_to_send.h"
#include "rtc_base/checks.h"
#include "test/gtest.h"
namespace webrtc {
namespace test {
namespace {
struct ExtensionPair {
RTPExtensionType type;
const char* name;
};
constexpr int kMaxCsrcs = 3;
// Maximum serialized size of a header extension, including 1 byte ID.
constexpr int kMaxExtensionSizeBytes = 4;
constexpr int kMaxNumExtensions = 5;
constexpr ExtensionPair kExtensions[kMaxNumExtensions] = {
{RTPExtensionType::kRtpExtensionTransmissionTimeOffset,
RtpExtension::kTimestampOffsetUri},
{RTPExtensionType::kRtpExtensionAbsoluteSendTime,
RtpExtension::kAbsSendTimeUri},
{RTPExtensionType::kRtpExtensionTransportSequenceNumber,
RtpExtension::kTransportSequenceNumberUri},
{RTPExtensionType::kRtpExtensionAudioLevel, RtpExtension::kAudioLevelUri},
{RTPExtensionType::kRtpExtensionVideoRotation,
RtpExtension::kVideoRotationUri}};
template <typename T>
void ShuffleInPlace(Random* prng, rtc::ArrayView<T> array) {
RTC_DCHECK_LE(array.size(), std::numeric_limits<uint32_t>::max());
for (uint32_t i = 0; i + 1 < array.size(); i++) {
uint32_t other = prng->Rand(i, static_cast<uint32_t>(array.size() - 1));
std::swap(array[i], array[other]);
}
}
absl::optional<int> GetExtensionId(const std::vector<RtpExtension>& extensions,
const std::string& uri) {
for (const auto& extension : extensions) {
if (extension.uri == uri)
return extension.id;
}
return absl::nullopt;
}
} // namespace
std::unique_ptr<RtcEventAlrState> EventGenerator::NewAlrState() {
return absl::make_unique<RtcEventAlrState>(prng_.Rand<bool>());
}
std::unique_ptr<RtcEventAudioPlayout> EventGenerator::NewAudioPlayout(
uint32_t ssrc) {
return absl::make_unique<RtcEventAudioPlayout>(ssrc);
}
std::unique_ptr<RtcEventAudioNetworkAdaptation>
EventGenerator::NewAudioNetworkAdaptation() {
std::unique_ptr<AudioEncoderRuntimeConfig> config =
absl::make_unique<AudioEncoderRuntimeConfig>();
config->bitrate_bps = prng_.Rand(0, 3000000);
config->enable_fec = prng_.Rand<bool>();
config->enable_dtx = prng_.Rand<bool>();
config->frame_length_ms = prng_.Rand(10, 120);
config->num_channels = prng_.Rand(1, 2);
config->uplink_packet_loss_fraction = prng_.Rand<float>();
return absl::make_unique<RtcEventAudioNetworkAdaptation>(std::move(config));
}
std::unique_ptr<RtcEventBweUpdateDelayBased>
EventGenerator::NewBweUpdateDelayBased() {
constexpr int32_t kMaxBweBps = 20000000;
int32_t bitrate_bps = prng_.Rand(0, kMaxBweBps);
BandwidthUsage state = static_cast<BandwidthUsage>(
prng_.Rand(static_cast<uint32_t>(BandwidthUsage::kLast) - 1));
return absl::make_unique<RtcEventBweUpdateDelayBased>(bitrate_bps, state);
}
std::unique_ptr<RtcEventBweUpdateLossBased>
EventGenerator::NewBweUpdateLossBased() {
constexpr int32_t kMaxBweBps = 20000000;
constexpr int32_t kMaxPackets = 1000;
int32_t bitrate_bps = prng_.Rand(0, kMaxBweBps);
uint8_t fraction_lost = prng_.Rand<uint8_t>();
int32_t total_packets = prng_.Rand(1, kMaxPackets);
return absl::make_unique<RtcEventBweUpdateLossBased>(
bitrate_bps, fraction_lost, total_packets);
}
std::unique_ptr<RtcEventProbeClusterCreated>
EventGenerator::NewProbeClusterCreated() {
constexpr int kMaxBweBps = 20000000;
constexpr int kMaxNumProbes = 10000;
int id = prng_.Rand(1, kMaxNumProbes);
int bitrate_bps = prng_.Rand(0, kMaxBweBps);
int min_probes = prng_.Rand(5, 50);
int min_bytes = prng_.Rand(500, 50000);
return absl::make_unique<RtcEventProbeClusterCreated>(id, bitrate_bps,
min_probes, min_bytes);
}
std::unique_ptr<RtcEventProbeResultFailure>
EventGenerator::NewProbeResultFailure() {
constexpr int kMaxNumProbes = 10000;
int id = prng_.Rand(1, kMaxNumProbes);
ProbeFailureReason reason = static_cast<ProbeFailureReason>(
prng_.Rand(static_cast<uint32_t>(ProbeFailureReason::kLast) - 1));
return absl::make_unique<RtcEventProbeResultFailure>(id, reason);
}
std::unique_ptr<RtcEventProbeResultSuccess>
EventGenerator::NewProbeResultSuccess() {
constexpr int kMaxBweBps = 20000000;
constexpr int kMaxNumProbes = 10000;
int id = prng_.Rand(1, kMaxNumProbes);
int bitrate_bps = prng_.Rand(0, kMaxBweBps);
return absl::make_unique<RtcEventProbeResultSuccess>(id, bitrate_bps);
}
std::unique_ptr<RtcEventIceCandidatePairConfig>
EventGenerator::NewIceCandidatePairConfig() {
IceCandidateType local_candidate_type = static_cast<IceCandidateType>(
prng_.Rand(static_cast<uint32_t>(IceCandidateType::kNumValues) - 1));
IceCandidateNetworkType local_network_type =
static_cast<IceCandidateNetworkType>(prng_.Rand(
static_cast<uint32_t>(IceCandidateNetworkType::kNumValues) - 1));
IceCandidatePairAddressFamily local_address_family =
static_cast<IceCandidatePairAddressFamily>(prng_.Rand(
static_cast<uint32_t>(IceCandidatePairAddressFamily::kNumValues) -
1));
IceCandidateType remote_candidate_type = static_cast<IceCandidateType>(
prng_.Rand(static_cast<uint32_t>(IceCandidateType::kNumValues) - 1));
IceCandidatePairAddressFamily remote_address_family =
static_cast<IceCandidatePairAddressFamily>(prng_.Rand(
static_cast<uint32_t>(IceCandidatePairAddressFamily::kNumValues) -
1));
IceCandidatePairProtocol protocol_type =
static_cast<IceCandidatePairProtocol>(prng_.Rand(
static_cast<uint32_t>(IceCandidatePairProtocol::kNumValues) - 1));
IceCandidatePairDescription desc;
desc.local_candidate_type = local_candidate_type;
desc.local_relay_protocol = protocol_type;
desc.local_network_type = local_network_type;
desc.local_address_family = local_address_family;
desc.remote_candidate_type = remote_candidate_type;
desc.remote_address_family = remote_address_family;
desc.candidate_pair_protocol = protocol_type;
IceCandidatePairConfigType type =
static_cast<IceCandidatePairConfigType>(prng_.Rand(
static_cast<uint32_t>(IceCandidatePairConfigType::kNumValues) - 1));
uint32_t pair_id = prng_.Rand<uint32_t>();
return absl::make_unique<RtcEventIceCandidatePairConfig>(type, pair_id, desc);
}
std::unique_ptr<RtcEventIceCandidatePair>
EventGenerator::NewIceCandidatePair() {
IceCandidatePairEventType type =
static_cast<IceCandidatePairEventType>(prng_.Rand(
static_cast<uint32_t>(IceCandidatePairEventType::kNumValues) - 1));
uint32_t pair_id = prng_.Rand<uint32_t>();
return absl::make_unique<RtcEventIceCandidatePair>(type, pair_id);
}
rtcp::ReportBlock EventGenerator::NewReportBlock() {
rtcp::ReportBlock report_block;
report_block.SetMediaSsrc(prng_.Rand<uint32_t>());
report_block.SetFractionLost(prng_.Rand<uint8_t>());
// cumulative_lost is a 3-byte signed value.
RTC_DCHECK(report_block.SetCumulativeLost(
prng_.Rand(-(1 << 23) + 1, (1 << 23) - 1)));
report_block.SetExtHighestSeqNum(prng_.Rand<uint32_t>());
report_block.SetJitter(prng_.Rand<uint32_t>());
report_block.SetLastSr(prng_.Rand<uint32_t>());
report_block.SetDelayLastSr(prng_.Rand<uint32_t>());
return report_block;
}
rtcp::SenderReport EventGenerator::NewSenderReport() {
rtcp::SenderReport sender_report;
sender_report.SetSenderSsrc(prng_.Rand<uint32_t>());
sender_report.SetNtp(NtpTime(prng_.Rand<uint32_t>(), prng_.Rand<uint32_t>()));
sender_report.SetPacketCount(prng_.Rand<uint32_t>());
sender_report.AddReportBlock(NewReportBlock());
return sender_report;
}
rtcp::ReceiverReport EventGenerator::NewReceiverReport() {
rtcp::ReceiverReport receiver_report;
receiver_report.SetSenderSsrc(prng_.Rand<uint32_t>());
receiver_report.AddReportBlock(NewReportBlock());
return receiver_report;
}
std::unique_ptr<RtcEventRtcpPacketIncoming>
EventGenerator::NewRtcpPacketIncoming() {
// TODO(terelius): Test the other RTCP types too.
switch (prng_.Rand(0, 1)) {
case 0: {
rtcp::SenderReport sender_report = NewSenderReport();
rtc::Buffer buffer = sender_report.Build();
return absl::make_unique<RtcEventRtcpPacketIncoming>(buffer);
}
case 1: {
rtcp::ReceiverReport receiver_report = NewReceiverReport();
rtc::Buffer buffer = receiver_report.Build();
return absl::make_unique<RtcEventRtcpPacketIncoming>(buffer);
}
default:
RTC_NOTREACHED();
rtc::Buffer buffer;
return absl::make_unique<RtcEventRtcpPacketIncoming>(buffer);
}
}
std::unique_ptr<RtcEventRtcpPacketOutgoing>
EventGenerator::NewRtcpPacketOutgoing() {
// TODO(terelius): Test the other RTCP types too.
switch (prng_.Rand(0, 1)) {
case 0: {
rtcp::SenderReport sender_report = NewSenderReport();
rtc::Buffer buffer = sender_report.Build();
return absl::make_unique<RtcEventRtcpPacketOutgoing>(buffer);
}
case 1: {
rtcp::ReceiverReport receiver_report = NewReceiverReport();
rtc::Buffer buffer = receiver_report.Build();
return absl::make_unique<RtcEventRtcpPacketOutgoing>(buffer);
}
default:
RTC_NOTREACHED();
rtc::Buffer buffer;
return absl::make_unique<RtcEventRtcpPacketOutgoing>(buffer);
}
}
void EventGenerator::RandomizeRtpPacket(
size_t payload_size,
size_t padding_size,
uint32_t ssrc,
const RtpHeaderExtensionMap& extension_map,
RtpPacket* rtp_packet) {
constexpr int kMaxPayloadType = 127;
rtp_packet->SetPayloadType(prng_.Rand(kMaxPayloadType));
rtp_packet->SetMarker(prng_.Rand<bool>());
rtp_packet->SetSequenceNumber(prng_.Rand<uint16_t>());
rtp_packet->SetSsrc(ssrc);
rtp_packet->SetTimestamp(prng_.Rand<uint32_t>());
uint32_t csrcs_count = prng_.Rand(0, kMaxCsrcs);
std::vector<uint32_t> csrcs;
for (size_t i = 0; i < csrcs_count; i++) {
csrcs.push_back(prng_.Rand<uint32_t>());
}
rtp_packet->SetCsrcs(csrcs);
if (extension_map.IsRegistered(TransmissionOffset::kId))
rtp_packet->SetExtension<TransmissionOffset>(prng_.Rand(0x00ffffff));
if (extension_map.IsRegistered(AudioLevel::kId))
rtp_packet->SetExtension<AudioLevel>(prng_.Rand<bool>(), prng_.Rand(127));
if (extension_map.IsRegistered(AbsoluteSendTime::kId))
rtp_packet->SetExtension<AbsoluteSendTime>(prng_.Rand(0x00ffffff));
if (extension_map.IsRegistered(VideoOrientation::kId))
rtp_packet->SetExtension<VideoOrientation>(prng_.Rand(3));
if (extension_map.IsRegistered(TransportSequenceNumber::kId))
rtp_packet->SetExtension<TransportSequenceNumber>(prng_.Rand<uint16_t>());
RTC_CHECK_LE(rtp_packet->headers_size() + payload_size, IP_PACKET_SIZE);
uint8_t* payload = rtp_packet->AllocatePayload(payload_size);
RTC_DCHECK(payload != nullptr);
for (size_t i = 0; i < payload_size; i++) {
payload[i] = prng_.Rand<uint8_t>();
}
RTC_CHECK(rtp_packet->SetPadding(padding_size));
}
std::unique_ptr<RtcEventRtpPacketIncoming> EventGenerator::NewRtpPacketIncoming(
uint32_t ssrc,
const RtpHeaderExtensionMap& extension_map) {
constexpr size_t kMaxPaddingLength = 224;
const bool padding = prng_.Rand(0, 9) == 0; // Let padding be 10% probable.
const size_t padding_size = !padding ? 0u : prng_.Rand(0u, kMaxPaddingLength);
// 12 bytes RTP header, 4 bytes for 0xBEDE + alignment, 4 bytes per CSRC.
constexpr size_t kMaxHeaderSize =
16 + 4 * kMaxCsrcs + kMaxExtensionSizeBytes * kMaxNumExtensions;
// In principle, a packet can contain both padding and other payload.
// Currently, RTC eventlog encoder-parser can only maintain padding length if
// packet is full padding.
// TODO(webrtc:9730): Remove the deterministic logic for padding_size > 0.
size_t payload_size =
padding_size > 0 ? 0
: prng_.Rand(0u, static_cast<uint32_t>(IP_PACKET_SIZE -
1 - padding_size -
kMaxHeaderSize));
RtpPacketReceived rtp_packet(&extension_map);
RandomizeRtpPacket(payload_size, padding_size, ssrc, extension_map,
&rtp_packet);
return absl::make_unique<RtcEventRtpPacketIncoming>(rtp_packet);
}
std::unique_ptr<RtcEventRtpPacketOutgoing> EventGenerator::NewRtpPacketOutgoing(
uint32_t ssrc,
const RtpHeaderExtensionMap& extension_map) {
constexpr size_t kMaxPaddingLength = 224;
const bool padding = prng_.Rand(0, 9) == 0; // Let padding be 10% probable.
const size_t padding_size = !padding ? 0u : prng_.Rand(0u, kMaxPaddingLength);
// 12 bytes RTP header, 4 bytes for 0xBEDE + alignment, 4 bytes per CSRC.
constexpr size_t kMaxHeaderSize =
16 + 4 * kMaxCsrcs + kMaxExtensionSizeBytes * kMaxNumExtensions;
// In principle,a packet can contain both padding and other payload.
// Currently, RTC eventlog encoder-parser can only maintain padding length if
// packet is full padding.
// TODO(webrtc:9730): Remove the deterministic logic for padding_size > 0.
size_t payload_size =
padding_size > 0 ? 0
: prng_.Rand(0u, static_cast<uint32_t>(IP_PACKET_SIZE -
1 - padding_size -
kMaxHeaderSize));
RtpPacketToSend rtp_packet(&extension_map,
kMaxHeaderSize + payload_size + padding_size);
RandomizeRtpPacket(payload_size, padding_size, ssrc, extension_map,
&rtp_packet);
int probe_cluster_id = prng_.Rand(0, 100000);
return absl::make_unique<RtcEventRtpPacketOutgoing>(rtp_packet,
probe_cluster_id);
}
RtpHeaderExtensionMap EventGenerator::NewRtpHeaderExtensionMap() {
RtpHeaderExtensionMap extension_map;
std::vector<int> id(RtpExtension::kOneByteHeaderExtensionMaxId -
RtpExtension::kMinId + 1);
std::iota(id.begin(), id.end(), RtpExtension::kMinId);
ShuffleInPlace(&prng_, rtc::ArrayView<int>(id));
if (prng_.Rand<bool>()) {
extension_map.Register<AudioLevel>(id[0]);
}
if (prng_.Rand<bool>()) {
extension_map.Register<TransmissionOffset>(id[1]);
}
if (prng_.Rand<bool>()) {
extension_map.Register<AbsoluteSendTime>(id[2]);
}
if (prng_.Rand<bool>()) {
extension_map.Register<VideoOrientation>(id[3]);
}
if (prng_.Rand<bool>()) {
extension_map.Register<TransportSequenceNumber>(id[4]);
}
return extension_map;
}
std::unique_ptr<RtcEventAudioReceiveStreamConfig>
EventGenerator::NewAudioReceiveStreamConfig(
uint32_t ssrc,
const RtpHeaderExtensionMap& extensions) {
auto config = absl::make_unique<rtclog::StreamConfig>();
// Add SSRCs for the stream.
config->remote_ssrc = ssrc;
config->local_ssrc = prng_.Rand<uint32_t>();
// Add header extensions.
for (size_t i = 0; i < kMaxNumExtensions; i++) {
uint8_t id = extensions.GetId(kExtensions[i].type);
if (id != RtpHeaderExtensionMap::kInvalidId) {
config->rtp_extensions.emplace_back(kExtensions[i].name, id);
}
}
return absl::make_unique<RtcEventAudioReceiveStreamConfig>(std::move(config));
}
std::unique_ptr<RtcEventAudioSendStreamConfig>
EventGenerator::NewAudioSendStreamConfig(
uint32_t ssrc,
const RtpHeaderExtensionMap& extensions) {
auto config = absl::make_unique<rtclog::StreamConfig>();
// Add SSRC to the stream.
config->local_ssrc = ssrc;
// Add header extensions.
for (size_t i = 0; i < kMaxNumExtensions; i++) {
uint8_t id = extensions.GetId(kExtensions[i].type);
if (id != RtpHeaderExtensionMap::kInvalidId) {
config->rtp_extensions.emplace_back(kExtensions[i].name, id);
}
}
return absl::make_unique<RtcEventAudioSendStreamConfig>(std::move(config));
}
std::unique_ptr<RtcEventVideoReceiveStreamConfig>
EventGenerator::NewVideoReceiveStreamConfig(
uint32_t ssrc,
const RtpHeaderExtensionMap& extensions) {
auto config = absl::make_unique<rtclog::StreamConfig>();
// Add SSRCs for the stream.
config->remote_ssrc = ssrc;
config->local_ssrc = prng_.Rand<uint32_t>();
// Add extensions and settings for RTCP.
config->rtcp_mode =
prng_.Rand<bool>() ? RtcpMode::kCompound : RtcpMode::kReducedSize;
config->remb = prng_.Rand<bool>();
config->rtx_ssrc = prng_.Rand<uint32_t>();
config->codecs.emplace_back(prng_.Rand<bool>() ? "VP8" : "H264",
prng_.Rand(127), prng_.Rand(127));
// Add header extensions.
for (size_t i = 0; i < kMaxNumExtensions; i++) {
uint8_t id = extensions.GetId(kExtensions[i].type);
if (id != RtpHeaderExtensionMap::kInvalidId) {
config->rtp_extensions.emplace_back(kExtensions[i].name, id);
}
}
return absl::make_unique<RtcEventVideoReceiveStreamConfig>(std::move(config));
}
std::unique_ptr<RtcEventVideoSendStreamConfig>
EventGenerator::NewVideoSendStreamConfig(
uint32_t ssrc,
const RtpHeaderExtensionMap& extensions) {
auto config = absl::make_unique<rtclog::StreamConfig>();
config->codecs.emplace_back(prng_.Rand<bool>() ? "VP8" : "H264",
prng_.Rand(127), prng_.Rand(127));
config->local_ssrc = ssrc;
config->rtx_ssrc = prng_.Rand<uint32_t>();
// Add header extensions.
for (size_t i = 0; i < kMaxNumExtensions; i++) {
uint8_t id = extensions.GetId(kExtensions[i].type);
if (id != RtpHeaderExtensionMap::kInvalidId) {
config->rtp_extensions.emplace_back(kExtensions[i].name, id);
}
}
return absl::make_unique<RtcEventVideoSendStreamConfig>(std::move(config));
}
void VerifyLoggedAlrStateEvent(const RtcEventAlrState& original_event,
const LoggedAlrStateEvent& logged_event) {
EXPECT_EQ(original_event.timestamp_us_ / 1000, logged_event.log_time_ms());
EXPECT_EQ(original_event.in_alr_, logged_event.in_alr);
}
void VerifyLoggedAudioPlayoutEvent(
const RtcEventAudioPlayout& original_event,
const LoggedAudioPlayoutEvent& logged_event) {
EXPECT_EQ(original_event.timestamp_us_ / 1000, logged_event.log_time_ms());
EXPECT_EQ(original_event.ssrc_, logged_event.ssrc);
}
void VerifyLoggedAudioNetworkAdaptationEvent(
const RtcEventAudioNetworkAdaptation& original_event,
const LoggedAudioNetworkAdaptationEvent& logged_event) {
EXPECT_EQ(original_event.timestamp_us_ / 1000, logged_event.log_time_ms());
EXPECT_EQ(original_event.config_->bitrate_bps,
logged_event.config.bitrate_bps);
EXPECT_EQ(original_event.config_->enable_dtx, logged_event.config.enable_dtx);
EXPECT_EQ(original_event.config_->enable_fec, logged_event.config.enable_fec);
EXPECT_EQ(original_event.config_->frame_length_ms,
logged_event.config.frame_length_ms);
EXPECT_EQ(original_event.config_->num_channels,
logged_event.config.num_channels);
EXPECT_EQ(original_event.config_->uplink_packet_loss_fraction,
logged_event.config.uplink_packet_loss_fraction);
}
void VerifyLoggedBweDelayBasedUpdate(
const RtcEventBweUpdateDelayBased& original_event,
const LoggedBweDelayBasedUpdate& logged_event) {
EXPECT_EQ(original_event.timestamp_us_ / 1000, logged_event.log_time_ms());
EXPECT_EQ(original_event.bitrate_bps_, logged_event.bitrate_bps);
EXPECT_EQ(original_event.detector_state_, logged_event.detector_state);
}
void VerifyLoggedBweLossBasedUpdate(
const RtcEventBweUpdateLossBased& original_event,
const LoggedBweLossBasedUpdate& logged_event) {
EXPECT_EQ(original_event.timestamp_us_ / 1000, logged_event.log_time_ms());
EXPECT_EQ(original_event.bitrate_bps_, logged_event.bitrate_bps);
EXPECT_EQ(original_event.fraction_loss_, logged_event.fraction_lost);
EXPECT_EQ(original_event.total_packets_, logged_event.expected_packets);
}
void VerifyLoggedBweProbeClusterCreatedEvent(
const RtcEventProbeClusterCreated& original_event,
const LoggedBweProbeClusterCreatedEvent& logged_event) {
EXPECT_EQ(original_event.timestamp_us_ / 1000, logged_event.log_time_ms());
EXPECT_EQ(original_event.id_, logged_event.id);
EXPECT_EQ(original_event.bitrate_bps_, logged_event.bitrate_bps);
EXPECT_EQ(original_event.min_probes_, logged_event.min_packets);
EXPECT_EQ(original_event.min_bytes_, logged_event.min_bytes);
}
void VerifyLoggedBweProbeFailureEvent(
const RtcEventProbeResultFailure& original_event,
const LoggedBweProbeFailureEvent& logged_event) {
EXPECT_EQ(original_event.timestamp_us_ / 1000, logged_event.log_time_ms());
EXPECT_EQ(original_event.id_, logged_event.id);
EXPECT_EQ(original_event.failure_reason_, logged_event.failure_reason);
}
void VerifyLoggedBweProbeSuccessEvent(
const RtcEventProbeResultSuccess& original_event,
const LoggedBweProbeSuccessEvent& logged_event) {
EXPECT_EQ(original_event.timestamp_us_ / 1000, logged_event.log_time_ms());
EXPECT_EQ(original_event.id_, logged_event.id);
EXPECT_EQ(original_event.bitrate_bps_, logged_event.bitrate_bps);
}
void VerifyLoggedIceCandidatePairConfig(
const RtcEventIceCandidatePairConfig& original_event,
const LoggedIceCandidatePairConfig& logged_event) {
EXPECT_EQ(original_event.timestamp_us_ / 1000, logged_event.log_time_ms());
EXPECT_EQ(original_event.type_, logged_event.type);
EXPECT_EQ(original_event.candidate_pair_id_, logged_event.candidate_pair_id);
EXPECT_EQ(original_event.candidate_pair_desc_.local_candidate_type,
logged_event.local_candidate_type);
EXPECT_EQ(original_event.candidate_pair_desc_.local_relay_protocol,
logged_event.local_relay_protocol);
EXPECT_EQ(original_event.candidate_pair_desc_.local_network_type,
logged_event.local_network_type);
EXPECT_EQ(original_event.candidate_pair_desc_.local_address_family,
logged_event.local_address_family);
EXPECT_EQ(original_event.candidate_pair_desc_.remote_candidate_type,
logged_event.remote_candidate_type);
EXPECT_EQ(original_event.candidate_pair_desc_.remote_address_family,
logged_event.remote_address_family);
EXPECT_EQ(original_event.candidate_pair_desc_.candidate_pair_protocol,
logged_event.candidate_pair_protocol);
}
void VerifyLoggedIceCandidatePairEvent(
const RtcEventIceCandidatePair& original_event,
const LoggedIceCandidatePairEvent& logged_event) {
EXPECT_EQ(original_event.timestamp_us_ / 1000, logged_event.log_time_ms());
EXPECT_EQ(original_event.type_, logged_event.type);
EXPECT_EQ(original_event.candidate_pair_id_, logged_event.candidate_pair_id);
}
void VerifyLoggedRtpHeader(const RtpPacket& original_header,
const RTPHeader& logged_header) {
// Standard RTP header.
EXPECT_EQ(original_header.Marker(), logged_header.markerBit);
EXPECT_EQ(original_header.PayloadType(), logged_header.payloadType);
EXPECT_EQ(original_header.SequenceNumber(), logged_header.sequenceNumber);
EXPECT_EQ(original_header.Timestamp(), logged_header.timestamp);
EXPECT_EQ(original_header.Ssrc(), logged_header.ssrc);
EXPECT_EQ(original_header.headers_size(), logged_header.headerLength);
// TransmissionOffset header extension.
ASSERT_EQ(original_header.HasExtension<TransmissionOffset>(),
logged_header.extension.hasTransmissionTimeOffset);
if (logged_header.extension.hasTransmissionTimeOffset) {
int32_t offset;
original_header.GetExtension<TransmissionOffset>(&offset);
EXPECT_EQ(offset, logged_header.extension.transmissionTimeOffset);
}
// AbsoluteSendTime header extension.
ASSERT_EQ(original_header.HasExtension<AbsoluteSendTime>(),
logged_header.extension.hasAbsoluteSendTime);
if (logged_header.extension.hasAbsoluteSendTime) {
uint32_t sendtime;
original_header.GetExtension<AbsoluteSendTime>(&sendtime);
EXPECT_EQ(sendtime, logged_header.extension.absoluteSendTime);
}
// TransportSequenceNumber header extension.
ASSERT_EQ(original_header.HasExtension<TransportSequenceNumber>(),
logged_header.extension.hasTransportSequenceNumber);
if (logged_header.extension.hasTransportSequenceNumber) {
uint16_t seqnum;
original_header.GetExtension<TransportSequenceNumber>(&seqnum);
EXPECT_EQ(seqnum, logged_header.extension.transportSequenceNumber);
}
// AudioLevel header extension.
ASSERT_EQ(original_header.HasExtension<AudioLevel>(),
logged_header.extension.hasAudioLevel);
if (logged_header.extension.hasAudioLevel) {
bool voice_activity;
uint8_t audio_level;
original_header.GetExtension<AudioLevel>(&voice_activity, &audio_level);
EXPECT_EQ(voice_activity, logged_header.extension.voiceActivity);
EXPECT_EQ(audio_level, logged_header.extension.audioLevel);
}
// VideoOrientation header extension.
ASSERT_EQ(original_header.HasExtension<VideoOrientation>(),
logged_header.extension.hasVideoRotation);
if (logged_header.extension.hasVideoRotation) {
uint8_t rotation;
original_header.GetExtension<VideoOrientation>(&rotation);
EXPECT_EQ(ConvertCVOByteToVideoRotation(rotation),
logged_header.extension.videoRotation);
}
}
void VerifyLoggedRtpPacketIncoming(
const RtcEventRtpPacketIncoming& original_event,
const LoggedRtpPacketIncoming& logged_event) {
EXPECT_EQ(original_event.timestamp_us_ / 1000, logged_event.log_time_ms());
EXPECT_EQ(original_event.header_.headers_size(),
logged_event.rtp.header_length);
EXPECT_EQ(original_event.packet_length(), logged_event.rtp.total_length);
// Currently, RTC eventlog encoder-parser can only maintain padding length
// if packet is full padding.
EXPECT_EQ(original_event.padding_length_,
logged_event.rtp.header.paddingLength);
VerifyLoggedRtpHeader(original_event.header_, logged_event.rtp.header);
}
void VerifyLoggedRtpPacketOutgoing(
const RtcEventRtpPacketOutgoing& original_event,
const LoggedRtpPacketOutgoing& logged_event) {
EXPECT_EQ(original_event.timestamp_us_ / 1000, logged_event.log_time_ms());
EXPECT_EQ(original_event.header_.headers_size(),
logged_event.rtp.header_length);
EXPECT_EQ(original_event.packet_length(), logged_event.rtp.total_length);
// Currently, RTC eventlog encoder-parser can only maintain padding length
// if packet is full padding.
EXPECT_EQ(original_event.padding_length_,
logged_event.rtp.header.paddingLength);
// TODO(terelius): Probe cluster ID isn't parsed, used or tested. Unless
// someone has a strong reason to keep it, it'll be removed.
VerifyLoggedRtpHeader(original_event.header_, logged_event.rtp.header);
}
void VerifyLoggedRtcpPacketIncoming(
const RtcEventRtcpPacketIncoming& original_event,
const LoggedRtcpPacketIncoming& logged_event) {
EXPECT_EQ(original_event.timestamp_us_ / 1000, logged_event.log_time_ms());
ASSERT_EQ(original_event.packet_.size(), logged_event.rtcp.raw_data.size());
EXPECT_EQ(
memcmp(original_event.packet_.data(), logged_event.rtcp.raw_data.data(),
original_event.packet_.size()),
0);
}
void VerifyLoggedRtcpPacketOutgoing(
const RtcEventRtcpPacketOutgoing& original_event,
const LoggedRtcpPacketOutgoing& logged_event) {
EXPECT_EQ(original_event.timestamp_us_ / 1000, logged_event.log_time_ms());
ASSERT_EQ(original_event.packet_.size(), logged_event.rtcp.raw_data.size());
EXPECT_EQ(
memcmp(original_event.packet_.data(), logged_event.rtcp.raw_data.data(),
original_event.packet_.size()),
0);
}
void VerifyLoggedStartEvent(int64_t start_time_us,
const LoggedStartEvent& logged_event) {
EXPECT_EQ(start_time_us / 1000, logged_event.log_time_ms());
}
void VerifyLoggedStopEvent(int64_t stop_time_us,
const LoggedStopEvent& logged_event) {
EXPECT_EQ(stop_time_us / 1000, logged_event.log_time_ms());
}
void VerifyLoggedStreamConfig(const rtclog::StreamConfig& original_config,
const rtclog::StreamConfig& logged_config) {
EXPECT_EQ(original_config.local_ssrc, logged_config.local_ssrc);
EXPECT_EQ(original_config.remote_ssrc, logged_config.remote_ssrc);
EXPECT_EQ(original_config.rtx_ssrc, logged_config.rtx_ssrc);
EXPECT_EQ(original_config.rsid, logged_config.rsid);
EXPECT_EQ(original_config.rtp_extensions.size(),
logged_config.rtp_extensions.size());
size_t recognized_extensions = 0;
for (size_t i = 0; i < kMaxNumExtensions; i++) {
auto original_id =
GetExtensionId(original_config.rtp_extensions, kExtensions[i].name);
auto logged_id =
GetExtensionId(logged_config.rtp_extensions, kExtensions[i].name);
EXPECT_EQ(original_id, logged_id)
<< "IDs for " << kExtensions[i].name << " don't match. Original ID "
<< original_id.value_or(-1) << ". Parsed ID " << logged_id.value_or(-1)
<< ".";
if (original_id) {
recognized_extensions++;
}
}
EXPECT_EQ(recognized_extensions, original_config.rtp_extensions.size());
}
void VerifyLoggedAudioRecvConfig(
const RtcEventAudioReceiveStreamConfig& original_event,
const LoggedAudioRecvConfig& logged_event) {
EXPECT_EQ(original_event.timestamp_us_ / 1000, logged_event.log_time_ms());
VerifyLoggedStreamConfig(*original_event.config_, logged_event.config);
}
void VerifyLoggedAudioSendConfig(
const RtcEventAudioSendStreamConfig& original_event,
const LoggedAudioSendConfig& logged_event) {
EXPECT_EQ(original_event.timestamp_us_ / 1000, logged_event.log_time_ms());
VerifyLoggedStreamConfig(*original_event.config_, logged_event.config);
}
void VerifyLoggedVideoRecvConfig(
const RtcEventVideoReceiveStreamConfig& original_event,
const LoggedVideoRecvConfig& logged_event) {
EXPECT_EQ(original_event.timestamp_us_ / 1000, logged_event.log_time_ms());
VerifyLoggedStreamConfig(*original_event.config_, logged_event.config);
}
void VerifyLoggedVideoSendConfig(
const RtcEventVideoSendStreamConfig& original_event,
const LoggedVideoSendConfig& logged_event) {
EXPECT_EQ(original_event.timestamp_us_ / 1000, logged_event.log_time_ms());
// TODO(terelius): In the past, we allowed storing multiple RtcStreamConfigs
// in the same RtcEventVideoSendStreamConfig. Look into whether we should drop
// backwards compatibility in the parser.
ASSERT_EQ(logged_event.configs.size(), 1u);
VerifyLoggedStreamConfig(*original_event.config_, logged_event.configs[0]);
}
} // namespace test
} // namespace webrtc