/* * 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 "modules/audio_coding/audio_network_adaptor/include/audio_network_adaptor.h" #include "modules/remote_bitrate_estimator/include/bwe_defines.h" #include "modules/rtp_rtcp/include/rtp_cvo.h" #include "modules/rtp_rtcp/source/rtp_header_extensions.h" #include "modules/rtp_rtcp/source/rtp_packet_received.h" #include "modules/rtp_rtcp/source/rtp_packet_to_send.h" #include "rtc_base/checks.h" 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 = 4; constexpr int kMaxNumExtensions = 5; constexpr ExtensionPair kExtensions[kMaxNumExtensions] = { {RTPExtensionType::kRtpExtensionTransmissionTimeOffset, RtpExtension::kTimestampOffsetUri}, {RTPExtensionType::kRtpExtensionAbsoluteSendTime, RtpExtension::kAbsSendTimeUri}, {RTPExtensionType::kRtpExtensionTransportSequenceNumber, RtpExtension::kTransportSequenceNumberUri}, {RTPExtensionType::kRtpExtensionAudioLevel, RtpExtension::kAudioLevelUri}, {RTPExtensionType::kRtpExtensionVideoRotation, RtpExtension::kVideoRotationUri}}; template void ShuffleInPlace(Random* prng, rtc::ArrayView array) { RTC_DCHECK_LE(array.size(), std::numeric_limits::max()); for (uint32_t i = 0; i + 1 < array.size(); i++) { uint32_t other = prng->Rand(i, static_cast(array.size() - 1)); std::swap(array[i], array[other]); } } } // namespace std::unique_ptr EventGenerator::NewAlrState() { return absl::make_unique(prng_.Rand()); } std::unique_ptr EventGenerator::NewAudioPlayout( uint32_t ssrc) { return absl::make_unique(ssrc); } std::unique_ptr EventGenerator::NewAudioNetworkAdaptation() { std::unique_ptr config = absl::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 absl::make_unique(std::move(config)); } 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 absl::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 absl::make_unique( bitrate_bps, fraction_lost, total_packets); } 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 absl::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 absl::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 absl::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 absl::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(); return absl::make_unique(type, pair_id); } rtcp::ReportBlock EventGenerator::NewReportBlock() { rtcp::ReportBlock report_block; report_block.SetMediaSsrc(prng_.Rand()); report_block.SetFractionLost(prng_.Rand()); // cumulative_lost is a 3-byte signed value. RTC_DCHECK(report_block.SetCumulativeLost( prng_.Rand(-(1 << 23) + 1, (1 << 23) - 1))); report_block.SetExtHighestSeqNum(prng_.Rand()); report_block.SetJitter(prng_.Rand()); report_block.SetLastSr(prng_.Rand()); report_block.SetDelayLastSr(prng_.Rand()); return report_block; } rtcp::SenderReport EventGenerator::NewSenderReport() { rtcp::SenderReport sender_report; sender_report.SetSenderSsrc(prng_.Rand()); sender_report.SetNtp(NtpTime(prng_.Rand(), prng_.Rand())); sender_report.SetPacketCount(prng_.Rand()); sender_report.AddReportBlock(NewReportBlock()); return sender_report; } rtcp::ReceiverReport EventGenerator::NewReceiverReport() { rtcp::ReceiverReport receiver_report; receiver_report.SetSenderSsrc(prng_.Rand()); receiver_report.AddReportBlock(NewReportBlock()); return receiver_report; } std::unique_ptr EventGenerator::NewRtcpPacketIncoming() { // TODO(terelius): Test the other RTCP types too. switch (prng_.Rand(0, 1)) { case 0: { rtcp::SenderReport sender_report = NewSenderReport(); rtc::Buffer buffer = sender_report.Build(); return absl::make_unique(buffer); } case 1: { rtcp::ReceiverReport receiver_report = NewReceiverReport(); rtc::Buffer buffer = receiver_report.Build(); return absl::make_unique(buffer); } default: RTC_NOTREACHED(); rtc::Buffer buffer; return absl::make_unique(buffer); } } std::unique_ptr EventGenerator::NewRtcpPacketOutgoing() { // TODO(terelius): Test the other RTCP types too. switch (prng_.Rand(0, 1)) { case 0: { rtcp::SenderReport sender_report = NewSenderReport(); rtc::Buffer buffer = sender_report.Build(); return absl::make_unique(buffer); } case 1: { rtcp::ReceiverReport receiver_report = NewReceiverReport(); rtc::Buffer buffer = receiver_report.Build(); return absl::make_unique(buffer); } default: RTC_NOTREACHED(); rtc::Buffer buffer; return absl::make_unique(buffer); } } void EventGenerator::RandomizeRtpPacket( size_t payload_size, size_t padding_size, uint32_t ssrc, const RtpHeaderExtensionMap& extension_map, RtpPacket* rtp_packet) { constexpr int kMaxPayloadType = 127; rtp_packet->SetPayloadType(prng_.Rand(kMaxPayloadType)); rtp_packet->SetMarker(prng_.Rand()); rtp_packet->SetSequenceNumber(prng_.Rand()); rtp_packet->SetSsrc(ssrc); rtp_packet->SetTimestamp(prng_.Rand()); uint32_t csrcs_count = prng_.Rand(0, kMaxCsrcs); std::vector csrcs; for (size_t i = 0; i < csrcs_count; i++) { csrcs.push_back(prng_.Rand()); } rtp_packet->SetCsrcs(csrcs); if (extension_map.IsRegistered(TransmissionOffset::kId)) rtp_packet->SetExtension(prng_.Rand(0x00ffffff)); if (extension_map.IsRegistered(AudioLevel::kId)) rtp_packet->SetExtension(prng_.Rand(), prng_.Rand(127)); if (extension_map.IsRegistered(AbsoluteSendTime::kId)) rtp_packet->SetExtension(prng_.Rand(0x00ffffff)); if (extension_map.IsRegistered(VideoOrientation::kId)) rtp_packet->SetExtension(prng_.Rand(3)); if (extension_map.IsRegistered(TransportSequenceNumber::kId)) rtp_packet->SetExtension(prng_.Rand()); RTC_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, &prng_)); } std::unique_ptr EventGenerator::NewRtpPacketIncoming( uint32_t ssrc, const RtpHeaderExtensionMap& extension_map) { 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); return absl::make_unique(rtp_packet); } std::unique_ptr EventGenerator::NewRtpPacketOutgoing( uint32_t ssrc, const RtpHeaderExtensionMap& extension_map) { 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, kMaxHeaderSize + payload_size + padding_size); RandomizeRtpPacket(payload_size, padding_size, ssrc, extension_map, &rtp_packet); int probe_cluster_id = prng_.Rand(0, 100000); return absl::make_unique(rtp_packet, probe_cluster_id); } RtpHeaderExtensionMap EventGenerator::NewRtpHeaderExtensionMap() { RtpHeaderExtensionMap extension_map; std::vector id(RtpExtension::kMaxId - RtpExtension::kMinId + 1); std::iota(id.begin(), id.end(), RtpExtension::kMinId); ShuffleInPlace(&prng_, rtc::ArrayView(id)); if (prng_.Rand()) { extension_map.Register(id[0]); } if (prng_.Rand()) { extension_map.Register(id[1]); } if (prng_.Rand()) { extension_map.Register(id[2]); } if (prng_.Rand()) { extension_map.Register(id[3]); } if (prng_.Rand()) { extension_map.Register(id[4]); } return extension_map; } std::unique_ptr EventGenerator::NewAudioReceiveStreamConfig( uint32_t ssrc, const RtpHeaderExtensionMap& extensions) { auto config = absl::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 absl::make_unique(std::move(config)); } std::unique_ptr EventGenerator::NewAudioSendStreamConfig( uint32_t ssrc, const RtpHeaderExtensionMap& extensions) { auto config = absl::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 absl::make_unique(std::move(config)); } std::unique_ptr EventGenerator::NewVideoReceiveStreamConfig( uint32_t ssrc, const RtpHeaderExtensionMap& extensions) { auto config = absl::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 absl::make_unique(std::move(config)); } std::unique_ptr EventGenerator::NewVideoSendStreamConfig( uint32_t ssrc, const RtpHeaderExtensionMap& extensions) { auto config = absl::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 absl::make_unique(std::move(config)); } bool VerifyLoggedAlrStateEvent(const RtcEventAlrState& original_event, const LoggedAlrStateEvent& logged_event) { if (original_event.timestamp_us_ != logged_event.log_time_us()) return false; if (original_event.in_alr_ != logged_event.in_alr) return false; return true; } bool VerifyLoggedAudioPlayoutEvent( const RtcEventAudioPlayout& original_event, const LoggedAudioPlayoutEvent& logged_event) { if (original_event.timestamp_us_ != logged_event.log_time_us()) return false; if (original_event.ssrc_ != logged_event.ssrc) return false; return true; } bool VerifyLoggedAudioNetworkAdaptationEvent( const RtcEventAudioNetworkAdaptation& original_event, const LoggedAudioNetworkAdaptationEvent& logged_event) { if (original_event.timestamp_us_ != logged_event.log_time_us()) return false; if (original_event.config_->bitrate_bps != logged_event.config.bitrate_bps) return false; if (original_event.config_->enable_dtx != logged_event.config.enable_dtx) return false; if (original_event.config_->enable_fec != logged_event.config.enable_fec) return false; if (original_event.config_->frame_length_ms != logged_event.config.frame_length_ms) return false; if (original_event.config_->num_channels != logged_event.config.num_channels) return false; if (original_event.config_->uplink_packet_loss_fraction != logged_event.config.uplink_packet_loss_fraction) return false; return true; } bool VerifyLoggedBweDelayBasedUpdate( const RtcEventBweUpdateDelayBased& original_event, const LoggedBweDelayBasedUpdate& logged_event) { if (original_event.timestamp_us_ != logged_event.log_time_us()) return false; if (original_event.bitrate_bps_ != logged_event.bitrate_bps) return false; if (original_event.detector_state_ != logged_event.detector_state) return false; return true; } bool VerifyLoggedBweLossBasedUpdate( const RtcEventBweUpdateLossBased& original_event, const LoggedBweLossBasedUpdate& logged_event) { if (original_event.timestamp_us_ != logged_event.log_time_us()) return false; if (original_event.bitrate_bps_ != logged_event.bitrate_bps) return false; if (original_event.fraction_loss_ != logged_event.fraction_lost) return false; if (original_event.total_packets_ != logged_event.expected_packets) return false; return true; } bool VerifyLoggedBweProbeClusterCreatedEvent( const RtcEventProbeClusterCreated& original_event, const LoggedBweProbeClusterCreatedEvent& logged_event) { if (original_event.timestamp_us_ != logged_event.log_time_us()) return false; if (original_event.id_ != logged_event.id) return false; if (original_event.bitrate_bps_ != logged_event.bitrate_bps) return false; if (original_event.min_probes_ != logged_event.min_packets) return false; if (original_event.min_bytes_ != logged_event.min_bytes) return false; return true; } bool VerifyLoggedBweProbeFailureEvent( const RtcEventProbeResultFailure& original_event, const LoggedBweProbeFailureEvent& logged_event) { if (original_event.timestamp_us_ != logged_event.log_time_us()) return false; if (original_event.id_ != logged_event.id) return false; if (original_event.failure_reason_ != logged_event.failure_reason) return false; return true; } bool VerifyLoggedBweProbeSuccessEvent( const RtcEventProbeResultSuccess& original_event, const LoggedBweProbeSuccessEvent& logged_event) { if (original_event.timestamp_us_ != logged_event.log_time_us()) return false; if (original_event.id_ != logged_event.id) return false; if (original_event.bitrate_bps_ != logged_event.bitrate_bps) return false; return true; } bool VerifyLoggedIceCandidatePairConfig( const RtcEventIceCandidatePairConfig& original_event, const LoggedIceCandidatePairConfig& logged_event) { if (original_event.timestamp_us_ != logged_event.log_time_us()) return false; if (original_event.type_ != logged_event.type) return false; if (original_event.candidate_pair_id_ != logged_event.candidate_pair_id) return false; if (original_event.candidate_pair_desc_.local_candidate_type != logged_event.local_candidate_type) return false; if (original_event.candidate_pair_desc_.local_relay_protocol != logged_event.local_relay_protocol) return false; if (original_event.candidate_pair_desc_.local_network_type != logged_event.local_network_type) return false; if (original_event.candidate_pair_desc_.local_address_family != logged_event.local_address_family) return false; if (original_event.candidate_pair_desc_.remote_candidate_type != logged_event.remote_candidate_type) return false; if (original_event.candidate_pair_desc_.remote_address_family != logged_event.remote_address_family) return false; if (original_event.candidate_pair_desc_.candidate_pair_protocol != logged_event.candidate_pair_protocol) return false; return true; } bool VerifyLoggedIceCandidatePairEvent( const RtcEventIceCandidatePair& original_event, const LoggedIceCandidatePairEvent& logged_event) { if (original_event.timestamp_us_ != logged_event.log_time_us()) return false; if (original_event.type_ != logged_event.type) return false; if (original_event.candidate_pair_id_ != logged_event.candidate_pair_id) return false; return true; } bool VerifyLoggedRtpHeader(const RtpPacket& original_header, const RTPHeader& logged_header) { // Standard RTP header. if (original_header.Marker() != logged_header.markerBit) return false; if (original_header.PayloadType() != logged_header.payloadType) return false; if (original_header.SequenceNumber() != logged_header.sequenceNumber) return false; if (original_header.Timestamp() != logged_header.timestamp) return false; if (original_header.Ssrc() != logged_header.ssrc) return false; if (original_header.Csrcs().size() != logged_header.numCSRCs) return false; for (size_t i = 0; i < logged_header.numCSRCs; i++) { if (original_header.Csrcs()[i] != logged_header.arrOfCSRCs[i]) return false; } if (original_header.headers_size() != logged_header.headerLength) return false; // TransmissionOffset header extension. if (original_header.HasExtension() != logged_header.extension.hasTransmissionTimeOffset) return false; if (logged_header.extension.hasTransmissionTimeOffset) { int32_t offset; original_header.GetExtension(&offset); if (offset != logged_header.extension.transmissionTimeOffset) return false; } // AbsoluteSendTime header extension. if (original_header.HasExtension() != logged_header.extension.hasAbsoluteSendTime) return false; if (logged_header.extension.hasAbsoluteSendTime) { uint32_t sendtime; original_header.GetExtension(&sendtime); if (sendtime != logged_header.extension.absoluteSendTime) return false; } // TransportSequenceNumber header extension. if (original_header.HasExtension() != logged_header.extension.hasTransportSequenceNumber) return false; if (logged_header.extension.hasTransportSequenceNumber) { uint16_t seqnum; original_header.GetExtension(&seqnum); if (seqnum != logged_header.extension.transportSequenceNumber) return false; } // AudioLevel header extension. if (original_header.HasExtension() != logged_header.extension.hasAudioLevel) return false; if (logged_header.extension.hasAudioLevel) { bool voice_activity; uint8_t audio_level; original_header.GetExtension(&voice_activity, &audio_level); if (voice_activity != logged_header.extension.voiceActivity) return false; if (audio_level != logged_header.extension.audioLevel) return false; } // VideoOrientation header extension. if (original_header.HasExtension() != logged_header.extension.hasVideoRotation) return false; if (logged_header.extension.hasVideoRotation) { uint8_t rotation; original_header.GetExtension(&rotation); if (ConvertCVOByteToVideoRotation(rotation) != logged_header.extension.videoRotation) return false; } return true; } bool VerifyLoggedRtpPacketIncoming( const RtcEventRtpPacketIncoming& original_event, const LoggedRtpPacketIncoming& logged_event) { if (original_event.timestamp_us_ != logged_event.log_time_us()) return false; if (original_event.header_.headers_size() != logged_event.rtp.header_length) return false; if (original_event.packet_length_ != logged_event.rtp.total_length) return false; if ((original_event.header_.data()[0] & 0x20) != 0 && // has padding original_event.packet_length_ - original_event.header_.headers_size() != logged_event.rtp.header.paddingLength) { // Currently, RTC eventlog encoder-parser can only maintain padding length // if packet is full padding. // TODO(webrtc:9730): Change the condition to something like // original_event.padding_length_ != logged_event.rtp.header.paddingLength. return false; } if (!VerifyLoggedRtpHeader(original_event.header_, logged_event.rtp.header)) return false; return true; } bool VerifyLoggedRtpPacketOutgoing( const RtcEventRtpPacketOutgoing& original_event, const LoggedRtpPacketOutgoing& logged_event) { if (original_event.timestamp_us_ != logged_event.log_time_us()) return false; if (original_event.header_.headers_size() != logged_event.rtp.header_length) return false; if (original_event.packet_length_ != logged_event.rtp.total_length) return false; if ((original_event.header_.data()[0] & 0x20) != 0 && // has padding original_event.packet_length_ - original_event.header_.headers_size() != logged_event.rtp.header.paddingLength) { // Currently, RTC eventlog encoder-parser can only maintain padding length // if packet is full padding. // TODO(webrtc:9730): Change the condition to something like // original_event.padding_length_ != logged_event.rtp.header.paddingLength. return false; } // TODO(terelius): Probe cluster ID isn't parsed, used or tested. Unless // someone has a strong reason to keep it, it'll be removed. if (!VerifyLoggedRtpHeader(original_event.header_, logged_event.rtp.header)) return false; return true; } bool VerifyLoggedRtcpPacketIncoming( const RtcEventRtcpPacketIncoming& original_event, const LoggedRtcpPacketIncoming& logged_event) { if (original_event.timestamp_us_ != logged_event.log_time_us()) return false; if (original_event.packet_.size() != logged_event.rtcp.raw_data.size()) return false; if (memcmp(original_event.packet_.data(), logged_event.rtcp.raw_data.data(), original_event.packet_.size()) != 0) { return false; } return true; } bool VerifyLoggedRtcpPacketOutgoing( const RtcEventRtcpPacketOutgoing& original_event, const LoggedRtcpPacketOutgoing& logged_event) { if (original_event.timestamp_us_ != logged_event.log_time_us()) return false; if (original_event.packet_.size() != logged_event.rtcp.raw_data.size()) return false; if (memcmp(original_event.packet_.data(), logged_event.rtcp.raw_data.data(), original_event.packet_.size()) != 0) { return false; } return true; } bool VerifyLoggedStartEvent(int64_t start_time_us, const LoggedStartEvent& logged_event) { if (start_time_us != logged_event.log_time_us()) return false; return true; } bool VerifyLoggedStopEvent(int64_t stop_time_us, const LoggedStopEvent& logged_event) { if (stop_time_us != logged_event.log_time_us()) return false; return true; } bool VerifyLoggedAudioRecvConfig( const RtcEventAudioReceiveStreamConfig& original_event, const LoggedAudioRecvConfig& logged_event) { if (original_event.timestamp_us_ != logged_event.log_time_us()) return false; if (*original_event.config_ != logged_event.config) return false; return true; } bool VerifyLoggedAudioSendConfig( const RtcEventAudioSendStreamConfig& original_event, const LoggedAudioSendConfig& logged_event) { if (original_event.timestamp_us_ != logged_event.log_time_us()) return false; if (*original_event.config_ != logged_event.config) return false; return true; } bool VerifyLoggedVideoRecvConfig( const RtcEventVideoReceiveStreamConfig& original_event, const LoggedVideoRecvConfig& logged_event) { if (original_event.timestamp_us_ != logged_event.log_time_us()) return false; if (*original_event.config_ != logged_event.config) return false; return true; } bool VerifyLoggedVideoSendConfig( const RtcEventVideoSendStreamConfig& original_event, const LoggedVideoSendConfig& logged_event) { if (original_event.timestamp_us_ != logged_event.log_time_us()) return false; // TODO(terelius): In the past, we allowed storing multiple RtcStreamConfigs // in the same RtcEventVideoSendStreamConfig. Look into whether we should drop // backwards compatibility in the parser. if (logged_event.configs.size() != 1) return false; if (*original_event.config_ != logged_event.configs[0]) return false; return true; } } // namespace test } // namespace webrtc