From 440216fcf38522f52c82d2cc4f7c46b0e98fc521 Mon Sep 17 00:00:00 2001 From: Bjorn Terelius Date: Fri, 29 Sep 2017 21:01:42 +0200 Subject: [PATCH] Split LogRtpHeader and LogRtcpPacket into separate versions for incoming and outgoing packets. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change LogIncomingRtcpPacket and LogOutgoingRtcpPacket to take ArrayView. Split LogSessionAndReadBack into three functions and create class to share state between them. Split VerifyRtpEvent into one incoming and one outgoing version. Originally uploaded as https://codereview.webrtc.org/2997973002/ Bug: webrtc:8111 Change-Id: I22bdc35163bef60bc8293679226b19e41e8f49b3 Reviewed-on: https://webrtc-review.googlesource.com/5020 Reviewed-by: Fredrik Solenberg Reviewed-by: Danil Chapovalov Reviewed-by: Elad Alon Commit-Queue: Björn Terelius Cr-Commit-Position: refs/heads/master@{#20063} --- call/call.cc | 6 +- logging/BUILD.gn | 1 + .../rtc_event_log/mock/mock_rtc_event_log.h | 23 +- logging/rtc_event_log/rtc_event_log.cc | 33 + logging/rtc_event_log/rtc_event_log.h | 58 +- .../rtc_event_log/rtc_event_log_unittest.cc | 764 ++++++++++++------ .../rtc_event_log_unittest_helper.cc | 61 +- .../rtc_event_log_unittest_helper.h | 14 +- modules/rtp_rtcp/source/rtcp_sender.cc | 6 +- modules/rtp_rtcp/source/rtp_sender.cc | 3 +- .../rtp_rtcp/source/rtp_sender_unittest.cc | 32 +- voice_engine/channel.cc | 38 +- 12 files changed, 685 insertions(+), 354 deletions(-) diff --git a/call/call.cc b/call/call.cc index 1bfde2e692..8bfab8a493 100644 --- a/call/call.cc +++ b/call/call.cc @@ -1303,7 +1303,7 @@ PacketReceiver::DeliveryStatus Call::DeliverRtcp(MediaType media_type, } if (rtcp_delivered) - event_log_->LogRtcpPacket(kIncomingPacket, packet, length); + event_log_->LogIncomingRtcpPacket(rtc::MakeArrayView(packet, length)); return rtcp_delivered ? DELIVERY_OK : DELIVERY_PACKET_ERROR; } @@ -1352,7 +1352,7 @@ PacketReceiver::DeliveryStatus Call::DeliverRtp(MediaType media_type, if (audio_receiver_controller_.OnRtpPacket(*parsed_packet)) { received_bytes_per_second_counter_.Add(static_cast(length)); received_audio_bytes_per_second_counter_.Add(static_cast(length)); - event_log_->LogRtpHeader(kIncomingPacket, packet, length); + event_log_->LogIncomingRtpHeader(*parsed_packet); const int64_t arrival_time_ms = parsed_packet->arrival_time_ms(); if (!first_received_rtp_audio_ms_) { first_received_rtp_audio_ms_.emplace(arrival_time_ms); @@ -1364,7 +1364,7 @@ PacketReceiver::DeliveryStatus Call::DeliverRtp(MediaType media_type, if (video_receiver_controller_.OnRtpPacket(*parsed_packet)) { received_bytes_per_second_counter_.Add(static_cast(length)); received_video_bytes_per_second_counter_.Add(static_cast(length)); - event_log_->LogRtpHeader(kIncomingPacket, packet, length); + event_log_->LogIncomingRtpHeader(*parsed_packet); const int64_t arrival_time_ms = parsed_packet->arrival_time_ms(); if (!first_received_rtp_video_ms_) { first_received_rtp_video_ms_.emplace(arrival_time_ms); diff --git a/logging/BUILD.gn b/logging/BUILD.gn index dc5f8adee4..eb4cec277c 100644 --- a/logging/BUILD.gn +++ b/logging/BUILD.gn @@ -31,6 +31,7 @@ rtc_source_set("rtc_event_log_api") { ] deps = [ "..:webrtc_common", + "../api:array_view", "../api:libjingle_peerconnection_api", "../call:video_stream_api", "../rtc_base:rtc_base_approved", diff --git a/logging/rtc_event_log/mock/mock_rtc_event_log.h b/logging/rtc_event_log/mock/mock_rtc_event_log.h index eb0d9b9596..d84a39e5be 100644 --- a/logging/rtc_event_log/mock/mock_rtc_event_log.h +++ b/logging/rtc_event_log/mock/mock_rtc_event_log.h @@ -16,6 +16,8 @@ #include "logging/rtc_event_log/rtc_event_log.h" #include "logging/rtc_event_log/rtc_stream_config.h" #include "modules/audio_coding/audio_network_adaptor/include/audio_network_adaptor.h" +#include "modules/rtp_rtcp/source/rtp_packet_received.h" +#include "modules/rtp_rtcp/source/rtp_packet_to_send.h" #include "test/gmock.h" namespace webrtc { @@ -42,21 +44,16 @@ class MockRtcEventLog : public RtcEventLog { MOCK_METHOD1(LogAudioSendStreamConfig, void(const rtclog::StreamConfig& config)); - MOCK_METHOD3(LogRtpHeader, - void(PacketDirection direction, - const uint8_t* header, - size_t packet_length)); + MOCK_METHOD1(LogIncomingRtpHeader, void(const RtpPacketReceived& packet)); - MOCK_METHOD4(LogRtpHeader, - void(PacketDirection direction, - const uint8_t* header, - size_t packet_length, - int probe_cluster_id)); + MOCK_METHOD2(LogOutgoingRtpHeader, + void(const RtpPacketToSend& packet, int probe_cluster_id)); - MOCK_METHOD3(LogRtcpPacket, - void(PacketDirection direction, - const uint8_t* packet, - size_t length)); + MOCK_METHOD1(LogIncomingRtcpPacket, + void(rtc::ArrayView packet)); + + MOCK_METHOD1(LogOutgoingRtcpPacket, + void(rtc::ArrayView packet)); MOCK_METHOD1(LogAudioPlayout, void(uint32_t ssrc)); diff --git a/logging/rtc_event_log/rtc_event_log.cc b/logging/rtc_event_log/rtc_event_log.cc index c6d67f21e1..5cb398da9f 100644 --- a/logging/rtc_event_log/rtc_event_log.cc +++ b/logging/rtc_event_log/rtc_event_log.cc @@ -33,6 +33,8 @@ #include "modules/rtp_rtcp/source/rtcp_packet/rtpfb.h" #include "modules/rtp_rtcp/source/rtcp_packet/sdes.h" #include "modules/rtp_rtcp/source/rtcp_packet/sender_report.h" +#include "modules/rtp_rtcp/source/rtp_packet_received.h" +#include "modules/rtp_rtcp/source/rtp_packet_to_send.h" #include "rtc_base/checks.h" #include "rtc_base/constructormagic.h" #include "rtc_base/event.h" @@ -112,16 +114,27 @@ class RtcEventLogImpl final : public RtcEventLog { void LogVideoSendStreamConfig(const rtclog::StreamConfig& config) override; void LogAudioReceiveStreamConfig(const rtclog::StreamConfig& config) override; void LogAudioSendStreamConfig(const rtclog::StreamConfig& config) override; + // TODO(terelius): This can be removed as soon as the interface has been + // updated. void LogRtpHeader(PacketDirection direction, const uint8_t* header, size_t packet_length) override; + // TODO(terelius): This can be made private, non-virtual as soon as the + // interface has been updated. void LogRtpHeader(PacketDirection direction, const uint8_t* header, size_t packet_length, int probe_cluster_id) override; + void LogIncomingRtpHeader(const RtpPacketReceived& packet) override; + void LogOutgoingRtpHeader(const RtpPacketToSend& packet, + int probe_cluster_id) override; + // TODO(terelius): This can be made private, non-virtual as soon as the + // interface has been updated. void LogRtcpPacket(PacketDirection direction, const uint8_t* packet, size_t length) override; + void LogIncomingRtcpPacket(rtc::ArrayView packet) override; + void LogOutgoingRtcpPacket(rtc::ArrayView packet) override; void LogAudioPlayout(uint32_t ssrc) override; void LogLossBasedBweUpdate(int32_t bitrate_bps, uint8_t fraction_loss, @@ -418,6 +431,16 @@ void RtcEventLogImpl::LogAudioSendStreamConfig( StoreEvent(std::move(event)); } +void RtcEventLogImpl::LogIncomingRtpHeader(const RtpPacketReceived& packet) { + LogRtpHeader(kIncomingPacket, packet.data(), packet.size(), + PacedPacketInfo::kNotAProbe); +} + +void RtcEventLogImpl::LogOutgoingRtpHeader(const RtpPacketToSend& packet, + int probe_cluster_id) { + LogRtpHeader(kOutgoingPacket, packet.data(), packet.size(), probe_cluster_id); +} + void RtcEventLogImpl::LogRtpHeader(PacketDirection direction, const uint8_t* header, size_t packet_length) { @@ -455,6 +478,16 @@ void RtcEventLogImpl::LogRtpHeader(PacketDirection direction, StoreEvent(std::move(rtp_event)); } +void RtcEventLogImpl::LogIncomingRtcpPacket( + rtc::ArrayView packet) { + LogRtcpPacket(kIncomingPacket, packet.data(), packet.size()); +} + +void RtcEventLogImpl::LogOutgoingRtcpPacket( + rtc::ArrayView packet) { + LogRtcpPacket(kOutgoingPacket, packet.data(), packet.size()); +} + void RtcEventLogImpl::LogRtcpPacket(PacketDirection direction, const uint8_t* packet, size_t length) { diff --git a/logging/rtc_event_log/rtc_event_log.h b/logging/rtc_event_log/rtc_event_log.h index b5336007d2..31caa447cd 100644 --- a/logging/rtc_event_log/rtc_event_log.h +++ b/logging/rtc_event_log/rtc_event_log.h @@ -15,6 +15,7 @@ #include #include +#include "api/array_view.h" // TODO(eladalon): Get rid of this later in the CL-stack. #include "api/rtpparameters.h" #include "common_types.h" // NOLINT(build/include) @@ -30,6 +31,8 @@ struct StreamConfig; class Clock; struct AudioEncoderRuntimeConfig; +class RtpPacketReceived; +class RtpPacketToSend; enum class MediaType; enum class BandwidthUsage; @@ -49,7 +52,7 @@ class RtcEventLog { static std::unique_ptr Create(); // TODO(nisse): webrtc::Clock is deprecated. Delete this method and // above forward declaration of Clock when - // webrtc/system_wrappers/include/clock.h is deleted. + // system_wrappers/include/clock.h is deleted. static std::unique_ptr Create(const Clock* clock) { return Create(); } @@ -98,23 +101,33 @@ class RtcEventLog { // Logs configuration information for an audio send stream. virtual void LogAudioSendStreamConfig(const rtclog::StreamConfig& config) = 0; - // Logs the header of an incoming or outgoing RTP packet. packet_length + RTC_DEPRECATED virtual void LogRtpHeader(PacketDirection direction, + const uint8_t* header, + size_t packet_length) {} + + RTC_DEPRECATED virtual void LogRtpHeader(PacketDirection direction, + const uint8_t* header, + size_t packet_length, + int probe_cluster_id) {} + + // Logs the header of an incoming RTP packet. |packet_length| // is the total length of the packet, including both header and payload. - virtual void LogRtpHeader(PacketDirection direction, - const uint8_t* header, - size_t packet_length) = 0; + virtual void LogIncomingRtpHeader(const RtpPacketReceived& packet) = 0; - // Same as above but used on the sender side to log packets that are part of - // a probe cluster. - virtual void LogRtpHeader(PacketDirection direction, - const uint8_t* header, - size_t packet_length, - int probe_cluster_id) = 0; + // Logs the header of an incoming RTP packet. |packet_length| + // is the total length of the packet, including both header and payload. + virtual void LogOutgoingRtpHeader(const RtpPacketToSend& packet, + int probe_cluster_id) = 0; - // Logs an incoming or outgoing RTCP packet. - virtual void LogRtcpPacket(PacketDirection direction, - const uint8_t* packet, - size_t length) = 0; + RTC_DEPRECATED virtual void LogRtcpPacket(PacketDirection direction, + const uint8_t* header, + size_t packet_length) {} + + // Logs an incoming RTCP packet. + virtual void LogIncomingRtcpPacket(rtc::ArrayView packet) = 0; + + // Logs an outgoing RTCP packet. + virtual void LogOutgoingRtcpPacket(rtc::ArrayView packet) = 0; // Logs an audio playout event. virtual void LogAudioPlayout(uint32_t ssrc) = 0; @@ -164,16 +177,11 @@ class RtcEventLogNullImpl : public RtcEventLog { void LogAudioReceiveStreamConfig( const rtclog::StreamConfig& config) override {} void LogAudioSendStreamConfig(const rtclog::StreamConfig& config) override {} - void LogRtpHeader(PacketDirection direction, - const uint8_t* header, - size_t packet_length) override {} - void LogRtpHeader(PacketDirection direction, - const uint8_t* header, - size_t packet_length, - int probe_cluster_id) override {} - void LogRtcpPacket(PacketDirection direction, - const uint8_t* packet, - size_t length) override {} + void LogIncomingRtpHeader(const RtpPacketReceived& packet) override {} + void LogOutgoingRtpHeader(const RtpPacketToSend& packet, + int probe_cluster_id) override {} + void LogIncomingRtcpPacket(rtc::ArrayView packet) override {} + void LogOutgoingRtcpPacket(rtc::ArrayView packet) override {} void LogAudioPlayout(uint32_t ssrc) override {} void LogLossBasedBweUpdate(int32_t bitrate_bps, uint8_t fraction_loss, diff --git a/logging/rtc_event_log/rtc_event_log_unittest.cc b/logging/rtc_event_log/rtc_event_log_unittest.cc index 7624420ede..99e3e7eeab 100644 --- a/logging/rtc_event_log/rtc_event_log_unittest.cc +++ b/logging/rtc_event_log/rtc_event_log_unittest.cc @@ -10,6 +10,7 @@ #include #include +#include #include #include #include @@ -25,10 +26,12 @@ #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" #include "rtc_base/random.h" #include "test/gtest.h" #include "test/testsupport/fileutils.h" @@ -44,72 +47,105 @@ 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; + +const uint8_t kExtensionIds[] = { + kTransmissionTimeOffsetExtensionId, kAbsoluteSendTimeExtensionId, + kTransportSequenceNumberExtensionId, kAudioLevelExtensionId, + kVideoRotationExtensionId}; const RTPExtensionType kExtensionTypes[] = { RTPExtensionType::kRtpExtensionTransmissionTimeOffset, - RTPExtensionType::kRtpExtensionAudioLevel, RTPExtensionType::kRtpExtensionAbsoluteSendTime, - RTPExtensionType::kRtpExtensionVideoRotation, - RTPExtensionType::kRtpExtensionTransportSequenceNumber}; + RTPExtensionType::kRtpExtensionTransportSequenceNumber, + RTPExtensionType::kRtpExtensionAudioLevel, + RTPExtensionType::kRtpExtensionVideoRotation}; const char* kExtensionNames[] = { - RtpExtension::kTimestampOffsetUri, RtpExtension::kAudioLevelUri, - RtpExtension::kAbsSendTimeUri, RtpExtension::kVideoRotationUri, - RtpExtension::kTransportSequenceNumberUri}; + RtpExtension::kTimestampOffsetUri, RtpExtension::kAbsSendTimeUri, + RtpExtension::kTransportSequenceNumberUri, RtpExtension::kAudioLevelUri, + RtpExtension::kVideoRotationUri}; + const size_t kNumExtensions = 5; -void PrintActualEvents(const ParsedRtcEventLog& parsed_log) { - std::map actual_event_counts; - for (size_t i = 0; i < parsed_log.GetNumberOfEvents(); i++) { - actual_event_counts[parsed_log.GetEventType(i)]++; - } - printf("Actual events: "); - for (auto kv : actual_event_counts) { - printf("%d_count = %zu, ", kv.first, kv.second); - } - printf("\n"); - for (size_t i = 0; i < parsed_log.GetNumberOfEvents(); i++) { - printf("%4d ", parsed_log.GetEventType(i)); - } - printf("\n"); -} +struct BweLossEvent { + int32_t bitrate_bps; + uint8_t fraction_loss; + int32_t total_packets; +}; -void PrintExpectedEvents(size_t rtp_count, - size_t rtcp_count, - size_t playout_count, - size_t bwe_loss_count) { - printf( - "Expected events: rtp_count = %zu, rtcp_count = %zu," - "playout_count = %zu, bwe_loss_count = %zu\n", - rtp_count, rtcp_count, playout_count, bwe_loss_count); - size_t rtcp_index = 1, playout_index = 1, bwe_loss_index = 1; - printf("strt cfg cfg "); - for (size_t i = 1; i <= rtp_count; i++) { - printf(" rtp "); - if (i * rtcp_count >= rtcp_index * rtp_count) { - printf("rtcp "); - rtcp_index++; - } - if (i * playout_count >= playout_index * rtp_count) { - printf("play "); - playout_index++; - } - if (i * bwe_loss_count >= bwe_loss_index * rtp_count) { - printf("loss "); - bwe_loss_index++; - } - } - printf("end \n"); -} +// 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( + {{ParsedRtcEventLog::EventType::UNKNOWN_EVENT, "UNKNOWN_EVENT"}, + {ParsedRtcEventLog::EventType::LOG_START, "LOG_START"}, + {ParsedRtcEventLog::EventType::LOG_END, "LOG_END"}, + {ParsedRtcEventLog::EventType::RTP_EVENT, "RTP"}, + {ParsedRtcEventLog::EventType::RTCP_EVENT, "RTCP"}, + {ParsedRtcEventLog::EventType::AUDIO_PLAYOUT_EVENT, "AUDIO_PLAYOUT"}, + {ParsedRtcEventLog::EventType::LOSS_BASED_BWE_UPDATE, + "LOSS_BASED_BWE_UPDATE"}, + {ParsedRtcEventLog::EventType::DELAY_BASED_BWE_UPDATE, + "DELAY_BASED_BWE_UPDATE"}, + {ParsedRtcEventLog::EventType::VIDEO_RECEIVER_CONFIG_EVENT, + "VIDEO_RECV_CONFIG"}, + {ParsedRtcEventLog::EventType::VIDEO_SENDER_CONFIG_EVENT, + "VIDEO_SEND_CONFIG"}, + {ParsedRtcEventLog::EventType::AUDIO_RECEIVER_CONFIG_EVENT, + "AUDIO_RECV_CONFIG"}, + {ParsedRtcEventLog::EventType::AUDIO_SENDER_CONFIG_EVENT, + "AUDIO_SEND_CONFIG"}, + {ParsedRtcEventLog::EventType::AUDIO_NETWORK_ADAPTATION_EVENT, + "AUDIO_NETWORK_ADAPTATION"}, + {ParsedRtcEventLog::EventType::BWE_PROBE_CLUSTER_CREATED_EVENT, + "BWE_PROBE_CREATED"}, + {ParsedRtcEventLog::EventType::BWE_PROBE_RESULT_EVENT, + "BWE_PROBE_RESULT"}}); } // namespace -/* - * Bit number i of extension_bitvector is set to indicate the - * presence of extension number i from kExtensionTypes / kExtensionNames. - * The least significant bit extension_bitvector has number 0. - */ -RtpPacketToSend GenerateRtpPacket(const RtpHeaderExtensionMap* extensions, - uint32_t csrcs_count, - size_t packet_size, - Random* prng) { +void PrintActualEvents(const ParsedRtcEventLog& 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; @@ -139,6 +175,18 @@ RtpPacketToSend GenerateRtpPacket(const RtpHeaderExtensionMap* extensions, 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. @@ -153,7 +201,7 @@ rtc::Buffer GenerateRtcpPacket(Random* prng) { return sender_report.Build(); } -void GenerateVideoReceiveConfig(uint32_t extensions_bitvector, +void GenerateVideoReceiveConfig(const RtpHeaderExtensionMap& extensions, rtclog::StreamConfig* config, Random* prng) { // Add SSRCs for the stream. @@ -168,14 +216,14 @@ void GenerateVideoReceiveConfig(uint32_t extensions_bitvector, prng->Rand(1, 127), prng->Rand(1, 127)); // Add header extensions. for (unsigned i = 0; i < kNumExtensions; i++) { - if (extensions_bitvector & (1u << i)) { - config->rtp_extensions.emplace_back(kExtensionNames[i], - prng->Rand()); + uint8_t id = extensions.GetId(kExtensionTypes[i]); + if (id != RtpHeaderExtensionMap::kInvalidId) { + config->rtp_extensions.emplace_back(kExtensionNames[i], id); } } } -void GenerateVideoSendConfig(uint32_t extensions_bitvector, +void GenerateVideoSendConfig(const RtpHeaderExtensionMap& extensions, rtclog::StreamConfig* config, Random* prng) { config->codecs.emplace_back(prng->Rand() ? "VP8" : "H264", @@ -184,14 +232,14 @@ void GenerateVideoSendConfig(uint32_t extensions_bitvector, config->rtx_ssrc = prng->Rand(); // Add header extensions. for (unsigned i = 0; i < kNumExtensions; i++) { - if (extensions_bitvector & (1u << i)) { - config->rtp_extensions.push_back( - RtpExtension(kExtensionNames[i], prng->Rand())); + uint8_t id = extensions.GetId(kExtensionTypes[i]); + if (id != RtpHeaderExtensionMap::kInvalidId) { + config->rtp_extensions.emplace_back(kExtensionNames[i], id); } } } -void GenerateAudioReceiveConfig(uint32_t extensions_bitvector, +void GenerateAudioReceiveConfig(const RtpHeaderExtensionMap& extensions, rtclog::StreamConfig* config, Random* prng) { // Add SSRCs for the stream. @@ -199,28 +247,36 @@ void GenerateAudioReceiveConfig(uint32_t extensions_bitvector, config->local_ssrc = prng->Rand(); // Add header extensions. for (unsigned i = 0; i < kNumExtensions; i++) { - if (extensions_bitvector & (1u << i)) { - config->rtp_extensions.push_back( - RtpExtension(kExtensionNames[i], prng->Rand())); + uint8_t id = extensions.GetId(kExtensionTypes[i]); + if (id != RtpHeaderExtensionMap::kInvalidId) { + config->rtp_extensions.emplace_back(kExtensionNames[i], id); } } } -void GenerateAudioSendConfig(uint32_t extensions_bitvector, +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++) { - if (extensions_bitvector & (1u << i)) { - config->rtp_extensions.push_back( - RtpExtension(kExtensionNames[i], prng->Rand())); + uint8_t id = extensions.GetId(kExtensionTypes[i]); + if (id != RtpHeaderExtensionMap::kInvalidId) { + config->rtp_extensions.emplace_back(kExtensionNames[i], id); } } } -void GenerateAudioNetworkAdaptation(uint32_t extensions_bitvector, +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 = rtc::Optional(prng->Rand(0, 3000000)); @@ -232,201 +288,414 @@ void GenerateAudioNetworkAdaptation(uint32_t extensions_bitvector, rtc::Optional(prng->Rand()); } -// Test for the RtcEventLog class. Dumps some RTP packets and other events -// to disk, then reads them back to see if they match. -void LogSessionAndReadBack(size_t rtp_count, - size_t rtcp_count, - size_t playout_count, - size_t bwe_loss_count, - uint32_t extensions_bitvector, - uint32_t csrcs_count, - unsigned int random_seed) { - ASSERT_LE(rtcp_count, rtp_count); - ASSERT_LE(playout_count, rtp_count); - ASSERT_LE(bwe_loss_count, rtp_count); - std::vector rtp_packets; - std::vector rtcp_packets; +class RtcEventLogSessionDescription { + public: + explicit RtcEventLogSessionDescription(unsigned int random_seed) + : prng(random_seed) {} + 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); + + 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_loss_updates; + std::vector > bwe_delay_updates; + std::vector receiver_configs; + std::vector sender_configs; + std::vector event_types; + Random prng; +}; - rtclog::StreamConfig receiver_config; - rtclog::StreamConfig sender_config; +void RtcEventLogSessionDescription::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); - Random prng(random_seed); + // 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; - // Initialize rtp header extensions to be used in generated rtp packets. - RtpHeaderExtensionMap extensions; - for (unsigned i = 0; i < kNumExtensions; i++) { - if (extensions_bitvector & (1u << i)) { - extensions.Register(kExtensionTypes[i], i + 1); - } - } - // Create rtp_count RTP packets containing random data. - for (size_t i = 0; i < rtp_count; i++) { + // 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); - rtp_packets.push_back( - GenerateRtpPacket(&extensions, csrcs_count, packet_size, &prng)); + incoming_rtp_packets.push_back(GenerateIncomingRtpPacket( + &extensions, csrcs_count, packet_size, &prng)); + event_types.push_back(EventType::kIncomingRtp); } - // Create rtcp_count RTCP packets containing random data. - for (size_t i = 0; i < rtcp_count; i++) { - rtcp_packets.push_back(GenerateRtcpPacket(&prng)); + 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 playout_count random SSRCs to use when logging AudioPlayout events. + // 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 bwe_loss_count random bitrate updates for LossBasedBwe. + // Create random bitrate updates for LossBasedBwe. for (size_t i = 0; i < bwe_loss_count; i++) { - bwe_loss_updates.push_back( - std::make_pair(prng.Rand(), prng.Rand())); + 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); } - // Create configurations for the video streams. - GenerateVideoReceiveConfig(extensions_bitvector, &receiver_config, &prng); - GenerateVideoSendConfig(extensions_bitvector, &sender_config, &prng); - const int config_count = 2; + // 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 RtcEventLogSessionDescription::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(); const std::string temp_filename = test::OutputPath() + test_info->test_case_name() + test_info->name(); + rtc::ScopedFakeClock fake_clock; + fake_clock.SetTimeMicros(prng.Rand()); + // When log_dumper goes out of scope, it causes the log file to be flushed // to disk. - { - rtc::ScopedFakeClock fake_clock; - fake_clock.SetTimeMicros(prng.Rand()); - std::unique_ptr log_dumper(RtcEventLog::Create()); - log_dumper->LogVideoReceiveStreamConfig(receiver_config); + std::unique_ptr log_dumper(RtcEventLog::Create()); + + 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; + + for (size_t i = 0; i < event_types.size(); i++) { fake_clock.AdvanceTimeMicros(prng.Rand(1, 1000)); - log_dumper->LogVideoSendStreamConfig(sender_config); - fake_clock.AdvanceTimeMicros(prng.Rand(1, 1000)); - size_t rtcp_index = 1; - size_t playout_index = 1; - size_t bwe_loss_index = 1; - for (size_t i = 1; i <= rtp_count; i++) { - log_dumper->LogRtpHeader( - (i % 2 == 0) ? kIncomingPacket : kOutgoingPacket, - rtp_packets[i - 1].data(), rtp_packets[i - 1].size()); - fake_clock.AdvanceTimeMicros(prng.Rand(1, 1000)); - if (i * rtcp_count >= rtcp_index * rtp_count) { - log_dumper->LogRtcpPacket( - (rtcp_index % 2 == 0) ? kIncomingPacket : kOutgoingPacket, - rtcp_packets[rtcp_index - 1].data(), - rtcp_packets[rtcp_index - 1].size()); - rtcp_index++; - fake_clock.AdvanceTimeMicros(prng.Rand(1, 1000)); - } - if (i * playout_count >= playout_index * rtp_count) { - log_dumper->LogAudioPlayout(playout_ssrcs[playout_index - 1]); - playout_index++; - fake_clock.AdvanceTimeMicros(prng.Rand(1, 1000)); - } - if (i * bwe_loss_count >= bwe_loss_index * rtp_count) { + if (i == event_types.size() / 2) + log_dumper->StartLogging(temp_filename, 10000000); + switch (event_types[i]) { + case EventType::kIncomingRtp: + RTC_CHECK(incoming_rtp_written < incoming_rtp_packets.size()); + log_dumper->LogIncomingRtpHeader( + incoming_rtp_packets[incoming_rtp_written++]); + break; + case EventType::kOutgoingRtp: + RTC_CHECK(outgoing_rtp_written < outgoing_rtp_packets.size()); + log_dumper->LogOutgoingRtpHeader( + outgoing_rtp_packets[outgoing_rtp_written++], + PacedPacketInfo::kNotAProbe); + break; + case EventType::kIncomingRtcp: + RTC_CHECK(incoming_rtcp_written < incoming_rtcp_packets.size()); + log_dumper->LogIncomingRtcpPacket( + incoming_rtcp_packets[incoming_rtcp_written++]); + break; + case EventType::kOutgoingRtcp: + RTC_CHECK(outgoing_rtcp_written < outgoing_rtcp_packets.size()); + log_dumper->LogOutgoingRtcpPacket( + outgoing_rtcp_packets[outgoing_rtcp_written++]); + break; + case EventType::kAudioPlayout: + RTC_CHECK(playouts_written < playout_ssrcs.size()); + log_dumper->LogAudioPlayout(playout_ssrcs[playouts_written++]); + break; + case EventType::kBweLossUpdate: + RTC_CHECK(bwe_loss_written < bwe_loss_updates.size()); log_dumper->LogLossBasedBweUpdate( - bwe_loss_updates[bwe_loss_index - 1].first, - bwe_loss_updates[bwe_loss_index - 1].second, i); - bwe_loss_index++; - fake_clock.AdvanceTimeMicros(prng.Rand(1, 1000)); - } - if (i == rtp_count / 2) { - log_dumper->StartLogging(temp_filename, 10000000); - fake_clock.AdvanceTimeMicros(prng.Rand(1, 1000)); - } + 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->LogDelayBasedBweUpdate( + 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->LogVideoReceiveStreamConfig( + receiver_configs[recv_configs_written++]); + break; + case EventType::kVideoSendConfig: + RTC_CHECK(send_configs_written < sender_configs.size()); + log_dumper->LogVideoSendStreamConfig( + 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; } - log_dumper->StopLogging(); } + log_dumper->StopLogging(); +} + +// Read the file and verify that what we read back from the event log is the +// same as what we wrote down. +void RtcEventLogSessionDescription::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(); + const std::string temp_filename = + test::OutputPath() + test_info->test_case_name() + test_info->name(); + // Read the generated file from disk. ParsedRtcEventLog parsed_log; - ASSERT_TRUE(parsed_log.ParseFile(temp_filename)); + EXPECT_GE(1000u, event_types.size() + + 2); // The events must fit in the message queue. + EXPECT_EQ(event_types.size() + 2, parsed_log.GetNumberOfEvents()); + + 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; - // Verify that what we read back from the event log is the same as - // what we wrote down. For RTCP we log the full packets, but for - // RTP we should only log the header. - const size_t event_count = config_count + playout_count + bwe_loss_count + - rtcp_count + rtp_count + 2; - EXPECT_GE(1000u, event_count); // The events must fit in the message queue. - EXPECT_EQ(event_count, parsed_log.GetNumberOfEvents()); - if (event_count != parsed_log.GetNumberOfEvents()) { - // Print the expected and actual event types for easier debugging. - PrintActualEvents(parsed_log); - PrintExpectedEvents(rtp_count, rtcp_count, playout_count, bwe_loss_count); - } RtcEventLogTestHelper::VerifyLogStartEvent(parsed_log, 0); - RtcEventLogTestHelper::VerifyVideoReceiveStreamConfig(parsed_log, 1, - receiver_config); - RtcEventLogTestHelper::VerifyVideoSendStreamConfig(parsed_log, 2, - sender_config); - size_t event_index = config_count + 1; - size_t rtcp_index = 1; - size_t playout_index = 1; - size_t bwe_loss_index = 1; - for (size_t i = 1; i <= rtp_count; i++) { - RtcEventLogTestHelper::VerifyRtpEvent( - parsed_log, event_index, - (i % 2 == 0) ? kIncomingPacket : kOutgoingPacket, - rtp_packets[i - 1].data(), rtp_packets[i - 1].headers_size(), - rtp_packets[i - 1].size()); - event_index++; - if (i * rtcp_count >= rtcp_index * rtp_count) { - RtcEventLogTestHelper::VerifyRtcpEvent( - parsed_log, event_index, - rtcp_index % 2 == 0 ? kIncomingPacket : kOutgoingPacket, - rtcp_packets[rtcp_index - 1].data(), - rtcp_packets[rtcp_index - 1].size()); - event_index++; - rtcp_index++; - } - if (i * playout_count >= playout_index * rtp_count) { - RtcEventLogTestHelper::VerifyPlayoutEvent( - parsed_log, event_index, playout_ssrcs[playout_index - 1]); - event_index++; - playout_index++; - } - if (i * bwe_loss_count >= bwe_loss_index * rtp_count) { - RtcEventLogTestHelper::VerifyBweLossEvent( - parsed_log, event_index, bwe_loss_updates[bwe_loss_index - 1].first, - bwe_loss_updates[bwe_loss_index - 1].second, i); - event_index++; - bwe_loss_index++; + + 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; } } + RtcEventLogTestHelper::VerifyLogEndEvent(parsed_log, + parsed_log.GetNumberOfEvents() - 1); + // Clean up temporary file - can be pretty slow. remove(temp_filename.c_str()); } -TEST(RtcEventLogTest, LogSessionAndReadBack) { - // Log 5 RTP, 2 RTCP, 0 playout events and 0 BWE events - // with no header extensions or CSRCS. - LogSessionAndReadBack(5, 2, 0, 0, 0, 0, 321); - - // Enable AbsSendTime and TransportSequenceNumbers. - uint32_t extensions = 0; - for (uint32_t i = 0; i < kNumExtensions; i++) { - if (kExtensionTypes[i] == RTPExtensionType::kRtpExtensionAbsoluteSendTime || - kExtensionTypes[i] == - RTPExtensionType::kRtpExtensionTransportSequenceNumber) { - extensions |= 1u << i; - } +void RtcEventLogSessionDescription::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 << " "; } - LogSessionAndReadBack(8, 2, 0, 0, extensions, 0, 3141592653u); + stream << std::endl; +} - extensions = (1u << kNumExtensions) - 1; // Enable all header extensions. - LogSessionAndReadBack(9, 2, 3, 2, extensions, 2, 2718281828u); +void PrintActualEvents(const ParsedRtcEventLog& 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(RtcEventLogTest, LogSessionAndReadBack) { + RtpHeaderExtensionMap extensions; + RtcEventLogSessionDescription session(321 /*Random seed*/); + session.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. + session.WriteSession(); + session.ReadAndVerifySession(); +} + +TEST(RtcEventLogTest, LogSessionAndReadBackWith2Extensions) { + RtpHeaderExtensionMap extensions; + extensions.Register(kRtpExtensionAbsoluteSendTime, + kAbsoluteSendTimeExtensionId); + extensions.Register(kRtpExtensionTransportSequenceNumber, + kTransportSequenceNumberExtensionId); + RtcEventLogSessionDescription session(3141592653u /*Random seed*/); + session.GenerateSessionDescription(4, 4, 1, 1, 0, 0, 0, extensions, 0); + session.WriteSession(); + session.ReadAndVerifySession(); +} + +TEST(RtcEventLogTest, LogSessionAndReadBackWithAllExtensions) { + RtpHeaderExtensionMap extensions; + for (uint32_t i = 0; i < kNumExtensions; i++) { + extensions.Register(kExtensionTypes[i], kExtensionIds[i]); + } + RtcEventLogSessionDescription session(2718281828u /*Random seed*/); + session.GenerateSessionDescription(5, 4, 1, 1, 3, 2, 2, extensions, 2); + session.WriteSession(); + session.ReadAndVerifySession(); +} + +TEST(RtcEventLogTest, LogSessionAndReadBackAllCombinations) { // Try all combinations of header extensions and up to 2 CSRCS. - for (extensions = 0; extensions < (1u << kNumExtensions); extensions++) { + for (uint32_t extension_selection = 0; + extension_selection < (1u << kNumExtensions); extension_selection++) { + RtpHeaderExtensionMap extensions; + for (uint32_t i = 0; i < kNumExtensions; i++) { + if (extension_selection & (1u << i)) { + extensions.Register(kExtensionTypes[i], kExtensionIds[i]); + } + } for (uint32_t csrcs_count = 0; csrcs_count < 3; csrcs_count++) { - LogSessionAndReadBack(5 + extensions, // Number of RTP packets. - 2 + csrcs_count, // Number of RTCP packets. - 3 + csrcs_count, // Number of playout events. - 1 + csrcs_count, // Number of BWE loss events. - extensions, // Bit vector choosing extensions. - csrcs_count, // Number of contributing sources. - extensions * 3 + csrcs_count + 1); // Random seed. + RtcEventLogSessionDescription session(extension_selection * 3 + + csrcs_count + 1 /*Random seed*/); + session.GenerateSessionDescription( + 2 + extension_selection, // Number of incoming RTP packets. + 2 + extension_selection, // Number of outgoing RTP packets. + 1 + csrcs_count, // Number of incoming RTCP packets. + 1 + csrcs_count, // Number of outgoing RTCP packets. + 3 + csrcs_count, // Number of playout events. + 1 + csrcs_count, // Number of BWE loss events. + 2 + csrcs_count, // Number of BWE delay events. + extensions, // Bit vector choosing extensions. + csrcs_count); // Number of contributing sources. + session.WriteSession(); + session.ReadAndVerifySession(); } } } @@ -436,8 +705,8 @@ TEST(RtcEventLogTest, LogEventAndReadBack) { // Create one RTP and one RTCP packet containing random data. size_t packet_size = prng.Rand(1000, 1100); - RtpPacketToSend rtp_packet = - GenerateRtpPacket(nullptr, 0, packet_size, &prng); + RtpPacketReceived rtp_packet = + GenerateIncomingRtpPacket(nullptr, 0, packet_size, &prng); rtc::Buffer rtcp_packet = GenerateRtcpPacket(&prng); // Find the name of the current test, in order to use it as a temporary @@ -451,15 +720,13 @@ TEST(RtcEventLogTest, LogEventAndReadBack) { fake_clock.SetTimeMicros(prng.Rand()); std::unique_ptr log_dumper(RtcEventLog::Create()); - log_dumper->LogRtpHeader(kIncomingPacket, rtp_packet.data(), - rtp_packet.size()); + log_dumper->LogIncomingRtpHeader(rtp_packet); fake_clock.AdvanceTimeMicros(prng.Rand(1, 1000)); log_dumper->StartLogging(temp_filename, 10000000); fake_clock.AdvanceTimeMicros(prng.Rand(1, 1000)); - log_dumper->LogRtcpPacket(kOutgoingPacket, rtcp_packet.data(), - rtcp_packet.size()); + log_dumper->LogOutgoingRtcpPacket(rtcp_packet); fake_clock.AdvanceTimeMicros(prng.Rand(1, 1000)); log_dumper->StopLogging(); @@ -474,9 +741,7 @@ TEST(RtcEventLogTest, LogEventAndReadBack) { RtcEventLogTestHelper::VerifyLogStartEvent(parsed_log, 0); - RtcEventLogTestHelper::VerifyRtpEvent( - parsed_log, 1, kIncomingPacket, rtp_packet.data(), - rtp_packet.headers_size(), rtp_packet.size()); + RtcEventLogTestHelper::VerifyIncomingRtpEvent(parsed_log, 1, rtp_packet); RtcEventLogTestHelper::VerifyRtcpEvent( parsed_log, 2, kOutgoingPacket, rtcp_packet.data(), rtcp_packet.size()); @@ -721,7 +986,7 @@ class ConfigReadWriteTest { public: ConfigReadWriteTest() : prng(987654321) {} virtual ~ConfigReadWriteTest() {} - virtual void GenerateConfig(uint32_t extensions_bitvector) = 0; + virtual void GenerateConfig(const RtpHeaderExtensionMap& extensions) = 0; virtual void VerifyConfig(const ParsedRtcEventLog& parsed_log, size_t index) = 0; virtual void LogConfig(RtcEventLog* event_log) = 0; @@ -734,8 +999,11 @@ class ConfigReadWriteTest { test::OutputPath() + test_info->test_case_name() + test_info->name(); // Use all extensions. - uint32_t extensions_bitvector = (1u << kNumExtensions) - 1; - GenerateConfig(extensions_bitvector); + RtpHeaderExtensionMap extensions; + for (uint32_t i = 0; i < kNumExtensions; i++) { + extensions.Register(kExtensionTypes[i], kExtensionIds[i]); + } + GenerateConfig(extensions); // Log a single config event and stop logging. rtc::ScopedFakeClock fake_clock; @@ -768,8 +1036,8 @@ class ConfigReadWriteTest { class AudioReceiveConfigReadWriteTest : public ConfigReadWriteTest { public: - void GenerateConfig(uint32_t extensions_bitvector) override { - GenerateAudioReceiveConfig(extensions_bitvector, &config, &prng); + void GenerateConfig(const RtpHeaderExtensionMap& extensions) override { + GenerateAudioReceiveConfig(extensions, &config, &prng); } void LogConfig(RtcEventLog* event_log) override { event_log->LogAudioReceiveStreamConfig(config); @@ -785,8 +1053,8 @@ class AudioReceiveConfigReadWriteTest : public ConfigReadWriteTest { class AudioSendConfigReadWriteTest : public ConfigReadWriteTest { public: AudioSendConfigReadWriteTest() {} - void GenerateConfig(uint32_t extensions_bitvector) override { - GenerateAudioSendConfig(extensions_bitvector, &config, &prng); + void GenerateConfig(const RtpHeaderExtensionMap& extensions) override { + GenerateAudioSendConfig(extensions, &config, &prng); } void LogConfig(RtcEventLog* event_log) override { event_log->LogAudioSendStreamConfig(config); @@ -802,8 +1070,8 @@ class AudioSendConfigReadWriteTest : public ConfigReadWriteTest { class VideoReceiveConfigReadWriteTest : public ConfigReadWriteTest { public: VideoReceiveConfigReadWriteTest() {} - void GenerateConfig(uint32_t extensions_bitvector) override { - GenerateVideoReceiveConfig(extensions_bitvector, &config, &prng); + void GenerateConfig(const RtpHeaderExtensionMap& extensions) override { + GenerateVideoReceiveConfig(extensions, &config, &prng); } void LogConfig(RtcEventLog* event_log) override { event_log->LogVideoReceiveStreamConfig(config); @@ -819,8 +1087,8 @@ class VideoReceiveConfigReadWriteTest : public ConfigReadWriteTest { class VideoSendConfigReadWriteTest : public ConfigReadWriteTest { public: VideoSendConfigReadWriteTest() {} - void GenerateConfig(uint32_t extensions_bitvector) override { - GenerateVideoSendConfig(extensions_bitvector, &config, &prng); + void GenerateConfig(const RtpHeaderExtensionMap& extensions) override { + GenerateVideoSendConfig(extensions, &config, &prng); } void LogConfig(RtcEventLog* event_log) override { event_log->LogVideoSendStreamConfig(config); @@ -835,8 +1103,8 @@ class VideoSendConfigReadWriteTest : public ConfigReadWriteTest { class AudioNetworkAdaptationReadWriteTest : public ConfigReadWriteTest { public: - void GenerateConfig(uint32_t extensions_bitvector) override { - GenerateAudioNetworkAdaptation(extensions_bitvector, &config, &prng); + void GenerateConfig(const RtpHeaderExtensionMap& extensions) override { + GenerateAudioNetworkAdaptation(extensions, &config, &prng); } void LogConfig(RtcEventLog* event_log) override { event_log->LogAudioNetworkAdaptation(config); 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 972411a836..ed9cab1590 100644 --- a/logging/rtc_event_log/rtc_event_log_unittest_helper.cc +++ b/logging/rtc_event_log/rtc_event_log_unittest_helper.cc @@ -18,6 +18,7 @@ #include "modules/audio_coding/audio_network_adaptor/include/audio_network_adaptor.h" #include "modules/remote_bitrate_estimator/include/bwe_defines.h" #include "rtc_base/checks.h" +#include "test/gmock.h" #include "test/gtest.h" #include "test/testsupport/fileutils.h" @@ -349,25 +350,23 @@ void RtcEventLogTestHelper::VerifyAudioSendStreamConfig( VerifyStreamConfigsAreEqual(config, parsed_config); } -void RtcEventLogTestHelper::VerifyRtpEvent(const ParsedRtcEventLog& parsed_log, - size_t index, - PacketDirection direction, - const uint8_t* header, - size_t header_size, - size_t total_size) { +void RtcEventLogTestHelper::VerifyIncomingRtpEvent( + const ParsedRtcEventLog& parsed_log, + size_t index, + const RtpPacketReceived& expected_packet) { 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_EQ(direction == kIncomingPacket, rtp_packet.incoming()); + EXPECT_TRUE(rtp_packet.incoming()); ASSERT_TRUE(rtp_packet.has_packet_length()); - EXPECT_EQ(total_size, rtp_packet.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()); - ASSERT_EQ(header_size, rtp_packet.header().size()); - for (size_t i = 0; i < header_size; i++) { - EXPECT_EQ(header[i], static_cast(rtp_packet.header()[i])); - } + 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; @@ -375,10 +374,40 @@ void RtcEventLogTestHelper::VerifyRtpEvent(const ParsedRtcEventLog& parsed_log, size_t parsed_header_size, parsed_total_size; parsed_log.GetRtpHeader(index, &parsed_direction, parsed_header, &parsed_header_size, &parsed_total_size); - EXPECT_EQ(direction, parsed_direction); - ASSERT_EQ(header_size, parsed_header_size); - EXPECT_EQ(0, std::memcmp(header, parsed_header, header_size)); - EXPECT_EQ(total_size, parsed_total_size); + 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 ParsedRtcEventLog& parsed_log, + size_t index, + const RtpPacketToSend& expected_packet) { + 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); + 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 ParsedRtcEventLog& parsed_log, 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 29031ed5f9..630f160a18 100644 --- a/logging/rtc_event_log/rtc_event_log_unittest_helper.h +++ b/logging/rtc_event_log/rtc_event_log_unittest_helper.h @@ -13,6 +13,8 @@ #include "call/call.h" #include "logging/rtc_event_log/rtc_event_log_parser.h" +#include "modules/rtp_rtcp/source/rtp_packet_received.h" +#include "modules/rtp_rtcp/source/rtp_packet_to_send.h" namespace webrtc { @@ -32,12 +34,12 @@ class RtcEventLogTestHelper { static void VerifyAudioSendStreamConfig(const ParsedRtcEventLog& parsed_log, size_t index, const rtclog::StreamConfig& config); - static void VerifyRtpEvent(const ParsedRtcEventLog& parsed_log, - size_t index, - PacketDirection direction, - const uint8_t* header, - size_t header_size, - size_t total_size); + static void VerifyIncomingRtpEvent(const ParsedRtcEventLog& parsed_log, + size_t index, + const RtpPacketReceived& expected_packet); + static void VerifyOutgoingRtpEvent(const ParsedRtcEventLog& parsed_log, + size_t index, + const RtpPacketToSend& expected_packet); static void VerifyRtcpEvent(const ParsedRtcEventLog& parsed_log, size_t index, PacketDirection direction, diff --git a/modules/rtp_rtcp/source/rtcp_sender.cc b/modules/rtp_rtcp/source/rtcp_sender.cc index 9145bbce16..c7e75b67e7 100644 --- a/modules/rtp_rtcp/source/rtcp_sender.cc +++ b/modules/rtp_rtcp/source/rtcp_sender.cc @@ -99,7 +99,8 @@ class PacketContainer : public rtcp::CompoundPacket, if (transport_->SendRtcp(data, length)) { bytes_sent_ += length; if (event_log_) { - event_log_->LogRtcpPacket(kOutgoingPacket, data, length); + event_log_->LogOutgoingRtcpPacket( + rtc::ArrayView(data, length)); } } } @@ -962,7 +963,8 @@ bool RTCPSender::SendFeedbackPacket(const rtcp::TransportFeedback& packet) { void OnPacketReady(uint8_t* data, size_t length) override { if (transport_->SendRtcp(data, length)) { if (event_log_) { - event_log_->LogRtcpPacket(kOutgoingPacket, data, length); + event_log_->LogOutgoingRtcpPacket( + rtc::ArrayView(data, length)); } } else { send_failure_ = true; diff --git a/modules/rtp_rtcp/source/rtp_sender.cc b/modules/rtp_rtcp/source/rtp_sender.cc index 1a47d97ece..34af1cbcb0 100644 --- a/modules/rtp_rtcp/source/rtp_sender.cc +++ b/modules/rtp_rtcp/source/rtp_sender.cc @@ -644,8 +644,7 @@ bool RTPSender::SendPacketToNetwork(const RtpPacketToSend& packet, ? static_cast(packet.size()) : -1; if (event_log_ && bytes_sent > 0) { - event_log_->LogRtpHeader(kOutgoingPacket, packet.data(), packet.size(), - pacing_info.probe_cluster_id); + event_log_->LogOutgoingRtpHeader(packet, pacing_info.probe_cluster_id); } } TRACE_EVENT_INSTANT2(TRACE_DISABLED_BY_DEFAULT("webrtc_rtp"), diff --git a/modules/rtp_rtcp/source/rtp_sender_unittest.cc b/modules/rtp_rtcp/source/rtp_sender_unittest.cc index 858c308346..e40406cb3b 100644 --- a/modules/rtp_rtcp/source/rtp_sender_unittest.cc +++ b/modules/rtp_rtcp/source/rtp_sender_unittest.cc @@ -530,8 +530,7 @@ TEST_P(RtpSenderTestWithoutPacer, WritesTimestampToTimingExtension) { TEST_P(RtpSenderTest, TrafficSmoothingWithExtensions) { EXPECT_CALL(mock_paced_sender_, InsertPacket(RtpPacketSender::kNormalPriority, kSsrc, kSeqNum, _, _, _)); - EXPECT_CALL(mock_rtc_event_log_, - LogRtpHeader(PacketDirection::kOutgoingPacket, _, _, _)); + EXPECT_CALL(mock_rtc_event_log_, LogOutgoingRtpHeader(_, _)); rtp_sender_->SetStorePacketsStatus(true, 10); EXPECT_EQ(0, rtp_sender_->RegisterRtpHeaderExtension( @@ -575,8 +574,7 @@ TEST_P(RtpSenderTest, TrafficSmoothingWithExtensions) { TEST_P(RtpSenderTest, TrafficSmoothingRetransmits) { EXPECT_CALL(mock_paced_sender_, InsertPacket(RtpPacketSender::kNormalPriority, kSsrc, kSeqNum, _, _, _)); - EXPECT_CALL(mock_rtc_event_log_, - LogRtpHeader(PacketDirection::kOutgoingPacket, _, _, _)); + EXPECT_CALL(mock_rtc_event_log_, LogOutgoingRtpHeader(_, _)); rtp_sender_->SetStorePacketsStatus(true, 10); EXPECT_EQ(0, rtp_sender_->RegisterRtpHeaderExtension( @@ -629,9 +627,7 @@ TEST_P(RtpSenderTest, SendPadding) { // Make all (non-padding) packets go to send queue. EXPECT_CALL(mock_paced_sender_, InsertPacket(RtpPacketSender::kNormalPriority, kSsrc, kSeqNum, _, _, _)); - EXPECT_CALL(mock_rtc_event_log_, - LogRtpHeader(PacketDirection::kOutgoingPacket, _, _, _)) - .Times(1 + 4 + 1); + EXPECT_CALL(mock_rtc_event_log_, LogOutgoingRtpHeader(_, _)).Times(1 + 4 + 1); uint16_t seq_num = kSeqNum; uint32_t timestamp = kTimestamp; @@ -830,8 +826,7 @@ TEST_P(RtpSenderTest, SendRedundantPayloads) { EXPECT_CALL(mock_paced_sender_, InsertPacket(RtpPacketSender::kNormalPriority, kSsrc, _, _, _, _)) .Times(kNumPayloadSizes); - EXPECT_CALL(mock_rtc_event_log_, - LogRtpHeader(PacketDirection::kOutgoingPacket, _, _, _)) + EXPECT_CALL(mock_rtc_event_log_, LogOutgoingRtpHeader(_, _)) .Times(kNumPayloadSizes); // Send 10 packets of increasing size. @@ -844,8 +839,7 @@ TEST_P(RtpSenderTest, SendRedundantPayloads) { fake_clock_.AdvanceTimeMilliseconds(33); } - EXPECT_CALL(mock_rtc_event_log_, - LogRtpHeader(PacketDirection::kOutgoingPacket, _, _, _)) + EXPECT_CALL(mock_rtc_event_log_, LogOutgoingRtpHeader(_, _)) .Times(::testing::AtLeast(4)); // The amount of padding to send it too small to send a payload packet. @@ -941,9 +935,7 @@ TEST_P(RtpSenderTest, SendFlexfecPackets) { kFlexfecSsrc, _, _, _, false)) .WillOnce(testing::SaveArg<2>(&flexfec_seq_num)); SendGenericPayload(); - EXPECT_CALL(mock_rtc_event_log_, - LogRtpHeader(PacketDirection::kOutgoingPacket, _, _, _)) - .Times(2); + EXPECT_CALL(mock_rtc_event_log_, LogOutgoingRtpHeader(_, _)).Times(2); EXPECT_TRUE(rtp_sender_->TimeToSendPacket(kMediaSsrc, kSeqNum, fake_clock_.TimeInMilliseconds(), false, PacedPacketInfo())); @@ -1018,9 +1010,7 @@ TEST_P(RtpSenderTest, NoFlexfecForTimingFrames) { sizeof(kPayloadData), nullptr, &video_header, nullptr, kDefaultExpectedRetransmissionTimeMs)); - EXPECT_CALL(mock_rtc_event_log_, - LogRtpHeader(PacketDirection::kOutgoingPacket, _, _, _)) - .Times(1); + EXPECT_CALL(mock_rtc_event_log_, LogOutgoingRtpHeader(_, _)).Times(1); EXPECT_TRUE(rtp_sender_->TimeToSendPacket(kMediaSsrc, kSeqNum, fake_clock_.TimeInMilliseconds(), false, PacedPacketInfo())); @@ -1044,9 +1034,7 @@ TEST_P(RtpSenderTest, NoFlexfecForTimingFrames) { kPayloadData, sizeof(kPayloadData), nullptr, &video_header, nullptr, kDefaultExpectedRetransmissionTimeMs)); - EXPECT_CALL(mock_rtc_event_log_, - LogRtpHeader(PacketDirection::kOutgoingPacket, _, _, _)) - .Times(2); + EXPECT_CALL(mock_rtc_event_log_, LogOutgoingRtpHeader(_, _)).Times(2); EXPECT_TRUE(rtp_sender_->TimeToSendPacket(kMediaSsrc, kSeqNum + 1, fake_clock_.TimeInMilliseconds(), false, PacedPacketInfo())); @@ -1092,9 +1080,7 @@ TEST_P(RtpSenderTestWithoutPacer, SendFlexfecPackets) { params.fec_mask_type = kFecMaskRandom; rtp_sender_->SetFecParameters(params, params); - EXPECT_CALL(mock_rtc_event_log_, - LogRtpHeader(PacketDirection::kOutgoingPacket, _, _, _)) - .Times(2); + EXPECT_CALL(mock_rtc_event_log_, LogOutgoingRtpHeader(_, _)).Times(2); SendGenericPayload(); ASSERT_EQ(2, transport_.packets_sent()); const RtpPacketReceived& media_packet = transport_.sent_packets_[0]; diff --git a/voice_engine/channel.cc b/voice_engine/channel.cc index 5fa7973b49..aab292b9e0 100644 --- a/voice_engine/channel.cc +++ b/voice_engine/channel.cc @@ -11,7 +11,10 @@ #include "voice_engine/channel.h" #include +#include +#include #include +#include #include "api/array_view.h" #include "audio/utility/audio_frame_operations.h" @@ -98,29 +101,32 @@ class RtcEventLogProxy final : public webrtc::RtcEventLog { } } - void LogRtpHeader(webrtc::PacketDirection direction, - const uint8_t* header, - size_t packet_length) override { - LogRtpHeader(direction, header, packet_length, PacedPacketInfo::kNotAProbe); - } - - void LogRtpHeader(webrtc::PacketDirection direction, - const uint8_t* header, - size_t packet_length, - int probe_cluster_id) override { + void LogIncomingRtpHeader(const RtpPacketReceived& packet) override { rtc::CritScope lock(&crit_); if (event_log_) { - event_log_->LogRtpHeader(direction, header, packet_length, - probe_cluster_id); + event_log_->LogIncomingRtpHeader(packet); } } - void LogRtcpPacket(webrtc::PacketDirection direction, - const uint8_t* packet, - size_t length) override { + void LogOutgoingRtpHeader(const RtpPacketToSend& packet, + int probe_cluster_id) override { rtc::CritScope lock(&crit_); if (event_log_) { - event_log_->LogRtcpPacket(direction, packet, length); + event_log_->LogOutgoingRtpHeader(packet, probe_cluster_id); + } + } + + void LogIncomingRtcpPacket(rtc::ArrayView packet) override { + rtc::CritScope lock(&crit_); + if (event_log_) { + event_log_->LogIncomingRtcpPacket(packet); + } + } + + void LogOutgoingRtcpPacket(rtc::ArrayView packet) override { + rtc::CritScope lock(&crit_); + if (event_log_) { + event_log_->LogOutgoingRtcpPacket(packet); } }