diff --git a/logging/rtc_event_log/encoder/rtc_event_log_encoder_unittest.cc b/logging/rtc_event_log/encoder/rtc_event_log_encoder_unittest.cc index 4c36684c8e..726161e180 100644 --- a/logging/rtc_event_log/encoder/rtc_event_log_encoder_unittest.cc +++ b/logging/rtc_event_log/encoder/rtc_event_log_encoder_unittest.cc @@ -11,9 +11,11 @@ #include #include #include +#include #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 { +class RtcEventLogEncoderTest + : public testing::TestWithParam> { 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(); + else + encoder_ = absl::make_unique(); + } ~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( 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 diff --git a/logging/rtc_event_log/rtc_event_log_parser_new.cc b/logging/rtc_event_log/rtc_event_log_parser_new.cc index 64d2e13479..d352817334 100644 --- a/logging/rtc_event_log/rtc_event_log_parser_new.cc +++ b/logging/rtc_event_log/rtc_event_log_parser_new.cc @@ -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 GetRuntimeRtpHeaderExtensionConfig( + const rtclog2::RtpHeaderExtensionConfig& proto_header_extensions) { + std::vector 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& 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 buffer(kMaxEventSize + 2 * kMaxVarintSize); + constexpr uint64_t kMaxEventSize = 10000000; // Sanity check. + std::vector 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 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(*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 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 diff --git a/logging/rtc_event_log/rtc_event_log_parser_new.h b/logging/rtc_event_log/rtc_event_log_parser_new.h index 5ab0c15b92..7d246843e4 100644 --- a/logging/rtc_event_log/rtc_event_log_parser_new.h +++ b/logging/rtc_event_log/rtc_event_log_parser_new.h @@ -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& 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 GetVideoSendConfig( @@ -873,8 +884,36 @@ class ParsedRtcEventLogNew { LoggedIceCandidatePairEvent GetIceCandidatePairEvent( const rtclog::Event& event) const; + // TODO(terelius): Remove std::vector 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, diff --git a/logging/rtc_event_log/rtc_event_log_unittest.cc b/logging/rtc_event_log/rtc_event_log_unittest.cc index 1b7fbce489..bd136bb77b 100644 --- a/logging/rtc_event_log/rtc_event_log_unittest.cc +++ b/logging/rtc_event_log/rtc_event_log_unittest.cc @@ -101,13 +101,15 @@ struct EventCounts { }; class RtcEventLogSession - : public ::testing::TestWithParam> { + : public ::testing::TestWithParam< + std::tuple> { 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()); // 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 event_log( - RtcEventLog::Create(RtcEventLog::EncodingType::Legacy)); + std::unique_ptr 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 { + 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 log_dumper( - RtcEventLog::Create(RtcEventLog::EncodingType::Legacy)); + std::unique_ptr 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