diff --git a/logging/BUILD.gn b/logging/BUILD.gn index ae38399024..66c87b9612 100644 --- a/logging/BUILD.gn +++ b/logging/BUILD.gn @@ -39,6 +39,7 @@ rtc_source_set("rtc_event_log_api") { deps = [ "../api:libjingle_logging_api", + "../rtc_base:ptr_util", "../rtc_base:rtc_base_approved", "../rtc_base:rtc_task_queue", ] @@ -66,6 +67,7 @@ rtc_source_set("rtc_event_pacing") { deps = [ ":rtc_event_log_api", "../:typedefs", + "../rtc_base:ptr_util", ] } @@ -85,6 +87,7 @@ rtc_source_set("rtc_event_audio") { ":rtc_event_log_api", ":rtc_stream_config", "../modules/audio_coding:audio_network_adaptor_config", + "../rtc_base:ptr_util", ] } @@ -105,6 +108,7 @@ rtc_source_set("rtc_event_bwe") { deps = [ ":rtc_event_log_api", "../modules/remote_bitrate_estimator:remote_bitrate_estimator", + "../rtc_base:ptr_util", ] } @@ -124,6 +128,7 @@ rtc_source_set("rtc_event_rtp_rtcp") { ":rtc_event_log_api", "../api:array_view", "../modules/rtp_rtcp:rtp_rtcp_format", + "../rtc_base:ptr_util", "../rtc_base:rtc_base_approved", ] } @@ -139,6 +144,7 @@ rtc_source_set("rtc_event_video") { deps = [ ":rtc_event_log_api", ":rtc_stream_config", + "../rtc_base:ptr_util", ] } @@ -314,6 +320,7 @@ if (rtc_enable_protobuf) { "rtc_event_log/rtc_event_log_unittest_helper.h", ] deps = [ + ":ice_log", ":rtc_event_audio", ":rtc_event_bwe", ":rtc_event_log_api", @@ -322,6 +329,7 @@ if (rtc_enable_protobuf) { ":rtc_event_log_impl_output", ":rtc_event_log_parser", ":rtc_event_log_proto", + ":rtc_event_pacing", ":rtc_event_rtp_rtcp", ":rtc_event_video", ":rtc_stream_config", diff --git a/logging/rtc_event_log/events/rtc_event.h b/logging/rtc_event_log/events/rtc_event.h index 25820ef8dc..21d6e48e0f 100644 --- a/logging/rtc_event_log/events/rtc_event.h +++ b/logging/rtc_event_log/events/rtc_event.h @@ -11,7 +11,7 @@ #ifndef LOGGING_RTC_EVENT_LOG_EVENTS_RTC_EVENT_H_ #define LOGGING_RTC_EVENT_LOG_EVENTS_RTC_EVENT_H_ -#include +#include #include "rtc_base/timeutils.h" @@ -57,7 +57,12 @@ class RtcEvent { virtual bool IsConfigEvent() const = 0; + virtual std::unique_ptr Copy() const = 0; + const int64_t timestamp_us_; + + protected: + explicit RtcEvent(int64_t timestamp_us) : timestamp_us_(timestamp_us) {} }; } // namespace webrtc diff --git a/logging/rtc_event_log/events/rtc_event_alr_state.cc b/logging/rtc_event_log/events/rtc_event_alr_state.cc index e329079c61..249cda9710 100644 --- a/logging/rtc_event_log/events/rtc_event_alr_state.cc +++ b/logging/rtc_event_log/events/rtc_event_alr_state.cc @@ -9,6 +9,7 @@ */ #include "logging/rtc_event_log/events/rtc_event_alr_state.h" +#include "rtc_base/ptr_util.h" namespace webrtc { @@ -24,4 +25,8 @@ bool RtcEventAlrState::IsConfigEvent() const { return false; } +std::unique_ptr RtcEventAlrState::Copy() const { + return rtc::MakeUnique(in_alr_); +} + } // namespace webrtc diff --git a/logging/rtc_event_log/events/rtc_event_alr_state.h b/logging/rtc_event_log/events/rtc_event_alr_state.h index d07f3f2019..2f041d02c6 100644 --- a/logging/rtc_event_log/events/rtc_event_alr_state.h +++ b/logging/rtc_event_log/events/rtc_event_alr_state.h @@ -11,9 +11,9 @@ #ifndef LOGGING_RTC_EVENT_LOG_EVENTS_RTC_EVENT_ALR_STATE_H_ #define LOGGING_RTC_EVENT_LOG_EVENTS_RTC_EVENT_ALR_STATE_H_ -#include "logging/rtc_event_log/events/rtc_event.h" +#include -#include "typedefs.h" // NOLINT(build/include) +#include "logging/rtc_event_log/events/rtc_event.h" namespace webrtc { @@ -26,6 +26,8 @@ class RtcEventAlrState final : public RtcEvent { bool IsConfigEvent() const override; + std::unique_ptr Copy() const override; + const bool in_alr_; }; diff --git a/logging/rtc_event_log/events/rtc_event_audio_network_adaptation.cc b/logging/rtc_event_log/events/rtc_event_audio_network_adaptation.cc index 5ab7da6796..ea41c879aa 100644 --- a/logging/rtc_event_log/events/rtc_event_audio_network_adaptation.cc +++ b/logging/rtc_event_log/events/rtc_event_audio_network_adaptation.cc @@ -13,6 +13,7 @@ #include #include "modules/audio_coding/audio_network_adaptor/include/audio_network_adaptor_config.h" +#include "rtc_base/ptr_util.h" namespace webrtc { @@ -30,4 +31,10 @@ bool RtcEventAudioNetworkAdaptation::IsConfigEvent() const { return false; } +std::unique_ptr RtcEventAudioNetworkAdaptation::Copy() const { + auto config_copy = rtc::MakeUnique(*config_); + return rtc::MakeUnique( + std::move(config_copy)); +} + } // namespace webrtc diff --git a/logging/rtc_event_log/events/rtc_event_audio_network_adaptation.h b/logging/rtc_event_log/events/rtc_event_audio_network_adaptation.h index 9b39d24bfa..0caacb4b3c 100644 --- a/logging/rtc_event_log/events/rtc_event_audio_network_adaptation.h +++ b/logging/rtc_event_log/events/rtc_event_audio_network_adaptation.h @@ -29,6 +29,8 @@ class RtcEventAudioNetworkAdaptation final : public RtcEvent { bool IsConfigEvent() const override; + std::unique_ptr Copy() const override; + const std::unique_ptr config_; }; diff --git a/logging/rtc_event_log/events/rtc_event_audio_playout.cc b/logging/rtc_event_log/events/rtc_event_audio_playout.cc index 8378993ace..fd02c1f446 100644 --- a/logging/rtc_event_log/events/rtc_event_audio_playout.cc +++ b/logging/rtc_event_log/events/rtc_event_audio_playout.cc @@ -10,6 +10,8 @@ #include "logging/rtc_event_log/events/rtc_event_audio_playout.h" +#include "rtc_base/ptr_util.h" + namespace webrtc { RtcEventAudioPlayout::RtcEventAudioPlayout(uint32_t ssrc) : ssrc_(ssrc) {} @@ -22,4 +24,8 @@ bool RtcEventAudioPlayout::IsConfigEvent() const { return false; } +std::unique_ptr RtcEventAudioPlayout::Copy() const { + return rtc::MakeUnique(ssrc_); +} + } // namespace webrtc diff --git a/logging/rtc_event_log/events/rtc_event_audio_playout.h b/logging/rtc_event_log/events/rtc_event_audio_playout.h index c74148109b..ab57a994de 100644 --- a/logging/rtc_event_log/events/rtc_event_audio_playout.h +++ b/logging/rtc_event_log/events/rtc_event_audio_playout.h @@ -11,6 +11,8 @@ #ifndef LOGGING_RTC_EVENT_LOG_EVENTS_RTC_EVENT_AUDIO_PLAYOUT_H_ #define LOGGING_RTC_EVENT_LOG_EVENTS_RTC_EVENT_AUDIO_PLAYOUT_H_ +#include + #include "logging/rtc_event_log/events/rtc_event.h" namespace webrtc { @@ -24,6 +26,8 @@ class RtcEventAudioPlayout final : public RtcEvent { bool IsConfigEvent() const override; + std::unique_ptr Copy() const override; + const uint32_t ssrc_; }; diff --git a/logging/rtc_event_log/events/rtc_event_audio_receive_stream_config.cc b/logging/rtc_event_log/events/rtc_event_audio_receive_stream_config.cc index 6bc9dc6b30..8aefb1f390 100644 --- a/logging/rtc_event_log/events/rtc_event_audio_receive_stream_config.cc +++ b/logging/rtc_event_log/events/rtc_event_audio_receive_stream_config.cc @@ -13,6 +13,7 @@ #include #include "logging/rtc_event_log/rtc_stream_config.h" +#include "rtc_base/ptr_util.h" namespace webrtc { @@ -30,4 +31,10 @@ bool RtcEventAudioReceiveStreamConfig::IsConfigEvent() const { return true; } +std::unique_ptr RtcEventAudioReceiveStreamConfig::Copy() const { + auto config_copy = rtc::MakeUnique(*config_); + return rtc::MakeUnique( + std::move(config_copy)); +} + } // namespace webrtc diff --git a/logging/rtc_event_log/events/rtc_event_audio_receive_stream_config.h b/logging/rtc_event_log/events/rtc_event_audio_receive_stream_config.h index ae79bbf44a..e5c7784cc4 100644 --- a/logging/rtc_event_log/events/rtc_event_audio_receive_stream_config.h +++ b/logging/rtc_event_log/events/rtc_event_audio_receive_stream_config.h @@ -31,6 +31,8 @@ class RtcEventAudioReceiveStreamConfig final : public RtcEvent { bool IsConfigEvent() const override; + std::unique_ptr Copy() const override; + const std::unique_ptr config_; }; diff --git a/logging/rtc_event_log/events/rtc_event_audio_send_stream_config.cc b/logging/rtc_event_log/events/rtc_event_audio_send_stream_config.cc index de88bcad5c..496c192fec 100644 --- a/logging/rtc_event_log/events/rtc_event_audio_send_stream_config.cc +++ b/logging/rtc_event_log/events/rtc_event_audio_send_stream_config.cc @@ -13,6 +13,7 @@ #include #include "logging/rtc_event_log/rtc_stream_config.h" +#include "rtc_base/ptr_util.h" namespace webrtc { @@ -30,4 +31,9 @@ bool RtcEventAudioSendStreamConfig::IsConfigEvent() const { return true; } +std::unique_ptr RtcEventAudioSendStreamConfig::Copy() const { + auto config_copy = rtc::MakeUnique(*config_); + return rtc::MakeUnique(std::move(config_copy)); +} + } // namespace webrtc diff --git a/logging/rtc_event_log/events/rtc_event_audio_send_stream_config.h b/logging/rtc_event_log/events/rtc_event_audio_send_stream_config.h index 44611f1e4b..13b35b34bc 100644 --- a/logging/rtc_event_log/events/rtc_event_audio_send_stream_config.h +++ b/logging/rtc_event_log/events/rtc_event_audio_send_stream_config.h @@ -31,6 +31,8 @@ class RtcEventAudioSendStreamConfig final : public RtcEvent { bool IsConfigEvent() const override; + std::unique_ptr Copy() const override; + const std::unique_ptr config_; }; diff --git a/logging/rtc_event_log/events/rtc_event_bwe_update_delay_based.cc b/logging/rtc_event_log/events/rtc_event_bwe_update_delay_based.cc index caf0f77c44..c814dcfe4b 100644 --- a/logging/rtc_event_log/events/rtc_event_bwe_update_delay_based.cc +++ b/logging/rtc_event_log/events/rtc_event_bwe_update_delay_based.cc @@ -11,6 +11,7 @@ #include "logging/rtc_event_log/events/rtc_event_bwe_update_delay_based.h" #include "modules/remote_bitrate_estimator/include/bwe_defines.h" +#include "rtc_base/ptr_util.h" namespace webrtc { @@ -29,4 +30,9 @@ bool RtcEventBweUpdateDelayBased::IsConfigEvent() const { return false; } +std::unique_ptr RtcEventBweUpdateDelayBased::Copy() const { + return rtc::MakeUnique(bitrate_bps_, + detector_state_); +} + } // namespace webrtc diff --git a/logging/rtc_event_log/events/rtc_event_bwe_update_delay_based.h b/logging/rtc_event_log/events/rtc_event_bwe_update_delay_based.h index b59b78cdcd..4d49a3f647 100644 --- a/logging/rtc_event_log/events/rtc_event_bwe_update_delay_based.h +++ b/logging/rtc_event_log/events/rtc_event_bwe_update_delay_based.h @@ -11,6 +11,8 @@ #ifndef LOGGING_RTC_EVENT_LOG_EVENTS_RTC_EVENT_BWE_UPDATE_DELAY_BASED_H_ #define LOGGING_RTC_EVENT_LOG_EVENTS_RTC_EVENT_BWE_UPDATE_DELAY_BASED_H_ +#include + #include "logging/rtc_event_log/events/rtc_event.h" namespace webrtc { @@ -27,6 +29,8 @@ class RtcEventBweUpdateDelayBased final : public RtcEvent { bool IsConfigEvent() const override; + std::unique_ptr Copy() const override; + const int32_t bitrate_bps_; const BandwidthUsage detector_state_; }; diff --git a/logging/rtc_event_log/events/rtc_event_bwe_update_loss_based.cc b/logging/rtc_event_log/events/rtc_event_bwe_update_loss_based.cc index 5d11200e73..54891c3ce8 100644 --- a/logging/rtc_event_log/events/rtc_event_bwe_update_loss_based.cc +++ b/logging/rtc_event_log/events/rtc_event_bwe_update_loss_based.cc @@ -10,6 +10,8 @@ #include "logging/rtc_event_log/events/rtc_event_bwe_update_loss_based.h" +#include "rtc_base/ptr_util.h" + namespace webrtc { RtcEventBweUpdateLossBased::RtcEventBweUpdateLossBased(int32_t bitrate_bps, @@ -29,4 +31,9 @@ bool RtcEventBweUpdateLossBased::IsConfigEvent() const { return false; } +std::unique_ptr RtcEventBweUpdateLossBased::Copy() const { + return rtc::MakeUnique( + bitrate_bps_, fraction_loss_, total_packets_); +} + } // namespace webrtc diff --git a/logging/rtc_event_log/events/rtc_event_bwe_update_loss_based.h b/logging/rtc_event_log/events/rtc_event_bwe_update_loss_based.h index 474b9de040..6b3200a0c7 100644 --- a/logging/rtc_event_log/events/rtc_event_bwe_update_loss_based.h +++ b/logging/rtc_event_log/events/rtc_event_bwe_update_loss_based.h @@ -11,6 +11,8 @@ #ifndef LOGGING_RTC_EVENT_LOG_EVENTS_RTC_EVENT_BWE_UPDATE_LOSS_BASED_H_ #define LOGGING_RTC_EVENT_LOG_EVENTS_RTC_EVENT_BWE_UPDATE_LOSS_BASED_H_ +#include + #include "logging/rtc_event_log/events/rtc_event.h" namespace webrtc { @@ -26,6 +28,8 @@ class RtcEventBweUpdateLossBased final : public RtcEvent { bool IsConfigEvent() const override; + std::unique_ptr Copy() const override; + const int32_t bitrate_bps_; const uint8_t fraction_loss_; const int32_t total_packets_; diff --git a/logging/rtc_event_log/events/rtc_event_ice_candidate_pair.cc b/logging/rtc_event_log/events/rtc_event_ice_candidate_pair.cc index b3d084e51c..2499b111e7 100644 --- a/logging/rtc_event_log/events/rtc_event_ice_candidate_pair.cc +++ b/logging/rtc_event_log/events/rtc_event_ice_candidate_pair.cc @@ -10,6 +10,8 @@ #include "logging/rtc_event_log/events/rtc_event_ice_candidate_pair.h" +#include "rtc_base/ptr_util.h" + namespace webrtc { RtcEventIceCandidatePair::RtcEventIceCandidatePair( @@ -27,4 +29,8 @@ bool RtcEventIceCandidatePair::IsConfigEvent() const { return false; } +std::unique_ptr RtcEventIceCandidatePair::Copy() const { + return rtc::MakeUnique(type_, candidate_pair_id_); +} + } // namespace webrtc diff --git a/logging/rtc_event_log/events/rtc_event_ice_candidate_pair.h b/logging/rtc_event_log/events/rtc_event_ice_candidate_pair.h index ac646ee265..d0bed5f17f 100644 --- a/logging/rtc_event_log/events/rtc_event_ice_candidate_pair.h +++ b/logging/rtc_event_log/events/rtc_event_ice_candidate_pair.h @@ -11,9 +11,9 @@ #ifndef LOGGING_RTC_EVENT_LOG_EVENTS_RTC_EVENT_ICE_CANDIDATE_PAIR_H_ #define LOGGING_RTC_EVENT_LOG_EVENTS_RTC_EVENT_ICE_CANDIDATE_PAIR_H_ -#include "logging/rtc_event_log/events/rtc_event.h" +#include -#include +#include "logging/rtc_event_log/events/rtc_event.h" namespace webrtc { @@ -36,6 +36,8 @@ class RtcEventIceCandidatePair final : public RtcEvent { bool IsConfigEvent() const override; + std::unique_ptr Copy() const override; + const IceCandidatePairEventType type_; const uint32_t candidate_pair_id_; }; diff --git a/logging/rtc_event_log/events/rtc_event_ice_candidate_pair_config.cc b/logging/rtc_event_log/events/rtc_event_ice_candidate_pair_config.cc index a825a3e44f..b3d55610ef 100644 --- a/logging/rtc_event_log/events/rtc_event_ice_candidate_pair_config.cc +++ b/logging/rtc_event_log/events/rtc_event_ice_candidate_pair_config.cc @@ -10,6 +10,8 @@ #include "logging/rtc_event_log/events/rtc_event_ice_candidate_pair_config.h" +#include "rtc_base/ptr_util.h" + namespace webrtc { IceCandidatePairDescription::IceCandidatePairDescription() { @@ -55,4 +57,9 @@ bool RtcEventIceCandidatePairConfig::IsConfigEvent() const { return false; } +std::unique_ptr RtcEventIceCandidatePairConfig::Copy() const { + return rtc::MakeUnique( + type_, candidate_pair_id_, candidate_pair_desc_); +} + } // namespace webrtc diff --git a/logging/rtc_event_log/events/rtc_event_ice_candidate_pair_config.h b/logging/rtc_event_log/events/rtc_event_ice_candidate_pair_config.h index 0a195dac74..4c161455a4 100644 --- a/logging/rtc_event_log/events/rtc_event_ice_candidate_pair_config.h +++ b/logging/rtc_event_log/events/rtc_event_ice_candidate_pair_config.h @@ -11,9 +11,9 @@ #ifndef LOGGING_RTC_EVENT_LOG_EVENTS_RTC_EVENT_ICE_CANDIDATE_PAIR_CONFIG_H_ #define LOGGING_RTC_EVENT_LOG_EVENTS_RTC_EVENT_ICE_CANDIDATE_PAIR_CONFIG_H_ -#include "logging/rtc_event_log/events/rtc_event.h" +#include -#include +#include "logging/rtc_event_log/events/rtc_event.h" namespace webrtc { @@ -92,6 +92,8 @@ class RtcEventIceCandidatePairConfig final : public RtcEvent { bool IsConfigEvent() const override; + std::unique_ptr Copy() const override; + const IceCandidatePairConfigType type_; const uint32_t candidate_pair_id_; const IceCandidatePairDescription candidate_pair_desc_; diff --git a/logging/rtc_event_log/events/rtc_event_probe_cluster_created.cc b/logging/rtc_event_log/events/rtc_event_probe_cluster_created.cc index a8ca59111a..a1ee9604e8 100644 --- a/logging/rtc_event_log/events/rtc_event_probe_cluster_created.cc +++ b/logging/rtc_event_log/events/rtc_event_probe_cluster_created.cc @@ -10,6 +10,8 @@ #include "logging/rtc_event_log/events/rtc_event_probe_cluster_created.h" +#include "rtc_base/ptr_util.h" + namespace webrtc { RtcEventProbeClusterCreated::RtcEventProbeClusterCreated(int32_t id, @@ -29,4 +31,9 @@ bool RtcEventProbeClusterCreated::IsConfigEvent() const { return false; } +std::unique_ptr RtcEventProbeClusterCreated::Copy() const { + return rtc::MakeUnique(id_, bitrate_bps_, + min_probes_, min_bytes_); +} + } // namespace webrtc diff --git a/logging/rtc_event_log/events/rtc_event_probe_cluster_created.h b/logging/rtc_event_log/events/rtc_event_probe_cluster_created.h index aa2e29f881..cbf80cbec5 100644 --- a/logging/rtc_event_log/events/rtc_event_probe_cluster_created.h +++ b/logging/rtc_event_log/events/rtc_event_probe_cluster_created.h @@ -11,6 +11,8 @@ #ifndef LOGGING_RTC_EVENT_LOG_EVENTS_RTC_EVENT_PROBE_CLUSTER_CREATED_H_ #define LOGGING_RTC_EVENT_LOG_EVENTS_RTC_EVENT_PROBE_CLUSTER_CREATED_H_ +#include + #include "logging/rtc_event_log/events/rtc_event.h" namespace webrtc { @@ -27,6 +29,8 @@ class RtcEventProbeClusterCreated final : public RtcEvent { bool IsConfigEvent() const override; + std::unique_ptr Copy() const override; + const int32_t id_; const int32_t bitrate_bps_; const uint32_t min_probes_; diff --git a/logging/rtc_event_log/events/rtc_event_probe_result_failure.cc b/logging/rtc_event_log/events/rtc_event_probe_result_failure.cc index 590d345146..c9b2233033 100644 --- a/logging/rtc_event_log/events/rtc_event_probe_result_failure.cc +++ b/logging/rtc_event_log/events/rtc_event_probe_result_failure.cc @@ -10,6 +10,8 @@ #include "logging/rtc_event_log/events/rtc_event_probe_result_failure.h" +#include "rtc_base/ptr_util.h" + namespace webrtc { RtcEventProbeResultFailure::RtcEventProbeResultFailure( @@ -25,4 +27,8 @@ bool RtcEventProbeResultFailure::IsConfigEvent() const { return false; } +std::unique_ptr RtcEventProbeResultFailure::Copy() const { + return rtc::MakeUnique(id_, failure_reason_); +} + } // 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 3cd52bc561..00b537adbd 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 @@ -11,6 +11,8 @@ #ifndef LOGGING_RTC_EVENT_LOG_EVENTS_RTC_EVENT_PROBE_RESULT_FAILURE_H_ #define LOGGING_RTC_EVENT_LOG_EVENTS_RTC_EVENT_PROBE_RESULT_FAILURE_H_ +#include + #include "logging/rtc_event_log/events/rtc_event.h" namespace webrtc { @@ -31,6 +33,8 @@ class RtcEventProbeResultFailure final : public RtcEvent { bool IsConfigEvent() const override; + std::unique_ptr Copy() const override; + const int32_t id_; const ProbeFailureReason failure_reason_; }; diff --git a/logging/rtc_event_log/events/rtc_event_probe_result_success.cc b/logging/rtc_event_log/events/rtc_event_probe_result_success.cc index 45cdf4dc4e..9257f9a3e4 100644 --- a/logging/rtc_event_log/events/rtc_event_probe_result_success.cc +++ b/logging/rtc_event_log/events/rtc_event_probe_result_success.cc @@ -10,6 +10,8 @@ #include "logging/rtc_event_log/events/rtc_event_probe_result_success.h" +#include "rtc_base/ptr_util.h" + namespace webrtc { RtcEventProbeResultSuccess::RtcEventProbeResultSuccess(int32_t id, @@ -24,4 +26,8 @@ bool RtcEventProbeResultSuccess::IsConfigEvent() const { return false; } +std::unique_ptr RtcEventProbeResultSuccess::Copy() const { + return rtc::MakeUnique(id_, bitrate_bps_); +} + } // namespace webrtc diff --git a/logging/rtc_event_log/events/rtc_event_probe_result_success.h b/logging/rtc_event_log/events/rtc_event_probe_result_success.h index 54da8a6e25..fa42fcb3d5 100644 --- a/logging/rtc_event_log/events/rtc_event_probe_result_success.h +++ b/logging/rtc_event_log/events/rtc_event_probe_result_success.h @@ -11,6 +11,8 @@ #ifndef LOGGING_RTC_EVENT_LOG_EVENTS_RTC_EVENT_PROBE_RESULT_SUCCESS_H_ #define LOGGING_RTC_EVENT_LOG_EVENTS_RTC_EVENT_PROBE_RESULT_SUCCESS_H_ +#include + #include "logging/rtc_event_log/events/rtc_event.h" namespace webrtc { @@ -24,6 +26,8 @@ class RtcEventProbeResultSuccess final : public RtcEvent { bool IsConfigEvent() const override; + std::unique_ptr Copy() const override; + const int32_t id_; const int32_t bitrate_bps_; }; diff --git a/logging/rtc_event_log/events/rtc_event_rtcp_packet_incoming.cc b/logging/rtc_event_log/events/rtc_event_rtcp_packet_incoming.cc index 1f0765e40c..d28916340c 100644 --- a/logging/rtc_event_log/events/rtc_event_rtcp_packet_incoming.cc +++ b/logging/rtc_event_log/events/rtc_event_rtcp_packet_incoming.cc @@ -10,6 +10,8 @@ #include "logging/rtc_event_log/events/rtc_event_rtcp_packet_incoming.h" +#include "rtc_base/ptr_util.h" + namespace webrtc { RtcEventRtcpPacketIncoming::RtcEventRtcpPacketIncoming( @@ -26,4 +28,9 @@ bool RtcEventRtcpPacketIncoming::IsConfigEvent() const { return false; } +std::unique_ptr RtcEventRtcpPacketIncoming::Copy() const { + return rtc::MakeUnique( + rtc::ArrayView(packet_.data(), packet_.size())); +} + } // namespace webrtc diff --git a/logging/rtc_event_log/events/rtc_event_rtcp_packet_incoming.h b/logging/rtc_event_log/events/rtc_event_rtcp_packet_incoming.h index f7af462c10..d8e4ed10ff 100644 --- a/logging/rtc_event_log/events/rtc_event_rtcp_packet_incoming.h +++ b/logging/rtc_event_log/events/rtc_event_rtcp_packet_incoming.h @@ -11,6 +11,8 @@ #ifndef LOGGING_RTC_EVENT_LOG_EVENTS_RTC_EVENT_RTCP_PACKET_INCOMING_H_ #define LOGGING_RTC_EVENT_LOG_EVENTS_RTC_EVENT_RTCP_PACKET_INCOMING_H_ +#include + #include "api/array_view.h" #include "logging/rtc_event_log/events/rtc_event.h" #include "rtc_base/buffer.h" @@ -26,6 +28,8 @@ class RtcEventRtcpPacketIncoming final : public RtcEvent { bool IsConfigEvent() const override; + std::unique_ptr Copy() const override; + rtc::Buffer packet_; }; diff --git a/logging/rtc_event_log/events/rtc_event_rtcp_packet_outgoing.cc b/logging/rtc_event_log/events/rtc_event_rtcp_packet_outgoing.cc index b2dfaf0867..6d74567144 100644 --- a/logging/rtc_event_log/events/rtc_event_rtcp_packet_outgoing.cc +++ b/logging/rtc_event_log/events/rtc_event_rtcp_packet_outgoing.cc @@ -10,6 +10,8 @@ #include "logging/rtc_event_log/events/rtc_event_rtcp_packet_outgoing.h" +#include "rtc_base/ptr_util.h" + namespace webrtc { RtcEventRtcpPacketOutgoing::RtcEventRtcpPacketOutgoing( @@ -26,4 +28,9 @@ bool RtcEventRtcpPacketOutgoing::IsConfigEvent() const { return false; } +std::unique_ptr RtcEventRtcpPacketOutgoing::Copy() const { + return rtc::MakeUnique( + rtc::ArrayView(packet_.data(), packet_.size())); +} + } // namespace webrtc diff --git a/logging/rtc_event_log/events/rtc_event_rtcp_packet_outgoing.h b/logging/rtc_event_log/events/rtc_event_rtcp_packet_outgoing.h index 2c38ae0878..ed6b9fb226 100644 --- a/logging/rtc_event_log/events/rtc_event_rtcp_packet_outgoing.h +++ b/logging/rtc_event_log/events/rtc_event_rtcp_packet_outgoing.h @@ -11,6 +11,8 @@ #ifndef LOGGING_RTC_EVENT_LOG_EVENTS_RTC_EVENT_RTCP_PACKET_OUTGOING_H_ #define LOGGING_RTC_EVENT_LOG_EVENTS_RTC_EVENT_RTCP_PACKET_OUTGOING_H_ +#include + #include "api/array_view.h" #include "logging/rtc_event_log/events/rtc_event.h" #include "rtc_base/buffer.h" @@ -26,6 +28,8 @@ class RtcEventRtcpPacketOutgoing final : public RtcEvent { bool IsConfigEvent() const override; + std::unique_ptr Copy() const override; + rtc::Buffer packet_; }; diff --git a/logging/rtc_event_log/events/rtc_event_rtp_packet_incoming.cc b/logging/rtc_event_log/events/rtc_event_rtp_packet_incoming.cc index e0dcec5e79..3c0be49147 100644 --- a/logging/rtc_event_log/events/rtc_event_rtp_packet_incoming.cc +++ b/logging/rtc_event_log/events/rtc_event_rtp_packet_incoming.cc @@ -11,6 +11,7 @@ #include "logging/rtc_event_log/events/rtc_event_rtp_packet_incoming.h" #include "modules/rtp_rtcp/source/rtp_packet_received.h" +#include "rtc_base/ptr_util.h" namespace webrtc { @@ -20,6 +21,12 @@ RtcEventRtpPacketIncoming::RtcEventRtpPacketIncoming( header_.CopyHeaderFrom(packet); } +RtcEventRtpPacketIncoming::RtcEventRtpPacketIncoming( + const RtcEventRtpPacketIncoming& other) + : RtcEvent(other.timestamp_us_), packet_length_(other.packet_length_) { + header_.CopyHeaderFrom(other.header_); +} + RtcEventRtpPacketIncoming::~RtcEventRtpPacketIncoming() = default; RtcEvent::Type RtcEventRtpPacketIncoming::GetType() const { @@ -30,4 +37,8 @@ bool RtcEventRtpPacketIncoming::IsConfigEvent() const { return false; } +std::unique_ptr RtcEventRtpPacketIncoming::Copy() const { + return rtc::MakeUnique(*this); +} + } // namespace webrtc diff --git a/logging/rtc_event_log/events/rtc_event_rtp_packet_incoming.h b/logging/rtc_event_log/events/rtc_event_rtp_packet_incoming.h index 4aaf86f289..513fcaf66a 100644 --- a/logging/rtc_event_log/events/rtc_event_rtp_packet_incoming.h +++ b/logging/rtc_event_log/events/rtc_event_rtp_packet_incoming.h @@ -11,6 +11,8 @@ #ifndef LOGGING_RTC_EVENT_LOG_EVENTS_RTC_EVENT_RTP_PACKET_INCOMING_H_ #define LOGGING_RTC_EVENT_LOG_EVENTS_RTC_EVENT_RTP_PACKET_INCOMING_H_ +#include + #include "logging/rtc_event_log/events/rtc_event.h" #include "modules/rtp_rtcp/source/rtp_packet.h" @@ -21,12 +23,15 @@ class RtpPacketReceived; class RtcEventRtpPacketIncoming final : public RtcEvent { public: explicit RtcEventRtpPacketIncoming(const RtpPacketReceived& packet); + RtcEventRtpPacketIncoming(const RtcEventRtpPacketIncoming& other); ~RtcEventRtpPacketIncoming() override; Type GetType() const override; bool IsConfigEvent() const override; + std::unique_ptr Copy() const override; + RtpPacket header_; // Only the packet's header will be stored here. const size_t packet_length_; // Length before stripping away all but header. }; diff --git a/logging/rtc_event_log/events/rtc_event_rtp_packet_outgoing.cc b/logging/rtc_event_log/events/rtc_event_rtp_packet_outgoing.cc index 207f76a511..18d386124d 100644 --- a/logging/rtc_event_log/events/rtc_event_rtp_packet_outgoing.cc +++ b/logging/rtc_event_log/events/rtc_event_rtp_packet_outgoing.cc @@ -11,6 +11,7 @@ #include "logging/rtc_event_log/events/rtc_event_rtp_packet_outgoing.h" #include "modules/rtp_rtcp/source/rtp_packet_to_send.h" +#include "rtc_base/ptr_util.h" namespace webrtc { @@ -21,6 +22,14 @@ RtcEventRtpPacketOutgoing::RtcEventRtpPacketOutgoing( header_.CopyHeaderFrom(packet); } +RtcEventRtpPacketOutgoing::RtcEventRtpPacketOutgoing( + const RtcEventRtpPacketOutgoing& other) + : RtcEvent(other.timestamp_us_), + packet_length_(other.packet_length_), + probe_cluster_id_(other.probe_cluster_id_) { + header_.CopyHeaderFrom(other.header_); +} + RtcEventRtpPacketOutgoing::~RtcEventRtpPacketOutgoing() = default; RtcEvent::Type RtcEventRtpPacketOutgoing::GetType() const { @@ -31,4 +40,8 @@ bool RtcEventRtpPacketOutgoing::IsConfigEvent() const { return false; } +std::unique_ptr RtcEventRtpPacketOutgoing::Copy() const { + return rtc::MakeUnique(*this); +} + } // namespace webrtc diff --git a/logging/rtc_event_log/events/rtc_event_rtp_packet_outgoing.h b/logging/rtc_event_log/events/rtc_event_rtp_packet_outgoing.h index 898cdce40e..f83ae20e4c 100644 --- a/logging/rtc_event_log/events/rtc_event_rtp_packet_outgoing.h +++ b/logging/rtc_event_log/events/rtc_event_rtp_packet_outgoing.h @@ -11,6 +11,8 @@ #ifndef LOGGING_RTC_EVENT_LOG_EVENTS_RTC_EVENT_RTP_PACKET_OUTGOING_H_ #define LOGGING_RTC_EVENT_LOG_EVENTS_RTC_EVENT_RTP_PACKET_OUTGOING_H_ +#include + #include "logging/rtc_event_log/events/rtc_event.h" #include "modules/rtp_rtcp/source/rtp_packet.h" @@ -22,12 +24,15 @@ class RtcEventRtpPacketOutgoing final : public RtcEvent { public: RtcEventRtpPacketOutgoing(const RtpPacketToSend& packet, int probe_cluster_id); + RtcEventRtpPacketOutgoing(const RtcEventRtpPacketOutgoing& other); ~RtcEventRtpPacketOutgoing() override; Type GetType() const override; bool IsConfigEvent() const override; + std::unique_ptr Copy() const override; + RtpPacket header_; // Only the packet's header will be stored here. const size_t packet_length_; // Length before stripping away all but header. const int probe_cluster_id_; diff --git a/logging/rtc_event_log/events/rtc_event_video_receive_stream_config.cc b/logging/rtc_event_log/events/rtc_event_video_receive_stream_config.cc index 514974b2ec..8d58542265 100644 --- a/logging/rtc_event_log/events/rtc_event_video_receive_stream_config.cc +++ b/logging/rtc_event_log/events/rtc_event_video_receive_stream_config.cc @@ -12,6 +12,8 @@ #include +#include "rtc_base/ptr_util.h" + namespace webrtc { RtcEventVideoReceiveStreamConfig::RtcEventVideoReceiveStreamConfig( @@ -28,4 +30,10 @@ bool RtcEventVideoReceiveStreamConfig::IsConfigEvent() const { return true; } +std::unique_ptr RtcEventVideoReceiveStreamConfig::Copy() const { + auto config_copy = rtc::MakeUnique(*config_); + return rtc::MakeUnique( + std::move(config_copy)); +} + } // namespace webrtc diff --git a/logging/rtc_event_log/events/rtc_event_video_receive_stream_config.h b/logging/rtc_event_log/events/rtc_event_video_receive_stream_config.h index 1d470e50ce..06188c2cc6 100644 --- a/logging/rtc_event_log/events/rtc_event_video_receive_stream_config.h +++ b/logging/rtc_event_log/events/rtc_event_video_receive_stream_config.h @@ -28,6 +28,8 @@ class RtcEventVideoReceiveStreamConfig final : public RtcEvent { bool IsConfigEvent() const override; + std::unique_ptr Copy() const override; + const std::unique_ptr config_; }; diff --git a/logging/rtc_event_log/events/rtc_event_video_send_stream_config.cc b/logging/rtc_event_log/events/rtc_event_video_send_stream_config.cc index 9bb2b5e38e..63300b3add 100644 --- a/logging/rtc_event_log/events/rtc_event_video_send_stream_config.cc +++ b/logging/rtc_event_log/events/rtc_event_video_send_stream_config.cc @@ -12,6 +12,8 @@ #include +#include "rtc_base/ptr_util.h" + namespace webrtc { RtcEventVideoSendStreamConfig::RtcEventVideoSendStreamConfig( @@ -28,4 +30,9 @@ bool RtcEventVideoSendStreamConfig::IsConfigEvent() const { return true; } +std::unique_ptr RtcEventVideoSendStreamConfig::Copy() const { + auto config_copy = rtc::MakeUnique(*config_); + return rtc::MakeUnique(std::move(config_copy)); +} + } // namespace webrtc diff --git a/logging/rtc_event_log/events/rtc_event_video_send_stream_config.h b/logging/rtc_event_log/events/rtc_event_video_send_stream_config.h index 97bdba9613..c36b506978 100644 --- a/logging/rtc_event_log/events/rtc_event_video_send_stream_config.h +++ b/logging/rtc_event_log/events/rtc_event_video_send_stream_config.h @@ -28,6 +28,8 @@ class RtcEventVideoSendStreamConfig final : public RtcEvent { bool IsConfigEvent() const override; + std::unique_ptr Copy() const override; + const std::unique_ptr config_; }; 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 6ce39c5573..70073d1038 100644 --- a/logging/rtc_event_log/rtc_event_log_parser_new.cc +++ b/logging/rtc_event_log/rtc_event_log_parser_new.cc @@ -532,6 +532,8 @@ void ParsedRtcEventLogNew::StoreParsedEvent(const rtclog::Event& event) { rtp_parser.Parse(&parsed_header, extension_map); } else { // Use the default extension map. + // TODO(terelius): This should be removed. GetRtpHeader will return the + // default map if the parser is configured for it. // TODO(ivoc): Once configuration of audio streams is stored in the // event log, this can be removed. // Tracking bug: webrtc:6399 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 98d7e4554b..a4a130228c 100644 --- a/logging/rtc_event_log/rtc_event_log_parser_new.h +++ b/logging/rtc_event_log/rtc_event_log_parser_new.h @@ -677,6 +677,23 @@ class ParsedRtcEventLogNew { return outgoing_audio_ssrcs_; } + // Stream configurations. + const std::vector& audio_recv_configs() const { + return audio_recv_configs_; + } + + const std::vector& audio_send_configs() const { + return audio_send_configs_; + } + + const std::vector& video_recv_configs() const { + return video_recv_configs_; + } + + const std::vector& video_send_configs() const { + return video_send_configs_; + } + // Beginning and end of log segments. const std::vector& start_log_events() const { return start_log_events_; diff --git a/logging/rtc_event_log/rtc_event_log_unittest.cc b/logging/rtc_event_log/rtc_event_log_unittest.cc index f40722da92..63c163821c 100644 --- a/logging/rtc_event_log/rtc_event_log_unittest.cc +++ b/logging/rtc_event_log/rtc_event_log_unittest.cc @@ -8,15 +8,14 @@ * be found in the AUTHORS file in the root of the source tree. */ +#include #include #include -#include #include #include #include #include -#include "call/call.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" @@ -37,15 +36,8 @@ #include "logging/rtc_event_log/rtc_event_log_parser_new.h" #include "logging/rtc_event_log/rtc_event_log_unittest_helper.h" #include "logging/rtc_event_log/rtc_stream_config.h" -#include "modules/audio_coding/audio_network_adaptor/include/audio_network_adaptor.h" -#include "modules/remote_bitrate_estimator/include/bwe_defines.h" #include "modules/rtp_rtcp/include/rtp_header_extension_map.h" -#include "modules/rtp_rtcp/source/rtcp_packet.h" -#include "modules/rtp_rtcp/source/rtcp_packet/sender_report.h" #include "modules/rtp_rtcp/source/rtp_header_extensions.h" -#include "modules/rtp_rtcp/source/rtp_packet_received.h" -#include "modules/rtp_rtcp/source/rtp_packet_to_send.h" -#include "rtc_base/buffer.h" #include "rtc_base/checks.h" #include "rtc_base/fakeclock.h" #include "rtc_base/ptr_util.h" @@ -57,665 +49,653 @@ namespace webrtc { namespace { -const uint8_t kTransmissionTimeOffsetExtensionId = 1; -const uint8_t kAbsoluteSendTimeExtensionId = 14; -const uint8_t kTransportSequenceNumberExtensionId = 13; -const uint8_t kAudioLevelExtensionId = 9; -const uint8_t kVideoRotationExtensionId = 5; +RtpHeaderExtensionMap ExtensionMapWithAllSupportedExtensions() { + RtpHeaderExtensionMap all_extensions; + all_extensions.Register(RtpExtension::kAudioLevelDefaultId); + all_extensions.Register( + RtpExtension::kTimestampOffsetDefaultId); + all_extensions.Register( + RtpExtension::kAbsSendTimeDefaultId); + all_extensions.Register( + RtpExtension::kVideoRotationDefaultId); + all_extensions.Register( + RtpExtension::kTransportSequenceNumberDefaultId); + return all_extensions; +} -const uint8_t kExtensionIds[] = { - kTransmissionTimeOffsetExtensionId, kAbsoluteSendTimeExtensionId, - kTransportSequenceNumberExtensionId, kAudioLevelExtensionId, - kVideoRotationExtensionId}; -const RTPExtensionType kExtensionTypes[] = { - RTPExtensionType::kRtpExtensionTransmissionTimeOffset, - RTPExtensionType::kRtpExtensionAbsoluteSendTime, - RTPExtensionType::kRtpExtensionTransportSequenceNumber, - RTPExtensionType::kRtpExtensionAudioLevel, - RTPExtensionType::kRtpExtensionVideoRotation}; -const char* kExtensionNames[] = { - RtpExtension::kTimestampOffsetUri, RtpExtension::kAbsSendTimeUri, - RtpExtension::kTransportSequenceNumberUri, RtpExtension::kAudioLevelUri, - RtpExtension::kVideoRotationUri}; +struct EventCounts { + size_t audio_send_streams = 0; + size_t audio_recv_streams = 0; + size_t video_send_streams = 0; + size_t video_recv_streams = 0; + size_t alr_states = 0; + size_t audio_playouts = 0; + size_t ana_configs = 0; + size_t bwe_loss_events = 0; + size_t bwe_delay_events = 0; + size_t probe_creations = 0; + size_t probe_successes = 0; + size_t probe_failures = 0; + size_t ice_configs = 0; + size_t ice_events = 0; + size_t incoming_rtp_packets = 0; + size_t outgoing_rtp_packets = 0; + size_t incoming_rtcp_packets = 0; + size_t outgoing_rtcp_packets = 0; -const size_t kNumExtensions = 5; + size_t total_nonconfig_events() const { + return alr_states + audio_playouts + ana_configs + bwe_loss_events + + bwe_delay_events + probe_creations + probe_successes + + probe_failures + ice_configs + ice_events + incoming_rtp_packets + + outgoing_rtp_packets + incoming_rtcp_packets + outgoing_rtcp_packets; + } -struct BweLossEvent { - int32_t bitrate_bps; - uint8_t fraction_loss; - int32_t total_packets; + size_t total_config_events() const { + return audio_send_streams + audio_recv_streams + video_send_streams + + video_recv_streams; + } + + size_t total_events() const { + return total_nonconfig_events() + total_config_events(); + } }; -// TODO(terelius): Merge with event type in parser once updated? -enum class EventType { - kIncomingRtp, - kOutgoingRtp, - kIncomingRtcp, - kOutgoingRtcp, - kAudioPlayout, - kBweLossUpdate, - kBweDelayUpdate, - kVideoRecvConfig, - kVideoSendConfig, - kAudioRecvConfig, - kAudioSendConfig, - kAudioNetworkAdaptation, - kBweProbeClusterCreated, - kBweProbeResult, -}; - -const std::map event_type_to_string( - {{EventType::kIncomingRtp, "RTP(in)"}, - {EventType::kOutgoingRtp, "RTP(out)"}, - {EventType::kIncomingRtcp, "RTCP(in)"}, - {EventType::kOutgoingRtcp, "RTCP(out)"}, - {EventType::kAudioPlayout, "PLAYOUT"}, - {EventType::kBweLossUpdate, "BWE_LOSS"}, - {EventType::kBweDelayUpdate, "BWE_DELAY"}, - {EventType::kVideoRecvConfig, "VIDEO_RECV_CONFIG"}, - {EventType::kVideoSendConfig, "VIDEO_SEND_CONFIG"}, - {EventType::kAudioRecvConfig, "AUDIO_RECV_CONFIG"}, - {EventType::kAudioSendConfig, "AUDIO_SEND_CONFIG"}, - {EventType::kAudioNetworkAdaptation, "AUDIO_NETWORK_ADAPTATION"}, - {EventType::kBweProbeClusterCreated, "BWE_PROBE_CREATED"}, - {EventType::kBweProbeResult, "BWE_PROBE_RESULT"}}); - -const std::map - parsed_event_type_to_string( - {{ParsedRtcEventLogNew::EventType::UNKNOWN_EVENT, "UNKNOWN_EVENT"}, - {ParsedRtcEventLogNew::EventType::LOG_START, "LOG_START"}, - {ParsedRtcEventLogNew::EventType::LOG_END, "LOG_END"}, - {ParsedRtcEventLogNew::EventType::RTP_EVENT, "RTP"}, - {ParsedRtcEventLogNew::EventType::RTCP_EVENT, "RTCP"}, - {ParsedRtcEventLogNew::EventType::AUDIO_PLAYOUT_EVENT, - "AUDIO_PLAYOUT"}, - {ParsedRtcEventLogNew::EventType::LOSS_BASED_BWE_UPDATE, - "LOSS_BASED_BWE_UPDATE"}, - {ParsedRtcEventLogNew::EventType::DELAY_BASED_BWE_UPDATE, - "DELAY_BASED_BWE_UPDATE"}, - {ParsedRtcEventLogNew::EventType::VIDEO_RECEIVER_CONFIG_EVENT, - "VIDEO_RECV_CONFIG"}, - {ParsedRtcEventLogNew::EventType::VIDEO_SENDER_CONFIG_EVENT, - "VIDEO_SEND_CONFIG"}, - {ParsedRtcEventLogNew::EventType::AUDIO_RECEIVER_CONFIG_EVENT, - "AUDIO_RECV_CONFIG"}, - {ParsedRtcEventLogNew::EventType::AUDIO_SENDER_CONFIG_EVENT, - "AUDIO_SEND_CONFIG"}, - {ParsedRtcEventLogNew::EventType::AUDIO_NETWORK_ADAPTATION_EVENT, - "AUDIO_NETWORK_ADAPTATION"}, - {ParsedRtcEventLogNew::EventType::BWE_PROBE_CLUSTER_CREATED_EVENT, - "BWE_PROBE_CREATED"}, - {ParsedRtcEventLogNew::EventType::BWE_PROBE_SUCCESS_EVENT, - "BWE_PROBE_SUCCESS"}, - {ParsedRtcEventLogNew::EventType::BWE_PROBE_FAILURE_EVENT, - "BWE_PROBE_FAILURE"}}); -} // namespace - -void PrintActualEvents(const ParsedRtcEventLogNew& parsed_log, - std::ostream& stream); - -RtpPacketToSend GenerateOutgoingRtpPacket( - const RtpHeaderExtensionMap* extensions, - uint32_t csrcs_count, - size_t packet_size, - Random* prng) { - RTC_CHECK_GE(packet_size, 16 + 4 * csrcs_count + 4 * kNumExtensions); - - std::vector csrcs; - for (unsigned i = 0; i < csrcs_count; i++) { - csrcs.push_back(prng->Rand()); - } - - RtpPacketToSend rtp_packet(extensions, packet_size); - rtp_packet.SetPayloadType(prng->Rand(127)); - rtp_packet.SetMarker(prng->Rand()); - rtp_packet.SetSequenceNumber(prng->Rand()); - rtp_packet.SetSsrc(prng->Rand()); - rtp_packet.SetTimestamp(prng->Rand()); - rtp_packet.SetCsrcs(csrcs); - - rtp_packet.SetExtension(prng->Rand(0x00ffffff)); - rtp_packet.SetExtension(prng->Rand(), prng->Rand(127)); - rtp_packet.SetExtension(prng->Rand(0x00ffffff)); - rtp_packet.SetExtension(prng->Rand(2)); - rtp_packet.SetExtension(prng->Rand()); - - size_t payload_size = packet_size - rtp_packet.headers_size(); - uint8_t* payload = rtp_packet.AllocatePayload(payload_size); - for (size_t i = 0; i < payload_size; i++) { - payload[i] = prng->Rand(); - } - return rtp_packet; -} - -RtpPacketReceived GenerateIncomingRtpPacket( - const RtpHeaderExtensionMap* extensions, - uint32_t csrcs_count, - size_t packet_size, - Random* prng) { - RtpPacketToSend packet_out = - GenerateOutgoingRtpPacket(extensions, csrcs_count, packet_size, prng); - RtpPacketReceived packet_in(extensions); - packet_in.Parse(packet_out.data(), packet_out.size()); - return packet_in; -} - -rtc::Buffer GenerateRtcpPacket(Random* prng) { - rtcp::ReportBlock report_block; - report_block.SetMediaSsrc(prng->Rand()); // Remote SSRC. - report_block.SetFractionLost(prng->Rand(50)); - - rtcp::SenderReport sender_report; - sender_report.SetSenderSsrc(prng->Rand()); - sender_report.SetNtp(NtpTime(prng->Rand(), prng->Rand())); - sender_report.SetPacketCount(prng->Rand()); - sender_report.AddReportBlock(report_block); - - return sender_report.Build(); -} - -void GenerateVideoReceiveConfig(const RtpHeaderExtensionMap& extensions, - rtclog::StreamConfig* config, - Random* prng) { - // Add SSRCs for the stream. - config->remote_ssrc = prng->Rand(); - config->local_ssrc = prng->Rand(); - // Add extensions and settings for RTCP. - config->rtcp_mode = - prng->Rand() ? RtcpMode::kCompound : RtcpMode::kReducedSize; - config->remb = prng->Rand(); - config->rtx_ssrc = prng->Rand(); - config->codecs.emplace_back(prng->Rand() ? "VP8" : "H264", - prng->Rand(1, 127), prng->Rand(1, 127)); - // Add header extensions. - for (unsigned i = 0; i < kNumExtensions; i++) { - uint8_t id = extensions.GetId(kExtensionTypes[i]); - if (id != RtpHeaderExtensionMap::kInvalidId) { - config->rtp_extensions.emplace_back(kExtensionNames[i], id); - } - } -} - -void GenerateVideoSendConfig(const RtpHeaderExtensionMap& extensions, - rtclog::StreamConfig* config, - Random* prng) { - config->codecs.emplace_back(prng->Rand() ? "VP8" : "H264", - prng->Rand(1, 127), prng->Rand(1, 127)); - config->local_ssrc = prng->Rand(); - config->rtx_ssrc = prng->Rand(); - // Add header extensions. - for (unsigned i = 0; i < kNumExtensions; i++) { - uint8_t id = extensions.GetId(kExtensionTypes[i]); - if (id != RtpHeaderExtensionMap::kInvalidId) { - config->rtp_extensions.emplace_back(kExtensionNames[i], id); - } - } -} - -void GenerateAudioReceiveConfig(const RtpHeaderExtensionMap& extensions, - rtclog::StreamConfig* config, - Random* prng) { - // Add SSRCs for the stream. - config->remote_ssrc = prng->Rand(); - config->local_ssrc = prng->Rand(); - // Add header extensions. - for (unsigned i = 0; i < kNumExtensions; i++) { - uint8_t id = extensions.GetId(kExtensionTypes[i]); - if (id != RtpHeaderExtensionMap::kInvalidId) { - config->rtp_extensions.emplace_back(kExtensionNames[i], id); - } - } -} - -void GenerateAudioSendConfig(const RtpHeaderExtensionMap& extensions, - rtclog::StreamConfig* config, - Random* prng) { - // Add SSRC to the stream. - config->local_ssrc = prng->Rand(); - // Add header extensions. - for (unsigned i = 0; i < kNumExtensions; i++) { - uint8_t id = extensions.GetId(kExtensionTypes[i]); - if (id != RtpHeaderExtensionMap::kInvalidId) { - config->rtp_extensions.emplace_back(kExtensionNames[i], id); - } - } -} - -BweLossEvent GenerateBweLossEvent(Random* prng) { - BweLossEvent loss_event; - loss_event.bitrate_bps = prng->Rand(6000, 10000000); - loss_event.fraction_loss = prng->Rand(); - loss_event.total_packets = prng->Rand(1, 1000); - return loss_event; -} - -void GenerateAudioNetworkAdaptation(const RtpHeaderExtensionMap& extensions, - AudioEncoderRuntimeConfig* config, - Random* prng) { - config->bitrate_bps = prng->Rand(0, 3000000); - config->enable_fec = prng->Rand(); - config->enable_dtx = prng->Rand(); - config->frame_length_ms = prng->Rand(10, 120); - config->num_channels = prng->Rand(1, 2); - config->uplink_packet_loss_fraction = prng->Rand(); -} - class RtcEventLogSession : public ::testing::TestWithParam> { public: RtcEventLogSession() - : prng(std::get<0>(GetParam())), - output_period_ms(std::get<1>(GetParam())) {} - void GenerateSessionDescription(size_t incoming_rtp_count, - size_t outgoing_rtp_count, - size_t incoming_rtcp_count, - size_t outgoing_rtcp_count, - size_t playout_count, - size_t bwe_loss_count, - size_t bwe_delay_count, - const RtpHeaderExtensionMap& extensions, - uint32_t csrcs_count); - void WriteSession(); - void ReadAndVerifySession(); - void PrintExpectedEvents(std::ostream& stream); + : seed_(std::get<0>(GetParam())), + prng_(seed_), + gen_(seed_ * 880001UL), + output_period_ms_(std::get<1>(GetParam())) { + clock_.SetTimeMicros(prng_.Rand()); + // Find the name of the current test, in order to use it as a temporary + // filename. + // TODO(terelius): Use a general utility function to generate a temp file. + auto test_info = ::testing::UnitTest::GetInstance()->current_test_info(); + std::string test_name = + std::string(test_info->test_case_name()) + "_" + test_info->name(); + std::replace(test_name.begin(), test_name.end(), '/', '_'); + temp_filename_ = test::OutputPath() + test_name; + } + + // Create and buffer the config events and |num_events_before_log_start| + // randomized non-config events. Then call StartLogging and finally create and + // write the remaining non-config events. + void WriteLog(EventCounts count, size_t num_events_before_log_start); + void ReadAndVerifyLog(); private: - std::vector incoming_rtp_packets; - std::vector outgoing_rtp_packets; - std::vector incoming_rtcp_packets; - std::vector outgoing_rtcp_packets; - std::vector playout_ssrcs; - std::vector bwe_loss_updates; - std::vector> bwe_delay_updates; - std::vector receiver_configs; - std::vector sender_configs; - std::vector event_types; - Random prng; - int64_t output_period_ms; + void WriteAudioRecvConfigs(size_t audio_recv_streams, RtcEventLog* event_log); + void WriteAudioSendConfigs(size_t audio_send_streams, RtcEventLog* event_log); + void WriteVideoRecvConfigs(size_t video_recv_streams, RtcEventLog* event_log); + void WriteVideoSendConfigs(size_t video_send_streams, RtcEventLog* event_log); + + std::vector> incoming_extensions_; + std::vector> outgoing_extensions_; + + // Config events. + std::vector> + audio_send_config_list_; + std::vector> + audio_recv_config_list_; + std::vector> + video_send_config_list_; + std::vector> + video_recv_config_list_; + + // Regular events. + std::vector> alr_state_list_; + std::map>> + audio_playout_map_; // Groups audio by SSRC. + std::vector> + ana_configs_list_; + std::vector> bwe_loss_list_; + std::vector> bwe_delay_list_; + std::vector> + probe_creation_list_; + std::vector> probe_success_list_; + std::vector> probe_failure_list_; + std::vector> ice_config_list_; + std::vector> ice_event_list_; + std::map>> + incoming_rtp_map_; // Groups incoming RTP by SSRC. + std::map>> + outgoing_rtp_map_; // Groups outgoing RTP by SSRC. + std::vector> incoming_rtcp_list_; + std::vector> outgoing_rtcp_list_; + + int64_t start_time_us_; + int64_t stop_time_us_; + + const uint64_t seed_; + Random prng_; + test::EventGenerator gen_; + int64_t output_period_ms_; + rtc::ScopedFakeClock clock_; + std::string temp_filename_; }; -void RtcEventLogSession::GenerateSessionDescription( - size_t incoming_rtp_count, - size_t outgoing_rtp_count, - size_t incoming_rtcp_count, - size_t outgoing_rtcp_count, - size_t playout_count, - size_t bwe_loss_count, - size_t bwe_delay_count, - const RtpHeaderExtensionMap& extensions, - uint32_t csrcs_count) { - // Create configuration for the video receive stream. - receiver_configs.push_back(rtclog::StreamConfig()); - GenerateVideoReceiveConfig(extensions, &receiver_configs.back(), &prng); - event_types.push_back(EventType::kVideoRecvConfig); +bool SsrcUsed( + uint32_t ssrc, + const std::vector>& streams) { + for (const auto& kv : streams) { + if (kv.first == ssrc) + return true; + } + return false; +} - // Create configuration for the video send stream. - sender_configs.push_back(rtclog::StreamConfig()); - GenerateVideoSendConfig(extensions, &sender_configs.back(), &prng); - event_types.push_back(EventType::kVideoSendConfig); - const size_t config_count = 2; - - // Create incoming and outgoing RTP packets containing random data. - for (size_t i = 0; i < incoming_rtp_count; i++) { - size_t packet_size = prng.Rand(1000, 1100); - incoming_rtp_packets.push_back(GenerateIncomingRtpPacket( - &extensions, csrcs_count, packet_size, &prng)); - event_types.push_back(EventType::kIncomingRtp); - } - for (size_t i = 0; i < outgoing_rtp_count; i++) { - size_t packet_size = prng.Rand(1000, 1100); - outgoing_rtp_packets.push_back(GenerateOutgoingRtpPacket( - &extensions, csrcs_count, packet_size, &prng)); - event_types.push_back(EventType::kOutgoingRtp); - } - // Create incoming and outgoing RTCP packets containing random data. - for (size_t i = 0; i < incoming_rtcp_count; i++) { - incoming_rtcp_packets.push_back(GenerateRtcpPacket(&prng)); - event_types.push_back(EventType::kIncomingRtcp); - } - for (size_t i = 0; i < outgoing_rtcp_count; i++) { - outgoing_rtcp_packets.push_back(GenerateRtcpPacket(&prng)); - event_types.push_back(EventType::kOutgoingRtcp); - } - // Create random SSRCs to use when logging AudioPlayout events. - for (size_t i = 0; i < playout_count; i++) { - playout_ssrcs.push_back(prng.Rand()); - event_types.push_back(EventType::kAudioPlayout); - } - // Create random bitrate updates for LossBasedBwe. - for (size_t i = 0; i < bwe_loss_count; i++) { - bwe_loss_updates.push_back(GenerateBweLossEvent(&prng)); - event_types.push_back(EventType::kBweLossUpdate); - } - // Create random bitrate updates for DelayBasedBwe. - for (size_t i = 0; i < bwe_delay_count; i++) { - bwe_delay_updates.push_back(std::make_pair( - prng.Rand(6000, 10000000), prng.Rand() - ? BandwidthUsage::kBwOverusing - : BandwidthUsage::kBwUnderusing)); - event_types.push_back(EventType::kBweDelayUpdate); - } - - // Order the events randomly. The configurations are stored in a separate - // buffer, so they might be written before any othe events. Hence, we can't - // mix the config events with other events. - for (size_t i = config_count; i < event_types.size(); i++) { - size_t other = prng.Rand(static_cast(i), - static_cast(event_types.size() - 1)); - RTC_CHECK(i <= other && other < event_types.size()); - std::swap(event_types[i], event_types[other]); +void RtcEventLogSession::WriteAudioRecvConfigs(size_t audio_recv_streams, + RtcEventLog* event_log) { + RTC_CHECK(event_log != nullptr); + uint32_t ssrc; + for (size_t i = 0; i < audio_recv_streams; i++) { + clock_.AdvanceTimeMicros(prng_.Rand(20) * 1000); + do { + ssrc = prng_.Rand(); + } while (SsrcUsed(ssrc, incoming_extensions_)); + RtpHeaderExtensionMap extensions = gen_.NewRtpHeaderExtensionMap(); + incoming_extensions_.emplace_back(ssrc, extensions); + auto event = gen_.NewAudioReceiveStreamConfig(ssrc, extensions); + event_log->Log(event->Copy()); + audio_recv_config_list_.push_back(std::move(event)); } } -void RtcEventLogSession::WriteSession() { - // Find the name of the current test, in order to use it as a temporary - // filename. - auto test_info = ::testing::UnitTest::GetInstance()->current_test_info(); - std::string test_name = test_info->name(); - std::replace(test_name.begin(), test_name.end(), '/', '_'); - const std::string temp_filename = - test::OutputPath() + "RtcEventLogTest_" + test_name; +void RtcEventLogSession::WriteAudioSendConfigs(size_t audio_send_streams, + RtcEventLog* event_log) { + RTC_CHECK(event_log != nullptr); + uint32_t ssrc; + for (size_t i = 0; i < audio_send_streams; i++) { + clock_.AdvanceTimeMicros(prng_.Rand(20) * 1000); + do { + ssrc = prng_.Rand(); + } while (SsrcUsed(ssrc, outgoing_extensions_)); + RtpHeaderExtensionMap extensions = gen_.NewRtpHeaderExtensionMap(); + outgoing_extensions_.emplace_back(ssrc, extensions); + auto event = gen_.NewAudioSendStreamConfig(ssrc, extensions); + event_log->Log(event->Copy()); + audio_send_config_list_.push_back(std::move(event)); + } +} - rtc::ScopedFakeClock fake_clock; - fake_clock.SetTimeMicros(prng.Rand()); +void RtcEventLogSession::WriteVideoRecvConfigs(size_t video_recv_streams, + RtcEventLog* event_log) { + RTC_CHECK(event_log != nullptr); + RTC_CHECK_GE(video_recv_streams, 1); - // When log_dumper goes out of scope, it causes the log file to be flushed - // to disk. - std::unique_ptr log_dumper( + // Force least one stream to use all header extensions, to ensure + // (statistically) that every extension is tested in packet creation. + RtpHeaderExtensionMap all_extensions = + ExtensionMapWithAllSupportedExtensions(); + + clock_.AdvanceTimeMicros(prng_.Rand(20) * 1000); + uint32_t ssrc = prng_.Rand(); + incoming_extensions_.emplace_back(prng_.Rand(), all_extensions); + auto event = gen_.NewVideoReceiveStreamConfig(ssrc, all_extensions); + event_log->Log(event->Copy()); + video_recv_config_list_.push_back(std::move(event)); + for (size_t i = 1; i < video_recv_streams; i++) { + clock_.AdvanceTimeMicros(prng_.Rand(20) * 1000); + do { + ssrc = prng_.Rand(); + } while (SsrcUsed(ssrc, incoming_extensions_)); + RtpHeaderExtensionMap extensions = gen_.NewRtpHeaderExtensionMap(); + incoming_extensions_.emplace_back(ssrc, extensions); + auto event = gen_.NewVideoReceiveStreamConfig(ssrc, extensions); + event_log->Log(event->Copy()); + video_recv_config_list_.push_back(std::move(event)); + } +} + +void RtcEventLogSession::WriteVideoSendConfigs(size_t video_send_streams, + RtcEventLog* event_log) { + RTC_CHECK(event_log != nullptr); + RTC_CHECK_GE(video_send_streams, 1); + + // Force least one stream to use all header extensions, to ensure + // (statistically) that every extension is tested in packet creation. + RtpHeaderExtensionMap all_extensions = + ExtensionMapWithAllSupportedExtensions(); + + clock_.AdvanceTimeMicros(prng_.Rand(20) * 1000); + uint32_t ssrc = prng_.Rand(); + outgoing_extensions_.emplace_back(prng_.Rand(), all_extensions); + auto event = gen_.NewVideoSendStreamConfig(ssrc, all_extensions); + event_log->Log(event->Copy()); + video_send_config_list_.push_back(std::move(event)); + for (size_t i = 1; i < video_send_streams; i++) { + clock_.AdvanceTimeMicros(prng_.Rand(20) * 1000); + do { + ssrc = prng_.Rand(); + } while (SsrcUsed(ssrc, outgoing_extensions_)); + RtpHeaderExtensionMap extensions = gen_.NewRtpHeaderExtensionMap(); + outgoing_extensions_.emplace_back(ssrc, extensions); + auto event = gen_.NewVideoSendStreamConfig(ssrc, extensions); + event_log->Log(event->Copy()); + video_send_config_list_.push_back(std::move(event)); + } +} + +void RtcEventLogSession::WriteLog(EventCounts count, + size_t num_events_before_start) { + // TODO(terelius): Allow test to run with either a real or a fake clock_. + // 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)); - size_t incoming_rtp_written = 0; - size_t outgoing_rtp_written = 0; - size_t incoming_rtcp_written = 0; - size_t outgoing_rtcp_written = 0; - size_t playouts_written = 0; - size_t bwe_loss_written = 0; - size_t bwe_delay_written = 0; - size_t recv_configs_written = 0; - size_t send_configs_written = 0; + // We can't send or receive packets without configured streams. + RTC_CHECK_GE(count.video_recv_streams, 1); + RTC_CHECK_GE(count.video_send_streams, 1); - for (size_t i = 0; i < event_types.size(); i++) { - fake_clock.AdvanceTimeMicros(prng.Rand(1, 1000)); - if (i == event_types.size() / 2) - log_dumper->StartLogging( - rtc::MakeUnique(temp_filename, 10000000), - output_period_ms); - switch (event_types[i]) { - case EventType::kIncomingRtp: - RTC_CHECK(incoming_rtp_written < incoming_rtp_packets.size()); - log_dumper->Log(rtc::MakeUnique( - incoming_rtp_packets[incoming_rtp_written++])); - break; - case EventType::kOutgoingRtp: { - RTC_CHECK(outgoing_rtp_written < outgoing_rtp_packets.size()); - constexpr int kNotAProbe = PacedPacketInfo::kNotAProbe; // Compiler... - log_dumper->Log(rtc::MakeUnique( - outgoing_rtp_packets[outgoing_rtp_written++], kNotAProbe)); - break; - } - case EventType::kIncomingRtcp: - RTC_CHECK(incoming_rtcp_written < incoming_rtcp_packets.size()); - log_dumper->Log(rtc::MakeUnique( - incoming_rtcp_packets[incoming_rtcp_written++])); - break; - case EventType::kOutgoingRtcp: - RTC_CHECK(outgoing_rtcp_written < outgoing_rtcp_packets.size()); - log_dumper->Log(rtc::MakeUnique( - outgoing_rtcp_packets[outgoing_rtcp_written++])); - break; - case EventType::kAudioPlayout: - RTC_CHECK(playouts_written < playout_ssrcs.size()); - log_dumper->Log(rtc::MakeUnique( - playout_ssrcs[playouts_written++])); - break; - case EventType::kBweLossUpdate: - RTC_CHECK(bwe_loss_written < bwe_loss_updates.size()); - log_dumper->Log(rtc::MakeUnique( - bwe_loss_updates[bwe_loss_written].bitrate_bps, - bwe_loss_updates[bwe_loss_written].fraction_loss, - bwe_loss_updates[bwe_loss_written].total_packets)); - bwe_loss_written++; - break; - case EventType::kBweDelayUpdate: - RTC_CHECK(bwe_delay_written < bwe_delay_updates.size()); - log_dumper->Log(rtc::MakeUnique( - bwe_delay_updates[bwe_delay_written].first, - bwe_delay_updates[bwe_delay_written].second)); - bwe_delay_written++; - break; - case EventType::kVideoRecvConfig: - RTC_CHECK(recv_configs_written < receiver_configs.size()); - log_dumper->Log(rtc::MakeUnique( - rtc::MakeUnique( - receiver_configs[recv_configs_written++]))); - break; - case EventType::kVideoSendConfig: - RTC_CHECK(send_configs_written < sender_configs.size()); - log_dumper->Log(rtc::MakeUnique( - rtc::MakeUnique( - sender_configs[send_configs_written++]))); - break; - case EventType::kAudioRecvConfig: - // Not implemented - RTC_NOTREACHED(); - break; - case EventType::kAudioSendConfig: - // Not implemented - RTC_NOTREACHED(); - break; - case EventType::kAudioNetworkAdaptation: - // Not implemented - RTC_NOTREACHED(); - break; - case EventType::kBweProbeClusterCreated: - // Not implemented - RTC_NOTREACHED(); - break; - case EventType::kBweProbeResult: - // Not implemented - RTC_NOTREACHED(); - break; + WriteAudioRecvConfigs(count.audio_recv_streams, event_log.get()); + WriteAudioSendConfigs(count.audio_send_streams, event_log.get()); + WriteVideoRecvConfigs(count.video_recv_streams, event_log.get()); + WriteVideoSendConfigs(count.video_send_streams, event_log.get()); + + size_t remaining_events = count.total_nonconfig_events(); + ASSERT_LE(num_events_before_start, remaining_events); + size_t remaining_events_at_start = remaining_events - num_events_before_start; + for (; remaining_events > 0; remaining_events--) { + if (remaining_events == remaining_events_at_start) { + clock_.AdvanceTimeMicros(prng_.Rand(20) * 1000); + event_log->StartLogging( + rtc::MakeUnique(temp_filename_, 10000000), + output_period_ms_); + start_time_us_ = rtc::TimeMicros(); } + + clock_.AdvanceTimeMicros(prng_.Rand(20) * 1000); + size_t selection = prng_.Rand(remaining_events - 1); + + if (selection < count.alr_states) { + auto event = gen_.NewAlrState(); + event_log->Log(event->Copy()); + alr_state_list_.push_back(std::move(event)); + count.alr_states--; + continue; + } + selection -= count.alr_states; + + if (selection < count.audio_playouts) { + size_t stream = prng_.Rand(incoming_extensions_.size() - 1); + // This might be a video SSRC, but the parser does not use the config. + uint32_t ssrc = incoming_extensions_[stream].first; + auto event = gen_.NewAudioPlayout(ssrc); + event_log->Log(event->Copy()); + audio_playout_map_[ssrc].push_back(std::move(event)); + count.audio_playouts--; + continue; + } + selection -= count.audio_playouts; + + if (selection < count.ana_configs) { + auto event = gen_.NewAudioNetworkAdaptation(); + event_log->Log(event->Copy()); + ana_configs_list_.push_back(std::move(event)); + count.ana_configs--; + continue; + } + selection -= count.ana_configs; + + if (selection < count.bwe_loss_events) { + auto event = gen_.NewBweUpdateLossBased(); + event_log->Log(event->Copy()); + bwe_loss_list_.push_back(std::move(event)); + count.bwe_loss_events--; + continue; + } + selection -= count.bwe_loss_events; + + if (selection < count.bwe_delay_events) { + auto event = gen_.NewBweUpdateDelayBased(); + event_log->Log(event->Copy()); + bwe_delay_list_.push_back(std::move(event)); + count.bwe_delay_events--; + continue; + } + selection -= count.bwe_delay_events; + + if (selection < count.probe_creations) { + auto event = gen_.NewProbeClusterCreated(); + event_log->Log(event->Copy()); + probe_creation_list_.push_back(std::move(event)); + count.probe_creations--; + continue; + } + selection -= count.probe_creations; + + if (selection < count.probe_successes) { + auto event = gen_.NewProbeResultSuccess(); + event_log->Log(event->Copy()); + probe_success_list_.push_back(std::move(event)); + count.probe_successes--; + continue; + } + selection -= count.probe_successes; + + if (selection < count.probe_failures) { + auto event = gen_.NewProbeResultFailure(); + event_log->Log(event->Copy()); + probe_failure_list_.push_back(std::move(event)); + count.probe_failures--; + continue; + } + selection -= count.probe_failures; + + if (selection < count.ice_configs) { + auto event = gen_.NewIceCandidatePairConfig(); + event_log->Log(event->Copy()); + ice_config_list_.push_back(std::move(event)); + count.ice_configs--; + continue; + } + selection -= count.ice_configs; + + if (selection < count.ice_events) { + auto event = gen_.NewIceCandidatePair(); + event_log->Log(event->Copy()); + ice_event_list_.push_back(std::move(event)); + count.ice_events--; + continue; + } + selection -= count.ice_events; + + if (selection < count.incoming_rtp_packets) { + size_t stream = prng_.Rand(incoming_extensions_.size() - 1); + uint32_t ssrc = incoming_extensions_[stream].first; + auto event = + gen_.NewRtpPacketIncoming(ssrc, incoming_extensions_[stream].second); + event_log->Log(event->Copy()); + incoming_rtp_map_[ssrc].push_back(std::move(event)); + count.incoming_rtp_packets--; + continue; + } + selection -= count.incoming_rtp_packets; + + if (selection < count.outgoing_rtp_packets) { + size_t stream = prng_.Rand(outgoing_extensions_.size() - 1); + uint32_t ssrc = outgoing_extensions_[stream].first; + auto event = + gen_.NewRtpPacketOutgoing(ssrc, outgoing_extensions_[stream].second); + event_log->Log(event->Copy()); + outgoing_rtp_map_[ssrc].push_back(std::move(event)); + count.outgoing_rtp_packets--; + continue; + } + selection -= count.outgoing_rtp_packets; + + if (selection < count.incoming_rtcp_packets) { + auto event = gen_.NewRtcpPacketIncoming(); + event_log->Log(event->Copy()); + incoming_rtcp_list_.push_back(std::move(event)); + count.incoming_rtcp_packets--; + continue; + } + selection -= count.incoming_rtcp_packets; + + if (selection < count.outgoing_rtcp_packets) { + auto event = gen_.NewRtcpPacketOutgoing(); + event_log->Log(event->Copy()); + outgoing_rtcp_list_.push_back(std::move(event)); + count.outgoing_rtcp_packets--; + continue; + } + selection -= count.outgoing_rtcp_packets; + + RTC_NOTREACHED(); } - log_dumper->StopLogging(); + event_log->StopLogging(); + stop_time_us_ = rtc::TimeMicros(); + + ASSERT_EQ(count.total_nonconfig_events(), static_cast(0)); } // Read the file and verify that what we read back from the event log is the // same as what we wrote down. -void RtcEventLogSession::ReadAndVerifySession() { - // Find the name of the current test, in order to use it as a temporary - // filename. - auto test_info = ::testing::UnitTest::GetInstance()->current_test_info(); - std::string test_name = test_info->name(); - std::replace(test_name.begin(), test_name.end(), '/', '_'); - const std::string temp_filename = - test::OutputPath() + "RtcEventLogTest_" + test_name; - +void RtcEventLogSession::ReadAndVerifyLog() { // Read the generated file from disk. ParsedRtcEventLogNew parsed_log; - ASSERT_TRUE(parsed_log.ParseFile(temp_filename)); - EXPECT_GE(5000u, event_types.size() + 2); // The events must fit. - EXPECT_EQ(event_types.size() + 2, parsed_log.GetNumberOfEvents()); + ASSERT_TRUE(parsed_log.ParseFile(temp_filename_)); - size_t incoming_rtp_read = 0; - size_t outgoing_rtp_read = 0; - size_t incoming_rtcp_read = 0; - size_t outgoing_rtcp_read = 0; - size_t playouts_read = 0; - size_t bwe_loss_read = 0; - size_t bwe_delay_read = 0; - size_t recv_configs_read = 0; - size_t send_configs_read = 0; + // Start and stop events. + auto& parsed_start_log_events = parsed_log.start_log_events(); + ASSERT_EQ(parsed_start_log_events.size(), static_cast(1)); + EXPECT_TRUE( + test::VerifyLoggedStartEvent(start_time_us_, parsed_start_log_events[0])); - RtcEventLogTestHelper::VerifyLogStartEvent(parsed_log, 0); + auto& parsed_stop_log_events = parsed_log.stop_log_events(); + ASSERT_EQ(parsed_stop_log_events.size(), static_cast(1)); + EXPECT_TRUE( + test::VerifyLoggedStopEvent(stop_time_us_, parsed_stop_log_events[0])); - for (size_t i = 0; i < event_types.size(); i++) { - switch (event_types[i]) { - case EventType::kIncomingRtp: - RTC_CHECK(incoming_rtp_read < incoming_rtp_packets.size()); - RtcEventLogTestHelper::VerifyIncomingRtpEvent( - parsed_log, i + 1, incoming_rtp_packets[incoming_rtp_read++]); - break; - case EventType::kOutgoingRtp: - RTC_CHECK(outgoing_rtp_read < outgoing_rtp_packets.size()); - RtcEventLogTestHelper::VerifyOutgoingRtpEvent( - parsed_log, i + 1, outgoing_rtp_packets[outgoing_rtp_read++]); - break; - case EventType::kIncomingRtcp: - RTC_CHECK(incoming_rtcp_read < incoming_rtcp_packets.size()); - RtcEventLogTestHelper::VerifyRtcpEvent( - parsed_log, i + 1, kIncomingPacket, - incoming_rtcp_packets[incoming_rtcp_read].data(), - incoming_rtcp_packets[incoming_rtcp_read].size()); - incoming_rtcp_read++; - break; - case EventType::kOutgoingRtcp: - RTC_CHECK(outgoing_rtcp_read < outgoing_rtcp_packets.size()); - RtcEventLogTestHelper::VerifyRtcpEvent( - parsed_log, i + 1, kOutgoingPacket, - outgoing_rtcp_packets[outgoing_rtcp_read].data(), - outgoing_rtcp_packets[outgoing_rtcp_read].size()); - outgoing_rtcp_read++; - break; - case EventType::kAudioPlayout: - RTC_CHECK(playouts_read < playout_ssrcs.size()); - RtcEventLogTestHelper::VerifyPlayoutEvent( - parsed_log, i + 1, playout_ssrcs[playouts_read++]); - break; - case EventType::kBweLossUpdate: - RTC_CHECK(bwe_loss_read < bwe_loss_updates.size()); - RtcEventLogTestHelper::VerifyBweLossEvent( - parsed_log, i + 1, bwe_loss_updates[bwe_loss_read].bitrate_bps, - bwe_loss_updates[bwe_loss_read].fraction_loss, - bwe_loss_updates[bwe_loss_read].total_packets); - bwe_loss_read++; - break; - case EventType::kBweDelayUpdate: - RTC_CHECK(bwe_delay_read < bwe_delay_updates.size()); - RtcEventLogTestHelper::VerifyBweDelayEvent( - parsed_log, i + 1, bwe_delay_updates[bwe_delay_read].first, - bwe_delay_updates[bwe_delay_read].second); - bwe_delay_read++; - break; - case EventType::kVideoRecvConfig: - RTC_CHECK(recv_configs_read < receiver_configs.size()); - RtcEventLogTestHelper::VerifyVideoReceiveStreamConfig( - parsed_log, i + 1, receiver_configs[recv_configs_read++]); - break; - case EventType::kVideoSendConfig: - RTC_CHECK(send_configs_read < sender_configs.size()); - RtcEventLogTestHelper::VerifyVideoSendStreamConfig( - parsed_log, i + 1, sender_configs[send_configs_read++]); - break; - case EventType::kAudioRecvConfig: - // Not implemented - RTC_NOTREACHED(); - break; - case EventType::kAudioSendConfig: - // Not implemented - RTC_NOTREACHED(); - break; - case EventType::kAudioNetworkAdaptation: - // Not implemented - RTC_NOTREACHED(); - break; - case EventType::kBweProbeClusterCreated: - // Not implemented - RTC_NOTREACHED(); - break; - case EventType::kBweProbeResult: - // Not implemented - RTC_NOTREACHED(); - break; + auto& parsed_alr_state_events = parsed_log.alr_state_events(); + ASSERT_EQ(parsed_alr_state_events.size(), alr_state_list_.size()); + for (size_t i = 0; i < parsed_alr_state_events.size(); i++) { + EXPECT_TRUE(test::VerifyLoggedAlrStateEvent(*alr_state_list_[i], + parsed_alr_state_events[i])); + } + + const auto& parsed_audio_playout_map = parsed_log.audio_playout_events(); + ASSERT_EQ(parsed_audio_playout_map.size(), audio_playout_map_.size()); + for (const auto& kv : parsed_audio_playout_map) { + uint32_t ssrc = kv.first; + const auto& parsed_audio_playout_stream = kv.second; + const auto& audio_playout_stream = audio_playout_map_[ssrc]; + ASSERT_EQ(parsed_audio_playout_stream.size(), audio_playout_stream.size()); + for (size_t i = 0; i < parsed_audio_playout_map.size(); i++) { + EXPECT_TRUE(test::VerifyLoggedAudioPlayoutEvent( + *audio_playout_stream[i], parsed_audio_playout_stream[i])); } } - RtcEventLogTestHelper::VerifyLogEndEvent(parsed_log, - parsed_log.GetNumberOfEvents() - 1); + auto& parsed_audio_network_adaptation_events = + parsed_log.audio_network_adaptation_events(); + ASSERT_EQ(parsed_audio_network_adaptation_events.size(), + ana_configs_list_.size()); + for (size_t i = 0; i < parsed_audio_network_adaptation_events.size(); i++) { + EXPECT_TRUE(test::VerifyLoggedAudioNetworkAdaptationEvent( + *ana_configs_list_[i], parsed_audio_network_adaptation_events[i])); + } + + auto& parsed_bwe_delay_updates = parsed_log.bwe_delay_updates(); + ASSERT_EQ(parsed_bwe_delay_updates.size(), bwe_delay_list_.size()); + for (size_t i = 0; i < parsed_bwe_delay_updates.size(); i++) { + EXPECT_TRUE(test::VerifyLoggedBweDelayBasedUpdate( + *bwe_delay_list_[i], parsed_bwe_delay_updates[i])); + } + + auto& parsed_bwe_loss_updates = parsed_log.bwe_loss_updates(); + ASSERT_EQ(parsed_bwe_loss_updates.size(), bwe_loss_list_.size()); + for (size_t i = 0; i < parsed_bwe_loss_updates.size(); i++) { + EXPECT_TRUE(test::VerifyLoggedBweLossBasedUpdate( + *bwe_loss_list_[i], parsed_bwe_loss_updates[i])); + } + + auto& parsed_bwe_probe_cluster_created_events = + parsed_log.bwe_probe_cluster_created_events(); + ASSERT_EQ(parsed_bwe_probe_cluster_created_events.size(), + probe_creation_list_.size()); + for (size_t i = 0; i < parsed_bwe_probe_cluster_created_events.size(); i++) { + EXPECT_TRUE(test::VerifyLoggedBweProbeClusterCreatedEvent( + *probe_creation_list_[i], parsed_bwe_probe_cluster_created_events[i])); + } + + auto& parsed_bwe_probe_failure_events = parsed_log.bwe_probe_failure_events(); + ASSERT_EQ(parsed_bwe_probe_failure_events.size(), probe_failure_list_.size()); + for (size_t i = 0; i < parsed_bwe_probe_failure_events.size(); i++) { + EXPECT_TRUE(test::VerifyLoggedBweProbeFailureEvent( + *probe_failure_list_[i], parsed_bwe_probe_failure_events[i])); + } + + auto& parsed_bwe_probe_success_events = parsed_log.bwe_probe_success_events(); + ASSERT_EQ(parsed_bwe_probe_success_events.size(), probe_success_list_.size()); + for (size_t i = 0; i < parsed_bwe_probe_success_events.size(); i++) { + EXPECT_TRUE(test::VerifyLoggedBweProbeSuccessEvent( + *probe_success_list_[i], parsed_bwe_probe_success_events[i])); + } + + auto& parsed_ice_candidate_pair_configs = + parsed_log.ice_candidate_pair_configs(); + ASSERT_EQ(parsed_ice_candidate_pair_configs.size(), ice_config_list_.size()); + for (size_t i = 0; i < parsed_ice_candidate_pair_configs.size(); i++) { + EXPECT_TRUE(test::VerifyLoggedIceCandidatePairConfig( + *ice_config_list_[i], parsed_ice_candidate_pair_configs[i])); + } + + auto& parsed_ice_candidate_pair_events = + parsed_log.ice_candidate_pair_events(); + ASSERT_EQ(parsed_ice_candidate_pair_events.size(), + parsed_ice_candidate_pair_events.size()); + for (size_t i = 0; i < parsed_ice_candidate_pair_events.size(); i++) { + EXPECT_TRUE(test::VerifyLoggedIceCandidatePairEvent( + *ice_event_list_[i], parsed_ice_candidate_pair_events[i])); + } + + auto& parsed_incoming_rtp_packets_by_ssrc = + parsed_log.incoming_rtp_packets_by_ssrc(); + ASSERT_EQ(parsed_incoming_rtp_packets_by_ssrc.size(), + incoming_rtp_map_.size()); + for (const auto& kv : parsed_incoming_rtp_packets_by_ssrc) { + uint32_t ssrc = kv.ssrc; + const auto& parsed_rtp_stream = kv.incoming_packets; + const auto& rtp_stream = incoming_rtp_map_[ssrc]; + ASSERT_EQ(parsed_rtp_stream.size(), rtp_stream.size()); + for (size_t i = 0; i < parsed_rtp_stream.size(); i++) { + EXPECT_TRUE(test::VerifyLoggedRtpPacketIncoming(*rtp_stream[i], + parsed_rtp_stream[i])); + } + } + + auto& parsed_outgoing_rtp_packets_by_ssrc = + parsed_log.outgoing_rtp_packets_by_ssrc(); + ASSERT_EQ(parsed_outgoing_rtp_packets_by_ssrc.size(), + outgoing_rtp_map_.size()); + for (const auto& kv : parsed_outgoing_rtp_packets_by_ssrc) { + uint32_t ssrc = kv.ssrc; + const auto& parsed_rtp_stream = kv.outgoing_packets; + const auto& rtp_stream = outgoing_rtp_map_[ssrc]; + ASSERT_EQ(parsed_rtp_stream.size(), rtp_stream.size()); + for (size_t i = 0; i < parsed_rtp_stream.size(); i++) { + EXPECT_TRUE(test::VerifyLoggedRtpPacketOutgoing(*rtp_stream[i], + parsed_rtp_stream[i])); + } + } + + auto& parsed_incoming_rtcp_packets = parsed_log.incoming_rtcp_packets(); + ASSERT_EQ(parsed_incoming_rtcp_packets.size(), incoming_rtcp_list_.size()); + for (size_t i = 0; i < parsed_incoming_rtcp_packets.size(); i++) { + EXPECT_TRUE(test::VerifyLoggedRtcpPacketIncoming( + *incoming_rtcp_list_[i], parsed_incoming_rtcp_packets[i])); + } + + auto& parsed_outgoing_rtcp_packets = parsed_log.outgoing_rtcp_packets(); + ASSERT_EQ(parsed_outgoing_rtcp_packets.size(), outgoing_rtcp_list_.size()); + for (size_t i = 0; i < parsed_outgoing_rtcp_packets.size(); i++) { + EXPECT_TRUE(test::VerifyLoggedRtcpPacketOutgoing( + *outgoing_rtcp_list_[i], parsed_outgoing_rtcp_packets[i])); + } + auto& parsed_audio_recv_configs = parsed_log.audio_recv_configs(); + ASSERT_EQ(parsed_audio_recv_configs.size(), audio_recv_config_list_.size()); + for (size_t i = 0; i < parsed_audio_recv_configs.size(); i++) { + EXPECT_TRUE(test::VerifyLoggedAudioRecvConfig( + *audio_recv_config_list_[i], parsed_audio_recv_configs[i])); + } + auto& parsed_audio_send_configs = parsed_log.audio_send_configs(); + ASSERT_EQ(parsed_audio_send_configs.size(), audio_send_config_list_.size()); + for (size_t i = 0; i < parsed_audio_send_configs.size(); i++) { + EXPECT_TRUE(test::VerifyLoggedAudioSendConfig( + *audio_send_config_list_[i], parsed_audio_send_configs[i])); + } + auto& parsed_video_recv_configs = parsed_log.video_recv_configs(); + ASSERT_EQ(parsed_video_recv_configs.size(), video_recv_config_list_.size()); + for (size_t i = 0; i < parsed_video_recv_configs.size(); i++) { + EXPECT_TRUE(test::VerifyLoggedVideoRecvConfig( + *video_recv_config_list_[i], parsed_video_recv_configs[i])); + } + auto& parsed_video_send_configs = parsed_log.video_send_configs(); + ASSERT_EQ(parsed_video_send_configs.size(), video_send_config_list_.size()); + for (size_t i = 0; i < parsed_video_send_configs.size(); i++) { + EXPECT_TRUE(test::VerifyLoggedVideoSendConfig( + *video_send_config_list_[i], parsed_video_send_configs[i])); + } // Clean up temporary file - can be pretty slow. - remove(temp_filename.c_str()); + remove(temp_filename_.c_str()); } -void RtcEventLogSession::PrintExpectedEvents(std::ostream& stream) { - for (size_t i = 0; i < event_types.size(); i++) { - auto it = event_type_to_string.find(event_types[i]); - RTC_CHECK(it != event_type_to_string.end()); - stream << it->second << " "; - } - stream << std::endl; +} // namespace + +TEST_P(RtcEventLogSession, StartLoggingFromBeginning) { + EventCounts count; + count.audio_send_streams = 2; + count.audio_recv_streams = 2; + count.video_send_streams = 3; + count.video_recv_streams = 4; + count.alr_states = 4; + count.audio_playouts = 100; + count.ana_configs = 3; + count.bwe_loss_events = 20; + count.bwe_delay_events = 20; + count.probe_creations = 4; + count.probe_successes = 2; + count.probe_failures = 2; + count.ice_configs = 3; + count.ice_events = 10; + count.incoming_rtp_packets = 100; + count.outgoing_rtp_packets = 100; + count.incoming_rtcp_packets = 20; + count.outgoing_rtcp_packets = 20; + + WriteLog(count, 0); + ReadAndVerifyLog(); } -void PrintActualEvents(const ParsedRtcEventLogNew& parsed_log, - std::ostream& stream) { - for (size_t i = 0; i < parsed_log.GetNumberOfEvents(); i++) { - auto it = parsed_event_type_to_string.find(parsed_log.GetEventType(i)); - RTC_CHECK(it != parsed_event_type_to_string.end()); - stream << it->second << " "; - } - stream << std::endl; -} +TEST_P(RtcEventLogSession, StartLoggingInTheMiddle) { + EventCounts count; + count.audio_send_streams = 3; + count.audio_recv_streams = 4; + count.video_send_streams = 5; + count.video_recv_streams = 6; + count.alr_states = 10; + count.audio_playouts = 500; + count.ana_configs = 10; + count.bwe_loss_events = 50; + count.bwe_delay_events = 50; + count.probe_creations = 10; + count.probe_successes = 5; + count.probe_failures = 5; + count.ice_configs = 10; + count.ice_events = 20; + count.incoming_rtp_packets = 500; + count.outgoing_rtp_packets = 500; + count.incoming_rtcp_packets = 50; + count.outgoing_rtcp_packets = 50; -TEST_P(RtcEventLogSession, LogSessionAndReadBack) { - RtpHeaderExtensionMap extensions; - GenerateSessionDescription(3, // Number of incoming RTP packets. - 2, // Number of outgoing RTP packets. - 1, // Number of incoming RTCP packets. - 1, // Number of outgoing RTCP packets. - 0, // Number of playout events. - 0, // Number of BWE loss events. - 0, // Number of BWE delay events. - extensions, // No extensions. - 0); // Number of contributing sources. - WriteSession(); - ReadAndVerifySession(); -} - -TEST_P(RtcEventLogSession, LogSessionAndReadBackWith2Extensions) { - RtpHeaderExtensionMap extensions; - extensions.Register(kRtpExtensionAbsoluteSendTime, - kAbsoluteSendTimeExtensionId); - extensions.Register(kRtpExtensionTransportSequenceNumber, - kTransportSequenceNumberExtensionId); - GenerateSessionDescription(4, 4, 1, 1, 0, 0, 0, extensions, 0); - WriteSession(); - ReadAndVerifySession(); -} - -TEST_P(RtcEventLogSession, LogSessionAndReadBackWithAllExtensions) { - RtpHeaderExtensionMap extensions; - for (uint32_t i = 0; i < kNumExtensions; i++) { - extensions.Register(kExtensionTypes[i], kExtensionIds[i]); - } - GenerateSessionDescription(5, 4, 1, 1, 3, 2, 2, extensions, 2); - WriteSession(); - ReadAndVerifySession(); -} - -TEST_P(RtcEventLogSession, LogLongSessionAndReadBack) { - RtpHeaderExtensionMap extensions; - for (uint32_t i = 0; i < kNumExtensions; i++) { - extensions.Register(kExtensionTypes[i], kExtensionIds[i]); - } - GenerateSessionDescription(1000, 1000, 250, 250, 200, 100, 100, extensions, - 1); - WriteSession(); - ReadAndVerifySession(); + WriteLog(count, 500); + ReadAndVerifyLog(); } TEST(RtcEventLogTest, CircularBufferKeepsMostRecentEvents) { + // TODO(terelius): Maybe make a separate RtcEventLogImplTest that can access + // the size of the cyclic buffer? constexpr size_t kNumEvents = 20000; constexpr int64_t kStartTime = 1000000; + constexpr int32_t kStartBitrate = 1000000; auto test_info = ::testing::UnitTest::GetInstance()->current_test_info(); - std::string test_name = test_info->name(); + std::string test_name = + std::string(test_info->test_case_name()) + "_" + test_info->name(); std::replace(test_name.begin(), test_name.end(), '/', '_'); - const std::string temp_filename = - test::OutputPath() + "RtcEventLogTest_" + test_name; + const std::string temp_filename = test::OutputPath() + test_name; - rtc::ScopedFakeClock fake_clock; - fake_clock.SetTimeMicros(kStartTime); + std::unique_ptr fake_clock = + rtc::MakeUnique(); + fake_clock->SetTimeMicros(kStartTime); // When log_dumper goes out of scope, it causes the log file to be flushed // to disk. @@ -725,49 +705,62 @@ TEST(RtcEventLogTest, CircularBufferKeepsMostRecentEvents) { for (size_t i = 0; i < kNumEvents; i++) { // The purpose of the test is to verify that the log can handle // more events than what fits in the internal circular buffer. The exact - // type of events does not matter so we chose AudioPlayouts for simplicity. - // We use the index as an ssrc to get a strict relationship between the ssrc - // and the timestamp. We use this for some basic consistency checks when we - // read back. - log_dumper->Log(rtc::MakeUnique(i)); - fake_clock.AdvanceTimeMicros(10000); + // type of events does not matter so we chose ProbeSuccess events for + // simplicity. + // We base the various values on the index. We use this for some basic + // consistency checks when we read back. + log_dumper->Log(rtc::MakeUnique( + i, kStartBitrate + i * 1000)); + fake_clock->AdvanceTimeMicros(10000); } + int64_t start_time_us = rtc::TimeMicros(); log_dumper->StartLogging( rtc::MakeUnique(temp_filename, 10000000), RtcEventLog::kImmediateOutput); + fake_clock->AdvanceTimeMicros(10000); + int64_t stop_time_us = rtc::TimeMicros(); log_dumper->StopLogging(); // Read the generated file from disk. ParsedRtcEventLogNew parsed_log; ASSERT_TRUE(parsed_log.ParseFile(temp_filename)); + + const auto& start_log_events = parsed_log.start_log_events(); + ASSERT_EQ(start_log_events.size(), 1u); + EXPECT_TRUE(test::VerifyLoggedStartEvent(start_time_us, start_log_events[0])); + + const auto& stop_log_events = parsed_log.stop_log_events(); + ASSERT_EQ(stop_log_events.size(), 1u); + EXPECT_TRUE(test::VerifyLoggedStopEvent(stop_time_us, stop_log_events[0])); + + const auto& probe_success_events = parsed_log.bwe_probe_success_events(); // If the following fails, it probably means that kNumEvents isn't larger // than the size of the cyclic buffer in the event log. Try increasing // kNumEvents. - EXPECT_LT(parsed_log.GetNumberOfEvents(), kNumEvents); - // We expect a start event, some number of playouts events and a stop event. - EXPECT_GT(parsed_log.GetNumberOfEvents(), 2u); + EXPECT_LT(probe_success_events.size(), kNumEvents); - RtcEventLogTestHelper::VerifyLogStartEvent(parsed_log, 0); - absl::optional last_timestamp; - absl::optional last_ssrc; - for (size_t i = 1; i < parsed_log.GetNumberOfEvents() - 1; i++) { - EXPECT_EQ(parsed_log.GetEventType(i), - ParsedRtcEventLogNew::EventType::AUDIO_PLAYOUT_EVENT); - LoggedAudioPlayoutEvent playout_event = parsed_log.GetAudioPlayout(i); - EXPECT_LT(playout_event.ssrc, kNumEvents); - EXPECT_EQ(static_cast(kStartTime + 10000 * playout_event.ssrc), - playout_event.timestamp_us); - if (last_ssrc) - EXPECT_EQ(playout_event.ssrc, *last_ssrc + 1); - if (last_timestamp) - EXPECT_EQ(playout_event.timestamp_us, *last_timestamp + 10000); - last_ssrc = playout_event.ssrc; - last_timestamp = playout_event.timestamp_us; + ASSERT_GT(probe_success_events.size(), 1u); + int64_t first_timestamp_us = probe_success_events[0].timestamp_us; + uint32_t first_id = probe_success_events[0].id; + int32_t first_bitrate_bps = probe_success_events[0].bitrate_bps; + // We want to reset the time to what we used when generating the events, but + // the fake clock implementation DCHECKS if time moves backwards. We therefore + // recreate the clock. However we must ensure that the old fake_clock is + // destroyed before the new one is created, so we have to reset() first. + fake_clock.reset(); + fake_clock = rtc::MakeUnique(); + fake_clock->SetTimeMicros(first_timestamp_us); + for (size_t i = 1; i < probe_success_events.size(); i++) { + fake_clock->AdvanceTimeMicros(10000); + ASSERT_TRUE(test::VerifyLoggedBweProbeSuccessEvent( + RtcEventProbeResultSuccess(first_id + i, first_bitrate_bps + i * 1000), + probe_success_events[i])); } - RtcEventLogTestHelper::VerifyLogEndEvent(parsed_log, - parsed_log.GetNumberOfEvents() - 1); } +// TODO(terelius): Verify parser behavior if the timestamps are not +// monotonically increasing in the log. + INSTANTIATE_TEST_CASE_P( RtcEventLogTest, RtcEventLogSession, 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 466069661f..76c8a0d729 100644 --- a/logging/rtc_event_log/rtc_event_log_unittest_helper.cc +++ b/logging/rtc_event_log/rtc_event_log_unittest_helper.cc @@ -10,610 +10,806 @@ #include "logging/rtc_event_log/rtc_event_log_unittest_helper.h" -#include +#include // memcmp -#include +#include +#include +#include +#include #include #include "modules/audio_coding/audio_network_adaptor/include/audio_network_adaptor.h" #include "modules/remote_bitrate_estimator/include/bwe_defines.h" +#include "modules/rtp_rtcp/include/rtp_cvo.h" +#include "modules/rtp_rtcp/source/rtp_header_extensions.h" +#include "modules/rtp_rtcp/source/rtp_packet_received.h" +#include "modules/rtp_rtcp/source/rtp_packet_to_send.h" #include "rtc_base/checks.h" -#include "test/gmock.h" -#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 test { + namespace { -BandwidthUsage GetRuntimeDetectorState( - rtclog::DelayBasedBweUpdate::DetectorState detector_state) { - switch (detector_state) { - case rtclog::DelayBasedBweUpdate::BWE_NORMAL: - return BandwidthUsage::kBwNormal; - case rtclog::DelayBasedBweUpdate::BWE_UNDERUSING: - return BandwidthUsage::kBwUnderusing; - case rtclog::DelayBasedBweUpdate::BWE_OVERUSING: - return BandwidthUsage::kBwOverusing; - } - RTC_NOTREACHED(); - return BandwidthUsage::kBwNormal; -} +struct ExtensionPair { + RTPExtensionType type; + const char* name; +}; -rtclog::BweProbeResult::ResultType GetProbeResultType( - 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(); +constexpr int kMaxCsrcs = 3; + +// Maximum serialized size of a header extension, including 1 byte ID. +constexpr int kMaxExtensionSizeBytes = 4; +constexpr int kMaxNumExtensions = 5; + +constexpr ExtensionPair kExtensions[kMaxNumExtensions] = { + {RTPExtensionType::kRtpExtensionTransmissionTimeOffset, + RtpExtension::kTimestampOffsetUri}, + {RTPExtensionType::kRtpExtensionAbsoluteSendTime, + RtpExtension::kAbsSendTimeUri}, + {RTPExtensionType::kRtpExtensionTransportSequenceNumber, + RtpExtension::kTransportSequenceNumberUri}, + {RTPExtensionType::kRtpExtensionAudioLevel, RtpExtension::kAudioLevelUri}, + {RTPExtensionType::kRtpExtensionVideoRotation, + RtpExtension::kVideoRotationUri}}; + +template +void ShuffleInPlace(Random* prng, rtc::ArrayView array) { + RTC_DCHECK_LE(array.size(), std::numeric_limits::max()); + for (uint32_t i = 0; i + 1 < array.size(); i++) { + uint32_t other = prng->Rand(i, static_cast(array.size() - 1)); + std::swap(array[i], array[other]); } - RTC_NOTREACHED(); - return rtclog::BweProbeResult::SUCCESS; } } // namespace -// Checks that the event has a timestamp, a type and exactly the data field -// corresponding to the type. -::testing::AssertionResult IsValidBasicEvent(const rtclog::Event& event) { - if (!event.has_timestamp_us()) { - return ::testing::AssertionFailure() << "Event has no timestamp"; - } - if (!event.has_type()) { - return ::testing::AssertionFailure() << "Event has no event type"; - } - rtclog::Event_EventType type = event.type(); - if ((type == rtclog::Event::RTP_EVENT) != event.has_rtp_packet()) { - return ::testing::AssertionFailure() - << "Event of type " << type << " has " - << (event.has_rtp_packet() ? "" : "no ") << "RTP packet"; - } - if ((type == rtclog::Event::RTCP_EVENT) != event.has_rtcp_packet()) { - return ::testing::AssertionFailure() - << "Event of type " << type << " has " - << (event.has_rtcp_packet() ? "" : "no ") << "RTCP packet"; - } - if ((type == rtclog::Event::LOSS_BASED_BWE_UPDATE) != - event.has_loss_based_bwe_update()) { - return ::testing::AssertionFailure() - << "Event of type " << type << " has " - << (event.has_loss_based_bwe_update() ? "" : "no ") << "loss update"; - } - if ((type == rtclog::Event::DELAY_BASED_BWE_UPDATE) != - event.has_delay_based_bwe_update()) { - return ::testing::AssertionFailure() - << "Event of type " << type << " has " - << (event.has_delay_based_bwe_update() ? "" : "no ") - << "delay update"; - } - if ((type == rtclog::Event::AUDIO_PLAYOUT_EVENT) != - event.has_audio_playout_event()) { - return ::testing::AssertionFailure() - << "Event of type " << type << " has " - << (event.has_audio_playout_event() ? "" : "no ") - << "audio_playout event"; - } - if ((type == rtclog::Event::VIDEO_RECEIVER_CONFIG_EVENT) != - event.has_video_receiver_config()) { - return ::testing::AssertionFailure() - << "Event of type " << type << " has " - << (event.has_video_receiver_config() ? "" : "no ") - << "receiver config"; - } - if ((type == rtclog::Event::VIDEO_SENDER_CONFIG_EVENT) != - event.has_video_sender_config()) { - return ::testing::AssertionFailure() - << "Event of type " << type << " has " - << (event.has_video_sender_config() ? "" : "no ") << "sender config"; - } - if ((type == rtclog::Event::AUDIO_RECEIVER_CONFIG_EVENT) != - event.has_audio_receiver_config()) { - return ::testing::AssertionFailure() - << "Event of type " << type << " has " - << (event.has_audio_receiver_config() ? "" : "no ") - << "audio receiver config"; - } - if ((type == rtclog::Event::AUDIO_SENDER_CONFIG_EVENT) != - event.has_audio_sender_config()) { - return ::testing::AssertionFailure() - << "Event of type " << type << " has " - << (event.has_audio_sender_config() ? "" : "no ") - << "audio sender config"; - } - if ((type == rtclog::Event::AUDIO_NETWORK_ADAPTATION_EVENT) != - event.has_audio_network_adaptation()) { - return ::testing::AssertionFailure() - << "Event of type " << type << " has " - << (event.has_audio_network_adaptation() ? "" : "no ") - << "audio network adaptation"; - } - if ((type == rtclog::Event::BWE_PROBE_CLUSTER_CREATED_EVENT) != - event.has_probe_cluster()) { - return ::testing::AssertionFailure() - << "Event of type " << type << " has " - << (event.has_probe_cluster() ? "" : "no ") << "bwe probe cluster"; - } - if ((type == rtclog::Event::BWE_PROBE_RESULT_EVENT) != - event.has_probe_result()) { - return ::testing::AssertionFailure() - << "Event of type " << type << " has " - << (event.has_probe_result() ? "" : "no ") << "bwe probe result"; - } - return ::testing::AssertionSuccess(); +std::unique_ptr EventGenerator::NewAlrState() { + return rtc::MakeUnique(prng_.Rand()); } -void VerifyStreamConfigsAreEqual(const rtclog::StreamConfig& config_1, - const rtclog::StreamConfig& config_2) { - EXPECT_EQ(config_1.remote_ssrc, config_2.remote_ssrc); - EXPECT_EQ(config_1.local_ssrc, config_2.local_ssrc); - EXPECT_EQ(config_1.rtx_ssrc, config_2.rtx_ssrc); - EXPECT_EQ(config_1.rtcp_mode, config_2.rtcp_mode); - EXPECT_EQ(config_1.remb, config_2.remb); - - ASSERT_EQ(config_1.rtp_extensions.size(), config_2.rtp_extensions.size()); - for (size_t i = 0; i < config_2.rtp_extensions.size(); i++) { - EXPECT_EQ(config_1.rtp_extensions[i].uri, config_2.rtp_extensions[i].uri); - EXPECT_EQ(config_1.rtp_extensions[i].id, config_2.rtp_extensions[i].id); - } - ASSERT_EQ(config_1.codecs.size(), config_2.codecs.size()); - for (size_t i = 0; i < config_2.codecs.size(); i++) { - EXPECT_EQ(config_1.codecs[i].payload_name, config_2.codecs[i].payload_name); - EXPECT_EQ(config_1.codecs[i].payload_type, config_2.codecs[i].payload_type); - EXPECT_EQ(config_1.codecs[i].rtx_payload_type, - config_2.codecs[i].rtx_payload_type); - } -} - -void RtcEventLogTestHelper::VerifyVideoReceiveStreamConfig( - const ParsedRtcEventLogNew& parsed_log, - size_t index, - const rtclog::StreamConfig& config) { - ASSERT_LT(index, parsed_log.events_.size()); - const rtclog::Event& event = parsed_log.events_[index]; - ASSERT_TRUE(IsValidBasicEvent(event)); - ASSERT_EQ(rtclog::Event::VIDEO_RECEIVER_CONFIG_EVENT, event.type()); - const rtclog::VideoReceiveConfig& receiver_config = - event.video_receiver_config(); - // Check SSRCs. - ASSERT_TRUE(receiver_config.has_remote_ssrc()); - EXPECT_EQ(config.remote_ssrc, receiver_config.remote_ssrc()); - ASSERT_TRUE(receiver_config.has_local_ssrc()); - EXPECT_EQ(config.local_ssrc, receiver_config.local_ssrc()); - // Check RTCP settings. - ASSERT_TRUE(receiver_config.has_rtcp_mode()); - if (config.rtcp_mode == RtcpMode::kCompound) { - EXPECT_EQ(rtclog::VideoReceiveConfig::RTCP_COMPOUND, - receiver_config.rtcp_mode()); - } else { - EXPECT_EQ(rtclog::VideoReceiveConfig::RTCP_REDUCEDSIZE, - receiver_config.rtcp_mode()); - } - ASSERT_TRUE(receiver_config.has_remb()); - EXPECT_EQ(config.remb, receiver_config.remb()); - // Check RTX map. - for (const rtclog::RtxMap& rtx_map : receiver_config.rtx_map()) { - ASSERT_TRUE(rtx_map.has_payload_type()); - ASSERT_TRUE(rtx_map.has_config()); - const rtclog::RtxConfig& rtx_config = rtx_map.config(); - ASSERT_TRUE(rtx_config.has_rtx_ssrc()); - ASSERT_TRUE(rtx_config.has_rtx_payload_type()); - - EXPECT_EQ(config.rtx_ssrc, rtx_config.rtx_ssrc()); - auto codec_found = - std::find_if(config.codecs.begin(), config.codecs.end(), - [&rtx_map](const rtclog::StreamConfig::Codec& codec) { - return rtx_map.payload_type() == codec.payload_type; - }); - ASSERT_TRUE(codec_found != config.codecs.end()); - EXPECT_EQ(rtx_config.rtx_payload_type(), codec_found->rtx_payload_type); - } - // Check header extensions. - ASSERT_EQ(static_cast(config.rtp_extensions.size()), - receiver_config.header_extensions_size()); - for (int i = 0; i < receiver_config.header_extensions_size(); i++) { - ASSERT_TRUE(receiver_config.header_extensions(i).has_name()); - ASSERT_TRUE(receiver_config.header_extensions(i).has_id()); - const std::string& name = receiver_config.header_extensions(i).name(); - int id = receiver_config.header_extensions(i).id(); - EXPECT_EQ(config.rtp_extensions[i].id, id); - EXPECT_EQ(config.rtp_extensions[i].uri, name); - } - // Check decoders. - ASSERT_EQ(static_cast(config.codecs.size()), - receiver_config.decoders_size()); - for (int i = 0; i < receiver_config.decoders_size(); i++) { - ASSERT_TRUE(receiver_config.decoders(i).has_name()); - ASSERT_TRUE(receiver_config.decoders(i).has_payload_type()); - const std::string& decoder_name = receiver_config.decoders(i).name(); - int decoder_type = receiver_config.decoders(i).payload_type(); - EXPECT_EQ(config.codecs[i].payload_name, decoder_name); - EXPECT_EQ(config.codecs[i].payload_type, decoder_type); - } - - // Check consistency of the parser. - rtclog::StreamConfig parsed_config = parsed_log.GetVideoReceiveConfig(index); - VerifyStreamConfigsAreEqual(config, parsed_config); -} - -void RtcEventLogTestHelper::VerifyVideoSendStreamConfig( - const ParsedRtcEventLogNew& parsed_log, - size_t index, - const rtclog::StreamConfig& config) { - ASSERT_LT(index, parsed_log.events_.size()); - const rtclog::Event& event = parsed_log.events_[index]; - ASSERT_TRUE(IsValidBasicEvent(event)); - ASSERT_EQ(rtclog::Event::VIDEO_SENDER_CONFIG_EVENT, event.type()); - const rtclog::VideoSendConfig& sender_config = event.video_sender_config(); - - EXPECT_EQ(config.local_ssrc, sender_config.ssrcs(0)); - EXPECT_EQ(config.rtx_ssrc, sender_config.rtx_ssrcs(0)); - - // Check header extensions. - ASSERT_EQ(static_cast(config.rtp_extensions.size()), - sender_config.header_extensions_size()); - for (int i = 0; i < sender_config.header_extensions_size(); i++) { - ASSERT_TRUE(sender_config.header_extensions(i).has_name()); - ASSERT_TRUE(sender_config.header_extensions(i).has_id()); - const std::string& name = sender_config.header_extensions(i).name(); - int id = sender_config.header_extensions(i).id(); - EXPECT_EQ(config.rtp_extensions[i].id, id); - EXPECT_EQ(config.rtp_extensions[i].uri, name); - } - // Check encoder. - ASSERT_TRUE(sender_config.has_encoder()); - ASSERT_TRUE(sender_config.encoder().has_name()); - ASSERT_TRUE(sender_config.encoder().has_payload_type()); - EXPECT_EQ(config.codecs[0].payload_name, sender_config.encoder().name()); - EXPECT_EQ(config.codecs[0].payload_type, - sender_config.encoder().payload_type()); - - EXPECT_EQ(config.codecs[0].rtx_payload_type, - sender_config.rtx_payload_type()); - - // Check consistency of the parser. - std::vector parsed_configs = - parsed_log.GetVideoSendConfig(index); - ASSERT_EQ(1u, parsed_configs.size()); - VerifyStreamConfigsAreEqual(config, parsed_configs[0]); -} - -void RtcEventLogTestHelper::VerifyAudioReceiveStreamConfig( - const ParsedRtcEventLogNew& parsed_log, - size_t index, - const rtclog::StreamConfig& config) { - ASSERT_LT(index, parsed_log.events_.size()); - const rtclog::Event& event = parsed_log.events_[index]; - ASSERT_TRUE(IsValidBasicEvent(event)); - ASSERT_EQ(rtclog::Event::AUDIO_RECEIVER_CONFIG_EVENT, event.type()); - const rtclog::AudioReceiveConfig& receiver_config = - event.audio_receiver_config(); - // Check SSRCs. - ASSERT_TRUE(receiver_config.has_remote_ssrc()); - EXPECT_EQ(config.remote_ssrc, receiver_config.remote_ssrc()); - ASSERT_TRUE(receiver_config.has_local_ssrc()); - EXPECT_EQ(config.local_ssrc, receiver_config.local_ssrc()); - // Check header extensions. - ASSERT_EQ(static_cast(config.rtp_extensions.size()), - receiver_config.header_extensions_size()); - for (int i = 0; i < receiver_config.header_extensions_size(); i++) { - ASSERT_TRUE(receiver_config.header_extensions(i).has_name()); - ASSERT_TRUE(receiver_config.header_extensions(i).has_id()); - const std::string& name = receiver_config.header_extensions(i).name(); - int id = receiver_config.header_extensions(i).id(); - EXPECT_EQ(config.rtp_extensions[i].id, id); - EXPECT_EQ(config.rtp_extensions[i].uri, name); - } - - // Check consistency of the parser. - rtclog::StreamConfig parsed_config = parsed_log.GetAudioReceiveConfig(index); - EXPECT_EQ(config.remote_ssrc, parsed_config.remote_ssrc); - EXPECT_EQ(config.local_ssrc, parsed_config.local_ssrc); - // Check header extensions. - EXPECT_EQ(config.rtp_extensions.size(), parsed_config.rtp_extensions.size()); - for (size_t i = 0; i < parsed_config.rtp_extensions.size(); i++) { - EXPECT_EQ(config.rtp_extensions[i].uri, - parsed_config.rtp_extensions[i].uri); - EXPECT_EQ(config.rtp_extensions[i].id, parsed_config.rtp_extensions[i].id); - } -} - -void RtcEventLogTestHelper::VerifyAudioSendStreamConfig( - const ParsedRtcEventLogNew& parsed_log, - size_t index, - const rtclog::StreamConfig& config) { - ASSERT_LT(index, parsed_log.events_.size()); - const rtclog::Event& event = parsed_log.events_[index]; - ASSERT_TRUE(IsValidBasicEvent(event)); - ASSERT_EQ(rtclog::Event::AUDIO_SENDER_CONFIG_EVENT, event.type()); - const rtclog::AudioSendConfig& sender_config = event.audio_sender_config(); - // Check SSRCs. - EXPECT_EQ(config.local_ssrc, sender_config.ssrc()); - // Check header extensions. - ASSERT_EQ(static_cast(config.rtp_extensions.size()), - sender_config.header_extensions_size()); - for (int i = 0; i < sender_config.header_extensions_size(); i++) { - ASSERT_TRUE(sender_config.header_extensions(i).has_name()); - ASSERT_TRUE(sender_config.header_extensions(i).has_id()); - const std::string& name = sender_config.header_extensions(i).name(); - int id = sender_config.header_extensions(i).id(); - EXPECT_EQ(config.rtp_extensions[i].id, id); - EXPECT_EQ(config.rtp_extensions[i].uri, name); - } - - // Check consistency of the parser. - rtclog::StreamConfig parsed_config = parsed_log.GetAudioSendConfig(index); - VerifyStreamConfigsAreEqual(config, parsed_config); -} - -void RtcEventLogTestHelper::VerifyIncomingRtpEvent( - const ParsedRtcEventLogNew& parsed_log, - size_t index, - const RtpPacketReceived& expected_packet) { - ASSERT_LT(index, parsed_log.events_.size()); - const rtclog::Event& event = parsed_log.events_[index]; - ASSERT_TRUE(IsValidBasicEvent(event)); - ASSERT_EQ(rtclog::Event::RTP_EVENT, event.type()); - const rtclog::RtpPacket& rtp_packet = event.rtp_packet(); - ASSERT_TRUE(rtp_packet.has_incoming()); - EXPECT_TRUE(rtp_packet.incoming()); - ASSERT_TRUE(rtp_packet.has_packet_length()); - EXPECT_EQ(expected_packet.size(), rtp_packet.packet_length()); - size_t header_size = expected_packet.headers_size(); - ASSERT_TRUE(rtp_packet.has_header()); - EXPECT_THAT(testing::make_tuple(expected_packet.data(), header_size), - testing::ElementsAreArray(rtp_packet.header().data(), - rtp_packet.header().size())); - - // Check consistency of the parser. - PacketDirection parsed_direction; - 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, nullptr); - EXPECT_EQ(kIncomingPacket, parsed_direction); - EXPECT_THAT(testing::make_tuple(expected_packet.data(), header_size), - testing::ElementsAreArray(parsed_header, parsed_header_size)); - EXPECT_EQ(expected_packet.size(), parsed_total_size); -} - -void RtcEventLogTestHelper::VerifyOutgoingRtpEvent( - const ParsedRtcEventLogNew& parsed_log, - size_t index, - const RtpPacketToSend& expected_packet) { - ASSERT_LT(index, parsed_log.events_.size()); - const rtclog::Event& event = parsed_log.events_[index]; - ASSERT_TRUE(IsValidBasicEvent(event)); - ASSERT_EQ(rtclog::Event::RTP_EVENT, event.type()); - const rtclog::RtpPacket& rtp_packet = event.rtp_packet(); - ASSERT_TRUE(rtp_packet.has_incoming()); - EXPECT_FALSE(rtp_packet.incoming()); - ASSERT_TRUE(rtp_packet.has_packet_length()); - EXPECT_EQ(expected_packet.size(), rtp_packet.packet_length()); - size_t header_size = expected_packet.headers_size(); - ASSERT_TRUE(rtp_packet.has_header()); - EXPECT_THAT(testing::make_tuple(expected_packet.data(), header_size), - testing::ElementsAreArray(rtp_packet.header().data(), - rtp_packet.header().size())); - - // Check consistency of the parser. - PacketDirection parsed_direction; - 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, nullptr); - EXPECT_EQ(kOutgoingPacket, parsed_direction); - EXPECT_THAT(testing::make_tuple(expected_packet.data(), header_size), - testing::ElementsAreArray(parsed_header, parsed_header_size)); - EXPECT_EQ(expected_packet.size(), parsed_total_size); -} - -void RtcEventLogTestHelper::VerifyRtcpEvent( - const ParsedRtcEventLogNew& parsed_log, - size_t index, - PacketDirection direction, - const uint8_t* packet, - size_t total_size) { - ASSERT_LT(index, parsed_log.events_.size()); - const rtclog::Event& event = parsed_log.events_[index]; - ASSERT_TRUE(IsValidBasicEvent(event)); - ASSERT_EQ(rtclog::Event::RTCP_EVENT, event.type()); - const rtclog::RtcpPacket& rtcp_packet = event.rtcp_packet(); - ASSERT_TRUE(rtcp_packet.has_incoming()); - EXPECT_EQ(direction == kIncomingPacket, rtcp_packet.incoming()); - ASSERT_TRUE(rtcp_packet.has_packet_data()); - ASSERT_EQ(total_size, rtcp_packet.packet_data().size()); - for (size_t i = 0; i < total_size; i++) { - EXPECT_EQ(packet[i], static_cast(rtcp_packet.packet_data()[i])); - } - - // Check consistency of the parser. - PacketDirection parsed_direction; - uint8_t parsed_packet[1500]; - size_t parsed_total_size; - parsed_log.GetRtcpPacket(index, &parsed_direction, parsed_packet, - &parsed_total_size); - EXPECT_EQ(direction, parsed_direction); - ASSERT_EQ(total_size, parsed_total_size); - EXPECT_EQ(0, std::memcmp(packet, parsed_packet, total_size)); -} - -void RtcEventLogTestHelper::VerifyPlayoutEvent( - const ParsedRtcEventLogNew& parsed_log, - size_t index, +std::unique_ptr EventGenerator::NewAudioPlayout( uint32_t ssrc) { - ASSERT_LT(index, parsed_log.events_.size()); - const rtclog::Event& event = parsed_log.events_[index]; - ASSERT_TRUE(IsValidBasicEvent(event)); - ASSERT_EQ(rtclog::Event::AUDIO_PLAYOUT_EVENT, event.type()); - const rtclog::AudioPlayoutEvent& playout_event = event.audio_playout_event(); - ASSERT_TRUE(playout_event.has_local_ssrc()); - EXPECT_EQ(ssrc, playout_event.local_ssrc()); - - // Check consistency of the parser. - LoggedAudioPlayoutEvent parsed_event = parsed_log.GetAudioPlayout(index); - EXPECT_EQ(ssrc, parsed_event.ssrc); + return rtc::MakeUnique(ssrc); } -void RtcEventLogTestHelper::VerifyBweLossEvent( - const ParsedRtcEventLogNew& parsed_log, - size_t index, - int32_t bitrate, - uint8_t fraction_loss, - int32_t total_packets) { - ASSERT_LT(index, parsed_log.events_.size()); - const rtclog::Event& event = parsed_log.events_[index]; - ASSERT_TRUE(IsValidBasicEvent(event)); - ASSERT_EQ(rtclog::Event::LOSS_BASED_BWE_UPDATE, event.type()); - const rtclog::LossBasedBweUpdate& bwe_event = event.loss_based_bwe_update(); - ASSERT_TRUE(bwe_event.has_bitrate_bps()); - EXPECT_EQ(bitrate, bwe_event.bitrate_bps()); - ASSERT_TRUE(bwe_event.has_fraction_loss()); - EXPECT_EQ(fraction_loss, bwe_event.fraction_loss()); - ASSERT_TRUE(bwe_event.has_total_packets()); - EXPECT_EQ(total_packets, bwe_event.total_packets()); +std::unique_ptr +EventGenerator::NewAudioNetworkAdaptation() { + std::unique_ptr config = + rtc::MakeUnique(); - // Check consistency of the parser. - LoggedBweLossBasedUpdate bwe_update = parsed_log.GetLossBasedBweUpdate(index); - EXPECT_EQ(bitrate, bwe_update.bitrate_bps); - EXPECT_EQ(fraction_loss, bwe_update.fraction_lost); - EXPECT_EQ(total_packets, bwe_update.expected_packets); + config->bitrate_bps = prng_.Rand(0, 3000000); + config->enable_fec = prng_.Rand(); + config->enable_dtx = prng_.Rand(); + config->frame_length_ms = prng_.Rand(10, 120); + config->num_channels = prng_.Rand(1, 2); + config->uplink_packet_loss_fraction = prng_.Rand(); + + return rtc::MakeUnique(std::move(config)); } -void RtcEventLogTestHelper::VerifyBweDelayEvent( - const ParsedRtcEventLogNew& parsed_log, - size_t index, - int32_t bitrate, - BandwidthUsage detector_state) { - ASSERT_LT(index, parsed_log.events_.size()); - const rtclog::Event& event = parsed_log.events_[index]; - ASSERT_TRUE(IsValidBasicEvent(event)); - ASSERT_EQ(rtclog::Event::DELAY_BASED_BWE_UPDATE, event.type()); - const rtclog::DelayBasedBweUpdate& bwe_event = event.delay_based_bwe_update(); - ASSERT_TRUE(bwe_event.has_bitrate_bps()); - EXPECT_EQ(bitrate, bwe_event.bitrate_bps()); - ASSERT_TRUE(bwe_event.has_detector_state()); - EXPECT_EQ(detector_state, - GetRuntimeDetectorState(bwe_event.detector_state())); - - // Check consistency of the parser. - LoggedBweDelayBasedUpdate res = parsed_log.GetDelayBasedBweUpdate(index); - EXPECT_EQ(res.bitrate_bps, bitrate); - EXPECT_EQ(res.detector_state, detector_state); +std::unique_ptr +EventGenerator::NewBweUpdateDelayBased() { + constexpr int32_t kMaxBweBps = 20000000; + int32_t bitrate_bps = prng_.Rand(0, kMaxBweBps); + BandwidthUsage state = static_cast( + prng_.Rand(static_cast(BandwidthUsage::kLast) - 1)); + return rtc::MakeUnique(bitrate_bps, state); } -void RtcEventLogTestHelper::VerifyAudioNetworkAdaptation( - const ParsedRtcEventLogNew& parsed_log, - size_t index, - const AudioEncoderRuntimeConfig& config) { - ASSERT_LT(index, parsed_log.events_.size()); - const rtclog::Event& event = parsed_log.events_[index]; - ASSERT_TRUE(IsValidBasicEvent(event)); - ASSERT_EQ(rtclog::Event::AUDIO_NETWORK_ADAPTATION_EVENT, event.type()); +std::unique_ptr +EventGenerator::NewBweUpdateLossBased() { + constexpr int32_t kMaxBweBps = 20000000; + constexpr int32_t kMaxPackets = 1000; + int32_t bitrate_bps = prng_.Rand(0, kMaxBweBps); + uint8_t fraction_lost = prng_.Rand(); + int32_t total_packets = prng_.Rand(1, kMaxPackets); - LoggedAudioNetworkAdaptationEvent parsed_event = - parsed_log.GetAudioNetworkAdaptation(index); - EXPECT_EQ(config.bitrate_bps, parsed_event.config.bitrate_bps); - EXPECT_EQ(config.enable_dtx, parsed_event.config.enable_dtx); - EXPECT_EQ(config.enable_fec, parsed_event.config.enable_fec); - EXPECT_EQ(config.frame_length_ms, parsed_event.config.frame_length_ms); - EXPECT_EQ(config.num_channels, parsed_event.config.num_channels); - EXPECT_EQ(config.uplink_packet_loss_fraction, - parsed_event.config.uplink_packet_loss_fraction); + return rtc::MakeUnique(bitrate_bps, fraction_lost, + total_packets); } -void RtcEventLogTestHelper::VerifyLogStartEvent( - const ParsedRtcEventLogNew& parsed_log, - size_t index) { - ASSERT_LT(index, parsed_log.events_.size()); - const rtclog::Event& event = parsed_log.events_[index]; - ASSERT_TRUE(IsValidBasicEvent(event)); - EXPECT_EQ(rtclog::Event::LOG_START, event.type()); +std::unique_ptr +EventGenerator::NewProbeClusterCreated() { + constexpr int kMaxBweBps = 20000000; + constexpr int kMaxNumProbes = 10000; + int id = prng_.Rand(1, kMaxNumProbes); + int bitrate_bps = prng_.Rand(0, kMaxBweBps); + int min_probes = prng_.Rand(5, 50); + int min_bytes = prng_.Rand(500, 50000); + + return rtc::MakeUnique(id, bitrate_bps, + min_probes, min_bytes); } -void RtcEventLogTestHelper::VerifyLogEndEvent( - const ParsedRtcEventLogNew& parsed_log, - size_t index) { - ASSERT_LT(index, parsed_log.events_.size()); - const rtclog::Event& event = parsed_log.events_[index]; - ASSERT_TRUE(IsValidBasicEvent(event)); - EXPECT_EQ(rtclog::Event::LOG_END, event.type()); +std::unique_ptr +EventGenerator::NewProbeResultFailure() { + constexpr int kMaxNumProbes = 10000; + int id = prng_.Rand(1, kMaxNumProbes); + ProbeFailureReason reason = static_cast( + prng_.Rand(static_cast(ProbeFailureReason::kLast) - 1)); + + return rtc::MakeUnique(id, reason); } -void RtcEventLogTestHelper::VerifyBweProbeCluster( - const ParsedRtcEventLogNew& parsed_log, - size_t index, - int32_t id, - int32_t bitrate_bps, - uint32_t min_probes, - uint32_t min_bytes) { - ASSERT_LT(index, parsed_log.events_.size()); - const rtclog::Event& event = parsed_log.events_[index]; - ASSERT_TRUE(IsValidBasicEvent(event)); - EXPECT_EQ(rtclog::Event::BWE_PROBE_CLUSTER_CREATED_EVENT, event.type()); +std::unique_ptr +EventGenerator::NewProbeResultSuccess() { + constexpr int kMaxBweBps = 20000000; + constexpr int kMaxNumProbes = 10000; + int id = prng_.Rand(1, kMaxNumProbes); + int bitrate_bps = prng_.Rand(0, kMaxBweBps); - const rtclog::BweProbeCluster& bwe_event = event.probe_cluster(); - ASSERT_TRUE(bwe_event.has_id()); - EXPECT_EQ(id, bwe_event.id()); - ASSERT_TRUE(bwe_event.has_bitrate_bps()); - EXPECT_EQ(bitrate_bps, bwe_event.bitrate_bps()); - ASSERT_TRUE(bwe_event.has_min_packets()); - EXPECT_EQ(min_probes, bwe_event.min_packets()); - ASSERT_TRUE(bwe_event.has_min_bytes()); - EXPECT_EQ(min_bytes, bwe_event.min_bytes()); - - // TODO(philipel): Verify the parser when parsing has been implemented. + return rtc::MakeUnique(id, bitrate_bps); } -void RtcEventLogTestHelper::VerifyProbeResultSuccess( - const ParsedRtcEventLogNew& parsed_log, - size_t index, - int32_t id, - int32_t bitrate_bps) { - ASSERT_LT(index, parsed_log.events_.size()); - const rtclog::Event& event = parsed_log.events_[index]; - ASSERT_TRUE(IsValidBasicEvent(event)); - EXPECT_EQ(rtclog::Event::BWE_PROBE_RESULT_EVENT, event.type()); +std::unique_ptr +EventGenerator::NewIceCandidatePairConfig() { + IceCandidateType local_candidate_type = static_cast( + prng_.Rand(static_cast(IceCandidateType::kNumValues) - 1)); + IceCandidateNetworkType local_network_type = + static_cast(prng_.Rand( + static_cast(IceCandidateNetworkType::kNumValues) - 1)); + IceCandidatePairAddressFamily local_address_family = + static_cast(prng_.Rand( + static_cast(IceCandidatePairAddressFamily::kNumValues) - + 1)); + IceCandidateType remote_candidate_type = static_cast( + prng_.Rand(static_cast(IceCandidateType::kNumValues) - 1)); + IceCandidatePairAddressFamily remote_address_family = + static_cast(prng_.Rand( + static_cast(IceCandidatePairAddressFamily::kNumValues) - + 1)); + IceCandidatePairProtocol protocol_type = + static_cast(prng_.Rand( + static_cast(IceCandidatePairProtocol::kNumValues) - 1)); - const rtclog::BweProbeResult& bwe_event = event.probe_result(); - ASSERT_TRUE(bwe_event.has_id()); - EXPECT_EQ(id, bwe_event.id()); - ASSERT_TRUE(bwe_event.has_bitrate_bps()); - EXPECT_EQ(bitrate_bps, bwe_event.bitrate_bps()); - ASSERT_TRUE(bwe_event.has_result()); - EXPECT_EQ(rtclog::BweProbeResult::SUCCESS, bwe_event.result()); + IceCandidatePairDescription desc; + desc.local_candidate_type = local_candidate_type; + desc.local_relay_protocol = protocol_type; + desc.local_network_type = local_network_type; + desc.local_address_family = local_address_family; + desc.remote_candidate_type = remote_candidate_type; + desc.remote_address_family = remote_address_family; + desc.candidate_pair_protocol = protocol_type; - // TODO(philipel): Verify the parser when parsing has been implemented. + IceCandidatePairConfigType type = + static_cast(prng_.Rand( + static_cast(IceCandidatePairConfigType::kNumValues) - 1)); + uint32_t pair_id = prng_.Rand(); + return rtc::MakeUnique(type, pair_id, desc); } -void RtcEventLogTestHelper::VerifyProbeResultFailure( - const ParsedRtcEventLogNew& parsed_log, - size_t index, - int32_t id, - ProbeFailureReason failure_reason) { - ASSERT_LT(index, parsed_log.events_.size()); - const rtclog::Event& event = parsed_log.events_[index]; - ASSERT_TRUE(IsValidBasicEvent(event)); - EXPECT_EQ(rtclog::Event::BWE_PROBE_RESULT_EVENT, event.type()); +std::unique_ptr +EventGenerator::NewIceCandidatePair() { + IceCandidatePairEventType type = + static_cast(prng_.Rand( + static_cast(IceCandidatePairEventType::kNumValues) - 1)); + uint32_t pair_id = prng_.Rand(); - const rtclog::BweProbeResult& bwe_event = event.probe_result(); - ASSERT_TRUE(bwe_event.has_id()); - EXPECT_EQ(id, bwe_event.id()); - ASSERT_TRUE(bwe_event.has_result()); - EXPECT_EQ(GetProbeResultType(failure_reason), bwe_event.result()); - ASSERT_FALSE(bwe_event.has_bitrate_bps()); - - // TODO(philipel): Verify the parser when parsing has been implemented. + return rtc::MakeUnique(type, pair_id); } +rtcp::ReportBlock EventGenerator::NewReportBlock() { + rtcp::ReportBlock report_block; + report_block.SetMediaSsrc(prng_.Rand()); + report_block.SetFractionLost(prng_.Rand()); + // cumulative_lost is a 3-byte signed value. + RTC_DCHECK(report_block.SetCumulativeLost( + prng_.Rand(-(1 << 23) + 1, (1 << 23) - 1))); + report_block.SetExtHighestSeqNum(prng_.Rand()); + report_block.SetJitter(prng_.Rand()); + report_block.SetLastSr(prng_.Rand()); + report_block.SetDelayLastSr(prng_.Rand()); + return report_block; +} + +rtcp::SenderReport EventGenerator::NewSenderReport() { + rtcp::SenderReport sender_report; + sender_report.SetSenderSsrc(prng_.Rand()); + sender_report.SetNtp(NtpTime(prng_.Rand(), prng_.Rand())); + sender_report.SetPacketCount(prng_.Rand()); + sender_report.AddReportBlock(NewReportBlock()); + return sender_report; +} + +rtcp::ReceiverReport EventGenerator::NewReceiverReport() { + rtcp::ReceiverReport receiver_report; + receiver_report.SetSenderSsrc(prng_.Rand()); + receiver_report.AddReportBlock(NewReportBlock()); + return receiver_report; +} + +std::unique_ptr +EventGenerator::NewRtcpPacketIncoming() { + // TODO(terelius): Test the other RTCP types too. + switch (prng_.Rand(0, 1)) { + case 0: { + rtcp::SenderReport sender_report = NewSenderReport(); + rtc::Buffer buffer = sender_report.Build(); + return rtc::MakeUnique(buffer); + } + case 1: { + rtcp::ReceiverReport receiver_report = NewReceiverReport(); + rtc::Buffer buffer = receiver_report.Build(); + return rtc::MakeUnique(buffer); + } + default: + RTC_NOTREACHED(); + } +} + +std::unique_ptr +EventGenerator::NewRtcpPacketOutgoing() { + // TODO(terelius): Test the other RTCP types too. + switch (prng_.Rand(0, 1)) { + case 0: { + rtcp::SenderReport sender_report = NewSenderReport(); + rtc::Buffer buffer = sender_report.Build(); + return rtc::MakeUnique(buffer); + } + case 1: { + rtcp::ReceiverReport receiver_report = NewReceiverReport(); + rtc::Buffer buffer = receiver_report.Build(); + return rtc::MakeUnique(buffer); + } + default: + RTC_NOTREACHED(); + } +} + +void EventGenerator::RandomizeRtpPacket( + size_t packet_size, + uint32_t ssrc, + const RtpHeaderExtensionMap& extension_map, + RtpPacket* rtp_packet) { + constexpr int kMaxPayloadType = 127; + rtp_packet->SetPayloadType(prng_.Rand(kMaxPayloadType)); + rtp_packet->SetMarker(prng_.Rand()); + rtp_packet->SetSequenceNumber(prng_.Rand()); + rtp_packet->SetSsrc(ssrc); + rtp_packet->SetTimestamp(prng_.Rand()); + + uint32_t csrcs_count = prng_.Rand(0, kMaxCsrcs); + std::vector csrcs; + for (size_t i = 0; i < csrcs_count; i++) { + csrcs.push_back(prng_.Rand()); + } + rtp_packet->SetCsrcs(csrcs); + + if (extension_map.IsRegistered(TransmissionOffset::kId)) + rtp_packet->SetExtension(prng_.Rand(0x00ffffff)); + if (extension_map.IsRegistered(AudioLevel::kId)) + rtp_packet->SetExtension(prng_.Rand(), prng_.Rand(127)); + if (extension_map.IsRegistered(AbsoluteSendTime::kId)) + rtp_packet->SetExtension(prng_.Rand(0x00ffffff)); + if (extension_map.IsRegistered(VideoOrientation::kId)) + rtp_packet->SetExtension(prng_.Rand(3)); + if (extension_map.IsRegistered(TransportSequenceNumber::kId)) + rtp_packet->SetExtension(prng_.Rand()); + + RTC_DCHECK_GE(packet_size, rtp_packet->headers_size()); + size_t payload_size = packet_size - rtp_packet->headers_size(); + RTC_CHECK_LE(rtp_packet->headers_size() + payload_size, IP_PACKET_SIZE); + uint8_t* payload = rtp_packet->AllocatePayload(payload_size); + RTC_DCHECK(payload != nullptr); + for (size_t i = 0; i < payload_size; i++) { + payload[i] = prng_.Rand(); + } +} + +std::unique_ptr EventGenerator::NewRtpPacketIncoming( + uint32_t ssrc, + const RtpHeaderExtensionMap& extension_map) { + // 12 bytes RTP header, 4 bytes for 0xBEDE + alignment, 4 bytes per CSRC. + constexpr size_t kMaxHeaderSize = + 16 + 4 * kMaxCsrcs + kMaxExtensionSizeBytes * kMaxNumExtensions; + size_t packet_size = + prng_.Rand(kMaxHeaderSize, static_cast(IP_PACKET_SIZE - 1)); + + RtpPacketReceived rtp_packet(&extension_map); + RandomizeRtpPacket(packet_size, ssrc, extension_map, &rtp_packet); + + return rtc::MakeUnique(rtp_packet); +} + +std::unique_ptr EventGenerator::NewRtpPacketOutgoing( + uint32_t ssrc, + const RtpHeaderExtensionMap& extension_map) { + // 12 bytes RTP header, 4 bytes for 0xBEDE + alignment, 4 bytes per CSRC. + constexpr size_t kMaxHeaderSize = + 16 + 4 * kMaxCsrcs + kMaxExtensionSizeBytes * kMaxNumExtensions; + size_t packet_size = + prng_.Rand(kMaxHeaderSize, static_cast(IP_PACKET_SIZE - 1)); + + RtpPacketToSend rtp_packet(&extension_map, packet_size); + RandomizeRtpPacket(packet_size, ssrc, extension_map, &rtp_packet); + + int probe_cluster_id = prng_.Rand(0, 100000); + return rtc::MakeUnique(rtp_packet, + probe_cluster_id); +} + +RtpHeaderExtensionMap EventGenerator::NewRtpHeaderExtensionMap() { + RtpHeaderExtensionMap extension_map; + RTC_DCHECK_EQ(RtpExtension::kMinId, 1); + std::vector id(RtpExtension::kMaxId); + iota(id.begin(), id.end(), 1); + ShuffleInPlace(&prng_, rtc::ArrayView(id)); + + if (prng_.Rand()) { + extension_map.Register(id[0]); + } + if (prng_.Rand()) { + extension_map.Register(id[1]); + } + if (prng_.Rand()) { + extension_map.Register(id[2]); + } + if (prng_.Rand()) { + extension_map.Register(id[3]); + } + if (prng_.Rand()) { + extension_map.Register(id[4]); + } + + return extension_map; +} + +std::unique_ptr +EventGenerator::NewAudioReceiveStreamConfig( + uint32_t ssrc, + const RtpHeaderExtensionMap& extensions) { + auto config = rtc::MakeUnique(); + // Add SSRCs for the stream. + config->remote_ssrc = ssrc; + config->local_ssrc = prng_.Rand(); + // Add header extensions. + for (size_t i = 0; i < kMaxNumExtensions; i++) { + uint8_t id = extensions.GetId(kExtensions[i].type); + if (id != RtpHeaderExtensionMap::kInvalidId) { + config->rtp_extensions.emplace_back(kExtensions[i].name, id); + } + } + + return rtc::MakeUnique(std::move(config)); +} + +std::unique_ptr +EventGenerator::NewAudioSendStreamConfig( + uint32_t ssrc, + const RtpHeaderExtensionMap& extensions) { + auto config = rtc::MakeUnique(); + // Add SSRC to the stream. + config->local_ssrc = ssrc; + // Add header extensions. + for (size_t i = 0; i < kMaxNumExtensions; i++) { + uint8_t id = extensions.GetId(kExtensions[i].type); + if (id != RtpHeaderExtensionMap::kInvalidId) { + config->rtp_extensions.emplace_back(kExtensions[i].name, id); + } + } + return rtc::MakeUnique(std::move(config)); +} + +std::unique_ptr +EventGenerator::NewVideoReceiveStreamConfig( + uint32_t ssrc, + const RtpHeaderExtensionMap& extensions) { + auto config = rtc::MakeUnique(); + + // Add SSRCs for the stream. + config->remote_ssrc = ssrc; + config->local_ssrc = prng_.Rand(); + // Add extensions and settings for RTCP. + config->rtcp_mode = + prng_.Rand() ? RtcpMode::kCompound : RtcpMode::kReducedSize; + config->remb = prng_.Rand(); + config->rtx_ssrc = prng_.Rand(); + config->codecs.emplace_back(prng_.Rand() ? "VP8" : "H264", + prng_.Rand(127), prng_.Rand(127)); + // Add header extensions. + for (size_t i = 0; i < kMaxNumExtensions; i++) { + uint8_t id = extensions.GetId(kExtensions[i].type); + if (id != RtpHeaderExtensionMap::kInvalidId) { + config->rtp_extensions.emplace_back(kExtensions[i].name, id); + } + } + return rtc::MakeUnique(std::move(config)); +} + +std::unique_ptr +EventGenerator::NewVideoSendStreamConfig( + uint32_t ssrc, + const RtpHeaderExtensionMap& extensions) { + auto config = rtc::MakeUnique(); + + config->codecs.emplace_back(prng_.Rand() ? "VP8" : "H264", + prng_.Rand(127), prng_.Rand(127)); + config->local_ssrc = ssrc; + config->rtx_ssrc = prng_.Rand(); + // Add header extensions. + for (size_t i = 0; i < kMaxNumExtensions; i++) { + uint8_t id = extensions.GetId(kExtensions[i].type); + if (id != RtpHeaderExtensionMap::kInvalidId) { + config->rtp_extensions.emplace_back(kExtensions[i].name, id); + } + } + return rtc::MakeUnique(std::move(config)); +} + +bool VerifyLoggedAlrStateEvent(const RtcEventAlrState& original_event, + const LoggedAlrStateEvent& logged_event) { + if (original_event.timestamp_us_ != logged_event.log_time_us()) + return false; + if (original_event.in_alr_ != logged_event.in_alr) + return false; + return true; +} + +bool VerifyLoggedAudioPlayoutEvent( + const RtcEventAudioPlayout& original_event, + const LoggedAudioPlayoutEvent& logged_event) { + if (original_event.timestamp_us_ != logged_event.log_time_us()) + return false; + if (original_event.ssrc_ != logged_event.ssrc) + return false; + return true; +} + +bool VerifyLoggedAudioNetworkAdaptationEvent( + const RtcEventAudioNetworkAdaptation& original_event, + const LoggedAudioNetworkAdaptationEvent& logged_event) { + if (original_event.timestamp_us_ != logged_event.log_time_us()) + return false; + + if (original_event.config_->bitrate_bps != logged_event.config.bitrate_bps) + return false; + if (original_event.config_->enable_dtx != logged_event.config.enable_dtx) + return false; + if (original_event.config_->enable_fec != logged_event.config.enable_fec) + return false; + if (original_event.config_->frame_length_ms != + logged_event.config.frame_length_ms) + return false; + if (original_event.config_->num_channels != logged_event.config.num_channels) + return false; + if (original_event.config_->uplink_packet_loss_fraction != + logged_event.config.uplink_packet_loss_fraction) + return false; + + return true; +} + +bool VerifyLoggedBweDelayBasedUpdate( + const RtcEventBweUpdateDelayBased& original_event, + const LoggedBweDelayBasedUpdate& logged_event) { + if (original_event.timestamp_us_ != logged_event.log_time_us()) + return false; + if (original_event.bitrate_bps_ != logged_event.bitrate_bps) + return false; + if (original_event.detector_state_ != logged_event.detector_state) + return false; + return true; +} + +bool VerifyLoggedBweLossBasedUpdate( + const RtcEventBweUpdateLossBased& original_event, + const LoggedBweLossBasedUpdate& logged_event) { + if (original_event.timestamp_us_ != logged_event.log_time_us()) + return false; + if (original_event.bitrate_bps_ != logged_event.bitrate_bps) + return false; + if (original_event.fraction_loss_ != logged_event.fraction_lost) + return false; + if (original_event.total_packets_ != logged_event.expected_packets) + return false; + return true; +} + +bool VerifyLoggedBweProbeClusterCreatedEvent( + const RtcEventProbeClusterCreated& original_event, + const LoggedBweProbeClusterCreatedEvent& logged_event) { + if (original_event.timestamp_us_ != logged_event.log_time_us()) + return false; + if (original_event.id_ != logged_event.id) + return false; + if (original_event.bitrate_bps_ != logged_event.bitrate_bps) + return false; + if (original_event.min_probes_ != logged_event.min_packets) + return false; + if (original_event.min_bytes_ != logged_event.min_bytes) + return false; + + return true; +} + +bool VerifyLoggedBweProbeFailureEvent( + const RtcEventProbeResultFailure& original_event, + const LoggedBweProbeFailureEvent& logged_event) { + if (original_event.timestamp_us_ != logged_event.log_time_us()) + return false; + if (original_event.id_ != logged_event.id) + return false; + if (original_event.failure_reason_ != logged_event.failure_reason) + return false; + return true; +} + +bool VerifyLoggedBweProbeSuccessEvent( + const RtcEventProbeResultSuccess& original_event, + const LoggedBweProbeSuccessEvent& logged_event) { + if (original_event.timestamp_us_ != logged_event.log_time_us()) + return false; + if (original_event.id_ != logged_event.id) + return false; + if (original_event.bitrate_bps_ != logged_event.bitrate_bps) + return false; + return true; +} + +bool VerifyLoggedIceCandidatePairConfig( + const RtcEventIceCandidatePairConfig& original_event, + const LoggedIceCandidatePairConfig& logged_event) { + if (original_event.timestamp_us_ != logged_event.log_time_us()) + return false; + + if (original_event.type_ != logged_event.type) + return false; + if (original_event.candidate_pair_id_ != logged_event.candidate_pair_id) + return false; + if (original_event.candidate_pair_desc_.local_candidate_type != + logged_event.local_candidate_type) + return false; + if (original_event.candidate_pair_desc_.local_relay_protocol != + logged_event.local_relay_protocol) + return false; + if (original_event.candidate_pair_desc_.local_network_type != + logged_event.local_network_type) + return false; + if (original_event.candidate_pair_desc_.local_address_family != + logged_event.local_address_family) + return false; + if (original_event.candidate_pair_desc_.remote_candidate_type != + logged_event.remote_candidate_type) + return false; + if (original_event.candidate_pair_desc_.remote_address_family != + logged_event.remote_address_family) + return false; + if (original_event.candidate_pair_desc_.candidate_pair_protocol != + logged_event.candidate_pair_protocol) + return false; + + return true; +} + +bool VerifyLoggedIceCandidatePairEvent( + const RtcEventIceCandidatePair& original_event, + const LoggedIceCandidatePairEvent& logged_event) { + if (original_event.timestamp_us_ != logged_event.log_time_us()) + return false; + + if (original_event.type_ != logged_event.type) + return false; + if (original_event.candidate_pair_id_ != logged_event.candidate_pair_id) + return false; + + return true; +} + +bool VerifyLoggedRtpHeader(const RtpPacket& original_header, + const RTPHeader& logged_header) { + // Standard RTP header. + if (original_header.Marker() != logged_header.markerBit) + return false; + if (original_header.PayloadType() != logged_header.payloadType) + return false; + if (original_header.SequenceNumber() != logged_header.sequenceNumber) + return false; + if (original_header.Timestamp() != logged_header.timestamp) + return false; + if (original_header.Ssrc() != logged_header.ssrc) + return false; + if (original_header.Csrcs().size() != logged_header.numCSRCs) + return false; + for (size_t i = 0; i < logged_header.numCSRCs; i++) { + if (original_header.Csrcs()[i] != logged_header.arrOfCSRCs[i]) + return false; + } + + if (original_header.padding_size() != logged_header.paddingLength) + return false; + if (original_header.headers_size() != logged_header.headerLength) + return false; + + // TransmissionOffset header extension. + if (original_header.HasExtension() != + logged_header.extension.hasTransmissionTimeOffset) + return false; + if (logged_header.extension.hasTransmissionTimeOffset) { + int32_t offset; + original_header.GetExtension(&offset); + if (offset != logged_header.extension.transmissionTimeOffset) + return false; + } + + // AbsoluteSendTime header extension. + if (original_header.HasExtension() != + logged_header.extension.hasAbsoluteSendTime) + return false; + if (logged_header.extension.hasAbsoluteSendTime) { + uint32_t sendtime; + original_header.GetExtension(&sendtime); + if (sendtime != logged_header.extension.absoluteSendTime) + return false; + } + + // TransportSequenceNumber header extension. + if (original_header.HasExtension() != + logged_header.extension.hasTransportSequenceNumber) + return false; + if (logged_header.extension.hasTransportSequenceNumber) { + uint16_t seqnum; + original_header.GetExtension(&seqnum); + if (seqnum != logged_header.extension.transportSequenceNumber) + return false; + } + + // AudioLevel header extension. + if (original_header.HasExtension() != + logged_header.extension.hasAudioLevel) + return false; + if (logged_header.extension.hasAudioLevel) { + bool voice_activity; + uint8_t audio_level; + original_header.GetExtension(&voice_activity, &audio_level); + if (voice_activity != logged_header.extension.voiceActivity) + return false; + if (audio_level != logged_header.extension.audioLevel) + return false; + } + + // VideoOrientation header extension. + if (original_header.HasExtension() != + logged_header.extension.hasVideoRotation) + return false; + if (logged_header.extension.hasVideoRotation) { + uint8_t rotation; + original_header.GetExtension(&rotation); + if (ConvertCVOByteToVideoRotation(rotation) != + logged_header.extension.videoRotation) + return false; + } + + return true; +} + +bool VerifyLoggedRtpPacketIncoming( + const RtcEventRtpPacketIncoming& original_event, + const LoggedRtpPacketIncoming& logged_event) { + if (original_event.timestamp_us_ != logged_event.log_time_us()) + return false; + + if (original_event.header_.headers_size() != logged_event.rtp.header_length) + return false; + + if (original_event.packet_length_ != logged_event.rtp.total_length) + return false; + + if (!VerifyLoggedRtpHeader(original_event.header_, logged_event.rtp.header)) + return false; + + return true; +} + +bool VerifyLoggedRtpPacketOutgoing( + const RtcEventRtpPacketOutgoing& original_event, + const LoggedRtpPacketOutgoing& logged_event) { + if (original_event.timestamp_us_ != logged_event.log_time_us()) + return false; + + if (original_event.header_.headers_size() != logged_event.rtp.header_length) + return false; + + if (original_event.packet_length_ != logged_event.rtp.total_length) + return false; + + // TODO(terelius): Probe cluster ID isn't parsed, used or tested. Unless + // someone has a strong reason to keep it, it'll be removed. + + if (!VerifyLoggedRtpHeader(original_event.header_, logged_event.rtp.header)) + return false; + + return true; +} + +bool VerifyLoggedRtcpPacketIncoming( + const RtcEventRtcpPacketIncoming& original_event, + const LoggedRtcpPacketIncoming& logged_event) { + if (original_event.timestamp_us_ != logged_event.log_time_us()) + return false; + + if (original_event.packet_.size() != logged_event.rtcp.raw_data.size()) + return false; + if (memcmp(original_event.packet_.data(), logged_event.rtcp.raw_data.data(), + original_event.packet_.size()) != 0) { + return false; + } + return true; +} + +bool VerifyLoggedRtcpPacketOutgoing( + const RtcEventRtcpPacketOutgoing& original_event, + const LoggedRtcpPacketOutgoing& logged_event) { + if (original_event.timestamp_us_ != logged_event.log_time_us()) + return false; + + if (original_event.packet_.size() != logged_event.rtcp.raw_data.size()) + return false; + if (memcmp(original_event.packet_.data(), logged_event.rtcp.raw_data.data(), + original_event.packet_.size()) != 0) { + return false; + } + return true; +} + +bool VerifyLoggedStartEvent(int64_t start_time_us, + const LoggedStartEvent& logged_event) { + if (start_time_us != logged_event.log_time_us()) + return false; + return true; +} + +bool VerifyLoggedStopEvent(int64_t stop_time_us, + const LoggedStopEvent& logged_event) { + if (stop_time_us != logged_event.log_time_us()) + return false; + return true; +} + +bool VerifyLoggedAudioRecvConfig( + const RtcEventAudioReceiveStreamConfig& original_event, + const LoggedAudioRecvConfig& logged_event) { + if (original_event.timestamp_us_ != logged_event.log_time_us()) + return false; + if (*original_event.config_ != logged_event.config) + return false; + return true; +} + +bool VerifyLoggedAudioSendConfig( + const RtcEventAudioSendStreamConfig& original_event, + const LoggedAudioSendConfig& logged_event) { + if (original_event.timestamp_us_ != logged_event.log_time_us()) + return false; + if (*original_event.config_ != logged_event.config) + return false; + return true; +} + +bool VerifyLoggedVideoRecvConfig( + const RtcEventVideoReceiveStreamConfig& original_event, + const LoggedVideoRecvConfig& logged_event) { + if (original_event.timestamp_us_ != logged_event.log_time_us()) + return false; + if (*original_event.config_ != logged_event.config) + return false; + return true; +} + +bool VerifyLoggedVideoSendConfig( + const RtcEventVideoSendStreamConfig& original_event, + const LoggedVideoSendConfig& logged_event) { + if (original_event.timestamp_us_ != logged_event.log_time_us()) + return false; + // TODO(terelius): In the past, we allowed storing multiple RtcStreamConfigs + // in the same RtcEventVideoSendStreamConfig. Look into whether we should drop + // backwards compatibility in the parser. + if (logged_event.configs.size() != 1) + return false; + if (*original_event.config_ != logged_event.configs[0]) + return false; + return true; +} + +} // namespace test } // namespace webrtc diff --git a/logging/rtc_event_log/rtc_event_log_unittest_helper.h b/logging/rtc_event_log/rtc_event_log_unittest_helper.h index d06a7d007f..d67469c0ff 100644 --- a/logging/rtc_event_log/rtc_event_log_unittest_helper.h +++ b/logging/rtc_event_log/rtc_event_log_unittest_helper.h @@ -11,83 +11,180 @@ #ifndef LOGGING_RTC_EVENT_LOG_RTC_EVENT_LOG_UNITTEST_HELPER_H_ #define LOGGING_RTC_EVENT_LOG_RTC_EVENT_LOG_UNITTEST_HELPER_H_ -#include "call/call.h" +#include + +#include "logging/rtc_event_log/events/rtc_event.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" +#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_ice_candidate_pair.h" +#include "logging/rtc_event_log/events/rtc_event_ice_candidate_pair_config.h" +#include "logging/rtc_event_log/events/rtc_event_probe_cluster_created.h" +#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_new.h" -#include "modules/rtp_rtcp/source/rtp_packet_received.h" -#include "modules/rtp_rtcp/source/rtp_packet_to_send.h" +#include "modules/rtp_rtcp/source/rtcp_packet/receiver_report.h" +#include "modules/rtp_rtcp/source/rtcp_packet/report_block.h" +#include "modules/rtp_rtcp/source/rtcp_packet/sender_report.h" +#include "rtc_base/random.h" namespace webrtc { -class RtcEventLogTestHelper { +namespace test { + +class EventGenerator { public: - static void VerifyVideoReceiveStreamConfig( - const ParsedRtcEventLogNew& parsed_log, - size_t index, - const rtclog::StreamConfig& config); - static void VerifyVideoSendStreamConfig( - const ParsedRtcEventLogNew& parsed_log, - size_t index, - const rtclog::StreamConfig& config); - static void VerifyAudioReceiveStreamConfig( - const ParsedRtcEventLogNew& parsed_log, - size_t index, - const rtclog::StreamConfig& config); - static void VerifyAudioSendStreamConfig( - const ParsedRtcEventLogNew& parsed_log, - size_t index, - const rtclog::StreamConfig& config); - static void VerifyIncomingRtpEvent(const ParsedRtcEventLogNew& parsed_log, - size_t index, - const RtpPacketReceived& expected_packet); - static void VerifyOutgoingRtpEvent(const ParsedRtcEventLogNew& parsed_log, - size_t index, - const RtpPacketToSend& expected_packet); - static void VerifyRtcpEvent(const ParsedRtcEventLogNew& parsed_log, - size_t index, - PacketDirection direction, - const uint8_t* packet, - size_t total_size); - static void VerifyPlayoutEvent(const ParsedRtcEventLogNew& parsed_log, - size_t index, - uint32_t ssrc); - static void VerifyBweLossEvent(const ParsedRtcEventLogNew& parsed_log, - size_t index, - int32_t bitrate, - uint8_t fraction_loss, - int32_t total_packets); - static void VerifyBweDelayEvent(const ParsedRtcEventLogNew& parsed_log, - size_t index, - int32_t bitrate, - BandwidthUsage detector_state); + explicit EventGenerator(uint64_t seed) : prng_(seed) {} - static void VerifyAudioNetworkAdaptation( - const ParsedRtcEventLogNew& parsed_log, - size_t index, - const AudioEncoderRuntimeConfig& config); + std::unique_ptr NewAlrState(); - static void VerifyLogStartEvent(const ParsedRtcEventLogNew& parsed_log, - size_t index); - static void VerifyLogEndEvent(const ParsedRtcEventLogNew& parsed_log, - size_t index); + std::unique_ptr NewAudioPlayout(uint32_t ssrc); - static void VerifyBweProbeCluster(const ParsedRtcEventLogNew& parsed_log, - size_t index, - int32_t id, - int32_t bitrate_bps, - uint32_t min_probes, - uint32_t min_bytes); + std::unique_ptr NewAudioNetworkAdaptation(); - static void VerifyProbeResultSuccess(const ParsedRtcEventLogNew& parsed_log, - size_t index, - int32_t id, - int32_t bitrate_bps); + std::unique_ptr NewBweUpdateDelayBased(); - static void VerifyProbeResultFailure(const ParsedRtcEventLogNew& parsed_log, - size_t index, - int32_t id, - ProbeFailureReason failure_reason); + std::unique_ptr NewBweUpdateLossBased(); + + std::unique_ptr NewProbeClusterCreated(); + + std::unique_ptr NewProbeResultFailure(); + + std::unique_ptr NewProbeResultSuccess(); + + std::unique_ptr NewIceCandidatePairConfig(); + + std::unique_ptr NewIceCandidatePair(); + + std::unique_ptr NewRtcpPacketIncoming(); + + std::unique_ptr NewRtcpPacketOutgoing(); + + void RandomizeRtpPacket(size_t packet_size, + uint32_t ssrc, + const RtpHeaderExtensionMap& extension_map, + RtpPacket* rtp_packet); + + std::unique_ptr NewRtpPacketIncoming( + uint32_t ssrc, + const RtpHeaderExtensionMap& extension_map); + + std::unique_ptr NewRtpPacketOutgoing( + uint32_t ssrc, + const RtpHeaderExtensionMap& extension_map); + + RtpHeaderExtensionMap NewRtpHeaderExtensionMap(); + + std::unique_ptr NewAudioReceiveStreamConfig( + uint32_t ssrc, + const RtpHeaderExtensionMap& extensions); + + std::unique_ptr NewAudioSendStreamConfig( + uint32_t ssrc, + const RtpHeaderExtensionMap& extensions); + + std::unique_ptr NewVideoReceiveStreamConfig( + uint32_t ssrc, + const RtpHeaderExtensionMap& extensions); + + std::unique_ptr NewVideoSendStreamConfig( + uint32_t ssrc, + const RtpHeaderExtensionMap& extensions); + + private: + rtcp::ReportBlock NewReportBlock(); + rtcp::SenderReport NewSenderReport(); + rtcp::ReceiverReport NewReceiverReport(); + + Random prng_; }; +bool VerifyLoggedAlrStateEvent(const RtcEventAlrState& original_event, + const LoggedAlrStateEvent& logged_event); + +bool VerifyLoggedAudioPlayoutEvent(const RtcEventAudioPlayout& original_event, + const LoggedAudioPlayoutEvent& logged_event); + +bool VerifyLoggedAudioNetworkAdaptationEvent( + const RtcEventAudioNetworkAdaptation& original_event, + const LoggedAudioNetworkAdaptationEvent& logged_event); + +bool VerifyLoggedBweDelayBasedUpdate( + const RtcEventBweUpdateDelayBased& original_event, + const LoggedBweDelayBasedUpdate& logged_event); + +bool VerifyLoggedBweLossBasedUpdate( + const RtcEventBweUpdateLossBased& original_event, + const LoggedBweLossBasedUpdate& logged_event); + +bool VerifyLoggedBweProbeClusterCreatedEvent( + const RtcEventProbeClusterCreated& original_event, + const LoggedBweProbeClusterCreatedEvent& logged_event); + +bool VerifyLoggedBweProbeFailureEvent( + const RtcEventProbeResultFailure& original_event, + const LoggedBweProbeFailureEvent& logged_event); + +bool VerifyLoggedBweProbeSuccessEvent( + const RtcEventProbeResultSuccess& original_event, + const LoggedBweProbeSuccessEvent& logged_event); + +bool VerifyLoggedIceCandidatePairConfig( + const RtcEventIceCandidatePairConfig& original_event, + const LoggedIceCandidatePairConfig& logged_event); + +bool VerifyLoggedIceCandidatePairEvent( + const RtcEventIceCandidatePair& original_event, + const LoggedIceCandidatePairEvent& logged_event); + +bool VerifyLoggedRtpPacketIncoming( + const RtcEventRtpPacketIncoming& original_event, + const LoggedRtpPacketIncoming& logged_event); + +bool VerifyLoggedRtpPacketOutgoing( + const RtcEventRtpPacketOutgoing& original_event, + const LoggedRtpPacketOutgoing& logged_event); + +bool VerifyLoggedRtcpPacketIncoming( + const RtcEventRtcpPacketIncoming& original_event, + const LoggedRtcpPacketIncoming& logged_event); + +bool VerifyLoggedRtcpPacketOutgoing( + const RtcEventRtcpPacketOutgoing& original_event, + const LoggedRtcpPacketOutgoing& logged_event); + +bool VerifyLoggedStartEvent(int64_t start_time_us, + const LoggedStartEvent& logged_event); +bool VerifyLoggedStopEvent(int64_t stop_time_us, + const LoggedStopEvent& logged_event); + +bool VerifyLoggedAudioRecvConfig( + const RtcEventAudioReceiveStreamConfig& original_event, + const LoggedAudioRecvConfig& logged_event); + +bool VerifyLoggedAudioSendConfig( + const RtcEventAudioSendStreamConfig& original_event, + const LoggedAudioSendConfig& logged_event); + +bool VerifyLoggedVideoRecvConfig( + const RtcEventVideoReceiveStreamConfig& original_event, + const LoggedVideoRecvConfig& logged_event); + +bool VerifyLoggedVideoSendConfig( + const RtcEventVideoSendStreamConfig& original_event, + const LoggedVideoSendConfig& logged_event); + +} // namespace test } // namespace webrtc #endif // LOGGING_RTC_EVENT_LOG_RTC_EVENT_LOG_UNITTEST_HELPER_H_ diff --git a/logging/rtc_event_log/rtc_stream_config.cc b/logging/rtc_event_log/rtc_stream_config.cc index 56c8c813ed..d4d30d00bc 100644 --- a/logging/rtc_event_log/rtc_stream_config.cc +++ b/logging/rtc_event_log/rtc_stream_config.cc @@ -17,6 +17,8 @@ StreamConfig::StreamConfig() {} StreamConfig::~StreamConfig() {} +StreamConfig::StreamConfig(const StreamConfig& other) = default; + 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 && @@ -24,6 +26,10 @@ bool StreamConfig::operator==(const StreamConfig& other) const { rtp_extensions == other.rtp_extensions && codecs == other.codecs; } +bool StreamConfig::operator!=(const StreamConfig& other) const { + return !(*this == other); +} + StreamConfig::Codec::Codec(const std::string& payload_name, int payload_type, int rtx_payload_type) diff --git a/logging/rtc_event_log/rtc_stream_config.h b/logging/rtc_event_log/rtc_stream_config.h index 771ba66c6a..d95c8359ec 100644 --- a/logging/rtc_event_log/rtc_stream_config.h +++ b/logging/rtc_event_log/rtc_stream_config.h @@ -23,9 +23,11 @@ namespace rtclog { struct StreamConfig { StreamConfig(); + StreamConfig(const StreamConfig& other); ~StreamConfig(); bool operator==(const StreamConfig& other) const; + bool operator!=(const StreamConfig& other) const; uint32_t local_ssrc = 0; uint32_t remote_ssrc = 0;