Reland of the test portion of:
https://webrtc-review.googlesource.com/c/src/+/172847
------------ original description --------------
Preparation for ReceiveStatisticsProxy lock reduction.
Update tests to call VideoReceiveStream::GetStats() in the same or at
least similar way it gets called in production (construction thread,
same TQ/thread).
Mapped out threads and context for ReceiveStatisticsProxy,
VideoQualityObserver and VideoReceiveStream. Added
follow-up TODOs for webrtc:11489.
One functional change in ReceiveStatisticsProxy is that when sender
side RtcpPacketTypesCounterUpdated calls are made, the counter is
updated asynchronously since the sender calls the method on a different
thread than the receiver.
Make CallClient::SendTask public to allow tests to run tasks in the
right context. CallClient already does this internally for GetStats.
Remove 10 sec sleep in StopSendingKeyframeRequestsForInactiveStream.
Bug: webrtc:11489
Change-Id: I491e13344b9fa714de0741dd927d907de7e39e83
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/173583
Commit-Queue: Tommi <tommi@webrtc.org>
Reviewed-by: Mirko Bonadei <mbonadei@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#31077}
diff --git a/call/call_perf_tests.cc b/call/call_perf_tests.cc
index 2d23087..123be7d 100644
--- a/call/call_perf_tests.cc
+++ b/call/call_perf_tests.cc
@@ -96,21 +96,24 @@
static const int kMinRunTimeMs = 30000;
public:
- explicit VideoRtcpAndSyncObserver(Clock* clock, const std::string& test_label)
+ explicit VideoRtcpAndSyncObserver(TaskQueueBase* task_queue,
+ Clock* clock,
+ const std::string& test_label)
: test::RtpRtcpObserver(CallPerfTest::kLongTimeoutMs),
clock_(clock),
test_label_(test_label),
creation_time_ms_(clock_->TimeInMilliseconds()),
- first_time_in_sync_(-1),
- receive_stream_(nullptr) {}
+ task_queue_(task_queue) {}
void OnFrame(const VideoFrame& video_frame) override {
- VideoReceiveStream::Stats stats;
- {
- rtc::CritScope lock(&crit_);
- if (receive_stream_)
- stats = receive_stream_->GetStats();
- }
+ task_queue_->PostTask(ToQueuedTask([this]() { CheckStats(); }));
+ }
+
+ void CheckStats() {
+ if (!receive_stream_)
+ return;
+
+ VideoReceiveStream::Stats stats = receive_stream_->GetStats();
if (stats.sync_offset_ms == std::numeric_limits<int>::max())
return;
@@ -135,7 +138,8 @@
}
void set_receive_stream(VideoReceiveStream* receive_stream) {
- rtc::CritScope lock(&crit_);
+ RTC_DCHECK_EQ(task_queue_, TaskQueueBase::Current());
+ // Note that receive_stream may be nullptr.
receive_stream_ = receive_stream;
}
@@ -148,10 +152,10 @@
Clock* const clock_;
std::string test_label_;
const int64_t creation_time_ms_;
- int64_t first_time_in_sync_;
- rtc::CriticalSection crit_;
- VideoReceiveStream* receive_stream_ RTC_GUARDED_BY(crit_);
+ int64_t first_time_in_sync_ = -1;
+ VideoReceiveStream* receive_stream_ = nullptr;
std::vector<double> sync_offset_ms_list_;
+ TaskQueueBase* const task_queue_;
};
void CallPerfTest::TestAudioVideoSync(FecMode fec,
@@ -168,7 +172,8 @@
audio_net_config.queue_delay_ms = 500;
audio_net_config.loss_percent = 5;
- VideoRtcpAndSyncObserver observer(Clock::GetRealTimeClock(), test_label);
+ auto observer = std::make_unique<VideoRtcpAndSyncObserver>(
+ task_queue(), Clock::GetRealTimeClock(), test_label);
std::map<uint8_t, MediaType> audio_pt_map;
std::map<uint8_t, MediaType> video_pt_map;
@@ -218,7 +223,7 @@
});
audio_send_transport = std::make_unique<test::PacketTransport>(
- task_queue(), sender_call_.get(), &observer,
+ task_queue(), sender_call_.get(), observer.get(),
test::PacketTransport::kSender, audio_pt_map,
std::make_unique<FakeNetworkPipe>(
Clock::GetRealTimeClock(),
@@ -226,7 +231,7 @@
audio_send_transport->SetReceiver(receiver_call_->Receiver());
video_send_transport = std::make_unique<test::PacketTransport>(
- task_queue(), sender_call_.get(), &observer,
+ task_queue(), sender_call_.get(), observer.get(),
test::PacketTransport::kSender, video_pt_map,
std::make_unique<FakeNetworkPipe>(Clock::GetRealTimeClock(),
std::make_unique<SimulatedNetwork>(
@@ -234,7 +239,7 @@
video_send_transport->SetReceiver(receiver_call_->Receiver());
receive_transport = std::make_unique<test::PacketTransport>(
- task_queue(), receiver_call_.get(), &observer,
+ task_queue(), receiver_call_.get(), observer.get(),
test::PacketTransport::kReceiver, payload_type_map_,
std::make_unique<FakeNetworkPipe>(Clock::GetRealTimeClock(),
std::make_unique<SimulatedNetwork>(
@@ -259,7 +264,7 @@
video_receive_configs_[0].rtp.ulpfec_payload_type = kUlpfecPayloadType;
}
video_receive_configs_[0].rtp.nack.rtp_history_ms = 1000;
- video_receive_configs_[0].renderer = &observer;
+ video_receive_configs_[0].renderer = observer.get();
video_receive_configs_[0].sync_group = kSyncGroup;
AudioReceiveStream::Config audio_recv_config;
@@ -281,7 +286,7 @@
receiver_call_->CreateAudioReceiveStream(audio_recv_config);
}
EXPECT_EQ(1u, video_receive_streams_.size());
- observer.set_receive_stream(video_receive_streams_[0]);
+ observer->set_receive_stream(video_receive_streams_[0]);
drifting_clock = std::make_unique<DriftingClock>(clock_, video_ntp_speed);
CreateFrameGeneratorCapturerWithDrift(drifting_clock.get(), video_rtp_speed,
kDefaultFramerate, kDefaultWidth,
@@ -293,10 +298,13 @@
audio_receive_stream->Start();
});
- EXPECT_TRUE(observer.Wait())
+ EXPECT_TRUE(observer->Wait())
<< "Timed out while waiting for audio and video to be synchronized.";
SendTask(RTC_FROM_HERE, task_queue(), [&]() {
+ // Clear the pointer to the receive stream since it will now be deleted.
+ observer->set_receive_stream(nullptr);
+
audio_send_stream->Stop();
audio_receive_stream->Stop();
@@ -314,7 +322,7 @@
DestroyCalls();
});
- observer.PrintResults();
+ observer->PrintResults();
// In quick test synchronization may not be achieved in time.
if (!field_trial::IsEnabled("WebRTC-QuickPerfTest")) {
@@ -323,6 +331,9 @@
EXPECT_METRIC_EQ(1, metrics::NumSamples("WebRTC.Video.AVSyncOffsetInMs"));
#endif
}
+
+ task_queue()->PostTask(
+ ToQueuedTask([to_delete = observer.release()]() { delete to_delete; }));
}
TEST_F(CallPerfTest, PlaysOutAudioAndVideoInSyncWithoutClockDrift) {