/* * Copyright 2023 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.
*/
uint32_t RtpNow() { // Note - the "random" offset of this timestamp is zero. return rtc::TimeMillis() * 1000 / kSampleRateHz;
}
RtpPacketReceived CreateRtpPacket() {
RtpPacketReceived packet;
packet.set_arrival_time(time_controller_.GetClock()->CurrentTime());
packet.SetTimestamp(RtpNow());
packet.SetSsrc(kLocalSsrc);
packet.SetPayloadType(kPayloadType); // Packet size should be enough to give at least 10 ms of data. // For PCMA, that's 80 bytes; this should be enough.
uint8_t* datapos = packet.SetPayloadSize(100);
memset(datapos, 0, 100); return packet;
}
std::vector<uint8_t> CreateRtcpReceiverReport() {
rtcp::ReportBlock block;
block.SetMediaSsrc(kLocalSsrc); // Middle 32 bits of the NTP timestamp from received SR
block.SetLastSr(CompactNtp(NtpNow()));
block.SetDelayLastSr(0);
int64_t ProbeCaptureStartNtpTime(ChannelReceiveInterface& channel) { // Computation of the capture_start_ntp_time_ms_ occurs when the // audio data is pulled, not when it is received. So we need to // inject an RTP packet, and then fetch its data.
AudioFrame audio_frame;
channel.OnRtpPacket(CreateRtpPacket());
channel.GetAudioFrameWithInfo(kSampleRateHz, &audio_frame);
CallReceiveStatistics stats = channel.GetRTCPStatistics(); return stats.capture_start_ntp_time_ms_;
}
TEST_F(ChannelReceiveTest, CreateAndDestroy) { auto channel = CreateTestChannelReceive();
EXPECT_THAT(channel, NotNull());
}
TEST_F(ChannelReceiveTest, ReceiveReportGeneratedOnTime) { auto channel = CreateTestChannelReceive();
bool receiver_report_sent = false;
EXPECT_CALL(transport_, SendRtcp)
.WillRepeatedly([&](rtc::ArrayView<const uint8_t> packet) { if (packet.size() >= 2 &&
packet[1] == rtcp::ReceiverReport::kPacketType) {
receiver_report_sent = true;
} returntrue;
}); // RFC 3550 section 6.2 mentions 5 seconds as a reasonable expectation // for the interval between RTCP packets.
time_controller_.AdvanceTime(TimeDelta::Seconds(5));
EXPECT_TRUE(receiver_report_sent);
}
TEST_F(ChannelReceiveTest, CaptureStartTimeBecomesValid) { auto channel = CreateTestChannelReceive();
EXPECT_CALL(transport_, SendRtcp)
.WillRepeatedly([&](rtc::ArrayView<const uint8_t> packet) {
HandleGeneratedRtcp(*channel, packet); returntrue;
}); // Before any packets are sent, CaptureStartTime is invalid.
EXPECT_EQ(ProbeCaptureStartNtpTime(*channel), -1);
// Must start playout, otherwise packet is discarded.
channel->StartPlayout(); // Send one RTP packet. This causes registration of the SSRC.
channel->OnRtpPacket(CreateRtpPacket());
EXPECT_EQ(ProbeCaptureStartNtpTime(*channel), -1);
// Receive a sender report. auto rtcp_packet_1 = CreateRtcpSenderReport();
channel->ReceivedRTCPPacket(rtcp_packet_1.data(), rtcp_packet_1.size());
EXPECT_EQ(ProbeCaptureStartNtpTime(*channel), -1);
// Receive a receiver report. This is necessary, which is odd. // Presumably it is because the receiver needs to know the RTT // before it can compute the capture start NTP time. // The receiver report must happen before the second sender report. auto rtcp_rr = CreateRtcpReceiverReport();
channel->ReceivedRTCPPacket(rtcp_rr.data(), rtcp_rr.size());
EXPECT_EQ(ProbeCaptureStartNtpTime(*channel), -1);
// Receive another sender report after 5 seconds. // This should be enough to establish the capture start NTP time. auto rtcp_packet_2 = CreateRtcpSenderReport();
channel->ReceivedRTCPPacket(rtcp_packet_2.data(), rtcp_packet_2.size());
// Set the same transformer again, shouldn't cause any additional callback // registration calls.
EXPECT_CALL(*mock_frame_transformer, RegisterTransformedFrameCallback)
.Times(0);
channel->SetDepacketizerToDecoderFrameTransformer(mock_frame_transformer);
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.