diff --git a/logging/BUILD.gn b/logging/BUILD.gn index e56111a59a..a654fc40ec 100644 --- a/logging/BUILD.gn +++ b/logging/BUILD.gn @@ -78,6 +78,9 @@ rtc_source_set("rtc_event_log_api") { rtc_static_library("rtc_event_log_impl") { sources = [ + "rtc_event_log/encoder/rtc_event_log_encoder.h", + "rtc_event_log/encoder/rtc_event_log_encoder_legacy.cc", + "rtc_event_log/encoder/rtc_event_log_encoder_legacy.h", "rtc_event_log/rtc_event_log.cc", "rtc_event_log/rtc_event_log_factory.cc", "rtc_event_log/rtc_event_log_factory.h", @@ -146,7 +149,10 @@ if (rtc_enable_protobuf) { if (rtc_include_tests) { rtc_source_set("rtc_event_log_tests") { testonly = true + assert(rtc_enable_protobuf) + defines = [ "ENABLE_RTC_EVENT_LOG" ] sources = [ + "rtc_event_log/encoder/rtc_event_log_encoder_unittest.cc", "rtc_event_log/rtc_event_log_unittest.cc", "rtc_event_log/rtc_event_log_unittest_helper.cc", "rtc_event_log/rtc_event_log_unittest_helper.h", diff --git a/logging/rtc_event_log/encoder/rtc_event_log_encoder.h b/logging/rtc_event_log/encoder/rtc_event_log_encoder.h new file mode 100644 index 0000000000..3580d9c076 --- /dev/null +++ b/logging/rtc_event_log/encoder/rtc_event_log_encoder.h @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2017 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. + */ + +#ifndef LOGGING_RTC_EVENT_LOG_ENCODER_RTC_EVENT_LOG_ENCODER_H_ +#define LOGGING_RTC_EVENT_LOG_ENCODER_RTC_EVENT_LOG_ENCODER_H_ + +#include + +#include "logging/rtc_event_log/events/rtc_event.h" + +namespace webrtc { +class RtcEventLogEncoder { + public: + virtual ~RtcEventLogEncoder() = default; + + virtual std::string Encode(const RtcEvent& event) = 0; +}; + +} // namespace webrtc + +#endif // LOGGING_RTC_EVENT_LOG_ENCODER_RTC_EVENT_LOG_ENCODER_H_ diff --git a/logging/rtc_event_log/encoder/rtc_event_log_encoder_legacy.cc b/logging/rtc_event_log/encoder/rtc_event_log_encoder_legacy.cc new file mode 100644 index 0000000000..47b4c1e76b --- /dev/null +++ b/logging/rtc_event_log/encoder/rtc_event_log_encoder_legacy.cc @@ -0,0 +1,571 @@ +/* + * Copyright (c) 2017 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/encoder/rtc_event_log_encoder_legacy.h" + +#include "logging/rtc_event_log/events/rtc_event_audio_network_adaptation.h" +#include "logging/rtc_event_log/events/rtc_event_audio_playout.h" +#include "logging/rtc_event_log/events/rtc_event_audio_receive_stream_config.h" +#include "logging/rtc_event_log/events/rtc_event_audio_send_stream_config.h" +#include "logging/rtc_event_log/events/rtc_event_bwe_update_delay_based.h" +#include "logging/rtc_event_log/events/rtc_event_bwe_update_loss_based.h" +#include "logging/rtc_event_log/events/rtc_event_logging_started.h" +#include "logging/rtc_event_log/events/rtc_event_logging_stopped.h" +#include "logging/rtc_event_log/events/rtc_event_probe_cluster_created.h" +#include "logging/rtc_event_log/events/rtc_event_probe_result_failure.h" +#include "logging/rtc_event_log/events/rtc_event_probe_result_success.h" +#include "logging/rtc_event_log/events/rtc_event_rtcp_packet_incoming.h" +#include "logging/rtc_event_log/events/rtc_event_rtcp_packet_outgoing.h" +#include "logging/rtc_event_log/events/rtc_event_rtp_packet_incoming.h" +#include "logging/rtc_event_log/events/rtc_event_rtp_packet_outgoing.h" +#include "logging/rtc_event_log/events/rtc_event_video_receive_stream_config.h" +#include "logging/rtc_event_log/events/rtc_event_video_send_stream_config.h" +#include "logging/rtc_event_log/rtc_stream_config.h" +#include "modules/audio_coding/audio_network_adaptor/include/audio_network_adaptor_config.h" +#include "modules/remote_bitrate_estimator/include/bwe_defines.h" +#include "modules/rtp_rtcp/include/rtp_rtcp_defines.h" +#include "modules/rtp_rtcp/source/rtcp_packet/app.h" +#include "modules/rtp_rtcp/source/rtcp_packet/bye.h" +#include "modules/rtp_rtcp/source/rtcp_packet/common_header.h" +#include "modules/rtp_rtcp/source/rtcp_packet/extended_jitter_report.h" +#include "modules/rtp_rtcp/source/rtcp_packet/extended_reports.h" +#include "modules/rtp_rtcp/source/rtcp_packet/psfb.h" +#include "modules/rtp_rtcp/source/rtcp_packet/receiver_report.h" +#include "modules/rtp_rtcp/source/rtcp_packet/rtpfb.h" +#include "modules/rtp_rtcp/source/rtcp_packet/sdes.h" +#include "modules/rtp_rtcp/source/rtcp_packet/sender_report.h" +#include "modules/rtp_rtcp/source/rtp_packet.h" +#include "rtc_base/checks.h" +#include "rtc_base/ignore_wundef.h" +#include "rtc_base/logging.h" + +#ifdef ENABLE_RTC_EVENT_LOG + +// *.pb.h files are generated at build-time by the protobuf compiler. +RTC_PUSH_IGNORING_WUNDEF() +#ifdef WEBRTC_ANDROID_PLATFORM_BUILD +#include "external/webrtc/webrtc/logging/rtc_event_log/rtc_event_log.pb.h" +#else +#include "logging/rtc_event_log/rtc_event_log.pb.h" +#endif +RTC_POP_IGNORING_WUNDEF() + +namespace webrtc { + +namespace { +rtclog::DelayBasedBweUpdate::DetectorState ConvertDetectorState( + BandwidthUsage state) { + switch (state) { + case BandwidthUsage::kBwNormal: + return rtclog::DelayBasedBweUpdate::BWE_NORMAL; + case BandwidthUsage::kBwUnderusing: + return rtclog::DelayBasedBweUpdate::BWE_UNDERUSING; + case BandwidthUsage::kBwOverusing: + return rtclog::DelayBasedBweUpdate::BWE_OVERUSING; + case BandwidthUsage::kLast: + RTC_NOTREACHED(); + } + RTC_NOTREACHED(); + return rtclog::DelayBasedBweUpdate::BWE_NORMAL; +} + +rtclog::BweProbeResult::ResultType ConvertProbeResultType( + ProbeFailureReason failure_reason) { + switch (failure_reason) { + case ProbeFailureReason::kInvalidSendReceiveInterval: + return rtclog::BweProbeResult::INVALID_SEND_RECEIVE_INTERVAL; + case ProbeFailureReason::kInvalidSendReceiveRatio: + return rtclog::BweProbeResult::INVALID_SEND_RECEIVE_RATIO; + case ProbeFailureReason::kTimeout: + return rtclog::BweProbeResult::TIMEOUT; + case ProbeFailureReason::kLast: + RTC_NOTREACHED(); + } + RTC_NOTREACHED(); + return rtclog::BweProbeResult::SUCCESS; +} + +rtclog::VideoReceiveConfig_RtcpMode ConvertRtcpMode(RtcpMode rtcp_mode) { + switch (rtcp_mode) { + case RtcpMode::kCompound: + return rtclog::VideoReceiveConfig::RTCP_COMPOUND; + case RtcpMode::kReducedSize: + return rtclog::VideoReceiveConfig::RTCP_REDUCEDSIZE; + case RtcpMode::kOff: + RTC_NOTREACHED(); + } + RTC_NOTREACHED(); + return rtclog::VideoReceiveConfig::RTCP_COMPOUND; +} +} // namespace + +std::string RtcEventLogEncoderLegacy::Encode(const RtcEvent& event) { + switch (event.GetType()) { + case RtcEvent::Type::AudioNetworkAdaptation: { + auto& rtc_event = + static_cast(event); + return EncodeAudioNetworkAdaptation(rtc_event); + } + + case RtcEvent::Type::AudioPlayout: { + auto& rtc_event = static_cast(event); + return EncodeAudioPlayout(rtc_event); + } + + case RtcEvent::Type::AudioReceiveStreamConfig: { + auto& rtc_event = + static_cast(event); + return EncodeAudioReceiveStreamConfig(rtc_event); + } + + case RtcEvent::Type::AudioSendStreamConfig: { + auto& rtc_event = + static_cast(event); + return EncodeAudioSendStreamConfig(rtc_event); + } + + case RtcEvent::Type::BweUpdateDelayBased: { + auto& rtc_event = static_cast(event); + return EncodeBweUpdateDelayBased(rtc_event); + } + + case RtcEvent::Type::BweUpdateLossBased: { + auto& rtc_event = static_cast(event); + return EncodeBweUpdateLossBased(rtc_event); + } + + case RtcEvent::Type::LoggingStarted: { + auto& rtc_event = static_cast(event); + return EncodeLoggingStarted(rtc_event); + } + + case RtcEvent::Type::LoggingStopped: { + auto& rtc_event = static_cast(event); + return EncodeLoggingStopped(rtc_event); + } + + case RtcEvent::Type::ProbeClusterCreated: { + auto& rtc_event = static_cast(event); + return EncodeProbeClusterCreated(rtc_event); + } + + case RtcEvent::Type::ProbeResultFailure: { + auto& rtc_event = static_cast(event); + return EncodeProbeResultFailure(rtc_event); + } + + case RtcEvent::Type::ProbeResultSuccess: { + auto& rtc_event = static_cast(event); + return EncodeProbeResultSuccess(rtc_event); + } + + case RtcEvent::Type::RtcpPacketIncoming: { + auto& rtc_event = static_cast(event); + return EncodeRtcpPacketIncoming(rtc_event); + } + + case RtcEvent::Type::RtcpPacketOutgoing: { + auto& rtc_event = static_cast(event); + return EncodeRtcpPacketOutgoing(rtc_event); + } + + case RtcEvent::Type::RtpPacketIncoming: { + auto& rtc_event = static_cast(event); + return EncodeRtpPacketIncoming(rtc_event); + } + + case RtcEvent::Type::RtpPacketOutgoing: { + auto& rtc_event = static_cast(event); + return EncodeRtpPacketOutgoing(rtc_event); + } + + case RtcEvent::Type::VideoReceiveStreamConfig: { + auto& rtc_event = + static_cast(event); + return EncodeVideoReceiveStreamConfig(rtc_event); + } + + case RtcEvent::Type::VideoSendStreamConfig: { + auto& rtc_event = + static_cast(event); + return EncodeVideoSendStreamConfig(rtc_event); + } + } + + int event_type = static_cast(event.GetType()); + RTC_NOTREACHED() << "Unknown event type (" << event_type << ")"; + return ""; +} + +std::string RtcEventLogEncoderLegacy::EncodeAudioNetworkAdaptation( + const RtcEventAudioNetworkAdaptation& event) { + rtclog::Event rtclog_event; + rtclog_event.set_timestamp_us(event.timestamp_us_); + rtclog_event.set_type(rtclog::Event::AUDIO_NETWORK_ADAPTATION_EVENT); + + auto audio_network_adaptation = + rtclog_event.mutable_audio_network_adaptation(); + if (event.config_->bitrate_bps) + audio_network_adaptation->set_bitrate_bps(*event.config_->bitrate_bps); + if (event.config_->frame_length_ms) + audio_network_adaptation->set_frame_length_ms( + *event.config_->frame_length_ms); + if (event.config_->uplink_packet_loss_fraction) { + audio_network_adaptation->set_uplink_packet_loss_fraction( + *event.config_->uplink_packet_loss_fraction); + } + if (event.config_->enable_fec) + audio_network_adaptation->set_enable_fec(*event.config_->enable_fec); + if (event.config_->enable_dtx) + audio_network_adaptation->set_enable_dtx(*event.config_->enable_dtx); + if (event.config_->num_channels) + audio_network_adaptation->set_num_channels(*event.config_->num_channels); + + return Serialize(&rtclog_event); +} + +std::string RtcEventLogEncoderLegacy::EncodeAudioPlayout( + const RtcEventAudioPlayout& event) { + rtclog::Event rtclog_event; + rtclog_event.set_timestamp_us(event.timestamp_us_); + rtclog_event.set_type(rtclog::Event::AUDIO_PLAYOUT_EVENT); + + auto playout_event = rtclog_event.mutable_audio_playout_event(); + playout_event->set_local_ssrc(event.ssrc_); + + return Serialize(&rtclog_event); +} + +std::string RtcEventLogEncoderLegacy::EncodeAudioReceiveStreamConfig( + const RtcEventAudioReceiveStreamConfig& event) { + rtclog::Event rtclog_event; + rtclog_event.set_timestamp_us(event.timestamp_us_); + rtclog_event.set_type(rtclog::Event::AUDIO_RECEIVER_CONFIG_EVENT); + + rtclog::AudioReceiveConfig* receiver_config = + rtclog_event.mutable_audio_receiver_config(); + receiver_config->set_remote_ssrc(event.config_->remote_ssrc); + receiver_config->set_local_ssrc(event.config_->local_ssrc); + + for (const auto& e : event.config_->rtp_extensions) { + rtclog::RtpHeaderExtension* extension = + receiver_config->add_header_extensions(); + extension->set_name(e.uri); + extension->set_id(e.id); + } + + return Serialize(&rtclog_event); +} + +std::string RtcEventLogEncoderLegacy::EncodeAudioSendStreamConfig( + const RtcEventAudioSendStreamConfig& event) { + rtclog::Event rtclog_event; + rtclog_event.set_timestamp_us(event.timestamp_us_); + rtclog_event.set_type(rtclog::Event::AUDIO_SENDER_CONFIG_EVENT); + + rtclog::AudioSendConfig* sender_config = + rtclog_event.mutable_audio_sender_config(); + + sender_config->set_ssrc(event.config_->local_ssrc); + + for (const auto& e : event.config_->rtp_extensions) { + rtclog::RtpHeaderExtension* extension = + sender_config->add_header_extensions(); + extension->set_name(e.uri); + extension->set_id(e.id); + } + + return Serialize(&rtclog_event); +} + +std::string RtcEventLogEncoderLegacy::EncodeBweUpdateDelayBased( + const RtcEventBweUpdateDelayBased& event) { + rtclog::Event rtclog_event; + rtclog_event.set_timestamp_us(event.timestamp_us_); + rtclog_event.set_type(rtclog::Event::DELAY_BASED_BWE_UPDATE); + + auto bwe_event = rtclog_event.mutable_delay_based_bwe_update(); + bwe_event->set_bitrate_bps(event.bitrate_bps_); + bwe_event->set_detector_state(ConvertDetectorState(event.detector_state_)); + + return Serialize(&rtclog_event); +} + +std::string RtcEventLogEncoderLegacy::EncodeBweUpdateLossBased( + const RtcEventBweUpdateLossBased& event) { + rtclog::Event rtclog_event; + rtclog_event.set_timestamp_us(event.timestamp_us_); + rtclog_event.set_type(rtclog::Event::LOSS_BASED_BWE_UPDATE); + + auto bwe_event = rtclog_event.mutable_loss_based_bwe_update(); + bwe_event->set_bitrate_bps(event.bitrate_bps_); + bwe_event->set_fraction_loss(event.fraction_loss_); + bwe_event->set_total_packets(event.total_packets_); + + return Serialize(&rtclog_event); +} + +std::string RtcEventLogEncoderLegacy::EncodeLoggingStarted( + const RtcEventLoggingStarted& event) { + rtclog::Event rtclog_event; + rtclog_event.set_timestamp_us(event.timestamp_us_); + rtclog_event.set_type(rtclog::Event::LOG_START); + return Serialize(&rtclog_event); +} + +std::string RtcEventLogEncoderLegacy::EncodeLoggingStopped( + const RtcEventLoggingStopped& event) { + rtclog::Event rtclog_event; + rtclog_event.set_timestamp_us(event.timestamp_us_); + rtclog_event.set_type(rtclog::Event::LOG_END); + return Serialize(&rtclog_event); +} + +std::string RtcEventLogEncoderLegacy::EncodeProbeClusterCreated( + const RtcEventProbeClusterCreated& event) { + rtclog::Event rtclog_event; + rtclog_event.set_timestamp_us(event.timestamp_us_); + rtclog_event.set_type(rtclog::Event::BWE_PROBE_CLUSTER_CREATED_EVENT); + + auto probe_cluster = rtclog_event.mutable_probe_cluster(); + probe_cluster->set_id(event.id_); + probe_cluster->set_bitrate_bps(event.bitrate_bps_); + probe_cluster->set_min_packets(event.min_probes_); + probe_cluster->set_min_bytes(event.min_bytes_); + + return Serialize(&rtclog_event); +} + +std::string RtcEventLogEncoderLegacy::EncodeProbeResultFailure( + const RtcEventProbeResultFailure& event) { + rtclog::Event rtclog_event; + rtclog_event.set_timestamp_us(event.timestamp_us_); + rtclog_event.set_type(rtclog::Event::BWE_PROBE_RESULT_EVENT); + + auto probe_result = rtclog_event.mutable_probe_result(); + probe_result->set_id(event.id_); + probe_result->set_result(ConvertProbeResultType(event.failure_reason_)); + + return Serialize(&rtclog_event); +} + +std::string RtcEventLogEncoderLegacy::EncodeProbeResultSuccess( + const RtcEventProbeResultSuccess& event) { + rtclog::Event rtclog_event; + rtclog_event.set_timestamp_us(event.timestamp_us_); + rtclog_event.set_type(rtclog::Event::BWE_PROBE_RESULT_EVENT); + + auto probe_result = rtclog_event.mutable_probe_result(); + probe_result->set_id(event.id_); + probe_result->set_result(rtclog::BweProbeResult::SUCCESS); + probe_result->set_bitrate_bps(event.bitrate_bps_); + + return Serialize(&rtclog_event); +} + +std::string RtcEventLogEncoderLegacy::EncodeRtcpPacketIncoming( + const RtcEventRtcpPacketIncoming& event) { + return EncodeRtcpPacket(event.timestamp_us_, event.packet_, true); +} + +std::string RtcEventLogEncoderLegacy::EncodeRtcpPacketOutgoing( + const RtcEventRtcpPacketOutgoing& event) { + return EncodeRtcpPacket(event.timestamp_us_, event.packet_, false); +} + +std::string RtcEventLogEncoderLegacy::EncodeRtpPacketIncoming( + const RtcEventRtpPacketIncoming& event) { + return EncodeRtpPacket(event.timestamp_us_, event.header_, + event.packet_length_, PacedPacketInfo::kNotAProbe, + true); +} + +std::string RtcEventLogEncoderLegacy::EncodeRtpPacketOutgoing( + const RtcEventRtpPacketOutgoing& event) { + return EncodeRtpPacket(event.timestamp_us_, event.header_, + event.packet_length_, event.probe_cluster_id_, false); +} + +std::string RtcEventLogEncoderLegacy::EncodeVideoReceiveStreamConfig( + const RtcEventVideoReceiveStreamConfig& event) { + rtclog::Event rtclog_event; + rtclog_event.set_timestamp_us(event.timestamp_us_); + rtclog_event.set_type(rtclog::Event::VIDEO_RECEIVER_CONFIG_EVENT); + + rtclog::VideoReceiveConfig* receiver_config = + rtclog_event.mutable_video_receiver_config(); + receiver_config->set_remote_ssrc(event.config_->remote_ssrc); + receiver_config->set_local_ssrc(event.config_->local_ssrc); + + // TODO(perkj): Add field for rsid. + receiver_config->set_rtcp_mode(ConvertRtcpMode(event.config_->rtcp_mode)); + receiver_config->set_remb(event.config_->remb); + + for (const auto& e : event.config_->rtp_extensions) { + rtclog::RtpHeaderExtension* extension = + receiver_config->add_header_extensions(); + extension->set_name(e.uri); + extension->set_id(e.id); + } + + for (const auto& d : event.config_->codecs) { + rtclog::DecoderConfig* decoder = receiver_config->add_decoders(); + decoder->set_name(d.payload_name); + decoder->set_payload_type(d.payload_type); + if (d.rtx_payload_type != 0) { + rtclog::RtxMap* rtx = receiver_config->add_rtx_map(); + rtx->set_payload_type(d.payload_type); + rtx->mutable_config()->set_rtx_ssrc(event.config_->rtx_ssrc); + rtx->mutable_config()->set_rtx_payload_type(d.rtx_payload_type); + } + } + + return Serialize(&rtclog_event); +} + +std::string RtcEventLogEncoderLegacy::EncodeVideoSendStreamConfig( + const RtcEventVideoSendStreamConfig& event) { + rtclog::Event rtclog_event; + rtclog_event.set_timestamp_us(event.timestamp_us_); + rtclog_event.set_type(rtclog::Event::VIDEO_SENDER_CONFIG_EVENT); + + rtclog::VideoSendConfig* sender_config = + rtclog_event.mutable_video_sender_config(); + + // TODO(perkj): rtclog::VideoSendConfig should only contain one SSRC. + sender_config->add_ssrcs(event.config_->local_ssrc); + if (event.config_->rtx_ssrc != 0) { + sender_config->add_rtx_ssrcs(event.config_->rtx_ssrc); + } + + for (const auto& e : event.config_->rtp_extensions) { + rtclog::RtpHeaderExtension* extension = + sender_config->add_header_extensions(); + extension->set_name(e.uri); + extension->set_id(e.id); + } + + // TODO(perkj): rtclog::VideoSendConfig should contain many possible codec + // configurations. + for (const auto& codec : event.config_->codecs) { + sender_config->set_rtx_payload_type(codec.rtx_payload_type); + rtclog::EncoderConfig* encoder = sender_config->mutable_encoder(); + encoder->set_name(codec.payload_name); + encoder->set_payload_type(codec.payload_type); + + if (event.config_->codecs.size() > 1) { + LOG(WARNING) << "LogVideoSendStreamConfig currently only supports one " + << "codec. Logging codec :" << codec.payload_name; + break; + } + } + + return Serialize(&rtclog_event); +} + +std::string RtcEventLogEncoderLegacy::EncodeRtcpPacket( + int64_t timestamp_us, + const rtc::Buffer& packet, + bool is_incoming) { + rtclog::Event rtclog_event; + rtclog_event.set_timestamp_us(timestamp_us); + rtclog_event.set_type(rtclog::Event::RTCP_EVENT); + rtclog_event.mutable_rtcp_packet()->set_incoming(is_incoming); + + rtcp::CommonHeader header; + const uint8_t* block_begin = packet.data(); + const uint8_t* packet_end = packet.data() + packet.size(); + RTC_DCHECK(packet.size() <= IP_PACKET_SIZE); + uint8_t buffer[IP_PACKET_SIZE]; + uint32_t buffer_length = 0; + while (block_begin < packet_end) { + if (!header.Parse(block_begin, packet_end - block_begin)) { + break; // Incorrect message header. + } + const uint8_t* next_block = header.NextPacket(); + uint32_t block_size = next_block - block_begin; + switch (header.type()) { + case rtcp::Bye::kPacketType: + case rtcp::ExtendedJitterReport::kPacketType: + case rtcp::ExtendedReports::kPacketType: + case rtcp::Psfb::kPacketType: + case rtcp::ReceiverReport::kPacketType: + case rtcp::Rtpfb::kPacketType: + case rtcp::SenderReport::kPacketType: + // We log sender reports, receiver reports, bye messages + // inter-arrival jitter, third-party loss reports, payload-specific + // feedback and extended reports. + memcpy(buffer + buffer_length, block_begin, block_size); + buffer_length += block_size; + break; + case rtcp::App::kPacketType: + case rtcp::Sdes::kPacketType: + default: + // We don't log sender descriptions, application defined messages + // or message blocks of unknown type. + break; + } + + block_begin += block_size; + } + rtclog_event.mutable_rtcp_packet()->set_packet_data(buffer, buffer_length); + + return Serialize(&rtclog_event); +} + +std::string RtcEventLogEncoderLegacy::EncodeRtpPacket( + int64_t timestamp_us, + const webrtc::RtpPacket& header, + size_t packet_length, + int probe_cluster_id, + bool is_incoming) { + rtclog::Event rtclog_event; + rtclog_event.set_timestamp_us(timestamp_us); + rtclog_event.set_type(rtclog::Event::RTP_EVENT); + + rtclog_event.mutable_rtp_packet()->set_incoming(is_incoming); + rtclog_event.mutable_rtp_packet()->set_packet_length(packet_length); + rtclog_event.mutable_rtp_packet()->set_header(header.data(), header.size()); + if (probe_cluster_id != PacedPacketInfo::kNotAProbe) { + RTC_DCHECK(!is_incoming); + rtclog_event.mutable_rtp_packet()->set_probe_cluster_id(probe_cluster_id); + } + + return Serialize(&rtclog_event); +} + +std::string RtcEventLogEncoderLegacy::Serialize(rtclog::Event* event) { + // Even though we're only serializing a single event during this call, what + // we intend to get is a list of events, with a tag and length preceding + // each actual event. To produce that, we serialize a list of a single event. + // If we later concatenate several results from this function, the result will + // be a proper concatenation of all those events. + + rtclog::EventStream event_stream; + event_stream.add_stream(); + + // As a tweak, we swap the new event into the event-stream, write that to + // file, then swap back. This saves on some copying, while making sure that + // the caller wouldn't be surprised by Serialize() modifying the object. + rtclog::Event* output_event = event_stream.mutable_stream(0); + output_event->Swap(event); + + std::string output_string = event_stream.SerializeAsString(); + RTC_DCHECK(!output_string.empty()); + + // When the function returns, the original Event will be unchanged. + output_event->Swap(event); + + return output_string; +} + +} // namespace webrtc + +#endif // ENABLE_RTC_EVENT_LOG diff --git a/logging/rtc_event_log/encoder/rtc_event_log_encoder_legacy.h b/logging/rtc_event_log/encoder/rtc_event_log_encoder_legacy.h new file mode 100644 index 0000000000..b0909e2c22 --- /dev/null +++ b/logging/rtc_event_log/encoder/rtc_event_log_encoder_legacy.h @@ -0,0 +1,97 @@ +/* + * Copyright (c) 2017 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. + */ + +#ifndef LOGGING_RTC_EVENT_LOG_ENCODER_RTC_EVENT_LOG_ENCODER_LEGACY_H_ +#define LOGGING_RTC_EVENT_LOG_ENCODER_RTC_EVENT_LOG_ENCODER_LEGACY_H_ + +#include +#include + +#include "logging/rtc_event_log/encoder/rtc_event_log_encoder.h" +#include "rtc_base/buffer.h" + +#if defined(ENABLE_RTC_EVENT_LOG) + +namespace webrtc { + +namespace rtclog { +class Event; // Auto-generated from protobuf. +} // namespace rtclog + +class RtcEventAudioNetworkAdaptation; +class RtcEventAudioPlayout; +class RtcEventAudioReceiveStreamConfig; +class RtcEventAudioSendStreamConfig; +class RtcEventBweUpdateDelayBased; +class RtcEventBweUpdateLossBased; +class RtcEventLoggingStarted; +class RtcEventLoggingStopped; +class RtcEventProbeClusterCreated; +class RtcEventProbeResultFailure; +class RtcEventProbeResultSuccess; +class RtcEventRtcpPacketIncoming; +class RtcEventRtcpPacketOutgoing; +class RtcEventRtpPacketIncoming; +class RtcEventRtpPacketOutgoing; +class RtcEventVideoReceiveStreamConfig; +class RtcEventVideoSendStreamConfig; +class RtpPacket; + +class RtcEventLogEncoderLegacy final : public RtcEventLogEncoder { + public: + ~RtcEventLogEncoderLegacy() override = default; + + std::string Encode(const RtcEvent& event) override; + + private: + // Encoding entry-point for the various RtcEvent subclasses. + std::string EncodeAudioNetworkAdaptation( + const RtcEventAudioNetworkAdaptation& event); + std::string EncodeAudioPlayout(const RtcEventAudioPlayout& event); + std::string EncodeAudioReceiveStreamConfig( + const RtcEventAudioReceiveStreamConfig& event); + std::string EncodeAudioSendStreamConfig( + const RtcEventAudioSendStreamConfig& event); + std::string EncodeBweUpdateDelayBased( + const RtcEventBweUpdateDelayBased& event); + std::string EncodeBweUpdateLossBased(const RtcEventBweUpdateLossBased& event); + std::string EncodeLoggingStarted(const RtcEventLoggingStarted& event); + std::string EncodeLoggingStopped(const RtcEventLoggingStopped& event); + std::string EncodeProbeClusterCreated( + const RtcEventProbeClusterCreated& event); + std::string EncodeProbeResultFailure(const RtcEventProbeResultFailure& event); + std::string EncodeProbeResultSuccess(const RtcEventProbeResultSuccess&); + std::string EncodeRtcpPacketIncoming(const RtcEventRtcpPacketIncoming& event); + std::string EncodeRtcpPacketOutgoing(const RtcEventRtcpPacketOutgoing& event); + std::string EncodeRtpPacketIncoming(const RtcEventRtpPacketIncoming& event); + std::string EncodeRtpPacketOutgoing(const RtcEventRtpPacketOutgoing& event); + std::string EncodeVideoReceiveStreamConfig( + const RtcEventVideoReceiveStreamConfig& event); + std::string EncodeVideoSendStreamConfig( + const RtcEventVideoSendStreamConfig& event); + + // RTCP/RTP are handled similarly for incoming/outgoing. + std::string EncodeRtcpPacket(int64_t timestamp_us, + const rtc::Buffer& packet, + bool is_incoming); + std::string EncodeRtpPacket(int64_t timestamp_us, + const RtpPacket& header, + size_t packet_length, + int probe_cluster_id, + bool is_incoming); + + std::string Serialize(rtclog::Event* event); +}; + +} // namespace webrtc + +#endif // ENABLE_RTC_EVENT_LOG + +#endif // LOGGING_RTC_EVENT_LOG_ENCODER_RTC_EVENT_LOG_ENCODER_LEGACY_H_ 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 new file mode 100644 index 0000000000..0423f57cbf --- /dev/null +++ b/logging/rtc_event_log/encoder/rtc_event_log_encoder_unittest.cc @@ -0,0 +1,537 @@ +/* + * Copyright (c) 2017 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 +#include +#include +#include + +#include "api/rtpparameters.h" // RtpExtension +#include "logging/rtc_event_log/encoder/rtc_event_log_encoder_legacy.h" +#include "logging/rtc_event_log/events/rtc_event_audio_network_adaptation.h" +#include "logging/rtc_event_log/events/rtc_event_audio_playout.h" +#include "logging/rtc_event_log/events/rtc_event_audio_receive_stream_config.h" +#include "logging/rtc_event_log/events/rtc_event_audio_send_stream_config.h" +#include "logging/rtc_event_log/events/rtc_event_bwe_update_delay_based.h" +#include "logging/rtc_event_log/events/rtc_event_bwe_update_loss_based.h" +#include "logging/rtc_event_log/events/rtc_event_logging_started.h" +#include "logging/rtc_event_log/events/rtc_event_logging_stopped.h" +#include "logging/rtc_event_log/events/rtc_event_probe_cluster_created.h" +#include "logging/rtc_event_log/events/rtc_event_probe_result_failure.h" +#include "logging/rtc_event_log/events/rtc_event_probe_result_success.h" +#include "logging/rtc_event_log/events/rtc_event_rtcp_packet_incoming.h" +#include "logging/rtc_event_log/events/rtc_event_rtcp_packet_outgoing.h" +#include "logging/rtc_event_log/events/rtc_event_rtp_packet_incoming.h" +#include "logging/rtc_event_log/events/rtc_event_rtp_packet_outgoing.h" +#include "logging/rtc_event_log/events/rtc_event_video_receive_stream_config.h" +#include "logging/rtc_event_log/events/rtc_event_video_send_stream_config.h" +#include "logging/rtc_event_log/rtc_event_log_parser.h" +#include "modules/audio_coding/audio_network_adaptor/include/audio_network_adaptor_config.h" +#include "modules/remote_bitrate_estimator/include/bwe_defines.h" +#include "modules/rtp_rtcp/source/rtcp_packet/bye.h" // Arbitrary RTCP message. +#include "modules/rtp_rtcp/source/rtp_packet_received.h" +#include "modules/rtp_rtcp/source/rtp_packet_to_send.h" +#include "rtc_base/ptr_util.h" +#include "rtc_base/random.h" +#include "rtc_base/safe_conversions.h" +#include "test/gtest.h" + +namespace webrtc { + +namespace { +const char* const arbitrary_uri = // Just a recognized URI. + "urn:ietf:params:rtp-hdrext:sdes:rtp-stream-id"; +} // namespace + +class RtcEventLogEncoderTest : public testing::TestWithParam { + protected: + RtcEventLogEncoderTest() + : encoder_(new RtcEventLogEncoderLegacy), prng_(GetParam()) {} + ~RtcEventLogEncoderTest() override = default; + + // ANA events have some optional fields, so we want to make sure that we get + // correct behavior both when all of the values are there, as well as when + // only some. + void TestRtcEventAudioNetworkAdaptation( + std::unique_ptr runtime_config); + + // These help prevent code duplication between incoming/outgoing variants. + void TestRtcEventRtcpPacket(PacketDirection direction); + void TestRtcEventRtpPacket(PacketDirection direction); + + int RandomInt() { + // Don't run this on a SNES. + static_assert(8 * sizeof(int) >= 32, "Don't run this on a SNES."); + int32_t rand = prng_.Rand(0, std::numeric_limits::max()); + return rtc::saturated_cast(rand); + } + + int RandomPositiveInt() { + int32_t rand = prng_.Rand(1, std::numeric_limits::max()); + return rtc::saturated_cast(rand); + } + + uint32_t RandomSsrc() { + return prng_.Rand(std::numeric_limits::max()); + } + + int RandomRtpExtensionId() { + return static_cast( + prng_.Rand(RtpExtension::kMinId, RtpExtension::kMaxId)); + } + + int RandomBitrate() { return RandomInt(); } + + // TODO(eladalon): Once we have more than once possible encoder, parameterize + // encoder selection. + std::unique_ptr encoder_; + ParsedRtcEventLog parsed_log_; + Random prng_; +}; + +void RtcEventLogEncoderTest::TestRtcEventAudioNetworkAdaptation( + std::unique_ptr runtime_config) { + auto original_runtime_config = *runtime_config; + auto event = rtc::MakeUnique( + std::move(runtime_config)); + const int64_t timestamp_us = event->timestamp_us_; + + ASSERT_TRUE(parsed_log_.ParseString(encoder_->Encode(*event))); + ASSERT_EQ(parsed_log_.GetNumberOfEvents(), 1u); + ASSERT_EQ(parsed_log_.GetEventType(0), + ParsedRtcEventLog::AUDIO_NETWORK_ADAPTATION_EVENT); + + AudioEncoderRuntimeConfig parsed_runtime_config; + parsed_log_.GetAudioNetworkAdaptation(0, &parsed_runtime_config); + + EXPECT_EQ(parsed_log_.GetTimestamp(0), timestamp_us); + EXPECT_EQ(parsed_runtime_config, original_runtime_config); +} + +TEST_P(RtcEventLogEncoderTest, RtcEventAudioNetworkAdaptationBitrate) { + auto runtime_config = rtc::MakeUnique(); + const int bitrate_bps = RandomBitrate(); + runtime_config->bitrate_bps = rtc::Optional(bitrate_bps); + TestRtcEventAudioNetworkAdaptation(std::move(runtime_config)); +} + +TEST_P(RtcEventLogEncoderTest, RtcEventAudioNetworkAdaptationFrameLength) { + auto runtime_config = rtc::MakeUnique(); + const int frame_length_ms = prng_.Rand(1, 1000); + runtime_config->frame_length_ms = rtc::Optional(frame_length_ms); + TestRtcEventAudioNetworkAdaptation(std::move(runtime_config)); +} + +TEST_P(RtcEventLogEncoderTest, RtcEventAudioNetworkAdaptationPacketLoss) { + // To simplify the test, we just check powers of two. + const float plr = std::pow(0.5f, prng_.Rand(1, 8)); + auto runtime_config = rtc::MakeUnique(); + runtime_config->uplink_packet_loss_fraction = rtc::Optional(plr); + TestRtcEventAudioNetworkAdaptation(std::move(runtime_config)); +} + +TEST_P(RtcEventLogEncoderTest, RtcEventAudioNetworkAdaptationFec) { + // The test might be trivially passing for one of the two boolean values, so + // for safety's sake, we test both. + for (bool fec_enabled : {false, true}) { + auto runtime_config = rtc::MakeUnique(); + runtime_config->enable_fec = rtc::Optional(fec_enabled); + TestRtcEventAudioNetworkAdaptation(std::move(runtime_config)); + } +} + +TEST_P(RtcEventLogEncoderTest, RtcEventAudioNetworkAdaptationDtx) { + // The test might be trivially passing for one of the two boolean values, so + // for safety's sake, we test both. + for (bool dtx_enabled : {false, true}) { + auto runtime_config = rtc::MakeUnique(); + runtime_config->enable_dtx = rtc::Optional(dtx_enabled); + TestRtcEventAudioNetworkAdaptation(std::move(runtime_config)); + } +} + +TEST_P(RtcEventLogEncoderTest, RtcEventAudioNetworkAdaptationChannels) { + // The test might be trivially passing for one of the two possible values, so + // for safety's sake, we test both. + for (size_t channels : {1, 2}) { + auto runtime_config = rtc::MakeUnique(); + runtime_config->num_channels = rtc::Optional(channels); + TestRtcEventAudioNetworkAdaptation(std::move(runtime_config)); + } +} + +TEST_P(RtcEventLogEncoderTest, RtcEventAudioNetworkAdaptationAll) { + const int bitrate_bps = RandomBitrate(); + const int frame_length_ms = prng_.Rand(1, 1000); + const float plr = std::pow(0.5f, prng_.Rand(1, 8)); + for (bool fec_enabled : {false, true}) { + for (bool dtx_enabled : {false, true}) { + for (size_t channels : {1, 2}) { + auto runtime_config = rtc::MakeUnique(); + runtime_config->bitrate_bps = rtc::Optional(bitrate_bps); + runtime_config->frame_length_ms = rtc::Optional(frame_length_ms); + runtime_config->uplink_packet_loss_fraction = rtc::Optional(plr); + runtime_config->enable_fec = rtc::Optional(fec_enabled); + runtime_config->enable_dtx = rtc::Optional(dtx_enabled); + runtime_config->num_channels = rtc::Optional(channels); + + TestRtcEventAudioNetworkAdaptation(std::move(runtime_config)); + } + } + } +} + +TEST_P(RtcEventLogEncoderTest, RtcEventAudioPlayout) { + const uint32_t ssrc = RandomSsrc(); + auto event = rtc::MakeUnique(ssrc); + const int64_t timestamp_us = event->timestamp_us_; + + ASSERT_TRUE(parsed_log_.ParseString(encoder_->Encode(*event))); + ASSERT_EQ(parsed_log_.GetNumberOfEvents(), 1u); + ASSERT_EQ(parsed_log_.GetEventType(0), + ParsedRtcEventLog::AUDIO_PLAYOUT_EVENT); + + uint32_t parsed_ssrc; + parsed_log_.GetAudioPlayout(0, &parsed_ssrc); + + EXPECT_EQ(parsed_log_.GetTimestamp(0), timestamp_us); + EXPECT_EQ(parsed_ssrc, ssrc); +} + +TEST_P(RtcEventLogEncoderTest, RtcEventAudioReceiveStreamConfig) { + auto stream_config = rtc::MakeUnique(); + stream_config->local_ssrc = RandomSsrc(); + stream_config->remote_ssrc = RandomSsrc(); + // TODO(eladalon): !!! Validate this, here and elsewhere. + stream_config->rtp_extensions.push_back( + RtpExtension(arbitrary_uri, RandomRtpExtensionId())); + + auto original_stream_config = *stream_config; + + auto event = rtc::MakeUnique( + std::move(stream_config)); + const int64_t timestamp_us = event->timestamp_us_; + + ASSERT_TRUE(parsed_log_.ParseString(encoder_->Encode(*event))); + ASSERT_EQ(parsed_log_.GetNumberOfEvents(), 1u); + ASSERT_EQ(parsed_log_.GetEventType(0), + ParsedRtcEventLog::AUDIO_RECEIVER_CONFIG_EVENT); + + auto parsed_event = parsed_log_.GetAudioReceiveConfig(0); + EXPECT_EQ(parsed_log_.GetTimestamp(0), timestamp_us); + EXPECT_EQ(parsed_event, original_stream_config); +} + +TEST_P(RtcEventLogEncoderTest, RtcEventAudioSendStreamConfig) { + auto stream_config = rtc::MakeUnique(); + stream_config->local_ssrc = RandomSsrc(); + stream_config->rtp_extensions.push_back( + RtpExtension(arbitrary_uri, RandomRtpExtensionId())); + + auto original_stream_config = *stream_config; + + auto event = + rtc::MakeUnique(std::move(stream_config)); + const int64_t timestamp_us = event->timestamp_us_; + + ASSERT_TRUE(parsed_log_.ParseString(encoder_->Encode(*event))); + ASSERT_EQ(parsed_log_.GetNumberOfEvents(), 1u); + ASSERT_EQ(parsed_log_.GetEventType(0), + ParsedRtcEventLog::AUDIO_SENDER_CONFIG_EVENT); + + auto parsed_event = parsed_log_.GetAudioSendConfig(0); + EXPECT_EQ(parsed_log_.GetTimestamp(0), timestamp_us); + EXPECT_EQ(parsed_event, original_stream_config); +} + +TEST_P(RtcEventLogEncoderTest, RtcEventBweUpdateDelayBased) { + const int32_t bitrate_bps = RandomBitrate(); + const BandwidthUsage detector_state = static_cast( + prng_.Rand(0, static_cast(BandwidthUsage::kLast) - 1)); + auto event = + rtc::MakeUnique(bitrate_bps, detector_state); + const int64_t timestamp_us = event->timestamp_us_; + + ASSERT_TRUE(parsed_log_.ParseString(encoder_->Encode(*event))); + ASSERT_EQ(parsed_log_.GetNumberOfEvents(), 1u); + ASSERT_EQ(parsed_log_.GetEventType(0), + ParsedRtcEventLog::DELAY_BASED_BWE_UPDATE); + + auto parsed_event = parsed_log_.GetDelayBasedBweUpdate(0); + + EXPECT_EQ(parsed_log_.GetTimestamp(0), timestamp_us); + EXPECT_EQ(parsed_event.bitrate_bps, bitrate_bps); + EXPECT_EQ(parsed_event.detector_state, detector_state); +} + +TEST_P(RtcEventLogEncoderTest, RtcEventBweUpdateLossBased) { + const int32_t bitrate_bps = RandomBitrate(); + const uint8_t fraction_loss = rtc::dchecked_cast( + prng_.Rand(0, std::numeric_limits::max())); + const int32_t total_packets = RandomInt(); + + auto event = rtc::MakeUnique( + bitrate_bps, fraction_loss, total_packets); + const int64_t timestamp_us = event->timestamp_us_; + + ASSERT_TRUE(parsed_log_.ParseString(encoder_->Encode(*event))); + ASSERT_EQ(parsed_log_.GetNumberOfEvents(), 1u); + ASSERT_EQ(parsed_log_.GetEventType(0), + ParsedRtcEventLog::LOSS_BASED_BWE_UPDATE); + + int32_t parsed_bitrate_bps; + uint8_t parsed_fraction_loss; + int32_t parsed_total_packets; + parsed_log_.GetLossBasedBweUpdate( + 0, &parsed_bitrate_bps, &parsed_fraction_loss, &parsed_total_packets); + + EXPECT_EQ(parsed_log_.GetTimestamp(0), timestamp_us); + EXPECT_EQ(parsed_bitrate_bps, bitrate_bps); + EXPECT_EQ(parsed_fraction_loss, fraction_loss); + EXPECT_EQ(parsed_total_packets, total_packets); +} + +TEST_P(RtcEventLogEncoderTest, RtcEventLoggingStarted) { + auto event = rtc::MakeUnique(); + const int64_t timestamp_us = event->timestamp_us_; + + ASSERT_TRUE(parsed_log_.ParseString(encoder_->Encode(*event))); + ASSERT_EQ(parsed_log_.GetNumberOfEvents(), 1u); + ASSERT_EQ(parsed_log_.GetEventType(0), ParsedRtcEventLog::LOG_START); + + EXPECT_EQ(parsed_log_.GetTimestamp(0), timestamp_us); +} + +TEST_P(RtcEventLogEncoderTest, RtcEventLoggingStopped) { + auto event = rtc::MakeUnique(); + const int64_t timestamp_us = event->timestamp_us_; + + ASSERT_TRUE(parsed_log_.ParseString(encoder_->Encode(*event))); + ASSERT_EQ(parsed_log_.GetNumberOfEvents(), 1u); + ASSERT_EQ(parsed_log_.GetEventType(0), ParsedRtcEventLog::LOG_END); + + EXPECT_EQ(parsed_log_.GetTimestamp(0), timestamp_us); +} + +TEST_P(RtcEventLogEncoderTest, RtcEventProbeClusterCreated) { + const int id = RandomPositiveInt(); + const int bitrate_bps = RandomBitrate(); + const int min_probes = RandomPositiveInt(); + const int min_bytes = RandomPositiveInt(); + + auto event = rtc::MakeUnique( + id, bitrate_bps, min_probes, min_bytes); + const int64_t timestamp_us = event->timestamp_us_; + + ASSERT_TRUE(parsed_log_.ParseString(encoder_->Encode(*event))); + ASSERT_EQ(parsed_log_.GetNumberOfEvents(), 1u); + ASSERT_EQ(parsed_log_.GetEventType(0), + ParsedRtcEventLog::BWE_PROBE_CLUSTER_CREATED_EVENT); + + auto parsed_event = parsed_log_.GetBweProbeClusterCreated(0); + + EXPECT_EQ(parsed_log_.GetTimestamp(0), timestamp_us); + EXPECT_EQ(rtc::dchecked_cast(parsed_event.id), id); + EXPECT_EQ(rtc::dchecked_cast(parsed_event.bitrate_bps), bitrate_bps); + EXPECT_EQ(rtc::dchecked_cast(parsed_event.min_packets), min_probes); + EXPECT_EQ(rtc::dchecked_cast(parsed_event.min_bytes), min_bytes); +} + +TEST_P(RtcEventLogEncoderTest, RtcEventProbeResultFailure) { + const int id = RandomPositiveInt(); + const ProbeFailureReason failure_reason = static_cast( + prng_.Rand(0, static_cast(ProbeFailureReason::kLast) - 1)); + + auto event = rtc::MakeUnique(id, failure_reason); + const int64_t timestamp_us = event->timestamp_us_; + + ASSERT_TRUE(parsed_log_.ParseString(encoder_->Encode(*event))); + ASSERT_EQ(parsed_log_.GetNumberOfEvents(), 1u); + ASSERT_EQ(parsed_log_.GetEventType(0), + ParsedRtcEventLog::BWE_PROBE_RESULT_EVENT); + + auto parsed_event = parsed_log_.GetBweProbeResult(0); + + EXPECT_EQ(parsed_log_.GetTimestamp(0), timestamp_us); + EXPECT_EQ(rtc::dchecked_cast(parsed_event.id), id); + ASSERT_FALSE(parsed_event.bitrate_bps); + ASSERT_TRUE(parsed_event.failure_reason); + EXPECT_EQ(parsed_event.failure_reason, failure_reason); +} + +TEST_P(RtcEventLogEncoderTest, RtcEventProbeResultSuccess) { + const int id = RandomPositiveInt(); + const int bitrate_bps = RandomBitrate(); + + auto event = rtc::MakeUnique(id, bitrate_bps); + const int64_t timestamp_us = event->timestamp_us_; + + ASSERT_TRUE(parsed_log_.ParseString(encoder_->Encode(*event))); + ASSERT_EQ(parsed_log_.GetNumberOfEvents(), 1u); + ASSERT_EQ(parsed_log_.GetEventType(0), + ParsedRtcEventLog::BWE_PROBE_RESULT_EVENT); + + auto parsed_event = parsed_log_.GetBweProbeResult(0); + + EXPECT_EQ(parsed_log_.GetTimestamp(0), timestamp_us); + EXPECT_EQ(rtc::dchecked_cast(parsed_event.id), id); + ASSERT_TRUE(parsed_event.bitrate_bps); + EXPECT_EQ(parsed_event.bitrate_bps, bitrate_bps); + ASSERT_FALSE(parsed_event.failure_reason); +} + +void RtcEventLogEncoderTest::TestRtcEventRtcpPacket(PacketDirection direction) { + rtcp::Bye bye_packet; // Arbitrarily chosen RTCP packet type. + bye_packet.SetReason("a man's reach should exceed his grasp"); + auto rtcp_packet = bye_packet.Build(); + + std::unique_ptr event; + if (direction == PacketDirection::kIncomingPacket) { + event = rtc::MakeUnique(rtcp_packet); + } else { + event = rtc::MakeUnique(rtcp_packet); + } + const int64_t timestamp_us = event->timestamp_us_; + + ASSERT_TRUE(parsed_log_.ParseString(encoder_->Encode(*event))); + ASSERT_EQ(parsed_log_.GetNumberOfEvents(), 1u); + ASSERT_EQ(parsed_log_.GetEventType(0), ParsedRtcEventLog::RTCP_EVENT); + + PacketDirection parsed_direction; + uint8_t parsed_packet[IP_PACKET_SIZE]; // "Parsed" = after event-encoding. + size_t parsed_packet_length; + parsed_log_.GetRtcpPacket(0, &parsed_direction, parsed_packet, + &parsed_packet_length); + + EXPECT_EQ(parsed_direction, direction); + EXPECT_EQ(parsed_log_.GetTimestamp(0), timestamp_us); + ASSERT_EQ(parsed_packet_length, rtcp_packet.size()); + ASSERT_EQ(memcmp(parsed_packet, rtcp_packet.data(), parsed_packet_length), 0); +} + +TEST_P(RtcEventLogEncoderTest, RtcEventRtcpPacketIncoming) { + TestRtcEventRtcpPacket(PacketDirection::kIncomingPacket); +} + +TEST_P(RtcEventLogEncoderTest, RtcEventRtcpPacketOutgoing) { + TestRtcEventRtcpPacket(PacketDirection::kOutgoingPacket); +} + +void RtcEventLogEncoderTest::TestRtcEventRtpPacket(PacketDirection direction) { + const int probe_cluster_id = RandomPositiveInt(); + + std::unique_ptr packet_received; + std::unique_ptr packet_to_send; + RtpPacket* packet; + if (direction == PacketDirection::kIncomingPacket) { + packet_received = rtc::MakeUnique(); + packet = packet_received.get(); + } else { + packet_to_send = rtc::MakeUnique(nullptr); + packet = packet_to_send.get(); + } + packet->SetSsrc(RandomSsrc()); + packet->SetSequenceNumber(static_cast(RandomInt())); + packet->SetPayloadSize(prng_.Rand(0u, 1000u)); + + std::unique_ptr event; + if (direction == PacketDirection::kIncomingPacket) { + event = rtc::MakeUnique(*packet_received); + } else { + event = rtc::MakeUnique(*packet_to_send, + probe_cluster_id); + } + const int64_t timestamp_us = event->timestamp_us_; + + ASSERT_TRUE(parsed_log_.ParseString(encoder_->Encode(*event))); + ASSERT_EQ(parsed_log_.GetNumberOfEvents(), 1u); + ASSERT_EQ(parsed_log_.GetEventType(0), ParsedRtcEventLog::RTP_EVENT); + + PacketDirection parsed_direction; + uint8_t parsed_rtp_header[IP_PACKET_SIZE]; + size_t parsed_header_length; + size_t parsed_total_length; + int parsed_probe_cluster_id; + parsed_log_.GetRtpHeader(0, &parsed_direction, parsed_rtp_header, + &parsed_header_length, &parsed_total_length, + &parsed_probe_cluster_id); + + EXPECT_EQ(parsed_log_.GetTimestamp(0), timestamp_us); + EXPECT_EQ(parsed_direction, direction); + if (parsed_direction == PacketDirection::kOutgoingPacket) { + EXPECT_EQ(parsed_probe_cluster_id, probe_cluster_id); + } + EXPECT_EQ(memcmp(parsed_rtp_header, packet->data(), parsed_header_length), 0); + EXPECT_EQ(parsed_header_length, packet->headers_size()); + EXPECT_EQ(parsed_total_length, packet->size()); +} + +TEST_P(RtcEventLogEncoderTest, RtcEventRtpPacketIncoming) { + TestRtcEventRtpPacket(PacketDirection::kIncomingPacket); +} + +TEST_P(RtcEventLogEncoderTest, RtcEventRtpPacketOutgoing) { + TestRtcEventRtpPacket(PacketDirection::kOutgoingPacket); +} + +TEST_P(RtcEventLogEncoderTest, RtcEventVideoReceiveStreamConfig) { + auto stream_config = rtc::MakeUnique(); + stream_config->local_ssrc = RandomSsrc(); + stream_config->remote_ssrc = RandomSsrc(); + stream_config->rtcp_mode = RtcpMode::kCompound; + stream_config->remb = prng_.Rand(); + stream_config->rtp_extensions.push_back( + RtpExtension(arbitrary_uri, RandomRtpExtensionId())); + stream_config->codecs.emplace_back("CODEC", 122, 7); + + auto original_stream_config = *stream_config; + + auto event = rtc::MakeUnique( + std::move(stream_config)); + const int64_t timestamp_us = event->timestamp_us_; + + ASSERT_TRUE(parsed_log_.ParseString(encoder_->Encode(*event))); + ASSERT_EQ(parsed_log_.GetNumberOfEvents(), 1u); + ASSERT_EQ(parsed_log_.GetEventType(0), + ParsedRtcEventLog::VIDEO_RECEIVER_CONFIG_EVENT); + + auto parsed_event = parsed_log_.GetVideoReceiveConfig(0); + EXPECT_EQ(parsed_log_.GetTimestamp(0), timestamp_us); + EXPECT_EQ(parsed_event, original_stream_config); +} + +TEST_P(RtcEventLogEncoderTest, RtcEventVideoSendStreamConfig) { + auto stream_config = rtc::MakeUnique(); + stream_config->local_ssrc = RandomSsrc(); + stream_config->rtp_extensions.push_back( + RtpExtension(arbitrary_uri, RandomRtpExtensionId())); + stream_config->codecs.emplace_back("CODEC", 120, 3); + + auto original_stream_config = *stream_config; + + auto event = + rtc::MakeUnique(std::move(stream_config)); + const int64_t timestamp_us = event->timestamp_us_; + + ASSERT_TRUE(parsed_log_.ParseString(encoder_->Encode(*event))); + ASSERT_EQ(parsed_log_.GetNumberOfEvents(), 1u); + ASSERT_EQ(parsed_log_.GetEventType(0), + ParsedRtcEventLog::VIDEO_SENDER_CONFIG_EVENT); + + auto parsed_event = parsed_log_.GetVideoSendConfig(0)[0]; + EXPECT_EQ(parsed_log_.GetTimestamp(0), timestamp_us); + EXPECT_EQ(parsed_event, original_stream_config); +} + +INSTANTIATE_TEST_CASE_P(RandomSeeds, + RtcEventLogEncoderTest, + ::testing::Values(1, 2, 3, 4, 5)); + +} // namespace webrtc diff --git a/logging/rtc_event_log/events/rtc_event_probe_result_failure.h b/logging/rtc_event_log/events/rtc_event_probe_result_failure.h index 76d8643799..90ef4dec51 100644 --- a/logging/rtc_event_log/events/rtc_event_probe_result_failure.h +++ b/logging/rtc_event_log/events/rtc_event_probe_result_failure.h @@ -15,10 +15,11 @@ namespace webrtc { -enum ProbeFailureReason { - kInvalidSendReceiveInterval, +enum class ProbeFailureReason { + kInvalidSendReceiveInterval = 0, kInvalidSendReceiveRatio, - kTimeout + kTimeout, + kLast }; class RtcEventProbeResultFailure final : public RtcEvent { diff --git a/logging/rtc_event_log/rtc_event_log.cc b/logging/rtc_event_log/rtc_event_log.cc index 5cb398da9f..bc9f1439ae 100644 --- a/logging/rtc_event_log/rtc_event_log.cc +++ b/logging/rtc_event_log/rtc_event_log.cc @@ -219,6 +219,8 @@ rtclog::DelayBasedBweUpdate::DetectorState ConvertDetectorState( return rtclog::DelayBasedBweUpdate::BWE_UNDERUSING; case BandwidthUsage::kBwOverusing: return rtclog::DelayBasedBweUpdate::BWE_OVERUSING; + case BandwidthUsage::kLast: + RTC_NOTREACHED(); } RTC_NOTREACHED(); return rtclog::DelayBasedBweUpdate::BWE_NORMAL; @@ -227,12 +229,14 @@ rtclog::DelayBasedBweUpdate::DetectorState ConvertDetectorState( rtclog::BweProbeResult::ResultType ConvertProbeResultType( ProbeFailureReason failure_reason) { switch (failure_reason) { - case kInvalidSendReceiveInterval: + case ProbeFailureReason::kInvalidSendReceiveInterval: return rtclog::BweProbeResult::INVALID_SEND_RECEIVE_INTERVAL; - case kInvalidSendReceiveRatio: + case ProbeFailureReason::kInvalidSendReceiveRatio: return rtclog::BweProbeResult::INVALID_SEND_RECEIVE_RATIO; - case kTimeout: + case ProbeFailureReason::kTimeout: return rtclog::BweProbeResult::TIMEOUT; + case ProbeFailureReason::kLast: + RTC_NOTREACHED(); } RTC_NOTREACHED(); return rtclog::BweProbeResult::SUCCESS; diff --git a/logging/rtc_event_log/rtc_event_log2rtp_dump.cc b/logging/rtc_event_log/rtc_event_log2rtp_dump.cc index dc4c496ecd..c6fa12997b 100644 --- a/logging/rtc_event_log/rtc_event_log2rtp_dump.cc +++ b/logging/rtc_event_log/rtc_event_log2rtp_dump.cc @@ -132,7 +132,7 @@ int main(int argc, char* argv[]) { webrtc::test::RtpPacket packet; webrtc::PacketDirection direction; parsed_stream.GetRtpHeader(i, &direction, packet.data, &packet.length, - &packet.original_length); + &packet.original_length, nullptr); if (packet.original_length > packet.length) header_only = true; packet.time_ms = parsed_stream.GetTimestamp(i) / 1000; diff --git a/logging/rtc_event_log/rtc_event_log2text.cc b/logging/rtc_event_log/rtc_event_log2text.cc index 7eca099d32..af38964b36 100644 --- a/logging/rtc_event_log/rtc_event_log2text.cc +++ b/logging/rtc_event_log/rtc_event_log2text.cc @@ -431,7 +431,7 @@ int main(int argc, char* argv[]) { webrtc::PacketDirection direction; webrtc::RtpHeaderExtensionMap* extension_map = parsed_stream.GetRtpHeader(i, &direction, header, &header_length, - &total_length); + &total_length, nullptr); if (extension_map == nullptr) extension_map = &default_map; @@ -728,7 +728,8 @@ int main(int argc, char* argv[]) { if (probe_result.failure_reason) { std::cout << parsed_stream.GetTimestamp(i) << "\tPROBE_SUCCESS(" << probe_result.id << ")" - << "\tfailure_reason=" << *probe_result.failure_reason + << "\tfailure_reason=" + << static_cast(*probe_result.failure_reason) << std::endl; } else { std::cout << parsed_stream.GetTimestamp(i) << "\tPROBE_SUCCESS(" diff --git a/logging/rtc_event_log/rtc_event_log_parser.cc b/logging/rtc_event_log/rtc_event_log_parser.cc index cb4fd8095c..ca9ae393de 100644 --- a/logging/rtc_event_log/rtc_event_log_parser.cc +++ b/logging/rtc_event_log/rtc_event_log_parser.cc @@ -280,7 +280,8 @@ webrtc::RtpHeaderExtensionMap* ParsedRtcEventLog::GetRtpHeader( PacketDirection* incoming, uint8_t* header, size_t* header_length, - size_t* total_length) const { + size_t* total_length, + int* probe_cluster_id) const { RTC_CHECK_LT(index, GetNumberOfEvents()); const rtclog::Event& event = events_[index]; RTC_CHECK(event.has_type()); @@ -317,6 +318,14 @@ webrtc::RtpHeaderExtensionMap* ParsedRtcEventLog::GetRtpHeader( return it->second; } } + if (probe_cluster_id != nullptr) { + if (rtp_packet.has_probe_cluster_id()) { + *probe_cluster_id = rtp_packet.probe_cluster_id(); + RTC_CHECK_NE(*probe_cluster_id, PacedPacketInfo::kNotAProbe); + } else { + *probe_cluster_id = PacedPacketInfo::kNotAProbe; + } + } return nullptr; } @@ -627,14 +636,15 @@ ParsedRtcEventLog::BweProbeResultEvent ParsedRtcEventLog::GetBweProbeResult( res.bitrate_bps = rtc::Optional(pr_event.bitrate_bps()); } else if (pr_event.result() == rtclog::BweProbeResult::INVALID_SEND_RECEIVE_INTERVAL) { - res.failure_reason = - rtc::Optional(kInvalidSendReceiveInterval); + res.failure_reason = rtc::Optional( + ProbeFailureReason::kInvalidSendReceiveInterval); } else if (pr_event.result() == rtclog::BweProbeResult::INVALID_SEND_RECEIVE_RATIO) { - res.failure_reason = - rtc::Optional(kInvalidSendReceiveRatio); + res.failure_reason = rtc::Optional( + ProbeFailureReason::kInvalidSendReceiveRatio); } else if (pr_event.result() == rtclog::BweProbeResult::TIMEOUT) { - res.failure_reason = rtc::Optional(kTimeout); + res.failure_reason = + rtc::Optional(ProbeFailureReason::kTimeout); } else { RTC_NOTREACHED(); } diff --git a/logging/rtc_event_log/rtc_event_log_parser.h b/logging/rtc_event_log/rtc_event_log_parser.h index 9f87c99a26..49809594c1 100644 --- a/logging/rtc_event_log/rtc_event_log_parser.h +++ b/logging/rtc_event_log/rtc_event_log_parser.h @@ -112,7 +112,8 @@ class ParsedRtcEventLog { PacketDirection* incoming, uint8_t* header, size_t* header_length, - size_t* total_length) const; + size_t* total_length, + int* probe_cluster_id) const; // Reads packet, direction and packet length from the RTCP event at |index|, // and stores the values in the corresponding output parameters. diff --git a/logging/rtc_event_log/rtc_event_log_unittest.cc b/logging/rtc_event_log/rtc_event_log_unittest.cc index 99e3e7eeab..629afbccba 100644 --- a/logging/rtc_event_log/rtc_event_log_unittest.cc +++ b/logging/rtc_event_log/rtc_event_log_unittest.cc @@ -36,13 +36,6 @@ #include "test/gtest.h" #include "test/testsupport/fileutils.h" -// Files generated at build-time by the protobuf compiler. -#ifdef WEBRTC_ANDROID_PLATFORM_BUILD -#include "external/webrtc/webrtc/logging/rtc_event_log/rtc_event_log.pb.h" -#else -#include "logging/rtc_event_log/rtc_event_log.pb.h" -#endif - namespace webrtc { namespace { diff --git a/logging/rtc_event_log/rtc_event_log_unittest_helper.cc b/logging/rtc_event_log/rtc_event_log_unittest_helper.cc index ed9cab1590..ff744cb5b2 100644 --- a/logging/rtc_event_log/rtc_event_log_unittest_helper.cc +++ b/logging/rtc_event_log/rtc_event_log_unittest_helper.cc @@ -50,12 +50,14 @@ BandwidthUsage GetRuntimeDetectorState( rtclog::BweProbeResult::ResultType GetProbeResultType( ProbeFailureReason failure_reason) { switch (failure_reason) { - case kInvalidSendReceiveInterval: + case ProbeFailureReason::kInvalidSendReceiveInterval: return rtclog::BweProbeResult::INVALID_SEND_RECEIVE_INTERVAL; - case kInvalidSendReceiveRatio: + case ProbeFailureReason::kInvalidSendReceiveRatio: return rtclog::BweProbeResult::INVALID_SEND_RECEIVE_RATIO; - case kTimeout: + case ProbeFailureReason::kTimeout: return rtclog::BweProbeResult::TIMEOUT; + case ProbeFailureReason::kLast: + RTC_NOTREACHED(); } RTC_NOTREACHED(); return rtclog::BweProbeResult::SUCCESS; @@ -373,7 +375,7 @@ void RtcEventLogTestHelper::VerifyIncomingRtpEvent( uint8_t parsed_header[1500]; size_t parsed_header_size, parsed_total_size; parsed_log.GetRtpHeader(index, &parsed_direction, parsed_header, - &parsed_header_size, &parsed_total_size); + &parsed_header_size, &parsed_total_size, nullptr); EXPECT_EQ(kIncomingPacket, parsed_direction); EXPECT_THAT(testing::make_tuple(expected_packet.data(), header_size), testing::ElementsAreArray(parsed_header, parsed_header_size)); @@ -403,7 +405,7 @@ void RtcEventLogTestHelper::VerifyOutgoingRtpEvent( uint8_t parsed_header[1500]; size_t parsed_header_size, parsed_total_size; parsed_log.GetRtpHeader(index, &parsed_direction, parsed_header, - &parsed_header_size, &parsed_total_size); + &parsed_header_size, &parsed_total_size, nullptr); EXPECT_EQ(kOutgoingPacket, parsed_direction); EXPECT_THAT(testing::make_tuple(expected_packet.data(), header_size), testing::ElementsAreArray(parsed_header, parsed_header_size)); diff --git a/logging/rtc_event_log/rtc_stream_config.cc b/logging/rtc_event_log/rtc_stream_config.cc index d54f6e08e2..b43c6dd6f3 100644 --- a/logging/rtc_event_log/rtc_stream_config.cc +++ b/logging/rtc_event_log/rtc_stream_config.cc @@ -17,6 +17,13 @@ StreamConfig::StreamConfig() {} StreamConfig::~StreamConfig() {} +bool StreamConfig::operator==(const StreamConfig& other) const { + return local_ssrc == other.local_ssrc && remote_ssrc == other.remote_ssrc && + rtx_ssrc == other.rtx_ssrc && rsid == other.rsid && + remb == other.remb && rtcp_mode == other.rtcp_mode && + rtp_extensions == other.rtp_extensions && codecs == other.codecs; +} + StreamConfig::Codec::Codec(const std::string& payload_name, int payload_type, int rtx_payload_type) @@ -24,6 +31,11 @@ StreamConfig::Codec::Codec(const std::string& payload_name, payload_type(payload_type), rtx_payload_type(rtx_payload_type) {} +bool StreamConfig::Codec::operator==(const Codec& other) const { + return payload_name == other.payload_name && + payload_type == other.payload_type && + rtx_payload_type == other.rtx_payload_type; +} } // namespace rtclog } // namespace webrtc diff --git a/logging/rtc_event_log/rtc_stream_config.h b/logging/rtc_event_log/rtc_stream_config.h index bbba251367..e43ee7e0de 100644 --- a/logging/rtc_event_log/rtc_stream_config.h +++ b/logging/rtc_event_log/rtc_stream_config.h @@ -24,6 +24,8 @@ struct StreamConfig { StreamConfig(); ~StreamConfig(); + bool operator==(const StreamConfig& other) const; + uint32_t local_ssrc = 0; uint32_t remote_ssrc = 0; uint32_t rtx_ssrc = 0; @@ -39,6 +41,8 @@ struct StreamConfig { int payload_type, int rtx_payload_type); + bool operator==(const Codec& other) const; + std::string payload_name; int payload_type; int rtx_payload_type; diff --git a/modules/audio_coding/audio_network_adaptor/audio_network_adaptor_config.cc b/modules/audio_coding/audio_network_adaptor/audio_network_adaptor_config.cc index 55b326d548..16fd2a1b9a 100644 --- a/modules/audio_coding/audio_network_adaptor/audio_network_adaptor_config.cc +++ b/modules/audio_coding/audio_network_adaptor/audio_network_adaptor_config.cc @@ -14,12 +14,21 @@ namespace webrtc { AudioEncoderRuntimeConfig::AudioEncoderRuntimeConfig() = default; -AudioEncoderRuntimeConfig::~AudioEncoderRuntimeConfig() = default; - AudioEncoderRuntimeConfig::AudioEncoderRuntimeConfig( const AudioEncoderRuntimeConfig& other) = default; +AudioEncoderRuntimeConfig::~AudioEncoderRuntimeConfig() = default; + AudioEncoderRuntimeConfig& AudioEncoderRuntimeConfig::operator=( const AudioEncoderRuntimeConfig& other) = default; +bool AudioEncoderRuntimeConfig::operator==( + const AudioEncoderRuntimeConfig& other) const { + return bitrate_bps == other.bitrate_bps && + frame_length_ms == other.frame_length_ms && + uplink_packet_loss_fraction == other.uplink_packet_loss_fraction && + enable_fec == other.enable_fec && enable_dtx == other.enable_dtx && + num_channels == other.num_channels; +} + } // namespace webrtc diff --git a/modules/audio_coding/audio_network_adaptor/include/audio_network_adaptor_config.h b/modules/audio_coding/audio_network_adaptor/include/audio_network_adaptor_config.h index 5af3e09ec8..cab8bae2c7 100644 --- a/modules/audio_coding/audio_network_adaptor/include/audio_network_adaptor_config.h +++ b/modules/audio_coding/audio_network_adaptor/include/audio_network_adaptor_config.h @@ -18,8 +18,12 @@ namespace webrtc { struct AudioEncoderRuntimeConfig { AudioEncoderRuntimeConfig(); AudioEncoderRuntimeConfig(const AudioEncoderRuntimeConfig& other); - AudioEncoderRuntimeConfig& operator=(const AudioEncoderRuntimeConfig& other); ~AudioEncoderRuntimeConfig(); + + AudioEncoderRuntimeConfig& operator=(const AudioEncoderRuntimeConfig& other); + + bool operator==(const AudioEncoderRuntimeConfig& other) const; + rtc::Optional bitrate_bps; rtc::Optional frame_length_ms; // Note: This is what we tell the encoder. It doesn't have to reflect diff --git a/modules/audio_coding/neteq/tools/rtc_event_log_source.cc b/modules/audio_coding/neteq/tools/rtc_event_log_source.cc index 1603ee8f0d..e2c9ac9371 100644 --- a/modules/audio_coding/neteq/tools/rtc_event_log_source.cc +++ b/modules/audio_coding/neteq/tools/rtc_event_log_source.cc @@ -47,7 +47,7 @@ std::unique_ptr RtcEventLogSource::NextPacket() { size_t packet_length; uint64_t timestamp_us = parsed_stream_.GetTimestamp(rtp_packet_index_); parsed_stream_.GetRtpHeader(rtp_packet_index_, &direction, nullptr, - &header_length, &packet_length); + &header_length, &packet_length, nullptr); if (direction != kIncomingPacket) { continue; @@ -55,7 +55,7 @@ std::unique_ptr RtcEventLogSource::NextPacket() { uint8_t* packet_header = new uint8_t[header_length]; parsed_stream_.GetRtpHeader(rtp_packet_index_, nullptr, packet_header, - nullptr, nullptr); + nullptr, nullptr, nullptr); std::unique_ptr packet( new Packet(packet_header, header_length, packet_length, static_cast(timestamp_us) / 1000, *parser_.get())); diff --git a/modules/congestion_controller/probe_bitrate_estimator.cc b/modules/congestion_controller/probe_bitrate_estimator.cc index 75e0ff7c47..e83d1e08cd 100644 --- a/modules/congestion_controller/probe_bitrate_estimator.cc +++ b/modules/congestion_controller/probe_bitrate_estimator.cc @@ -103,8 +103,8 @@ int ProbeBitrateEstimator::HandleProbeAndEstimateBitrate( << "] [send interval: " << send_interval_ms << " ms]" << " [receive interval: " << receive_interval_ms << " ms]"; if (event_log_) { - event_log_->LogProbeResultFailure(cluster_id, - kInvalidSendReceiveInterval); + event_log_->LogProbeResultFailure( + cluster_id, ProbeFailureReason::kInvalidSendReceiveInterval); } return -1; } @@ -135,7 +135,8 @@ int ProbeBitrateEstimator::HandleProbeAndEstimateBitrate( << send_bps / 1000 << " = " << ratio << " > kMaxValidRatio (" << kMaxValidRatio << ")]"; if (event_log_) - event_log_->LogProbeResultFailure(cluster_id, kInvalidSendReceiveRatio); + event_log_->LogProbeResultFailure( + cluster_id, ProbeFailureReason::kInvalidSendReceiveRatio); return -1; } LOG(LS_INFO) << "Probing successful" diff --git a/modules/remote_bitrate_estimator/include/bwe_defines.h b/modules/remote_bitrate_estimator/include/bwe_defines.h index 5787fd035e..9b5b48b4fa 100644 --- a/modules/remote_bitrate_estimator/include/bwe_defines.h +++ b/modules/remote_bitrate_estimator/include/bwe_defines.h @@ -39,6 +39,7 @@ enum class BandwidthUsage { kBwNormal = 0, kBwUnderusing = 1, kBwOverusing = 2, + kLast }; enum RateControlState { kRcHold, kRcIncrease, kRcDecrease }; diff --git a/rtc_tools/event_log_visualizer/analyzer.cc b/rtc_tools/event_log_visualizer/analyzer.cc index bd8cb99c1b..9447483f46 100644 --- a/rtc_tools/event_log_visualizer/analyzer.cc +++ b/rtc_tools/event_log_visualizer/analyzer.cc @@ -373,7 +373,7 @@ EventLogAnalyzer::EventLogAnalyzer(const ParsedRtcEventLog& log) } case ParsedRtcEventLog::RTP_EVENT: { RtpHeaderExtensionMap* extension_map = parsed_log_.GetRtpHeader( - i, &direction, header, &header_length, &total_length); + i, &direction, header, &header_length, &total_length, nullptr); RtpUtility::RtpHeaderParser rtp_parser(header, header_length); RTPHeader parsed_header; if (extension_map != nullptr) { @@ -923,7 +923,8 @@ void EventLogAnalyzer::CreateTotalBitrateGraph( for (size_t i = 0; i < parsed_log_.GetNumberOfEvents(); i++) { ParsedRtcEventLog::EventType event_type = parsed_log_.GetEventType(i); if (event_type == ParsedRtcEventLog::RTP_EVENT) { - parsed_log_.GetRtpHeader(i, &direction, nullptr, nullptr, &total_length); + parsed_log_.GetRtpHeader(i, &direction, nullptr, nullptr, &total_length, + nullptr); if (direction == desired_direction) { uint64_t timestamp = parsed_log_.GetTimestamp(i); packets.push_back(TimestampSize(timestamp, total_length)); @@ -999,6 +1000,8 @@ void EventLogAnalyzer::CreateTotalBitrateGraph( case BandwidthUsage::kBwOverusing: last_series = &overusing_series; break; + case BandwidthUsage::kLast: + RTC_NOTREACHED(); } }