Add parser and unittests for new RTC event log format.

Bug: webrtc:8111
Change-Id: I78db0765449a07fb94caef6b1452024105d7a69b
Reviewed-on: https://webrtc-review.googlesource.com/c/106709
Commit-Queue: Björn Terelius <terelius@webrtc.org>
Reviewed-by: Elad Alon <eladalon@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#25390}
This commit is contained in:
Bjorn Terelius
2018-10-22 15:23:32 +02:00
committed by Commit Bot
parent 916ae08a04
commit fdee701fa8
4 changed files with 840 additions and 50 deletions

View File

@ -11,9 +11,11 @@
#include <deque>
#include <limits>
#include <string>
#include <tuple>
#include "absl/memory/memory.h"
#include "logging/rtc_event_log/encoder/rtc_event_log_encoder_legacy.h"
#include "logging/rtc_event_log/encoder/rtc_event_log_encoder_new_format.h"
#include "logging/rtc_event_log/events/rtc_event_alr_state.h"
#include "logging/rtc_event_log/events/rtc_event_audio_network_adaptation.h"
#include "logging/rtc_event_log/events/rtc_event_audio_playout.h"
@ -40,14 +42,16 @@
namespace webrtc {
class RtcEventLogEncoderTest : public testing::TestWithParam<int> {
class RtcEventLogEncoderTest
: public testing::TestWithParam<std::tuple<int, bool>> {
protected:
RtcEventLogEncoderTest()
: encoder_(new RtcEventLogEncoderLegacy),
seed_(GetParam()),
prng_(seed_),
gen_(seed_ * 880001UL) {}
: seed_(std::get<0>(GetParam())), prng_(seed_), gen_(seed_ * 880001UL) {
if (std::get<1>(GetParam()))
encoder_ = absl::make_unique<RtcEventLogEncoderNewFormat>();
else
encoder_ = absl::make_unique<RtcEventLogEncoderLegacy>();
}
~RtcEventLogEncoderTest() override = default;
// ANA events have some optional fields, so we want to make sure that we get
@ -85,16 +89,14 @@ void RtcEventLogEncoderTest::TestRtcEventAudioNetworkAdaptation(
auto original_runtime_config = *runtime_config;
auto event = absl::make_unique<RtcEventAudioNetworkAdaptation>(
std::move(runtime_config));
const int64_t timestamp_us = event->timestamp_us_;
history_.push_back(std::move(event));
history_.push_back(event->Copy());
std::string encoded = encoder_->EncodeBatch(history_.begin(), history_.end());
ASSERT_TRUE(parsed_log_.ParseString(encoded));
const auto& ana_configs = parsed_log_.audio_network_adaptation_events();
ASSERT_EQ(ana_configs.size(), 1u);
EXPECT_EQ(ana_configs[0].timestamp_us, timestamp_us);
EXPECT_EQ(ana_configs[0].config, original_runtime_config);
ASSERT_EQ(ana_configs.size(), 1u);
test::VerifyLoggedAudioNetworkAdaptationEvent(*event, ana_configs[0]);
}
TEST_P(RtcEventLogEncoderTest, RtcEventAudioNetworkAdaptationBitrate) {
@ -184,6 +186,7 @@ TEST_P(RtcEventLogEncoderTest, RtcEventAudioPlayout) {
ASSERT_EQ(playout_events.size(), 1u);
const auto playout_stream = playout_events.find(ssrc);
ASSERT_TRUE(playout_stream != playout_events.end());
ASSERT_EQ(playout_stream->second.size(), 1u);
LoggedAudioPlayoutEvent playout_event = playout_stream->second[0];
test::VerifyLoggedAudioPlayoutEvent(*event, playout_event);
@ -242,7 +245,6 @@ TEST_P(RtcEventLogEncoderTest, RtcEventBweUpdateLossBased) {
const auto& bwe_loss_updates = parsed_log_.bwe_loss_updates();
ASSERT_EQ(bwe_loss_updates.size(), 1u);
test::VerifyLoggedBweLossBasedUpdate(*event, bwe_loss_updates[0]);
}
@ -281,7 +283,7 @@ TEST_P(RtcEventLogEncoderTest, RtcEventLoggingStarted) {
const auto& start_log_events = parsed_log_.start_log_events();
ASSERT_EQ(start_log_events.size(), 1u);
EXPECT_EQ(start_log_events[0].timestamp_us, timestamp_us);
test::VerifyLoggedStartEvent(timestamp_us, start_log_events[0]);
}
TEST_P(RtcEventLogEncoderTest, RtcEventLoggingStopped) {
@ -291,7 +293,7 @@ TEST_P(RtcEventLogEncoderTest, RtcEventLoggingStopped) {
const auto& stop_log_events = parsed_log_.stop_log_events();
ASSERT_EQ(stop_log_events.size(), 1u);
EXPECT_EQ(stop_log_events[0].timestamp_us, timestamp_us);
test::VerifyLoggedStopEvent(timestamp_us, stop_log_events[0]);
}
TEST_P(RtcEventLogEncoderTest, RtcEventProbeClusterCreated) {
@ -435,6 +437,7 @@ TEST_P(RtcEventLogEncoderTest, RtcEventVideoSendStreamConfig) {
INSTANTIATE_TEST_CASE_P(RandomSeeds,
RtcEventLogEncoderTest,
::testing::Values(1, 2, 3, 4, 5));
::testing::Combine(::testing::Values(1, 2, 3, 4, 5),
::testing::Bool()));
} // namespace webrtc

View File

@ -28,6 +28,7 @@
#include "modules/audio_coding/audio_network_adaptor/include/audio_network_adaptor.h"
#include "modules/congestion_controller/rtp/transport_feedback_adapter.h"
#include "modules/remote_bitrate_estimator/include/bwe_defines.h"
#include "modules/rtp_rtcp/include/rtp_cvo.h"
#include "modules/rtp_rtcp/include/rtp_rtcp_defines.h"
#include "modules/rtp_rtcp/source/byte_io.h"
#include "modules/rtp_rtcp/source/rtp_header_extensions.h"
@ -39,6 +40,7 @@
namespace webrtc {
namespace {
// Conversion functions for legacy wire format.
RtcpMode GetRuntimeRtcpMode(rtclog::VideoReceiveConfig::RtcpMode rtcp_mode) {
switch (rtcp_mode) {
case rtclog::VideoReceiveConfig::RTCP_COMPOUND:
@ -212,6 +214,175 @@ IceCandidatePairEventType GetRuntimeIceCandidatePairEventType(
return IceCandidatePairEventType::kCheckSent;
}
// Conversion functions for version 2 of the wire format.
BandwidthUsage GetRuntimeDetectorState(
rtclog2::DelayBasedBweUpdates::DetectorState detector_state) {
switch (detector_state) {
case rtclog2::DelayBasedBweUpdates::BWE_NORMAL:
return BandwidthUsage::kBwNormal;
case rtclog2::DelayBasedBweUpdates::BWE_UNDERUSING:
return BandwidthUsage::kBwUnderusing;
case rtclog2::DelayBasedBweUpdates::BWE_OVERUSING:
return BandwidthUsage::kBwOverusing;
case rtclog2::DelayBasedBweUpdates::BWE_UNKNOWN_STATE:
break;
}
RTC_NOTREACHED();
return BandwidthUsage::kBwNormal;
}
ProbeFailureReason GetRuntimeProbeFailureReason(
rtclog2::BweProbeResultFailure::FailureReason failure) {
switch (failure) {
case rtclog2::BweProbeResultFailure::INVALID_SEND_RECEIVE_INTERVAL:
return ProbeFailureReason::kInvalidSendReceiveInterval;
case rtclog2::BweProbeResultFailure::INVALID_SEND_RECEIVE_RATIO:
return ProbeFailureReason::kInvalidSendReceiveRatio;
case rtclog2::BweProbeResultFailure::TIMEOUT:
return ProbeFailureReason::kTimeout;
case rtclog2::BweProbeResultFailure::UNKNOWN:
break;
}
RTC_NOTREACHED();
return ProbeFailureReason::kTimeout;
}
IceCandidatePairConfigType GetRuntimeIceCandidatePairConfigType(
rtclog2::IceCandidatePairConfig::IceCandidatePairConfigType type) {
switch (type) {
case rtclog2::IceCandidatePairConfig::ADDED:
return IceCandidatePairConfigType::kAdded;
case rtclog2::IceCandidatePairConfig::UPDATED:
return IceCandidatePairConfigType::kUpdated;
case rtclog2::IceCandidatePairConfig::DESTROYED:
return IceCandidatePairConfigType::kDestroyed;
case rtclog2::IceCandidatePairConfig::SELECTED:
return IceCandidatePairConfigType::kSelected;
case rtclog2::IceCandidatePairConfig::UNKNOWN_CONFIG_TYPE:
break;
}
RTC_NOTREACHED();
return IceCandidatePairConfigType::kAdded;
}
IceCandidateType GetRuntimeIceCandidateType(
rtclog2::IceCandidatePairConfig::IceCandidateType type) {
switch (type) {
case rtclog2::IceCandidatePairConfig::LOCAL:
return IceCandidateType::kLocal;
case rtclog2::IceCandidatePairConfig::STUN:
return IceCandidateType::kStun;
case rtclog2::IceCandidatePairConfig::PRFLX:
return IceCandidateType::kPrflx;
case rtclog2::IceCandidatePairConfig::RELAY:
return IceCandidateType::kRelay;
case rtclog2::IceCandidatePairConfig::UNKNOWN_CANDIDATE_TYPE:
return IceCandidateType::kUnknown;
}
RTC_NOTREACHED();
return IceCandidateType::kUnknown;
}
IceCandidatePairProtocol GetRuntimeIceCandidatePairProtocol(
rtclog2::IceCandidatePairConfig::Protocol protocol) {
switch (protocol) {
case rtclog2::IceCandidatePairConfig::UDP:
return IceCandidatePairProtocol::kUdp;
case rtclog2::IceCandidatePairConfig::TCP:
return IceCandidatePairProtocol::kTcp;
case rtclog2::IceCandidatePairConfig::SSLTCP:
return IceCandidatePairProtocol::kSsltcp;
case rtclog2::IceCandidatePairConfig::TLS:
return IceCandidatePairProtocol::kTls;
case rtclog2::IceCandidatePairConfig::UNKNOWN_PROTOCOL:
return IceCandidatePairProtocol::kUnknown;
}
RTC_NOTREACHED();
return IceCandidatePairProtocol::kUnknown;
}
IceCandidatePairAddressFamily GetRuntimeIceCandidatePairAddressFamily(
rtclog2::IceCandidatePairConfig::AddressFamily address_family) {
switch (address_family) {
case rtclog2::IceCandidatePairConfig::IPV4:
return IceCandidatePairAddressFamily::kIpv4;
case rtclog2::IceCandidatePairConfig::IPV6:
return IceCandidatePairAddressFamily::kIpv6;
case rtclog2::IceCandidatePairConfig::UNKNOWN_ADDRESS_FAMILY:
return IceCandidatePairAddressFamily::kUnknown;
}
RTC_NOTREACHED();
return IceCandidatePairAddressFamily::kUnknown;
}
IceCandidateNetworkType GetRuntimeIceCandidateNetworkType(
rtclog2::IceCandidatePairConfig::NetworkType network_type) {
switch (network_type) {
case rtclog2::IceCandidatePairConfig::ETHERNET:
return IceCandidateNetworkType::kEthernet;
case rtclog2::IceCandidatePairConfig::LOOPBACK:
return IceCandidateNetworkType::kLoopback;
case rtclog2::IceCandidatePairConfig::WIFI:
return IceCandidateNetworkType::kWifi;
case rtclog2::IceCandidatePairConfig::VPN:
return IceCandidateNetworkType::kVpn;
case rtclog2::IceCandidatePairConfig::CELLULAR:
return IceCandidateNetworkType::kCellular;
case rtclog2::IceCandidatePairConfig::UNKNOWN_NETWORK_TYPE:
return IceCandidateNetworkType::kUnknown;
}
RTC_NOTREACHED();
return IceCandidateNetworkType::kUnknown;
}
IceCandidatePairEventType GetRuntimeIceCandidatePairEventType(
rtclog2::IceCandidatePairEvent::IceCandidatePairEventType type) {
switch (type) {
case rtclog2::IceCandidatePairEvent::CHECK_SENT:
return IceCandidatePairEventType::kCheckSent;
case rtclog2::IceCandidatePairEvent::CHECK_RECEIVED:
return IceCandidatePairEventType::kCheckReceived;
case rtclog2::IceCandidatePairEvent::CHECK_RESPONSE_SENT:
return IceCandidatePairEventType::kCheckResponseSent;
case rtclog2::IceCandidatePairEvent::CHECK_RESPONSE_RECEIVED:
return IceCandidatePairEventType::kCheckResponseReceived;
case rtclog2::IceCandidatePairEvent::UNKNOWN_CHECK_TYPE:
break;
}
RTC_NOTREACHED();
return IceCandidatePairEventType::kCheckSent;
}
std::vector<RtpExtension> GetRuntimeRtpHeaderExtensionConfig(
const rtclog2::RtpHeaderExtensionConfig& proto_header_extensions) {
std::vector<RtpExtension> rtp_extensions;
if (proto_header_extensions.has_transmission_time_offset_id()) {
rtp_extensions.emplace_back(
RtpExtension::kTimestampOffsetUri,
proto_header_extensions.transmission_time_offset_id());
}
if (proto_header_extensions.has_absolute_send_time_id()) {
rtp_extensions.emplace_back(
RtpExtension::kAbsSendTimeUri,
proto_header_extensions.absolute_send_time_id());
}
if (proto_header_extensions.has_transport_sequence_number_id()) {
rtp_extensions.emplace_back(
RtpExtension::kTransportSequenceNumberUri,
proto_header_extensions.transport_sequence_number_id());
}
if (proto_header_extensions.has_audio_level_id()) {
rtp_extensions.emplace_back(RtpExtension::kAudioLevelUri,
proto_header_extensions.audio_level_id());
}
if (proto_header_extensions.has_video_rotation_id()) {
rtp_extensions.emplace_back(RtpExtension::kVideoRotationUri,
proto_header_extensions.video_rotation_id());
}
return rtp_extensions;
}
// End of conversion functions.
// Reads a VarInt from |stream| and returns it. Also writes the read bytes to
// |buffer| starting |bytes_written| bytes into the buffer. |bytes_written| is
// incremented for each written byte.
@ -277,9 +448,15 @@ LoggedRtcpPacket::LoggedRtcpPacket(uint64_t timestamp_us,
const uint8_t* packet,
size_t total_length)
: timestamp_us(timestamp_us), raw_data(packet, packet + total_length) {}
LoggedRtcpPacket::LoggedRtcpPacket(uint64_t timestamp_us,
const std::string& packet)
: timestamp_us(timestamp_us), raw_data(packet.size()) {
memcpy(raw_data.data(), packet.data(), packet.size());
}
LoggedRtcpPacket::LoggedRtcpPacket(const LoggedRtcpPacket& rhs) = default;
LoggedRtcpPacket::~LoggedRtcpPacket() = default;
LoggedVideoSendConfig::LoggedVideoSendConfig() = default;
LoggedVideoSendConfig::LoggedVideoSendConfig(
int64_t timestamp_us,
const std::vector<rtclog::StreamConfig>& configs)
@ -478,9 +655,8 @@ bool ParsedRtcEventLogNew::ParseStream(
bool ParsedRtcEventLogNew::ParseStreamInternal(
std::istream& stream) { // no-presubmit-check TODO(webrtc:8982)
const size_t kMaxEventSize = (1u << 16) - 1;
const size_t kMaxVarintSize = 10;
std::vector<char> buffer(kMaxEventSize + 2 * kMaxVarintSize);
constexpr uint64_t kMaxEventSize = 10000000; // Sanity check.
std::vector<char> buffer(0xFFFF);
RTC_DCHECK(stream.good());
@ -491,10 +667,12 @@ bool ParsedRtcEventLogNew::ParseStreamInternal(
break;
}
// Read the next message tag. The tag number is defined as
// (fieldnumber << 3) | wire_type. In our case, the field number is
// supposed to be 1 and the wire type for a length-delimited field is 2.
const uint64_t kExpectedV1Tag = (1 << 3) | 2;
// Read the next message tag. Protobuf defines the message tag as
// (field_number << 3) | wire_type. In the legacy encoding, the field number
// is supposed to be 1 and the wire type for a length-delimited field is 2.
// In the new encoding we still expect the wire type to be 2, but the field
// number will be greater than 1.
constexpr uint64_t kExpectedV1Tag = (1 << 3) | 2;
size_t bytes_written = 0;
absl::optional<uint64_t> tag =
ParseVarInt(stream, buffer.data(), &bytes_written);
@ -502,9 +680,13 @@ bool ParsedRtcEventLogNew::ParseStreamInternal(
RTC_LOG(LS_WARNING)
<< "Missing field tag from beginning of protobuf event.";
return false;
} else if (*tag != kExpectedV1Tag) {
RTC_LOG(LS_WARNING)
<< "Unexpected field tag at beginning of protobuf event.";
}
constexpr uint64_t kWireTypeMask = 0x07;
const uint64_t wire_type = *tag & kWireTypeMask;
if (wire_type != 2) {
RTC_LOG(LS_WARNING) << "Expected field tag with wire type 2 (length "
"delimited message). Found wire type "
<< wire_type;
return false;
}
@ -520,6 +702,8 @@ bool ParsedRtcEventLogNew::ParseStreamInternal(
}
// Read the next protobuf event to a temporary char buffer.
if (buffer.size() < bytes_written + *message_length)
buffer.resize(bytes_written + *message_length);
stream.read(buffer.data() + bytes_written, *message_length);
if (stream.gcount() != static_cast<int>(*message_length)) {
RTC_LOG(LS_WARNING) << "Failed to read protobuf message from file.";
@ -527,21 +711,32 @@ bool ParsedRtcEventLogNew::ParseStreamInternal(
}
size_t buffer_size = bytes_written + *message_length;
// Parse the protobuf event from the buffer.
rtclog::EventStream event_stream;
if (!event_stream.ParseFromArray(buffer.data(), buffer_size)) {
RTC_LOG(LS_WARNING) << "Failed to parse protobuf message.";
return false;
}
if (*tag == kExpectedV1Tag) {
// Parse the protobuf event from the buffer.
rtclog::EventStream event_stream;
if (!event_stream.ParseFromArray(buffer.data(), buffer_size)) {
RTC_LOG(LS_WARNING)
<< "Failed to parse legacy-format protobuf message.";
return false;
}
RTC_CHECK_EQ(event_stream.stream_size(), 1);
StoreParsedEvent(event_stream.stream(0));
events_.push_back(event_stream.stream(0));
RTC_CHECK_EQ(event_stream.stream_size(), 1);
StoreParsedLegacyEvent(event_stream.stream(0));
events_.push_back(event_stream.stream(0));
} else {
// Parse the protobuf event from the buffer.
rtclog2::EventStream event_stream;
if (!event_stream.ParseFromArray(buffer.data(), buffer_size)) {
RTC_LOG(LS_WARNING) << "Failed to parse new-format protobuf message.";
return false;
}
StoreParsedNewFormatEvent(event_stream);
}
}
return true;
}
void ParsedRtcEventLogNew::StoreParsedEvent(const rtclog::Event& event) {
void ParsedRtcEventLogNew::StoreParsedLegacyEvent(const rtclog::Event& event) {
if (event.type() != rtclog::Event::VIDEO_RECEIVER_CONFIG_EVENT &&
event.type() != rtclog::Event::VIDEO_SENDER_CONFIG_EVENT &&
event.type() != rtclog::Event::AUDIO_RECEIVER_CONFIG_EVENT &&
@ -1480,4 +1675,539 @@ const std::vector<MatchedSendArrivalTimes> GetNetworkTrace(
return rtp_rtcp_matched;
}
// Helper functions for new format starts here
void ParsedRtcEventLogNew::StoreParsedNewFormatEvent(
const rtclog2::EventStream& stream) {
RTC_DCHECK_EQ(stream.stream_size(), 0);
RTC_DCHECK_LE(stream.incoming_rtp_packets_size(), 1);
if (stream.incoming_rtp_packets_size() == 1) {
StoreIncomingRtpPackets(stream.incoming_rtp_packets(0));
}
RTC_DCHECK_LE(stream.outgoing_rtp_packets_size(), 1);
if (stream.outgoing_rtp_packets_size() == 1) {
StoreOutgoingRtpPacket(stream.outgoing_rtp_packets(0));
}
RTC_DCHECK_LE(stream.incoming_rtcp_packets_size(), 1);
if (stream.incoming_rtcp_packets_size() == 1) {
StoreIncomingRtcpPackets(stream.incoming_rtcp_packets(0));
}
RTC_DCHECK_LE(stream.outgoing_rtcp_packets_size(), 1);
if (stream.outgoing_rtcp_packets_size() == 1) {
StoreOutgoingRtcpPackets(stream.outgoing_rtcp_packets(0));
}
RTC_DCHECK_LE(stream.audio_playout_events_size(), 1);
if (stream.audio_playout_events_size() == 1) {
StoreAudioPlayoutEvent(stream.audio_playout_events(0));
}
RTC_DCHECK_LE(stream.begin_log_events_size(), 1);
if (stream.begin_log_events_size() == 1) {
StoreStartEvent(stream.begin_log_events(0));
}
RTC_DCHECK_LE(stream.end_log_events_size(), 1);
if (stream.end_log_events_size() == 1) {
StoreStopEvent(stream.end_log_events(0));
}
RTC_DCHECK_LE(stream.loss_based_bwe_updates_size(), 1);
if (stream.loss_based_bwe_updates_size() == 1) {
StoreBweLossBasedUpdate(stream.loss_based_bwe_updates(0));
}
RTC_DCHECK_LE(stream.delay_based_bwe_updates_size(), 1);
if (stream.delay_based_bwe_updates_size() == 1) {
StoreBweDelayBasedUpdate(stream.delay_based_bwe_updates(0));
}
RTC_DCHECK_LE(stream.audio_network_adaptations_size(), 1);
if (stream.audio_network_adaptations_size() == 1) {
StoreAudioNetworkAdaptationEvent(stream.audio_network_adaptations(0));
}
RTC_DCHECK_LE(stream.probe_clusters_size(), 1);
if (stream.probe_clusters_size() == 1) {
StoreBweProbeClusterCreated(stream.probe_clusters(0));
}
RTC_DCHECK_LE(stream.probe_success_size(), 1);
if (stream.probe_success_size() == 1) {
StoreBweProbeSuccessEvent(stream.probe_success(0));
}
RTC_DCHECK_LE(stream.probe_failure_size(), 1);
if (stream.probe_failure_size() == 1) {
StoreBweProbeFailureEvent(stream.probe_failure(0));
}
RTC_DCHECK_LE(stream.alr_states_size(), 1);
if (stream.alr_states_size() == 1) {
StoreAlrStateEvent(stream.alr_states(0));
}
RTC_DCHECK_LE(stream.ice_candidate_configs_size(), 1);
if (stream.ice_candidate_configs_size() == 1) {
StoreIceCandidatePairConfig(stream.ice_candidate_configs(0));
}
RTC_DCHECK_LE(stream.ice_candidate_events_size(), 1);
if (stream.ice_candidate_events_size() == 1) {
StoreIceCandidateEvent(stream.ice_candidate_events(0));
}
RTC_DCHECK_LE(stream.audio_recv_stream_configs_size(), 1);
if (stream.audio_recv_stream_configs_size() == 1) {
StoreAudioRecvConfig(stream.audio_recv_stream_configs(0));
}
RTC_DCHECK_LE(stream.audio_send_stream_configs_size(), 1);
if (stream.audio_send_stream_configs_size() == 1) {
StoreAudioSendConfig(stream.audio_send_stream_configs(0));
}
RTC_DCHECK_LE(stream.video_recv_stream_configs_size(), 1);
if (stream.video_recv_stream_configs_size() == 1) {
StoreVideoRecvConfig(stream.video_recv_stream_configs(0));
}
RTC_DCHECK_LE(stream.video_send_stream_configs_size(), 1);
if (stream.video_send_stream_configs_size() == 1) {
StoreVideoSendConfig(stream.video_send_stream_configs(0));
}
}
void ParsedRtcEventLogNew::StoreAlrStateEvent(const rtclog2::AlrState& proto) {
RTC_CHECK(proto.has_timestamp_ms());
RTC_CHECK(proto.has_in_alr());
LoggedAlrStateEvent alr_event;
alr_event.timestamp_us = proto.timestamp_ms() * 1000;
alr_event.in_alr = proto.in_alr();
alr_state_events_.push_back(alr_event);
// TODO(terelius): Should we delta encode this event type?
}
void ParsedRtcEventLogNew::StoreAudioPlayoutEvent(
const rtclog2::AudioPlayoutEvents& proto) {
RTC_CHECK(proto.has_timestamp_ms());
RTC_CHECK(proto.has_local_ssrc());
LoggedAudioPlayoutEvent audio_playout_event;
audio_playout_event.timestamp_us = proto.timestamp_ms() * 1000;
audio_playout_event.ssrc = proto.local_ssrc();
audio_playout_events_[audio_playout_event.ssrc].push_back(
audio_playout_event);
// TODO(terelius): Parse deltas.
}
void ParsedRtcEventLogNew::StoreIncomingRtpPackets(
const rtclog2::IncomingRtpPackets& proto) {
RTC_CHECK(proto.has_timestamp_ms());
int64_t timestamp_ms = proto.timestamp_ms();
RTC_CHECK(proto.has_header_size());
size_t header_length = proto.header_size();
RTC_CHECK(proto.has_padding_size());
size_t padding_length = proto.padding_size();
RTC_CHECK(proto.has_payload_size());
size_t total_length = proto.payload_size() + header_length + padding_length;
RTPHeader header;
RTC_CHECK(proto.has_marker());
header.markerBit = proto.marker();
RTC_CHECK(proto.has_payload_type());
header.payloadType = proto.payload_type();
RTC_CHECK(proto.has_sequence_number());
header.sequenceNumber = proto.sequence_number();
RTC_CHECK(proto.has_rtp_timestamp());
header.timestamp = proto.rtp_timestamp();
RTC_CHECK(proto.has_ssrc());
header.ssrc = proto.ssrc();
header.numCSRCs = 0; // TODO(terelius): Implement CSRC.
header.paddingLength = padding_length;
header.headerLength = header_length;
// TODO(terelius): Should we implement payload_type_frequency?
if (proto.has_transmission_time_offset()) {
header.extension.hasTransmissionTimeOffset = true;
header.extension.transmissionTimeOffset = proto.transmission_time_offset();
}
if (proto.has_absolute_send_time()) {
header.extension.hasAbsoluteSendTime = true;
header.extension.absoluteSendTime = proto.absolute_send_time();
}
if (proto.has_transport_sequence_number()) {
header.extension.hasTransportSequenceNumber = true;
header.extension.transportSequenceNumber =
proto.transport_sequence_number();
}
if (proto.has_audio_level()) {
header.extension.hasAudioLevel = true;
header.extension.voiceActivity = (proto.audio_level() >> 7) != 0;
header.extension.audioLevel = proto.audio_level() & 0x7Fu;
}
if (proto.has_video_rotation()) {
header.extension.hasVideoRotation = true;
header.extension.videoRotation =
ConvertCVOByteToVideoRotation(proto.video_rotation());
}
incoming_rtp_packets_map_[header.ssrc].push_back(LoggedRtpPacketIncoming(
timestamp_ms * 1000, header, header_length, total_length));
// TODO(terelius): Parse deltas.
}
void ParsedRtcEventLogNew::StoreOutgoingRtpPacket(
const rtclog2::OutgoingRtpPackets& proto) {
RTC_CHECK(proto.has_timestamp_ms());
int64_t timestamp_ms = proto.timestamp_ms();
RTC_CHECK(proto.has_header_size());
size_t header_length = proto.header_size();
RTC_CHECK(proto.has_padding_size());
size_t padding_length = proto.padding_size();
RTC_CHECK(proto.has_payload_size());
size_t total_length = proto.payload_size() + header_length + padding_length;
RTPHeader header;
RTC_CHECK(proto.has_marker());
header.markerBit = proto.marker();
RTC_CHECK(proto.has_payload_type());
header.payloadType = proto.payload_type();
RTC_CHECK(proto.has_sequence_number());
header.sequenceNumber = proto.sequence_number();
RTC_CHECK(proto.has_rtp_timestamp());
header.timestamp = proto.rtp_timestamp();
RTC_CHECK(proto.has_ssrc());
header.ssrc = proto.ssrc();
header.numCSRCs = 0; // TODO(terelius): Implement CSRC.
header.paddingLength = padding_length;
header.headerLength = header_length;
// TODO(terelius): Should we implement payload_type_frequency?
if (proto.has_transmission_time_offset()) {
header.extension.hasTransmissionTimeOffset = true;
header.extension.transmissionTimeOffset = proto.transmission_time_offset();
}
if (proto.has_absolute_send_time()) {
header.extension.hasAbsoluteSendTime = true;
header.extension.absoluteSendTime = proto.absolute_send_time();
}
if (proto.has_transport_sequence_number()) {
header.extension.hasTransportSequenceNumber = true;
header.extension.transportSequenceNumber =
proto.transport_sequence_number();
}
if (proto.has_audio_level()) {
header.extension.hasAudioLevel = true;
header.extension.voiceActivity = (proto.audio_level() >> 7) != 0;
header.extension.audioLevel = proto.audio_level() & 0x7Fu;
}
if (proto.has_video_rotation()) {
header.extension.hasVideoRotation = true;
header.extension.videoRotation =
ConvertCVOByteToVideoRotation(proto.video_rotation());
}
outgoing_rtp_packets_map_[header.ssrc].push_back(LoggedRtpPacketOutgoing(
timestamp_ms * 1000, header, header_length, total_length));
// TODO(terelius): Parse deltas.
}
void ParsedRtcEventLogNew::StoreIncomingRtcpPackets(
const rtclog2::IncomingRtcpPackets& proto) {
RTC_CHECK(proto.has_timestamp_ms());
int64_t timestamp_ms = proto.timestamp_ms();
RTC_CHECK(proto.has_raw_packet());
incoming_rtcp_packets_.push_back(
LoggedRtcpPacketIncoming(timestamp_ms * 1000, proto.raw_packet()));
// TODO(terelius): Parse deltas.
}
void ParsedRtcEventLogNew::StoreOutgoingRtcpPackets(
const rtclog2::OutgoingRtcpPackets& proto) {
RTC_CHECK(proto.has_timestamp_ms());
int64_t timestamp_ms = proto.timestamp_ms();
RTC_CHECK(proto.has_raw_packet());
outgoing_rtcp_packets_.push_back(
LoggedRtcpPacketOutgoing(timestamp_ms * 1000, proto.raw_packet()));
// TODO(terelius): Parse deltas.
}
void ParsedRtcEventLogNew::StoreStartEvent(
const rtclog2::BeginLogEvent& proto) {
RTC_CHECK(proto.has_timestamp_ms());
LoggedStartEvent start_event(proto.timestamp_ms() * 1000);
start_log_events_.push_back(start_event);
}
void ParsedRtcEventLogNew::StoreStopEvent(const rtclog2::EndLogEvent& proto) {
RTC_CHECK(proto.has_timestamp_ms());
LoggedStopEvent stop_event(proto.timestamp_ms() * 1000);
stop_log_events_.push_back(stop_event);
}
void ParsedRtcEventLogNew::StoreBweLossBasedUpdate(
const rtclog2::LossBasedBweUpdates& proto) {
RTC_CHECK(proto.has_timestamp_ms());
RTC_CHECK(proto.has_bitrate_bps());
RTC_CHECK(proto.has_fraction_loss());
RTC_CHECK(proto.has_total_packets());
LoggedBweLossBasedUpdate loss_update;
loss_update.timestamp_us = proto.timestamp_ms() * 1000;
loss_update.bitrate_bps = proto.bitrate_bps();
loss_update.fraction_lost = proto.fraction_loss();
loss_update.expected_packets = proto.total_packets();
bwe_loss_updates_.push_back(loss_update);
// TODO(terelius): Parse deltas.
}
void ParsedRtcEventLogNew::StoreBweDelayBasedUpdate(
const rtclog2::DelayBasedBweUpdates& proto) {
RTC_CHECK(proto.has_timestamp_ms());
RTC_CHECK(proto.has_bitrate_bps());
RTC_CHECK(proto.has_detector_state());
LoggedBweDelayBasedUpdate delay_update;
delay_update.timestamp_us = proto.timestamp_ms() * 1000;
delay_update.bitrate_bps = proto.bitrate_bps();
delay_update.detector_state = GetRuntimeDetectorState(proto.detector_state());
bwe_delay_updates_.push_back(delay_update);
// TODO(terelius): Parse deltas.
}
void ParsedRtcEventLogNew::StoreBweProbeClusterCreated(
const rtclog2::BweProbeCluster& proto) {
LoggedBweProbeClusterCreatedEvent probe_cluster;
RTC_CHECK(proto.has_timestamp_ms());
probe_cluster.timestamp_us = proto.timestamp_ms() * 1000;
RTC_CHECK(proto.has_id());
probe_cluster.id = proto.id();
RTC_CHECK(proto.has_bitrate_bps());
probe_cluster.bitrate_bps = proto.bitrate_bps();
RTC_CHECK(proto.has_min_packets());
probe_cluster.min_packets = proto.min_packets();
RTC_CHECK(proto.has_min_bytes());
probe_cluster.min_bytes = proto.min_bytes();
bwe_probe_cluster_created_events_.push_back(probe_cluster);
// TODO(terelius): Should we delta encode this event type?
}
void ParsedRtcEventLogNew::StoreBweProbeSuccessEvent(
const rtclog2::BweProbeResultSuccess& proto) {
LoggedBweProbeSuccessEvent probe_result;
RTC_CHECK(proto.has_timestamp_ms());
probe_result.timestamp_us = proto.timestamp_ms() * 1000;
RTC_CHECK(proto.has_id());
probe_result.id = proto.id();
RTC_CHECK(proto.has_bitrate_bps());
probe_result.bitrate_bps = proto.bitrate_bps();
bwe_probe_success_events_.push_back(probe_result);
// TODO(terelius): Should we delta encode this event type?
}
void ParsedRtcEventLogNew::StoreBweProbeFailureEvent(
const rtclog2::BweProbeResultFailure& proto) {
LoggedBweProbeFailureEvent probe_result;
RTC_CHECK(proto.has_timestamp_ms());
probe_result.timestamp_us = proto.timestamp_ms() * 1000;
RTC_CHECK(proto.has_id());
probe_result.id = proto.id();
RTC_CHECK(proto.has_failure());
probe_result.failure_reason = GetRuntimeProbeFailureReason(proto.failure());
bwe_probe_failure_events_.push_back(probe_result);
// TODO(terelius): Should we delta encode this event type?
}
void ParsedRtcEventLogNew::StoreAudioNetworkAdaptationEvent(
const rtclog2::AudioNetworkAdaptations& proto) {
LoggedAudioNetworkAdaptationEvent ana_event;
RTC_CHECK(proto.has_timestamp_ms());
ana_event.timestamp_us = proto.timestamp_ms() * 1000;
if (proto.has_bitrate_bps()) {
ana_event.config.bitrate_bps = proto.bitrate_bps();
}
if (proto.has_frame_length_ms()) {
ana_event.config.frame_length_ms = proto.frame_length_ms();
}
if (proto.has_uplink_packet_loss_fraction()) {
ana_event.config.uplink_packet_loss_fraction =
proto.uplink_packet_loss_fraction();
}
if (proto.has_enable_fec()) {
ana_event.config.enable_fec = proto.enable_fec();
}
if (proto.has_enable_dtx()) {
ana_event.config.enable_dtx = proto.enable_dtx();
}
if (proto.has_num_channels()) {
ana_event.config.num_channels = proto.num_channels();
}
audio_network_adaptation_events_.push_back(ana_event);
// TODO(terelius): Parse deltas.
}
void ParsedRtcEventLogNew::StoreIceCandidatePairConfig(
const rtclog2::IceCandidatePairConfig& proto) {
LoggedIceCandidatePairConfig ice_config;
RTC_CHECK(proto.has_timestamp_ms());
ice_config.timestamp_us = proto.timestamp_ms() * 1000;
RTC_CHECK(proto.has_config_type());
ice_config.type = GetRuntimeIceCandidatePairConfigType(proto.config_type());
RTC_CHECK(proto.has_candidate_pair_id());
ice_config.candidate_pair_id = proto.candidate_pair_id();
RTC_CHECK(proto.has_local_candidate_type());
ice_config.local_candidate_type =
GetRuntimeIceCandidateType(proto.local_candidate_type());
RTC_CHECK(proto.has_local_relay_protocol());
ice_config.local_relay_protocol =
GetRuntimeIceCandidatePairProtocol(proto.local_relay_protocol());
RTC_CHECK(proto.has_local_network_type());
ice_config.local_network_type =
GetRuntimeIceCandidateNetworkType(proto.local_network_type());
RTC_CHECK(proto.has_local_address_family());
ice_config.local_address_family =
GetRuntimeIceCandidatePairAddressFamily(proto.local_address_family());
RTC_CHECK(proto.has_remote_candidate_type());
ice_config.remote_candidate_type =
GetRuntimeIceCandidateType(proto.remote_candidate_type());
RTC_CHECK(proto.has_remote_address_family());
ice_config.remote_address_family =
GetRuntimeIceCandidatePairAddressFamily(proto.remote_address_family());
RTC_CHECK(proto.has_candidate_pair_protocol());
ice_config.candidate_pair_protocol =
GetRuntimeIceCandidatePairProtocol(proto.candidate_pair_protocol());
ice_candidate_pair_configs_.push_back(ice_config);
// TODO(terelius): Should we delta encode this event type?
}
void ParsedRtcEventLogNew::StoreIceCandidateEvent(
const rtclog2::IceCandidatePairEvent& proto) {
LoggedIceCandidatePairEvent ice_event;
RTC_CHECK(proto.has_timestamp_ms());
ice_event.timestamp_us = proto.timestamp_ms() * 1000;
RTC_CHECK(proto.has_event_type());
ice_event.type = GetRuntimeIceCandidatePairEventType(proto.event_type());
RTC_CHECK(proto.has_candidate_pair_id());
ice_event.candidate_pair_id = proto.candidate_pair_id();
ice_candidate_pair_events_.push_back(ice_event);
// TODO(terelius): Should we delta encode this event type?
}
void ParsedRtcEventLogNew::StoreVideoRecvConfig(
const rtclog2::VideoRecvStreamConfig& proto) {
LoggedVideoRecvConfig stream;
RTC_CHECK(proto.has_timestamp_ms());
stream.timestamp_us = proto.timestamp_ms() * 1000;
RTC_CHECK(proto.has_remote_ssrc());
stream.config.remote_ssrc = proto.remote_ssrc();
RTC_CHECK(proto.has_local_ssrc());
stream.config.local_ssrc = proto.local_ssrc();
if (proto.has_rtx_ssrc()) {
stream.config.rtx_ssrc = proto.rtx_ssrc();
}
if (proto.has_rsid()) {
stream.config.rsid = proto.rsid();
}
if (proto.has_header_extensions()) {
stream.config.rtp_extensions =
GetRuntimeRtpHeaderExtensionConfig(proto.header_extensions());
}
video_recv_configs_.push_back(stream);
}
void ParsedRtcEventLogNew::StoreVideoSendConfig(
const rtclog2::VideoSendStreamConfig& proto) {
LoggedVideoSendConfig stream;
RTC_CHECK(proto.has_timestamp_ms());
stream.timestamp_us = proto.timestamp_ms() * 1000;
rtclog::StreamConfig config;
RTC_CHECK(proto.has_ssrc());
config.local_ssrc = proto.ssrc();
if (proto.has_rtx_ssrc()) {
config.rtx_ssrc = proto.rtx_ssrc();
}
if (proto.has_rsid()) {
config.rsid = proto.rsid();
}
if (proto.has_header_extensions()) {
config.rtp_extensions =
GetRuntimeRtpHeaderExtensionConfig(proto.header_extensions());
}
stream.configs.push_back(config);
video_send_configs_.push_back(stream);
}
void ParsedRtcEventLogNew::StoreAudioRecvConfig(
const rtclog2::AudioRecvStreamConfig& proto) {
LoggedAudioRecvConfig stream;
RTC_CHECK(proto.has_timestamp_ms());
stream.timestamp_us = proto.timestamp_ms() * 1000;
RTC_CHECK(proto.has_remote_ssrc());
stream.config.remote_ssrc = proto.remote_ssrc();
RTC_CHECK(proto.has_local_ssrc());
stream.config.local_ssrc = proto.local_ssrc();
if (proto.has_rsid()) {
stream.config.rsid = proto.rsid();
}
if (proto.has_header_extensions()) {
stream.config.rtp_extensions =
GetRuntimeRtpHeaderExtensionConfig(proto.header_extensions());
}
audio_recv_configs_.push_back(stream);
}
void ParsedRtcEventLogNew::StoreAudioSendConfig(
const rtclog2::AudioSendStreamConfig& proto) {
LoggedAudioSendConfig stream;
RTC_CHECK(proto.has_timestamp_ms());
stream.timestamp_us = proto.timestamp_ms() * 1000;
RTC_CHECK(proto.has_ssrc());
stream.config.local_ssrc = proto.ssrc();
if (proto.has_rsid()) {
stream.config.rsid = proto.rsid();
}
if (proto.has_header_extensions()) {
stream.config.rtp_extensions =
GetRuntimeRtpHeaderExtensionConfig(proto.header_extensions());
}
audio_send_configs_.push_back(stream);
}
} // namespace webrtc

View File

@ -25,7 +25,7 @@
#include "logging/rtc_event_log/events/rtc_event_probe_result_failure.h"
#include "logging/rtc_event_log/rtc_event_log.h"
#include "logging/rtc_event_log/rtc_stream_config.h"
#include "modules/audio_coding/audio_network_adaptor/include/audio_network_adaptor.h"
#include "modules/audio_coding/audio_network_adaptor/include/audio_network_adaptor_config.h"
#include "modules/rtp_rtcp/include/rtp_header_extension_map.h"
#include "modules/rtp_rtcp/source/rtcp_packet/common_header.h"
#include "modules/rtp_rtcp/source/rtcp_packet/nack.h"
@ -39,8 +39,10 @@
RTC_PUSH_IGNORING_WUNDEF()
#ifdef WEBRTC_ANDROID_PLATFORM_BUILD
#include "external/webrtc/webrtc/logging/rtc_event_log/rtc_event_log.pb.h"
#include "external/webrtc/webrtc/logging/rtc_event_log/rtc_event_log2.pb.h"
#else
#include "logging/rtc_event_log/rtc_event_log.pb.h"
#include "logging/rtc_event_log/rtc_event_log2.pb.h"
#endif
RTC_POP_IGNORING_WUNDEF()
@ -185,6 +187,7 @@ struct LoggedRtcpPacket {
LoggedRtcpPacket(uint64_t timestamp_us,
const uint8_t* packet,
size_t total_length);
LoggedRtcpPacket(uint64_t timestamp_us, const std::string& packet);
LoggedRtcpPacket(const LoggedRtcpPacket&);
~LoggedRtcpPacket();
int64_t timestamp_us;
@ -198,6 +201,8 @@ struct LoggedRtcpPacketIncoming {
const uint8_t* packet,
size_t total_length)
: rtcp(timestamp_us, packet, total_length) {}
LoggedRtcpPacketIncoming(uint64_t timestamp_us, const std::string& packet)
: rtcp(timestamp_us, packet) {}
LoggedRtcpPacket rtcp;
int64_t log_time_us() const { return rtcp.timestamp_us; }
int64_t log_time_ms() const { return rtcp.timestamp_us / 1000; }
@ -208,6 +213,8 @@ struct LoggedRtcpPacketOutgoing {
const uint8_t* packet,
size_t total_length)
: rtcp(timestamp_us, packet, total_length) {}
LoggedRtcpPacketOutgoing(uint64_t timestamp_us, const std::string& packet)
: rtcp(timestamp_us, packet) {}
LoggedRtcpPacket rtcp;
int64_t log_time_us() const { return rtcp.timestamp_us; }
int64_t log_time_ms() const { return rtcp.timestamp_us / 1000; }
@ -264,6 +271,7 @@ struct LoggedStopEvent {
};
struct LoggedAudioRecvConfig {
LoggedAudioRecvConfig() = default;
LoggedAudioRecvConfig(int64_t timestamp_us, const rtclog::StreamConfig config)
: timestamp_us(timestamp_us), config(config) {}
int64_t timestamp_us;
@ -273,6 +281,7 @@ struct LoggedAudioRecvConfig {
};
struct LoggedAudioSendConfig {
LoggedAudioSendConfig() = default;
LoggedAudioSendConfig(int64_t timestamp_us, const rtclog::StreamConfig config)
: timestamp_us(timestamp_us), config(config) {}
int64_t timestamp_us;
@ -282,6 +291,7 @@ struct LoggedAudioSendConfig {
};
struct LoggedVideoRecvConfig {
LoggedVideoRecvConfig() = default;
LoggedVideoRecvConfig(int64_t timestamp_us, const rtclog::StreamConfig config)
: timestamp_us(timestamp_us), config(config) {}
int64_t timestamp_us;
@ -291,6 +301,7 @@ struct LoggedVideoRecvConfig {
};
struct LoggedVideoSendConfig {
LoggedVideoSendConfig();
LoggedVideoSendConfig(int64_t timestamp_us,
const std::vector<rtclog::StreamConfig>& configs);
LoggedVideoSendConfig(const LoggedVideoSendConfig&);
@ -841,7 +852,7 @@ class ParsedRtcEventLogNew {
bool ParseStreamInternal(
std::istream& stream); // no-presubmit-check TODO(webrtc:8982)
void StoreParsedEvent(const rtclog::Event& event);
void StoreParsedLegacyEvent(const rtclog::Event& event);
rtclog::StreamConfig GetVideoReceiveConfig(const rtclog::Event& event) const;
std::vector<rtclog::StreamConfig> GetVideoSendConfig(
@ -873,8 +884,36 @@ class ParsedRtcEventLogNew {
LoggedIceCandidatePairEvent GetIceCandidatePairEvent(
const rtclog::Event& event) const;
// TODO(terelius): Remove
std::vector<rtclog::Event> events_;
// Parsing functions for new format.
void StoreParsedNewFormatEvent(const rtclog2::EventStream& event);
void StoreIncomingRtpPackets(const rtclog2::IncomingRtpPackets& proto);
void StoreOutgoingRtpPacket(const rtclog2::OutgoingRtpPackets& proto);
void StoreIncomingRtcpPackets(const rtclog2::IncomingRtcpPackets& proto);
void StoreOutgoingRtcpPackets(const rtclog2::OutgoingRtcpPackets& proto);
void StoreAudioPlayoutEvent(const rtclog2::AudioPlayoutEvents& proto);
void StoreStartEvent(const rtclog2::BeginLogEvent& proto);
void StoreStopEvent(const rtclog2::EndLogEvent& proto);
void StoreBweLossBasedUpdate(const rtclog2::LossBasedBweUpdates& proto);
void StoreBweDelayBasedUpdate(const rtclog2::DelayBasedBweUpdates& proto);
void StoreAudioNetworkAdaptationEvent(
const rtclog2::AudioNetworkAdaptations& proto);
void StoreBweProbeClusterCreated(const rtclog2::BweProbeCluster& proto);
void StoreBweProbeSuccessEvent(const rtclog2::BweProbeResultSuccess& proto);
void StoreBweProbeFailureEvent(const rtclog2::BweProbeResultFailure& proto);
void StoreAlrStateEvent(const rtclog2::AlrState& proto);
void StoreIceCandidatePairConfig(
const rtclog2::IceCandidatePairConfig& proto);
void StoreIceCandidateEvent(const rtclog2::IceCandidatePairEvent& proto);
void StoreAudioRecvConfig(const rtclog2::AudioRecvStreamConfig& proto);
void StoreAudioSendConfig(const rtclog2::AudioSendStreamConfig& proto);
void StoreVideoRecvConfig(const rtclog2::VideoRecvStreamConfig& proto);
void StoreVideoSendConfig(const rtclog2::VideoSendStreamConfig& proto);
// End of new parsing functions.
struct Stream {
Stream(uint32_t ssrc,
MediaType media_type,

View File

@ -101,13 +101,15 @@ struct EventCounts {
};
class RtcEventLogSession
: public ::testing::TestWithParam<std::tuple<uint64_t, int64_t>> {
: public ::testing::TestWithParam<
std::tuple<uint64_t, int64_t, RtcEventLog::EncodingType>> {
public:
RtcEventLogSession()
: seed_(std::get<0>(GetParam())),
prng_(seed_),
gen_(seed_ * 880001UL),
output_period_ms_(std::get<1>(GetParam())) {
output_period_ms_(std::get<1>(GetParam())),
encoding_type_(std::get<2>(GetParam())) {
clock_.SetTimeMicros(prng_.Rand<uint32_t>());
// Find the name of the current test, in order to use it as a temporary
// filename.
@ -171,7 +173,8 @@ class RtcEventLogSession
const uint64_t seed_;
Random prng_;
test::EventGenerator gen_;
int64_t output_period_ms_;
const int64_t output_period_ms_;
const RtcEventLog::EncodingType encoding_type_;
rtc::ScopedFakeClock clock_;
std::string temp_filename_;
};
@ -284,8 +287,7 @@ void RtcEventLogSession::WriteLog(EventCounts count,
// Maybe always use the ScopedFakeClock, but conditionally SleepMs()?
// The log file will be flushed to disk when the event_log goes out of scope.
std::unique_ptr<RtcEventLog> event_log(
RtcEventLog::Create(RtcEventLog::EncodingType::Legacy));
std::unique_ptr<RtcEventLog> event_log(RtcEventLog::Create(encoding_type_));
// We can't send or receive packets without configured streams.
RTC_CHECK_GE(count.video_recv_streams, 1);
@ -676,7 +678,23 @@ TEST_P(RtcEventLogSession, StartLoggingInTheMiddle) {
ReadAndVerifyLog();
}
TEST(RtcEventLogTest, CircularBufferKeepsMostRecentEvents) {
INSTANTIATE_TEST_CASE_P(
RtcEventLogTest,
RtcEventLogSession,
::testing::Combine(
::testing::Values(1234567, 7654321),
::testing::Values(RtcEventLog::kImmediateOutput, 1, 5),
::testing::Values(RtcEventLog::EncodingType::Legacy,
RtcEventLog::EncodingType::NewFormat)));
class RtcEventLogCircularBufferTest
: public ::testing::TestWithParam<RtcEventLog::EncodingType> {
public:
RtcEventLogCircularBufferTest() : encoding_type_(GetParam()) {}
const RtcEventLog::EncodingType encoding_type_;
};
TEST_P(RtcEventLogCircularBufferTest, KeepsMostRecentEvents) {
// TODO(terelius): Maybe make a separate RtcEventLogImplTest that can access
// the size of the cyclic buffer?
constexpr size_t kNumEvents = 20000;
@ -695,8 +713,7 @@ TEST(RtcEventLogTest, CircularBufferKeepsMostRecentEvents) {
// When log_dumper goes out of scope, it causes the log file to be flushed
// to disk.
std::unique_ptr<RtcEventLog> log_dumper(
RtcEventLog::Create(RtcEventLog::EncodingType::Legacy));
std::unique_ptr<RtcEventLog> log_dumper(RtcEventLog::Create(encoding_type_));
for (size_t i = 0; i < kNumEvents; i++) {
// The purpose of the test is to verify that the log can handle
@ -754,13 +771,14 @@ TEST(RtcEventLogTest, CircularBufferKeepsMostRecentEvents) {
}
}
INSTANTIATE_TEST_CASE_P(
RtcEventLogTest,
RtcEventLogCircularBufferTest,
::testing::Values(RtcEventLog::EncodingType::Legacy,
RtcEventLog::EncodingType::NewFormat));
// TODO(terelius): Verify parser behavior if the timestamps are not
// monotonically increasing in the log.
INSTANTIATE_TEST_CASE_P(
RtcEventLogTest,
RtcEventLogSession,
::testing::Combine(::testing::Values(1234567, 7654321),
::testing::Values(RtcEventLog::kImmediateOutput, 1, 5)));
} // namespace webrtc