mirror of
https://github.com/mollyim/webrtc.git
synced 2025-05-16 23:30:48 +01:00
ChannelStatistics RTT test case around remote SSRC change.
Bug: webrtc:11989 Change-Id: I7211ffa83ad381b6367d78e553cd5943dca515f2 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/201880 Reviewed-by: Sam Zackrisson <saza@webrtc.org> Reviewed-by: Danil Chapovalov <danilchap@webrtc.org> Commit-Queue: Tim Na <natim@webrtc.org> Cr-Commit-Position: refs/heads/master@{#33039}
This commit is contained in:
parent
a24d35eb09
commit
1cbf21e157
1 changed files with 100 additions and 15 deletions
|
@ -28,6 +28,7 @@ namespace {
|
||||||
|
|
||||||
using ::testing::Invoke;
|
using ::testing::Invoke;
|
||||||
using ::testing::NiceMock;
|
using ::testing::NiceMock;
|
||||||
|
using ::testing::Return;
|
||||||
using ::testing::Unused;
|
using ::testing::Unused;
|
||||||
|
|
||||||
constexpr uint64_t kStartTime = 123456789;
|
constexpr uint64_t kStartTime = 123456789;
|
||||||
|
@ -53,23 +54,27 @@ class AudioChannelTest : public ::testing::Test {
|
||||||
Invoke([&](std::unique_ptr<QueuedTask> task) { task->Run(); }));
|
Invoke([&](std::unique_ptr<QueuedTask> task) { task->Run(); }));
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetUp() override {
|
void SetUp() override { audio_channel_ = CreateAudioChannel(kLocalSsrc); }
|
||||||
audio_channel_ = new rtc::RefCountedObject<AudioChannel>(
|
|
||||||
&transport_, kLocalSsrc, task_queue_factory_.get(),
|
|
||||||
process_thread_.get(), audio_mixer_.get(), decoder_factory_);
|
|
||||||
|
|
||||||
audio_channel_->SetEncoder(kPcmuPayload, kPcmuFormat,
|
void TearDown() override { audio_channel_ = nullptr; }
|
||||||
encoder_factory_->MakeAudioEncoder(
|
|
||||||
kPcmuPayload, kPcmuFormat, absl::nullopt));
|
|
||||||
audio_channel_->SetReceiveCodecs({{kPcmuPayload, kPcmuFormat}});
|
|
||||||
audio_channel_->StartSend();
|
|
||||||
audio_channel_->StartPlay();
|
|
||||||
}
|
|
||||||
|
|
||||||
void TearDown() override {
|
rtc::scoped_refptr<AudioChannel> CreateAudioChannel(uint32_t ssrc) {
|
||||||
audio_channel_->StopSend();
|
// Use same audio mixer here for simplicity sake as we are not checking
|
||||||
audio_channel_->StopPlay();
|
// audio activity of RTP in our testcases. If we need to do test on audio
|
||||||
audio_channel_ = nullptr;
|
// signal activity then we need to assign audio mixer for each channel.
|
||||||
|
// Also this uses the same transport object for different audio channel to
|
||||||
|
// simplify network routing logic.
|
||||||
|
rtc::scoped_refptr<AudioChannel> audio_channel =
|
||||||
|
new rtc::RefCountedObject<AudioChannel>(
|
||||||
|
&transport_, ssrc, task_queue_factory_.get(), process_thread_.get(),
|
||||||
|
audio_mixer_.get(), decoder_factory_);
|
||||||
|
audio_channel->SetEncoder(kPcmuPayload, kPcmuFormat,
|
||||||
|
encoder_factory_->MakeAudioEncoder(
|
||||||
|
kPcmuPayload, kPcmuFormat, absl::nullopt));
|
||||||
|
audio_channel->SetReceiveCodecs({{kPcmuPayload, kPcmuFormat}});
|
||||||
|
audio_channel->StartSend();
|
||||||
|
audio_channel->StartPlay();
|
||||||
|
return audio_channel;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<AudioFrame> GetAudioFrame(int order) {
|
std::unique_ptr<AudioFrame> GetAudioFrame(int order) {
|
||||||
|
@ -269,5 +274,85 @@ TEST_F(AudioChannelTest, TestChannelStatistics) {
|
||||||
EXPECT_FALSE(channel_stats->remote_rtcp->round_trip_time.has_value());
|
EXPECT_FALSE(channel_stats->remote_rtcp->round_trip_time.has_value());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Check ChannelStatistics RTT metric after processing RTP and RTCP packets
|
||||||
|
// using three audio channels where each represents media endpoint.
|
||||||
|
//
|
||||||
|
// 1) AC1 <- RTP/RTCP -> AC2
|
||||||
|
// 2) AC1 <- RTP/RTCP -> AC3
|
||||||
|
//
|
||||||
|
// During step 1), AC1 should be able to check RTT from AC2's SSRC.
|
||||||
|
// During step 2), AC1 should be able to check RTT from AC3's SSRC.
|
||||||
|
TEST_F(AudioChannelTest, RttIsAvailableAfterChangeOfRemoteSsrc) {
|
||||||
|
// Create AC2 and AC3.
|
||||||
|
constexpr uint32_t kAc2Ssrc = 0xdeadbeef;
|
||||||
|
constexpr uint32_t kAc3Ssrc = 0xdeafbeef;
|
||||||
|
|
||||||
|
auto ac_2 = CreateAudioChannel(kAc2Ssrc);
|
||||||
|
auto ac_3 = CreateAudioChannel(kAc3Ssrc);
|
||||||
|
|
||||||
|
auto send_recv_rtp = [&](rtc::scoped_refptr<AudioChannel> rtp_sender,
|
||||||
|
rtc::scoped_refptr<AudioChannel> rtp_receiver) {
|
||||||
|
// Setup routing logic via transport_.
|
||||||
|
auto route_rtp = [&](const uint8_t* packet, size_t length, Unused) {
|
||||||
|
rtp_receiver->ReceivedRTPPacket(rtc::MakeArrayView(packet, length));
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
ON_CALL(transport_, SendRtp).WillByDefault(route_rtp);
|
||||||
|
|
||||||
|
// This will trigger route_rtp callback via transport_.
|
||||||
|
rtp_sender->GetAudioSender()->SendAudioData(GetAudioFrame(0));
|
||||||
|
rtp_sender->GetAudioSender()->SendAudioData(GetAudioFrame(1));
|
||||||
|
|
||||||
|
// Process received RTP in receiver.
|
||||||
|
AudioFrame audio_frame;
|
||||||
|
audio_mixer_->Mix(/*number_of_channels=*/1, &audio_frame);
|
||||||
|
audio_mixer_->Mix(/*number_of_channels=*/1, &audio_frame);
|
||||||
|
|
||||||
|
// Revert to default to avoid using reference in route_rtp lambda.
|
||||||
|
ON_CALL(transport_, SendRtp).WillByDefault(Return(true));
|
||||||
|
};
|
||||||
|
|
||||||
|
auto send_recv_rtcp = [&](rtc::scoped_refptr<AudioChannel> rtcp_sender,
|
||||||
|
rtc::scoped_refptr<AudioChannel> rtcp_receiver) {
|
||||||
|
// Setup routing logic via transport_.
|
||||||
|
auto route_rtcp = [&](const uint8_t* packet, size_t length) {
|
||||||
|
rtcp_receiver->ReceivedRTCPPacket(rtc::MakeArrayView(packet, length));
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
ON_CALL(transport_, SendRtcp).WillByDefault(route_rtcp);
|
||||||
|
|
||||||
|
// This will trigger route_rtcp callback via transport_.
|
||||||
|
rtcp_sender->SendRTCPReportForTesting(kRtcpSr);
|
||||||
|
|
||||||
|
// Revert to default to avoid using reference in route_rtcp lambda.
|
||||||
|
ON_CALL(transport_, SendRtcp).WillByDefault(Return(true));
|
||||||
|
};
|
||||||
|
|
||||||
|
// AC1 <-- RTP/RTCP --> AC2
|
||||||
|
send_recv_rtp(audio_channel_, ac_2);
|
||||||
|
send_recv_rtp(ac_2, audio_channel_);
|
||||||
|
send_recv_rtcp(audio_channel_, ac_2);
|
||||||
|
send_recv_rtcp(ac_2, audio_channel_);
|
||||||
|
|
||||||
|
absl::optional<ChannelStatistics> channel_stats =
|
||||||
|
audio_channel_->GetChannelStatistics();
|
||||||
|
ASSERT_TRUE(channel_stats);
|
||||||
|
EXPECT_EQ(channel_stats->remote_ssrc, kAc2Ssrc);
|
||||||
|
ASSERT_TRUE(channel_stats->remote_rtcp);
|
||||||
|
EXPECT_GT(channel_stats->remote_rtcp->round_trip_time, 0.0);
|
||||||
|
|
||||||
|
// AC1 <-- RTP/RTCP --> AC3
|
||||||
|
send_recv_rtp(audio_channel_, ac_3);
|
||||||
|
send_recv_rtp(ac_3, audio_channel_);
|
||||||
|
send_recv_rtcp(audio_channel_, ac_3);
|
||||||
|
send_recv_rtcp(ac_3, audio_channel_);
|
||||||
|
|
||||||
|
channel_stats = audio_channel_->GetChannelStatistics();
|
||||||
|
ASSERT_TRUE(channel_stats);
|
||||||
|
EXPECT_EQ(channel_stats->remote_ssrc, kAc3Ssrc);
|
||||||
|
ASSERT_TRUE(channel_stats->remote_rtcp);
|
||||||
|
EXPECT_GT(channel_stats->remote_rtcp->round_trip_time, 0.0);
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
} // namespace webrtc
|
} // namespace webrtc
|
||||||
|
|
Loading…
Reference in a new issue