/* * Copyright (c) 2016 The WebRTC project authors. All Rights Reserved. * * Use of this source code is governed by a BSD-style license * that can be found in the LICENSE file in the root of the source * tree. An additional intellectual property rights grant can be found * in the file PATENTS. All contributing project authors may * be found in the AUTHORS file in the root of the source tree. */ #include "logging/rtc_event_log/rtc_event_log_unittest_helper.h" #include // memcmp #include #include #include #include #include #include #include #include #include "absl/strings/string_view.h" #include "absl/types/optional.h" #include "api/array_view.h" #include "api/network_state_predictor.h" #include "api/rtp_headers.h" #include "api/rtp_parameters.h" #include "api/units/time_delta.h" #include "api/units/timestamp.h" #include "modules/audio_coding/audio_network_adaptor/include/audio_network_adaptor_config.h" #include "modules/rtp_rtcp/include/rtp_cvo.h" #include "modules/rtp_rtcp/include/rtp_rtcp_defines.h" #include "modules/rtp_rtcp/source/rtcp_packet/dlrr.h" #include "modules/rtp_rtcp/source/rtcp_packet/rrtr.h" #include "modules/rtp_rtcp/source/rtcp_packet/target_bitrate.h" #include "modules/rtp_rtcp/source/rtp_dependency_descriptor_extension.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/time_utils.h" #include "system_wrappers/include/field_trial.h" #include "system_wrappers/include/ntp_time.h" #include "test/gtest.h" namespace webrtc { namespace test { namespace { struct ExtensionPair { RTPExtensionType type; const char* name; }; constexpr int kMaxCsrcs = 3; // Maximum serialized size of a header extension, including 1 byte ID. constexpr int kMaxExtensionSizeBytes = 10; constexpr int kMaxNumExtensions = 6; constexpr ExtensionPair kExtensions[kMaxNumExtensions] = { {RTPExtensionType::kRtpExtensionTransmissionTimeOffset, RtpExtension::kTimestampOffsetUri}, {RTPExtensionType::kRtpExtensionAbsoluteSendTime, RtpExtension::kAbsSendTimeUri}, {RTPExtensionType::kRtpExtensionTransportSequenceNumber, RtpExtension::kTransportSequenceNumberUri}, {RTPExtensionType::kRtpExtensionAudioLevel, RtpExtension::kAudioLevelUri}, {RTPExtensionType::kRtpExtensionVideoRotation, RtpExtension::kVideoRotationUri}, {RTPExtensionType::kRtpExtensionDependencyDescriptor, RtpExtension::kDependencyDescriptorUri}}; 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]); } } absl::optional GetExtensionId(const std::vector& extensions, absl::string_view uri) { for (const auto& extension : extensions) { if (extension.uri == uri) return extension.id; } return absl::nullopt; } } // namespace std::unique_ptr EventGenerator::NewAlrState() { return std::make_unique(prng_.Rand()); } std::unique_ptr EventGenerator::NewAudioPlayout( uint32_t ssrc) { return std::make_unique(ssrc); } std::unique_ptr EventGenerator::NewAudioNetworkAdaptation() { std::unique_ptr config = std::make_unique(); 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 std::make_unique(std::move(config)); } std::unique_ptr EventGenerator::NewNetEqSetMinimumDelay(uint32_t ssrc) { return std::make_unique( ssrc, prng_.Rand(std::numeric_limits::max())); } 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 std::make_unique(bitrate_bps, state); } 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); return std::make_unique( bitrate_bps, fraction_lost, total_packets); } std::unique_ptr EventGenerator::NewDtlsTransportState() { DtlsTransportState state = static_cast( prng_.Rand(static_cast(DtlsTransportState::kNumValues) - 1)); return std::make_unique(state); } std::unique_ptr EventGenerator::NewDtlsWritableState() { bool writable = prng_.Rand(); return std::make_unique(writable); } std::unique_ptr EventGenerator::NewFrameDecodedEvent( uint32_t ssrc) { constexpr int kMinRenderDelayMs = 1; constexpr int kMaxRenderDelayMs = 2000000; constexpr int kMaxWidth = 15360; constexpr int kMaxHeight = 8640; constexpr int kMinWidth = 16; constexpr int kMinHeight = 16; constexpr int kNumCodecTypes = 6; constexpr VideoCodecType kCodecList[kNumCodecTypes] = { kVideoCodecGeneric, kVideoCodecVP8, kVideoCodecVP9, kVideoCodecAV1, kVideoCodecH264, kVideoCodecH265}; const int64_t render_time_ms = rtc::TimeMillis() + prng_.Rand(kMinRenderDelayMs, kMaxRenderDelayMs); const int width = prng_.Rand(kMinWidth, kMaxWidth); const int height = prng_.Rand(kMinHeight, kMaxHeight); const VideoCodecType codec = kCodecList[prng_.Rand(0, kNumCodecTypes - 1)]; const uint8_t qp = prng_.Rand(); return std::make_unique(render_time_ms, ssrc, width, height, codec, qp); } 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 std::make_unique(id, bitrate_bps, min_probes, min_bytes); } 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 std::make_unique(id, reason); } 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); return std::make_unique(id, bitrate_bps); } 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)); 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; IceCandidatePairConfigType type = static_cast(prng_.Rand( static_cast(IceCandidatePairConfigType::kNumValues) - 1)); uint32_t pair_id = prng_.Rand(); return std::make_unique(type, pair_id, desc); } std::unique_ptr EventGenerator::NewIceCandidatePair() { IceCandidatePairEventType type = static_cast(prng_.Rand( static_cast(IceCandidatePairEventType::kNumValues) - 1)); uint32_t pair_id = prng_.Rand(); uint32_t transaction_id = prng_.Rand(); return std::make_unique(type, pair_id, transaction_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.SetRtpTimestamp(prng_.Rand()); sender_report.SetPacketCount(prng_.Rand()); sender_report.SetOctetCount(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; } rtcp::ExtendedReports EventGenerator::NewExtendedReports() { rtcp::ExtendedReports extended_report; extended_report.SetSenderSsrc(prng_.Rand()); rtcp::Rrtr rrtr; rrtr.SetNtp(NtpTime(prng_.Rand(), prng_.Rand())); extended_report.SetRrtr(rrtr); rtcp::ReceiveTimeInfo time_info( prng_.Rand(), prng_.Rand(), prng_.Rand()); extended_report.AddDlrrItem(time_info); rtcp::TargetBitrate target_bitrate; target_bitrate.AddTargetBitrate(/*spatial layer*/ prng_.Rand(0, 3), /*temporal layer*/ prng_.Rand(0, 3), /*bitrate kbps*/ prng_.Rand(0, 50000)); target_bitrate.AddTargetBitrate(/*spatial layer*/ prng_.Rand(4, 7), /*temporal layer*/ prng_.Rand(4, 7), /*bitrate kbps*/ prng_.Rand(0, 50000)); extended_report.SetTargetBitrate(target_bitrate); return extended_report; } rtcp::Nack EventGenerator::NewNack() { rtcp::Nack nack; uint16_t base_seq_no = prng_.Rand(); std::vector nack_list; nack_list.push_back(base_seq_no); for (uint16_t i = 1u; i < 10u; i++) { if (prng_.Rand()) nack_list.push_back(base_seq_no + i); } nack.SetPacketIds(nack_list); return nack; } rtcp::Fir EventGenerator::NewFir() { rtcp::Fir fir; fir.SetSenderSsrc(prng_.Rand()); fir.AddRequestTo(/*ssrc*/ prng_.Rand(), /*seq num*/ prng_.Rand()); fir.AddRequestTo(/*ssrc*/ prng_.Rand(), /*seq num*/ prng_.Rand()); return fir; } rtcp::Pli EventGenerator::NewPli() { rtcp::Pli pli; pli.SetSenderSsrc(prng_.Rand()); pli.SetMediaSsrc(prng_.Rand()); return pli; } rtcp::Bye EventGenerator::NewBye() { rtcp::Bye bye; bye.SetSenderSsrc(prng_.Rand()); std::vector csrcs{prng_.Rand(), prng_.Rand()}; bye.SetCsrcs(csrcs); if (prng_.Rand(0, 2)) { bye.SetReason("foo"); } else { bye.SetReason("bar"); } return bye; } rtcp::TransportFeedback EventGenerator::NewTransportFeedback() { rtcp::TransportFeedback transport_feedback; uint16_t base_seq_no = prng_.Rand(); Timestamp base_time = Timestamp::Micros(prng_.Rand()); transport_feedback.SetBase(base_seq_no, base_time); transport_feedback.AddReceivedPacket(base_seq_no, base_time); Timestamp time = base_time; for (uint16_t i = 1u; i < 10u; i++) { time += TimeDelta::Micros(prng_.Rand(0, 100'000)); if (prng_.Rand()) { transport_feedback.AddReceivedPacket(base_seq_no + i, time); } } return transport_feedback; } rtcp::Remb EventGenerator::NewRemb() { rtcp::Remb remb; // The remb bitrate is transported as a 16-bit mantissa and an 8-bit exponent. uint64_t bitrate_bps = prng_.Rand(0, (1 << 16) - 1) << prng_.Rand(7); std::vector ssrcs{prng_.Rand(), prng_.Rand()}; remb.SetSsrcs(ssrcs); remb.SetBitrateBps(bitrate_bps); return remb; } rtcp::LossNotification EventGenerator::NewLossNotification() { rtcp::LossNotification loss_notification; const uint16_t last_decoded = prng_.Rand(); const uint16_t last_received = last_decoded + (prng_.Rand() & 0x7fff); const bool decodability_flag = prng_.Rand(); EXPECT_TRUE( loss_notification.Set(last_decoded, last_received, decodability_flag)); return loss_notification; } std::unique_ptr EventGenerator::NewRouteChange() { return std::make_unique(prng_.Rand(), prng_.Rand(0, 128)); } std::unique_ptr EventGenerator::NewRemoteEstimate() { return std::make_unique( DataRate::KilobitsPerSec(prng_.Rand(0, 100000)), DataRate::KilobitsPerSec(prng_.Rand(0, 100000))); } std::unique_ptr EventGenerator::NewRtcpPacketIncoming() { enum class SupportedRtcpTypes { kSenderReport = 0, kReceiverReport, kExtendedReports, kFir, kPli, kNack, kRemb, kBye, kTransportFeedback, kNumValues }; SupportedRtcpTypes type = static_cast( prng_.Rand(0, static_cast(SupportedRtcpTypes::kNumValues) - 1)); switch (type) { case SupportedRtcpTypes::kSenderReport: { rtcp::SenderReport sender_report = NewSenderReport(); rtc::Buffer buffer = sender_report.Build(); return std::make_unique(buffer); } case SupportedRtcpTypes::kReceiverReport: { rtcp::ReceiverReport receiver_report = NewReceiverReport(); rtc::Buffer buffer = receiver_report.Build(); return std::make_unique(buffer); } case SupportedRtcpTypes::kExtendedReports: { rtcp::ExtendedReports extended_report = NewExtendedReports(); rtc::Buffer buffer = extended_report.Build(); return std::make_unique(buffer); } case SupportedRtcpTypes::kFir: { rtcp::Fir fir = NewFir(); rtc::Buffer buffer = fir.Build(); return std::make_unique(buffer); } case SupportedRtcpTypes::kPli: { rtcp::Pli pli = NewPli(); rtc::Buffer buffer = pli.Build(); return std::make_unique(buffer); } case SupportedRtcpTypes::kNack: { rtcp::Nack nack = NewNack(); rtc::Buffer buffer = nack.Build(); return std::make_unique(buffer); } case SupportedRtcpTypes::kRemb: { rtcp::Remb remb = NewRemb(); rtc::Buffer buffer = remb.Build(); return std::make_unique(buffer); } case SupportedRtcpTypes::kBye: { rtcp::Bye bye = NewBye(); rtc::Buffer buffer = bye.Build(); return std::make_unique(buffer); } case SupportedRtcpTypes::kTransportFeedback: { rtcp::TransportFeedback transport_feedback = NewTransportFeedback(); rtc::Buffer buffer = transport_feedback.Build(); return std::make_unique(buffer); } default: RTC_DCHECK_NOTREACHED(); rtc::Buffer buffer; return std::make_unique(buffer); } } std::unique_ptr EventGenerator::NewRtcpPacketOutgoing() { enum class SupportedRtcpTypes { kSenderReport = 0, kReceiverReport, kExtendedReports, kFir, kPli, kNack, kRemb, kBye, kTransportFeedback, kNumValues }; SupportedRtcpTypes type = static_cast( prng_.Rand(0, static_cast(SupportedRtcpTypes::kNumValues) - 1)); switch (type) { case SupportedRtcpTypes::kSenderReport: { rtcp::SenderReport sender_report = NewSenderReport(); rtc::Buffer buffer = sender_report.Build(); return std::make_unique(buffer); } case SupportedRtcpTypes::kReceiverReport: { rtcp::ReceiverReport receiver_report = NewReceiverReport(); rtc::Buffer buffer = receiver_report.Build(); return std::make_unique(buffer); } case SupportedRtcpTypes::kExtendedReports: { rtcp::ExtendedReports extended_report = NewExtendedReports(); rtc::Buffer buffer = extended_report.Build(); return std::make_unique(buffer); } case SupportedRtcpTypes::kFir: { rtcp::Fir fir = NewFir(); rtc::Buffer buffer = fir.Build(); return std::make_unique(buffer); } case SupportedRtcpTypes::kPli: { rtcp::Pli pli = NewPli(); rtc::Buffer buffer = pli.Build(); return std::make_unique(buffer); } case SupportedRtcpTypes::kNack: { rtcp::Nack nack = NewNack(); rtc::Buffer buffer = nack.Build(); return std::make_unique(buffer); } case SupportedRtcpTypes::kRemb: { rtcp::Remb remb = NewRemb(); rtc::Buffer buffer = remb.Build(); return std::make_unique(buffer); } case SupportedRtcpTypes::kBye: { rtcp::Bye bye = NewBye(); rtc::Buffer buffer = bye.Build(); return std::make_unique(buffer); } case SupportedRtcpTypes::kTransportFeedback: { rtcp::TransportFeedback transport_feedback = NewTransportFeedback(); rtc::Buffer buffer = transport_feedback.Build(); return std::make_unique(buffer); } default: RTC_DCHECK_NOTREACHED(); rtc::Buffer buffer; return std::make_unique(buffer); } } std::unique_ptr EventGenerator::NewGenericPacketSent() { return std::make_unique( sent_packet_number_++, prng_.Rand(40, 50), prng_.Rand(0, 150), prng_.Rand(0, 1000)); } std::unique_ptr EventGenerator::NewGenericPacketReceived() { return std::make_unique( received_packet_number_++, prng_.Rand(40, 250)); } std::unique_ptr EventGenerator::NewGenericAckReceived() { absl::optional receive_timestamp = absl::nullopt; if (prng_.Rand(0, 2) > 0) { receive_timestamp = prng_.Rand(0, 100000); } AckedPacket packet = {prng_.Rand(40, 250), receive_timestamp}; return std::move(RtcEventGenericAckReceived::CreateLogs( received_packet_number_++, std::vector{packet})[0]); } void EventGenerator::RandomizeRtpPacket( size_t payload_size, size_t padding_size, uint32_t ssrc, const RtpHeaderExtensionMap& extension_map, RtpPacket* rtp_packet, bool all_configured_exts) { 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) && (all_configured_exts || prng_.Rand())) { rtp_packet->SetExtension(prng_.Rand(0x00ffffff)); } if (extension_map.IsRegistered(AudioLevel::kId) && (all_configured_exts || prng_.Rand())) { rtp_packet->SetExtension(prng_.Rand(), prng_.Rand(127)); } if (extension_map.IsRegistered(AbsoluteSendTime::kId) && (all_configured_exts || prng_.Rand())) { rtp_packet->SetExtension(prng_.Rand(0x00ffffff)); } if (extension_map.IsRegistered(VideoOrientation::kId) && (all_configured_exts || prng_.Rand())) { rtp_packet->SetExtension(prng_.Rand(3)); } if (extension_map.IsRegistered(TransportSequenceNumber::kId) && (all_configured_exts || prng_.Rand())) { rtp_packet->SetExtension(prng_.Rand()); } if (extension_map.IsRegistered(RtpDependencyDescriptorExtension::kId) && (all_configured_exts || prng_.Rand())) { std::vector raw_data(3 + prng_.Rand(6)); for (uint8_t& d : raw_data) { d = prng_.Rand(); } rtp_packet->SetRawExtension(raw_data); } 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(); } RTC_CHECK(rtp_packet->SetPadding(padding_size)); } std::unique_ptr EventGenerator::NewRtpPacketIncoming( uint32_t ssrc, const RtpHeaderExtensionMap& extension_map, bool all_configured_exts) { constexpr size_t kMaxPaddingLength = 224; const bool padding = prng_.Rand(0, 9) == 0; // Let padding be 10% probable. const size_t padding_size = !padding ? 0u : prng_.Rand(0u, kMaxPaddingLength); // 12 bytes RTP header, 4 bytes for 0xBEDE + alignment, 4 bytes per CSRC. constexpr size_t kMaxHeaderSize = 16 + 4 * kMaxCsrcs + kMaxExtensionSizeBytes * kMaxNumExtensions; // In principle, a packet can contain both padding and other payload. // Currently, RTC eventlog encoder-parser can only maintain padding length if // packet is full padding. // TODO(webrtc:9730): Remove the deterministic logic for padding_size > 0. size_t payload_size = padding_size > 0 ? 0 : prng_.Rand(0u, static_cast(IP_PACKET_SIZE - 1 - padding_size - kMaxHeaderSize)); RtpPacketReceived rtp_packet(&extension_map); RandomizeRtpPacket(payload_size, padding_size, ssrc, extension_map, &rtp_packet, all_configured_exts); return std::make_unique(rtp_packet); } std::unique_ptr EventGenerator::NewRtpPacketOutgoing( uint32_t ssrc, const RtpHeaderExtensionMap& extension_map, bool all_configured_exts) { constexpr size_t kMaxPaddingLength = 224; const bool padding = prng_.Rand(0, 9) == 0; // Let padding be 10% probable. const size_t padding_size = !padding ? 0u : prng_.Rand(0u, kMaxPaddingLength); // 12 bytes RTP header, 4 bytes for 0xBEDE + alignment, 4 bytes per CSRC. constexpr size_t kMaxHeaderSize = 16 + 4 * kMaxCsrcs + kMaxExtensionSizeBytes * kMaxNumExtensions; // In principle,a packet can contain both padding and other payload. // Currently, RTC eventlog encoder-parser can only maintain padding length if // packet is full padding. // TODO(webrtc:9730): Remove the deterministic logic for padding_size > 0. size_t payload_size = padding_size > 0 ? 0 : prng_.Rand(0u, static_cast(IP_PACKET_SIZE - 1 - padding_size - kMaxHeaderSize)); RtpPacketToSend rtp_packet(&extension_map); RandomizeRtpPacket(payload_size, padding_size, ssrc, extension_map, &rtp_packet, all_configured_exts); int probe_cluster_id = prng_.Rand(0, 100000); return std::make_unique(rtp_packet, probe_cluster_id); } RtpHeaderExtensionMap EventGenerator::NewRtpHeaderExtensionMap( bool configure_all, const std::vector& excluded_extensions) { RtpHeaderExtensionMap extension_map; std::vector id(RtpExtension::kOneByteHeaderExtensionMaxId - RtpExtension::kMinId + 1); std::iota(id.begin(), id.end(), RtpExtension::kMinId); ShuffleInPlace(&prng_, rtc::ArrayView(id)); auto not_excluded = [&](RTPExtensionType type) -> bool { return !absl::c_linear_search(excluded_extensions, type); }; if (not_excluded(AudioLevel::kId) && (configure_all || prng_.Rand())) { extension_map.Register(id[0]); } if (not_excluded(TransmissionOffset::kId) && (configure_all || prng_.Rand())) { extension_map.Register(id[1]); } if (not_excluded(AbsoluteSendTime::kId) && (configure_all || prng_.Rand())) { extension_map.Register(id[2]); } if (not_excluded(VideoOrientation::kId) && (configure_all || prng_.Rand())) { extension_map.Register(id[3]); } if (not_excluded(TransportSequenceNumber::kId) && (configure_all || prng_.Rand())) { extension_map.Register(id[4]); } if (not_excluded(RtpDependencyDescriptorExtension::kId) && (configure_all || prng_.Rand())) { extension_map.Register(id[5]); } return extension_map; } std::unique_ptr EventGenerator::NewAudioReceiveStreamConfig( uint32_t ssrc, const RtpHeaderExtensionMap& extensions) { auto config = std::make_unique(); // 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 std::make_unique(std::move(config)); } std::unique_ptr EventGenerator::NewAudioSendStreamConfig( uint32_t ssrc, const RtpHeaderExtensionMap& extensions) { auto config = std::make_unique(); // 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 std::make_unique(std::move(config)); } std::unique_ptr EventGenerator::NewVideoReceiveStreamConfig( uint32_t ssrc, const RtpHeaderExtensionMap& extensions) { auto config = std::make_unique(); // 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 std::make_unique(std::move(config)); } std::unique_ptr EventGenerator::NewVideoSendStreamConfig( uint32_t ssrc, const RtpHeaderExtensionMap& extensions) { auto config = std::make_unique(); 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 std::make_unique(std::move(config)); } void EventVerifier::VerifyLoggedAlrStateEvent( const RtcEventAlrState& original_event, const LoggedAlrStateEvent& logged_event) const { EXPECT_EQ(original_event.timestamp_ms(), logged_event.log_time_ms()); EXPECT_EQ(original_event.in_alr(), logged_event.in_alr); } void EventVerifier::VerifyLoggedAudioPlayoutEvent( const RtcEventAudioPlayout& original_event, const LoggedAudioPlayoutEvent& logged_event) const { EXPECT_EQ(original_event.timestamp_ms(), logged_event.log_time_ms()); EXPECT_EQ(original_event.ssrc(), logged_event.ssrc); } void EventVerifier::VerifyLoggedAudioNetworkAdaptationEvent( const RtcEventAudioNetworkAdaptation& original_event, const LoggedAudioNetworkAdaptationEvent& logged_event) const { EXPECT_EQ(original_event.timestamp_ms(), logged_event.log_time_ms()); EXPECT_EQ(original_event.config().bitrate_bps, logged_event.config.bitrate_bps); EXPECT_EQ(original_event.config().enable_dtx, logged_event.config.enable_dtx); EXPECT_EQ(original_event.config().enable_fec, logged_event.config.enable_fec); EXPECT_EQ(original_event.config().frame_length_ms, logged_event.config.frame_length_ms); EXPECT_EQ(original_event.config().num_channels, logged_event.config.num_channels); // uplink_packet_loss_fraction ASSERT_EQ(original_event.config().uplink_packet_loss_fraction.has_value(), logged_event.config.uplink_packet_loss_fraction.has_value()); if (original_event.config().uplink_packet_loss_fraction.has_value()) { const float original = original_event.config().uplink_packet_loss_fraction.value(); const float logged = logged_event.config.uplink_packet_loss_fraction.value(); const float uplink_packet_loss_fraction_delta = std::abs(original - logged); EXPECT_LE(uplink_packet_loss_fraction_delta, 0.0001f); } } void EventVerifier::VerifyLoggedBweDelayBasedUpdate( const RtcEventBweUpdateDelayBased& original_event, const LoggedBweDelayBasedUpdate& logged_event) const { EXPECT_EQ(original_event.timestamp_ms(), logged_event.log_time_ms()); EXPECT_EQ(original_event.bitrate_bps(), logged_event.bitrate_bps); EXPECT_EQ(original_event.detector_state(), logged_event.detector_state); } void EventVerifier::VerifyLoggedBweLossBasedUpdate( const RtcEventBweUpdateLossBased& original_event, const LoggedBweLossBasedUpdate& logged_event) const { EXPECT_EQ(original_event.timestamp_ms(), logged_event.log_time_ms()); EXPECT_EQ(original_event.bitrate_bps(), logged_event.bitrate_bps); EXPECT_EQ(original_event.fraction_loss(), logged_event.fraction_lost); EXPECT_EQ(original_event.total_packets(), logged_event.expected_packets); } void EventVerifier::VerifyLoggedBweProbeClusterCreatedEvent( const RtcEventProbeClusterCreated& original_event, const LoggedBweProbeClusterCreatedEvent& logged_event) const { EXPECT_EQ(original_event.timestamp_ms(), logged_event.log_time_ms()); EXPECT_EQ(original_event.id(), logged_event.id); EXPECT_EQ(original_event.bitrate_bps(), logged_event.bitrate_bps); EXPECT_EQ(original_event.min_probes(), logged_event.min_packets); EXPECT_EQ(original_event.min_bytes(), logged_event.min_bytes); } void EventVerifier::VerifyLoggedBweProbeFailureEvent( const RtcEventProbeResultFailure& original_event, const LoggedBweProbeFailureEvent& logged_event) const { EXPECT_EQ(original_event.timestamp_ms(), logged_event.log_time_ms()); EXPECT_EQ(original_event.id(), logged_event.id); EXPECT_EQ(original_event.failure_reason(), logged_event.failure_reason); } void EventVerifier::VerifyLoggedBweProbeSuccessEvent( const RtcEventProbeResultSuccess& original_event, const LoggedBweProbeSuccessEvent& logged_event) const { EXPECT_EQ(original_event.timestamp_ms(), logged_event.log_time_ms()); EXPECT_EQ(original_event.id(), logged_event.id); EXPECT_EQ(original_event.bitrate_bps(), logged_event.bitrate_bps); } void EventVerifier::VerifyLoggedDtlsTransportState( const RtcEventDtlsTransportState& original_event, const LoggedDtlsTransportState& logged_event) const { EXPECT_EQ(original_event.timestamp_ms(), logged_event.log_time_ms()); EXPECT_EQ(original_event.dtls_transport_state(), logged_event.dtls_transport_state); } void EventVerifier::VerifyLoggedDtlsWritableState( const RtcEventDtlsWritableState& original_event, const LoggedDtlsWritableState& logged_event) const { EXPECT_EQ(original_event.timestamp_ms(), logged_event.log_time_ms()); EXPECT_EQ(original_event.writable(), logged_event.writable); } void EventVerifier::VerifyLoggedFrameDecoded( const RtcEventFrameDecoded& original_event, const LoggedFrameDecoded& logged_event) const { EXPECT_EQ(original_event.timestamp_ms(), logged_event.log_time_ms()); EXPECT_EQ(original_event.ssrc(), logged_event.ssrc); EXPECT_EQ(original_event.render_time_ms(), logged_event.render_time_ms); EXPECT_EQ(original_event.width(), logged_event.width); EXPECT_EQ(original_event.height(), logged_event.height); EXPECT_EQ(original_event.codec(), logged_event.codec); EXPECT_EQ(original_event.qp(), logged_event.qp); } void EventVerifier::VerifyLoggedIceCandidatePairConfig( const RtcEventIceCandidatePairConfig& original_event, const LoggedIceCandidatePairConfig& logged_event) const { EXPECT_EQ(original_event.timestamp_ms(), logged_event.log_time_ms()); EXPECT_EQ(original_event.type(), logged_event.type); EXPECT_EQ(original_event.candidate_pair_id(), logged_event.candidate_pair_id); EXPECT_EQ(original_event.candidate_pair_desc().local_candidate_type, logged_event.local_candidate_type); EXPECT_EQ(original_event.candidate_pair_desc().local_relay_protocol, logged_event.local_relay_protocol); EXPECT_EQ(original_event.candidate_pair_desc().local_network_type, logged_event.local_network_type); EXPECT_EQ(original_event.candidate_pair_desc().local_address_family, logged_event.local_address_family); EXPECT_EQ(original_event.candidate_pair_desc().remote_candidate_type, logged_event.remote_candidate_type); EXPECT_EQ(original_event.candidate_pair_desc().remote_address_family, logged_event.remote_address_family); EXPECT_EQ(original_event.candidate_pair_desc().candidate_pair_protocol, logged_event.candidate_pair_protocol); } void EventVerifier::VerifyLoggedIceCandidatePairEvent( const RtcEventIceCandidatePair& original_event, const LoggedIceCandidatePairEvent& logged_event) const { EXPECT_EQ(original_event.timestamp_ms(), logged_event.log_time_ms()); EXPECT_EQ(original_event.type(), logged_event.type); EXPECT_EQ(original_event.candidate_pair_id(), logged_event.candidate_pair_id); if (encoding_type_ == RtcEventLog::EncodingType::NewFormat) { EXPECT_EQ(original_event.transaction_id(), logged_event.transaction_id); } } template void VerifyLoggedRtpHeader(const Event& original_header, const RTPHeader& logged_header) { // Standard RTP header. EXPECT_EQ(original_header.Marker(), logged_header.markerBit); EXPECT_EQ(original_header.PayloadType(), logged_header.payloadType); EXPECT_EQ(original_header.SequenceNumber(), logged_header.sequenceNumber); EXPECT_EQ(original_header.Timestamp(), logged_header.timestamp); EXPECT_EQ(original_header.Ssrc(), logged_header.ssrc); EXPECT_EQ(original_header.header_length(), logged_header.headerLength); // TransmissionOffset header extension. ASSERT_EQ(original_header.template HasExtension(), logged_header.extension.hasTransmissionTimeOffset); if (logged_header.extension.hasTransmissionTimeOffset) { int32_t offset; ASSERT_TRUE( original_header.template GetExtension(&offset)); EXPECT_EQ(offset, logged_header.extension.transmissionTimeOffset); } // AbsoluteSendTime header extension. ASSERT_EQ(original_header.template HasExtension(), logged_header.extension.hasAbsoluteSendTime); if (logged_header.extension.hasAbsoluteSendTime) { uint32_t sendtime; ASSERT_TRUE( original_header.template GetExtension(&sendtime)); EXPECT_EQ(sendtime, logged_header.extension.absoluteSendTime); } // TransportSequenceNumber header extension. ASSERT_EQ(original_header.template HasExtension(), logged_header.extension.hasTransportSequenceNumber); if (logged_header.extension.hasTransportSequenceNumber) { uint16_t seqnum; ASSERT_TRUE(original_header.template GetExtension( &seqnum)); EXPECT_EQ(seqnum, logged_header.extension.transportSequenceNumber); } // AudioLevel header extension. ASSERT_EQ(original_header.template HasExtension(), logged_header.extension.hasAudioLevel); if (logged_header.extension.hasAudioLevel) { bool voice_activity; uint8_t audio_level; ASSERT_TRUE(original_header.template GetExtension( &voice_activity, &audio_level)); EXPECT_EQ(voice_activity, logged_header.extension.voiceActivity); EXPECT_EQ(audio_level, logged_header.extension.audioLevel); } // VideoOrientation header extension. ASSERT_EQ(original_header.template HasExtension(), logged_header.extension.hasVideoRotation); if (logged_header.extension.hasVideoRotation) { uint8_t rotation; ASSERT_TRUE( original_header.template GetExtension(&rotation)); EXPECT_EQ(ConvertCVOByteToVideoRotation(rotation), logged_header.extension.videoRotation); } } template void VerifyLoggedDependencyDescriptor(const Event& packet, const std::vector& logged_dd) { if (webrtc::field_trial::IsDisabled( "WebRTC-RtcEventLogEncodeDependencyDescriptor")) { EXPECT_TRUE(logged_dd.empty()); } else { rtc::ArrayView original = packet.template GetRawExtension(); EXPECT_EQ(logged_dd.size(), original.size()); bool dd_is_same = true; for (size_t i = 0; i < logged_dd.size(); ++i) { dd_is_same = logged_dd[i] == original[i]; if (!dd_is_same) { break; } } EXPECT_TRUE(dd_is_same); } } void EventVerifier::VerifyLoggedRouteChangeEvent( const RtcEventRouteChange& original_event, const LoggedRouteChangeEvent& logged_event) const { EXPECT_EQ(original_event.timestamp_ms(), logged_event.log_time_ms()); EXPECT_EQ(original_event.connected(), logged_event.connected); EXPECT_EQ(original_event.overhead(), logged_event.overhead); } void EventVerifier::VerifyLoggedRemoteEstimateEvent( const RtcEventRemoteEstimate& original_event, const LoggedRemoteEstimateEvent& logged_event) const { EXPECT_EQ(original_event.timestamp_ms(), logged_event.log_time_ms()); EXPECT_EQ(original_event.link_capacity_lower_, logged_event.link_capacity_lower); EXPECT_EQ(original_event.link_capacity_upper_, logged_event.link_capacity_upper); } void EventVerifier::VerifyLoggedRtpPacketIncoming( const RtcEventRtpPacketIncoming& original_event, const LoggedRtpPacketIncoming& logged_event) const { EXPECT_EQ(original_event.timestamp_ms(), logged_event.log_time_ms()); EXPECT_EQ(original_event.header_length(), logged_event.rtp.header_length); EXPECT_EQ(original_event.packet_length(), logged_event.rtp.total_length); // Currently, RTC eventlog encoder-parser can only maintain padding length // if packet is full padding. EXPECT_EQ(original_event.padding_length(), logged_event.rtp.header.paddingLength); VerifyLoggedRtpHeader(original_event, logged_event.rtp.header); VerifyLoggedDependencyDescriptor( original_event, logged_event.rtp.dependency_descriptor_wire_format); } void EventVerifier::VerifyLoggedRtpPacketOutgoing( const RtcEventRtpPacketOutgoing& original_event, const LoggedRtpPacketOutgoing& logged_event) const { EXPECT_EQ(original_event.timestamp_ms(), logged_event.log_time_ms()); EXPECT_EQ(original_event.header_length(), logged_event.rtp.header_length); EXPECT_EQ(original_event.packet_length(), logged_event.rtp.total_length); // Currently, RTC eventlog encoder-parser can only maintain padding length // if packet is full padding. EXPECT_EQ(original_event.padding_length(), logged_event.rtp.header.paddingLength); // TODO(terelius): Probe cluster ID isn't parsed, used or tested. Unless // someone has a strong reason to keep it, it'll be removed. VerifyLoggedRtpHeader(original_event, logged_event.rtp.header); VerifyLoggedDependencyDescriptor( original_event, logged_event.rtp.dependency_descriptor_wire_format); } void EventVerifier::VerifyLoggedGenericPacketSent( const RtcEventGenericPacketSent& original_event, const LoggedGenericPacketSent& logged_event) const { EXPECT_EQ(original_event.timestamp_ms(), logged_event.log_time_ms()); EXPECT_EQ(original_event.packet_number(), logged_event.packet_number); EXPECT_EQ(original_event.overhead_length(), logged_event.overhead_length); EXPECT_EQ(original_event.payload_length(), logged_event.payload_length); EXPECT_EQ(original_event.padding_length(), logged_event.padding_length); } void EventVerifier::VerifyLoggedGenericPacketReceived( const RtcEventGenericPacketReceived& original_event, const LoggedGenericPacketReceived& logged_event) const { EXPECT_EQ(original_event.timestamp_ms(), logged_event.log_time_ms()); EXPECT_EQ(original_event.packet_number(), logged_event.packet_number); EXPECT_EQ(static_cast(original_event.packet_length()), logged_event.packet_length); } void EventVerifier::VerifyLoggedGenericAckReceived( const RtcEventGenericAckReceived& original_event, const LoggedGenericAckReceived& logged_event) const { EXPECT_EQ(original_event.timestamp_ms(), logged_event.log_time_ms()); EXPECT_EQ(original_event.packet_number(), logged_event.packet_number); EXPECT_EQ(original_event.acked_packet_number(), logged_event.acked_packet_number); EXPECT_EQ(original_event.receive_acked_packet_time_ms(), logged_event.receive_acked_packet_time_ms); } void EventVerifier::VerifyLoggedRtcpPacketIncoming( const RtcEventRtcpPacketIncoming& original_event, const LoggedRtcpPacketIncoming& logged_event) const { EXPECT_EQ(original_event.timestamp_ms(), logged_event.log_time_ms()); ASSERT_EQ(original_event.packet().size(), logged_event.rtcp.raw_data.size()); EXPECT_EQ( memcmp(original_event.packet().data(), logged_event.rtcp.raw_data.data(), original_event.packet().size()), 0); } void EventVerifier::VerifyLoggedRtcpPacketOutgoing( const RtcEventRtcpPacketOutgoing& original_event, const LoggedRtcpPacketOutgoing& logged_event) const { EXPECT_EQ(original_event.timestamp_ms(), logged_event.log_time_ms()); ASSERT_EQ(original_event.packet().size(), logged_event.rtcp.raw_data.size()); EXPECT_EQ( memcmp(original_event.packet().data(), logged_event.rtcp.raw_data.data(), original_event.packet().size()), 0); } void EventVerifier::VerifyReportBlock( const rtcp::ReportBlock& original_report_block, const rtcp::ReportBlock& logged_report_block) { EXPECT_EQ(original_report_block.source_ssrc(), logged_report_block.source_ssrc()); EXPECT_EQ(original_report_block.fraction_lost(), logged_report_block.fraction_lost()); EXPECT_EQ(original_report_block.cumulative_lost(), logged_report_block.cumulative_lost()); EXPECT_EQ(original_report_block.extended_high_seq_num(), logged_report_block.extended_high_seq_num()); EXPECT_EQ(original_report_block.jitter(), logged_report_block.jitter()); EXPECT_EQ(original_report_block.last_sr(), logged_report_block.last_sr()); EXPECT_EQ(original_report_block.delay_since_last_sr(), logged_report_block.delay_since_last_sr()); } void EventVerifier::VerifyLoggedSenderReport( int64_t log_time_ms, const rtcp::SenderReport& original_sr, const LoggedRtcpPacketSenderReport& logged_sr) { EXPECT_EQ(log_time_ms, logged_sr.log_time_ms()); EXPECT_EQ(original_sr.sender_ssrc(), logged_sr.sr.sender_ssrc()); EXPECT_EQ(original_sr.ntp(), logged_sr.sr.ntp()); EXPECT_EQ(original_sr.rtp_timestamp(), logged_sr.sr.rtp_timestamp()); EXPECT_EQ(original_sr.sender_packet_count(), logged_sr.sr.sender_packet_count()); EXPECT_EQ(original_sr.sender_octet_count(), logged_sr.sr.sender_octet_count()); ASSERT_EQ(original_sr.report_blocks().size(), logged_sr.sr.report_blocks().size()); for (size_t i = 0; i < original_sr.report_blocks().size(); i++) { VerifyReportBlock(original_sr.report_blocks()[i], logged_sr.sr.report_blocks()[i]); } } void EventVerifier::VerifyLoggedReceiverReport( int64_t log_time_ms, const rtcp::ReceiverReport& original_rr, const LoggedRtcpPacketReceiverReport& logged_rr) { EXPECT_EQ(log_time_ms, logged_rr.log_time_ms()); EXPECT_EQ(original_rr.sender_ssrc(), logged_rr.rr.sender_ssrc()); ASSERT_EQ(original_rr.report_blocks().size(), logged_rr.rr.report_blocks().size()); for (size_t i = 0; i < original_rr.report_blocks().size(); i++) { VerifyReportBlock(original_rr.report_blocks()[i], logged_rr.rr.report_blocks()[i]); } } void EventVerifier::VerifyLoggedExtendedReports( int64_t log_time_ms, const rtcp::ExtendedReports& original_xr, const LoggedRtcpPacketExtendedReports& logged_xr) { EXPECT_EQ(log_time_ms, logged_xr.log_time_ms()); EXPECT_EQ(original_xr.sender_ssrc(), logged_xr.xr.sender_ssrc()); EXPECT_EQ(original_xr.rrtr().has_value(), logged_xr.xr.rrtr().has_value()); if (original_xr.rrtr().has_value() && logged_xr.xr.rrtr().has_value()) { EXPECT_EQ(original_xr.rrtr()->ntp(), logged_xr.xr.rrtr()->ntp()); } const auto& original_subblocks = original_xr.dlrr().sub_blocks(); const auto& logged_subblocks = logged_xr.xr.dlrr().sub_blocks(); ASSERT_EQ(original_subblocks.size(), logged_subblocks.size()); for (size_t i = 0; i < original_subblocks.size(); i++) { EXPECT_EQ(original_subblocks[i].ssrc, logged_subblocks[i].ssrc); EXPECT_EQ(original_subblocks[i].last_rr, logged_subblocks[i].last_rr); EXPECT_EQ(original_subblocks[i].delay_since_last_rr, logged_subblocks[i].delay_since_last_rr); } EXPECT_EQ(original_xr.target_bitrate().has_value(), logged_xr.xr.target_bitrate().has_value()); if (original_xr.target_bitrate().has_value() && logged_xr.xr.target_bitrate().has_value()) { const auto& original_bitrates = original_xr.target_bitrate()->GetTargetBitrates(); const auto& logged_bitrates = logged_xr.xr.target_bitrate()->GetTargetBitrates(); ASSERT_EQ(original_bitrates.size(), logged_bitrates.size()); for (size_t i = 0; i < original_bitrates.size(); i++) { EXPECT_EQ(original_bitrates[i].spatial_layer, logged_bitrates[i].spatial_layer); EXPECT_EQ(original_bitrates[i].temporal_layer, logged_bitrates[i].temporal_layer); EXPECT_EQ(original_bitrates[i].target_bitrate_kbps, logged_bitrates[i].target_bitrate_kbps); } } } void EventVerifier::VerifyLoggedFir(int64_t log_time_ms, const rtcp::Fir& original_fir, const LoggedRtcpPacketFir& logged_fir) { EXPECT_EQ(log_time_ms, logged_fir.log_time_ms()); EXPECT_EQ(original_fir.sender_ssrc(), logged_fir.fir.sender_ssrc()); const auto& original_requests = original_fir.requests(); const auto& logged_requests = logged_fir.fir.requests(); ASSERT_EQ(original_requests.size(), logged_requests.size()); for (size_t i = 0; i < original_requests.size(); i++) { EXPECT_EQ(original_requests[i].ssrc, logged_requests[i].ssrc); EXPECT_EQ(original_requests[i].seq_nr, logged_requests[i].seq_nr); } } void EventVerifier::VerifyLoggedPli(int64_t log_time_ms, const rtcp::Pli& original_pli, const LoggedRtcpPacketPli& logged_pli) { EXPECT_EQ(log_time_ms, logged_pli.log_time_ms()); EXPECT_EQ(original_pli.sender_ssrc(), logged_pli.pli.sender_ssrc()); EXPECT_EQ(original_pli.media_ssrc(), logged_pli.pli.media_ssrc()); } void EventVerifier::VerifyLoggedBye(int64_t log_time_ms, const rtcp::Bye& original_bye, const LoggedRtcpPacketBye& logged_bye) { EXPECT_EQ(log_time_ms, logged_bye.log_time_ms()); EXPECT_EQ(original_bye.sender_ssrc(), logged_bye.bye.sender_ssrc()); EXPECT_EQ(original_bye.csrcs(), logged_bye.bye.csrcs()); EXPECT_EQ(original_bye.reason(), logged_bye.bye.reason()); } void EventVerifier::VerifyLoggedNack(int64_t log_time_ms, const rtcp::Nack& original_nack, const LoggedRtcpPacketNack& logged_nack) { EXPECT_EQ(log_time_ms, logged_nack.log_time_ms()); EXPECT_EQ(original_nack.packet_ids(), logged_nack.nack.packet_ids()); } void EventVerifier::VerifyLoggedTransportFeedback( int64_t log_time_ms, const rtcp::TransportFeedback& original_transport_feedback, const LoggedRtcpPacketTransportFeedback& logged_transport_feedback) { EXPECT_EQ(log_time_ms, logged_transport_feedback.log_time_ms()); ASSERT_EQ( original_transport_feedback.GetReceivedPackets().size(), logged_transport_feedback.transport_feedback.GetReceivedPackets().size()); for (size_t i = 0; i < original_transport_feedback.GetReceivedPackets().size(); i++) { EXPECT_EQ( original_transport_feedback.GetReceivedPackets()[i].sequence_number(), logged_transport_feedback.transport_feedback.GetReceivedPackets()[i] .sequence_number()); EXPECT_EQ( original_transport_feedback.GetReceivedPackets()[i].delta(), logged_transport_feedback.transport_feedback.GetReceivedPackets()[i] .delta()); } } void EventVerifier::VerifyLoggedRemb(int64_t log_time_ms, const rtcp::Remb& original_remb, const LoggedRtcpPacketRemb& logged_remb) { EXPECT_EQ(log_time_ms, logged_remb.log_time_ms()); EXPECT_EQ(original_remb.ssrcs(), logged_remb.remb.ssrcs()); EXPECT_EQ(original_remb.bitrate_bps(), logged_remb.remb.bitrate_bps()); } void EventVerifier::VerifyLoggedLossNotification( int64_t log_time_ms, const rtcp::LossNotification& original_loss_notification, const LoggedRtcpPacketLossNotification& logged_loss_notification) { EXPECT_EQ(log_time_ms, logged_loss_notification.log_time_ms()); EXPECT_EQ(original_loss_notification.last_decoded(), logged_loss_notification.loss_notification.last_decoded()); EXPECT_EQ(original_loss_notification.last_received(), logged_loss_notification.loss_notification.last_received()); EXPECT_EQ(original_loss_notification.decodability_flag(), logged_loss_notification.loss_notification.decodability_flag()); } void EventVerifier::VerifyLoggedStartEvent( int64_t start_time_us, int64_t utc_start_time_us, const LoggedStartEvent& logged_event) const { EXPECT_EQ(start_time_us / 1000, logged_event.log_time_ms()); if (encoding_type_ == RtcEventLog::EncodingType::NewFormat) { EXPECT_EQ(utc_start_time_us / 1000, logged_event.utc_start_time.ms()); } } void EventVerifier::VerifyLoggedStopEvent( int64_t stop_time_us, const LoggedStopEvent& logged_event) const { EXPECT_EQ(stop_time_us / 1000, logged_event.log_time_ms()); } void VerifyLoggedStreamConfig(const rtclog::StreamConfig& original_config, const rtclog::StreamConfig& logged_config) { EXPECT_EQ(original_config.local_ssrc, logged_config.local_ssrc); EXPECT_EQ(original_config.remote_ssrc, logged_config.remote_ssrc); EXPECT_EQ(original_config.rtx_ssrc, logged_config.rtx_ssrc); EXPECT_EQ(original_config.rtp_extensions.size(), logged_config.rtp_extensions.size()); size_t recognized_extensions = 0; for (size_t i = 0; i < kMaxNumExtensions; i++) { auto original_id = GetExtensionId(original_config.rtp_extensions, kExtensions[i].name); auto logged_id = GetExtensionId(logged_config.rtp_extensions, kExtensions[i].name); EXPECT_EQ(original_id, logged_id) << "IDs for " << kExtensions[i].name << " don't match. Original ID " << original_id.value_or(-1) << ". Parsed ID " << logged_id.value_or(-1) << "."; if (original_id) { recognized_extensions++; } } EXPECT_EQ(recognized_extensions, original_config.rtp_extensions.size()); } void EventVerifier::VerifyLoggedAudioRecvConfig( const RtcEventAudioReceiveStreamConfig& original_event, const LoggedAudioRecvConfig& logged_event) const { EXPECT_EQ(original_event.timestamp_ms(), logged_event.log_time_ms()); VerifyLoggedStreamConfig(original_event.config(), logged_event.config); } void EventVerifier::VerifyLoggedAudioSendConfig( const RtcEventAudioSendStreamConfig& original_event, const LoggedAudioSendConfig& logged_event) const { EXPECT_EQ(original_event.timestamp_ms(), logged_event.log_time_ms()); VerifyLoggedStreamConfig(original_event.config(), logged_event.config); } void EventVerifier::VerifyLoggedVideoRecvConfig( const RtcEventVideoReceiveStreamConfig& original_event, const LoggedVideoRecvConfig& logged_event) const { EXPECT_EQ(original_event.timestamp_ms(), logged_event.log_time_ms()); VerifyLoggedStreamConfig(original_event.config(), logged_event.config); } void EventVerifier::VerifyLoggedVideoSendConfig( const RtcEventVideoSendStreamConfig& original_event, const LoggedVideoSendConfig& logged_event) const { EXPECT_EQ(original_event.timestamp_ms(), logged_event.log_time_ms()); VerifyLoggedStreamConfig(original_event.config(), logged_event.config); } void EventVerifier::VerifyLoggedNetEqSetMinimumDelay( const RtcEventNetEqSetMinimumDelay& original_event, const LoggedNetEqSetMinimumDelayEvent& logged_event) const { EXPECT_EQ(original_event.timestamp_ms(), logged_event.timestamp.ms()); EXPECT_EQ(original_event.remote_ssrc(), logged_event.remote_ssrc); EXPECT_EQ(original_event.minimum_delay_ms(), logged_event.minimum_delay_ms); } } // namespace test } // namespace webrtc