diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 19:33:14 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 19:33:14 +0000 |
commit | 36d22d82aa202bb199967e9512281e9a53db42c9 (patch) | |
tree | 105e8c98ddea1c1e4784a60a5a6410fa416be2de /third_party/libwebrtc/video/stream_synchronization_unittest.cc | |
parent | Initial commit. (diff) | |
download | firefox-esr-36d22d82aa202bb199967e9512281e9a53db42c9.tar.xz firefox-esr-36d22d82aa202bb199967e9512281e9a53db42c9.zip |
Adding upstream version 115.7.0esr.upstream/115.7.0esr
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'third_party/libwebrtc/video/stream_synchronization_unittest.cc')
-rw-r--r-- | third_party/libwebrtc/video/stream_synchronization_unittest.cc | 532 |
1 files changed, 532 insertions, 0 deletions
diff --git a/third_party/libwebrtc/video/stream_synchronization_unittest.cc b/third_party/libwebrtc/video/stream_synchronization_unittest.cc new file mode 100644 index 0000000000..b733a1d2cf --- /dev/null +++ b/third_party/libwebrtc/video/stream_synchronization_unittest.cc @@ -0,0 +1,532 @@ +/* + * Copyright (c) 2012 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 "video/stream_synchronization.h" + +#include <algorithm> + +#include "system_wrappers/include/clock.h" +#include "system_wrappers/include/ntp_time.h" +#include "test/gtest.h" + +namespace webrtc { +namespace { +constexpr int kMaxChangeMs = 80; // From stream_synchronization.cc +constexpr int kDefaultAudioFrequency = 8000; +constexpr int kDefaultVideoFrequency = 90000; +constexpr int kSmoothingFilter = 4 * 2; +} // namespace + +class StreamSynchronizationTest : public ::testing::Test { + public: + StreamSynchronizationTest() + : sync_(0, 0), clock_sender_(98765000), clock_receiver_(43210000) {} + + protected: + // Generates the necessary RTCP measurements and RTP timestamps and computes + // the audio and video delays needed to get the two streams in sync. + // `audio_delay_ms` and `video_delay_ms` are the number of milliseconds after + // capture which the frames are received. + // `current_audio_delay_ms` is the number of milliseconds which audio is + // currently being delayed by the receiver. + bool DelayedStreams(int audio_delay_ms, + int video_delay_ms, + int current_audio_delay_ms, + int* total_audio_delay_ms, + int* total_video_delay_ms) { + int audio_frequency = + static_cast<int>(kDefaultAudioFrequency * audio_clock_drift_ + 0.5); + int video_frequency = + static_cast<int>(kDefaultVideoFrequency * video_clock_drift_ + 0.5); + + // Generate NTP/RTP timestamp pair for both streams corresponding to RTCP. + StreamSynchronization::Measurements audio; + StreamSynchronization::Measurements video; + NtpTime ntp_time = clock_sender_.CurrentNtpTime(); + uint32_t rtp_timestamp = + clock_sender_.CurrentTime().ms() * audio_frequency / 1000; + EXPECT_EQ(audio.rtp_to_ntp.UpdateMeasurements(ntp_time, rtp_timestamp), + RtpToNtpEstimator::kNewMeasurement); + clock_sender_.AdvanceTimeMilliseconds(100); + clock_receiver_.AdvanceTimeMilliseconds(100); + ntp_time = clock_sender_.CurrentNtpTime(); + rtp_timestamp = clock_sender_.CurrentTime().ms() * video_frequency / 1000; + EXPECT_EQ(video.rtp_to_ntp.UpdateMeasurements(ntp_time, rtp_timestamp), + RtpToNtpEstimator::kNewMeasurement); + clock_sender_.AdvanceTimeMilliseconds(900); + clock_receiver_.AdvanceTimeMilliseconds(900); + ntp_time = clock_sender_.CurrentNtpTime(); + rtp_timestamp = clock_sender_.CurrentTime().ms() * audio_frequency / 1000; + EXPECT_EQ(audio.rtp_to_ntp.UpdateMeasurements(ntp_time, rtp_timestamp), + RtpToNtpEstimator::kNewMeasurement); + clock_sender_.AdvanceTimeMilliseconds(100); + clock_receiver_.AdvanceTimeMilliseconds(100); + ntp_time = clock_sender_.CurrentNtpTime(); + rtp_timestamp = clock_sender_.CurrentTime().ms() * video_frequency / 1000; + EXPECT_EQ(video.rtp_to_ntp.UpdateMeasurements(ntp_time, rtp_timestamp), + RtpToNtpEstimator::kNewMeasurement); + clock_sender_.AdvanceTimeMilliseconds(900); + clock_receiver_.AdvanceTimeMilliseconds(900); + + // Capture an audio and a video frame at the same time. + audio.latest_timestamp = + clock_sender_.CurrentTime().ms() * audio_frequency / 1000; + video.latest_timestamp = + clock_sender_.CurrentTime().ms() * video_frequency / 1000; + + if (audio_delay_ms > video_delay_ms) { + // Audio later than video. + clock_receiver_.AdvanceTimeMilliseconds(video_delay_ms); + video.latest_receive_time_ms = clock_receiver_.CurrentTime().ms(); + clock_receiver_.AdvanceTimeMilliseconds(audio_delay_ms - video_delay_ms); + audio.latest_receive_time_ms = clock_receiver_.CurrentTime().ms(); + } else { + // Video later than audio. + clock_receiver_.AdvanceTimeMilliseconds(audio_delay_ms); + audio.latest_receive_time_ms = clock_receiver_.CurrentTime().ms(); + clock_receiver_.AdvanceTimeMilliseconds(video_delay_ms - audio_delay_ms); + video.latest_receive_time_ms = clock_receiver_.CurrentTime().ms(); + } + + int relative_delay_ms; + EXPECT_TRUE(StreamSynchronization::ComputeRelativeDelay( + audio, video, &relative_delay_ms)); + EXPECT_EQ(video_delay_ms - audio_delay_ms, relative_delay_ms); + + return sync_.ComputeDelays(relative_delay_ms, current_audio_delay_ms, + total_audio_delay_ms, total_video_delay_ms); + } + + // Simulate audio playback 300 ms after capture and video rendering 100 ms + // after capture. Verify that the correct extra delays are calculated for + // audio and video, and that they change correctly when we simulate that + // NetEQ or the VCM adds more delay to the streams. + void BothDelayedAudioLaterTest(int base_target_delay_ms) { + const int kAudioDelayMs = base_target_delay_ms + 300; + const int kVideoDelayMs = base_target_delay_ms + 100; + int current_audio_delay_ms = base_target_delay_ms; + int total_audio_delay_ms = 0; + int total_video_delay_ms = base_target_delay_ms; + int filtered_move = (kAudioDelayMs - kVideoDelayMs) / kSmoothingFilter; + + EXPECT_TRUE(DelayedStreams(kAudioDelayMs, kVideoDelayMs, + current_audio_delay_ms, &total_audio_delay_ms, + &total_video_delay_ms)); + EXPECT_EQ(base_target_delay_ms + filtered_move, total_video_delay_ms); + EXPECT_EQ(base_target_delay_ms, total_audio_delay_ms); + + // Set new current delay. + current_audio_delay_ms = total_audio_delay_ms; + clock_sender_.AdvanceTimeMilliseconds(1000); + clock_receiver_.AdvanceTimeMilliseconds( + 1000 - std::max(kAudioDelayMs, kVideoDelayMs)); + // Simulate base_target_delay_ms minimum delay in the VCM. + total_video_delay_ms = base_target_delay_ms; + EXPECT_TRUE(DelayedStreams(kAudioDelayMs, kVideoDelayMs, + current_audio_delay_ms, &total_audio_delay_ms, + &total_video_delay_ms)); + EXPECT_EQ(base_target_delay_ms + 2 * filtered_move, total_video_delay_ms); + EXPECT_EQ(base_target_delay_ms, total_audio_delay_ms); + + // Set new current delay. + current_audio_delay_ms = total_audio_delay_ms; + clock_sender_.AdvanceTimeMilliseconds(1000); + clock_receiver_.AdvanceTimeMilliseconds( + 1000 - std::max(kAudioDelayMs, kVideoDelayMs)); + // Simulate base_target_delay_ms minimum delay in the VCM. + total_video_delay_ms = base_target_delay_ms; + EXPECT_TRUE(DelayedStreams(kAudioDelayMs, kVideoDelayMs, + current_audio_delay_ms, &total_audio_delay_ms, + &total_video_delay_ms)); + EXPECT_EQ(base_target_delay_ms + 3 * filtered_move, total_video_delay_ms); + EXPECT_EQ(base_target_delay_ms, total_audio_delay_ms); + + // Simulate that NetEQ introduces some audio delay. + const int kNeteqDelayIncrease = 50; + current_audio_delay_ms = base_target_delay_ms + kNeteqDelayIncrease; + clock_sender_.AdvanceTimeMilliseconds(1000); + clock_receiver_.AdvanceTimeMilliseconds( + 1000 - std::max(kAudioDelayMs, kVideoDelayMs)); + // Simulate base_target_delay_ms minimum delay in the VCM. + total_video_delay_ms = base_target_delay_ms; + EXPECT_TRUE(DelayedStreams(kAudioDelayMs, kVideoDelayMs, + current_audio_delay_ms, &total_audio_delay_ms, + &total_video_delay_ms)); + filtered_move = 3 * filtered_move + + (kNeteqDelayIncrease + kAudioDelayMs - kVideoDelayMs) / + kSmoothingFilter; + EXPECT_EQ(base_target_delay_ms + filtered_move, total_video_delay_ms); + EXPECT_EQ(base_target_delay_ms, total_audio_delay_ms); + + // Simulate that NetEQ reduces its delay. + const int kNeteqDelayDecrease = 10; + current_audio_delay_ms = base_target_delay_ms + kNeteqDelayDecrease; + clock_sender_.AdvanceTimeMilliseconds(1000); + clock_receiver_.AdvanceTimeMilliseconds( + 1000 - std::max(kAudioDelayMs, kVideoDelayMs)); + // Simulate base_target_delay_ms minimum delay in the VCM. + total_video_delay_ms = base_target_delay_ms; + EXPECT_TRUE(DelayedStreams(kAudioDelayMs, kVideoDelayMs, + current_audio_delay_ms, &total_audio_delay_ms, + &total_video_delay_ms)); + filtered_move = + filtered_move + (kNeteqDelayDecrease + kAudioDelayMs - kVideoDelayMs) / + kSmoothingFilter; + EXPECT_EQ(base_target_delay_ms + filtered_move, total_video_delay_ms); + EXPECT_EQ(base_target_delay_ms, total_audio_delay_ms); + } + + void BothDelayedVideoLaterTest(int base_target_delay_ms) { + const int kAudioDelayMs = base_target_delay_ms + 100; + const int kVideoDelayMs = base_target_delay_ms + 300; + int current_audio_delay_ms = base_target_delay_ms; + int total_audio_delay_ms = 0; + int total_video_delay_ms = base_target_delay_ms; + + EXPECT_TRUE(DelayedStreams(kAudioDelayMs, kVideoDelayMs, + current_audio_delay_ms, &total_audio_delay_ms, + &total_video_delay_ms)); + EXPECT_EQ(base_target_delay_ms, total_video_delay_ms); + // The audio delay is not allowed to change more than this. + EXPECT_GE(base_target_delay_ms + kMaxChangeMs, total_audio_delay_ms); + int last_total_audio_delay_ms = total_audio_delay_ms; + + // Set new current audio delay. + current_audio_delay_ms = total_audio_delay_ms; + clock_sender_.AdvanceTimeMilliseconds(1000); + clock_receiver_.AdvanceTimeMilliseconds(800); + EXPECT_TRUE(DelayedStreams(kAudioDelayMs, kVideoDelayMs, + current_audio_delay_ms, &total_audio_delay_ms, + &total_video_delay_ms)); + EXPECT_EQ(base_target_delay_ms, total_video_delay_ms); + EXPECT_EQ(last_total_audio_delay_ms + + MaxAudioDelayChangeMs( + current_audio_delay_ms, + base_target_delay_ms + kVideoDelayMs - kAudioDelayMs), + total_audio_delay_ms); + last_total_audio_delay_ms = total_audio_delay_ms; + + // Set new current audio delay. + current_audio_delay_ms = total_audio_delay_ms; + clock_sender_.AdvanceTimeMilliseconds(1000); + clock_receiver_.AdvanceTimeMilliseconds(800); + EXPECT_TRUE(DelayedStreams(kAudioDelayMs, kVideoDelayMs, + current_audio_delay_ms, &total_audio_delay_ms, + &total_video_delay_ms)); + EXPECT_EQ(base_target_delay_ms, total_video_delay_ms); + EXPECT_EQ(last_total_audio_delay_ms + + MaxAudioDelayChangeMs( + current_audio_delay_ms, + base_target_delay_ms + kVideoDelayMs - kAudioDelayMs), + total_audio_delay_ms); + last_total_audio_delay_ms = total_audio_delay_ms; + + // Simulate that NetEQ for some reason reduced the delay. + current_audio_delay_ms = base_target_delay_ms + 10; + clock_sender_.AdvanceTimeMilliseconds(1000); + clock_receiver_.AdvanceTimeMilliseconds(800); + EXPECT_TRUE(DelayedStreams(kAudioDelayMs, kVideoDelayMs, + current_audio_delay_ms, &total_audio_delay_ms, + &total_video_delay_ms)); + EXPECT_EQ(base_target_delay_ms, total_video_delay_ms); + EXPECT_EQ(last_total_audio_delay_ms + + MaxAudioDelayChangeMs( + current_audio_delay_ms, + base_target_delay_ms + kVideoDelayMs - kAudioDelayMs), + total_audio_delay_ms); + last_total_audio_delay_ms = total_audio_delay_ms; + + // Simulate that NetEQ for some reason significantly increased the delay. + current_audio_delay_ms = base_target_delay_ms + 350; + clock_sender_.AdvanceTimeMilliseconds(1000); + clock_receiver_.AdvanceTimeMilliseconds(800); + EXPECT_TRUE(DelayedStreams(kAudioDelayMs, kVideoDelayMs, + current_audio_delay_ms, &total_audio_delay_ms, + &total_video_delay_ms)); + EXPECT_EQ(base_target_delay_ms, total_video_delay_ms); + EXPECT_EQ(last_total_audio_delay_ms + + MaxAudioDelayChangeMs( + current_audio_delay_ms, + base_target_delay_ms + kVideoDelayMs - kAudioDelayMs), + total_audio_delay_ms); + } + + int MaxAudioDelayChangeMs(int current_audio_delay_ms, int delay_ms) const { + int diff_ms = (delay_ms - current_audio_delay_ms) / kSmoothingFilter; + diff_ms = std::min(diff_ms, kMaxChangeMs); + diff_ms = std::max(diff_ms, -kMaxChangeMs); + return diff_ms; + } + + StreamSynchronization sync_; + SimulatedClock clock_sender_; + SimulatedClock clock_receiver_; + double audio_clock_drift_ = 1.0; + double video_clock_drift_ = 1.0; +}; + +TEST_F(StreamSynchronizationTest, NoDelay) { + int total_audio_delay_ms = 0; + int total_video_delay_ms = 0; + + EXPECT_FALSE(DelayedStreams(/*audio_delay_ms=*/0, /*video_delay_ms=*/0, + /*current_audio_delay_ms=*/0, + &total_audio_delay_ms, &total_video_delay_ms)); + EXPECT_EQ(0, total_audio_delay_ms); + EXPECT_EQ(0, total_video_delay_ms); +} + +TEST_F(StreamSynchronizationTest, VideoDelayed) { + const int kAudioDelayMs = 200; + int total_audio_delay_ms = 0; + int total_video_delay_ms = 0; + + EXPECT_TRUE(DelayedStreams(kAudioDelayMs, /*video_delay_ms=*/0, + /*current_audio_delay_ms=*/0, + &total_audio_delay_ms, &total_video_delay_ms)); + EXPECT_EQ(0, total_audio_delay_ms); + // The delay is not allowed to change more than this. + EXPECT_EQ(kAudioDelayMs / kSmoothingFilter, total_video_delay_ms); + + // Simulate 0 minimum delay in the VCM. + total_video_delay_ms = 0; + clock_sender_.AdvanceTimeMilliseconds(1000); + clock_receiver_.AdvanceTimeMilliseconds(800); + EXPECT_TRUE(DelayedStreams(kAudioDelayMs, /*video_delay_ms=*/0, + /*current_audio_delay_ms=*/0, + &total_audio_delay_ms, &total_video_delay_ms)); + EXPECT_EQ(0, total_audio_delay_ms); + EXPECT_EQ(2 * kAudioDelayMs / kSmoothingFilter, total_video_delay_ms); + + // Simulate 0 minimum delay in the VCM. + total_video_delay_ms = 0; + clock_sender_.AdvanceTimeMilliseconds(1000); + clock_receiver_.AdvanceTimeMilliseconds(800); + EXPECT_TRUE(DelayedStreams(kAudioDelayMs, /*video_delay_ms=*/0, + /*current_audio_delay_ms=*/0, + &total_audio_delay_ms, &total_video_delay_ms)); + EXPECT_EQ(0, total_audio_delay_ms); + EXPECT_EQ(3 * kAudioDelayMs / kSmoothingFilter, total_video_delay_ms); +} + +TEST_F(StreamSynchronizationTest, AudioDelayed) { + const int kVideoDelayMs = 200; + int current_audio_delay_ms = 0; + int total_audio_delay_ms = 0; + int total_video_delay_ms = 0; + + EXPECT_TRUE(DelayedStreams(/*audio_delay_ms=*/0, kVideoDelayMs, + current_audio_delay_ms, &total_audio_delay_ms, + &total_video_delay_ms)); + EXPECT_EQ(0, total_video_delay_ms); + // The delay is not allowed to change more than this. + EXPECT_EQ(kVideoDelayMs / kSmoothingFilter, total_audio_delay_ms); + int last_total_audio_delay_ms = total_audio_delay_ms; + + // Set new current audio delay. + current_audio_delay_ms = total_audio_delay_ms; + clock_sender_.AdvanceTimeMilliseconds(1000); + clock_receiver_.AdvanceTimeMilliseconds(800); + EXPECT_TRUE(DelayedStreams(/*audio_delay_ms=*/0, kVideoDelayMs, + current_audio_delay_ms, &total_audio_delay_ms, + &total_video_delay_ms)); + EXPECT_EQ(0, total_video_delay_ms); + EXPECT_EQ(last_total_audio_delay_ms + + MaxAudioDelayChangeMs(current_audio_delay_ms, kVideoDelayMs), + total_audio_delay_ms); + last_total_audio_delay_ms = total_audio_delay_ms; + + // Set new current audio delay. + current_audio_delay_ms = total_audio_delay_ms; + clock_sender_.AdvanceTimeMilliseconds(1000); + clock_receiver_.AdvanceTimeMilliseconds(800); + EXPECT_TRUE(DelayedStreams(/*audio_delay_ms=*/0, kVideoDelayMs, + current_audio_delay_ms, &total_audio_delay_ms, + &total_video_delay_ms)); + EXPECT_EQ(0, total_video_delay_ms); + EXPECT_EQ(last_total_audio_delay_ms + + MaxAudioDelayChangeMs(current_audio_delay_ms, kVideoDelayMs), + total_audio_delay_ms); + last_total_audio_delay_ms = total_audio_delay_ms; + + // Simulate that NetEQ for some reason reduced the delay. + current_audio_delay_ms = 10; + clock_sender_.AdvanceTimeMilliseconds(1000); + clock_receiver_.AdvanceTimeMilliseconds(800); + EXPECT_TRUE(DelayedStreams(/*audio_delay_ms=*/0, kVideoDelayMs, + current_audio_delay_ms, &total_audio_delay_ms, + &total_video_delay_ms)); + EXPECT_EQ(0, total_video_delay_ms); + EXPECT_EQ(last_total_audio_delay_ms + + MaxAudioDelayChangeMs(current_audio_delay_ms, kVideoDelayMs), + total_audio_delay_ms); + last_total_audio_delay_ms = total_audio_delay_ms; + + // Simulate that NetEQ for some reason significantly increased the delay. + current_audio_delay_ms = 350; + clock_sender_.AdvanceTimeMilliseconds(1000); + clock_receiver_.AdvanceTimeMilliseconds(800); + EXPECT_TRUE(DelayedStreams(/*audio_delay_ms=*/0, kVideoDelayMs, + current_audio_delay_ms, &total_audio_delay_ms, + &total_video_delay_ms)); + EXPECT_EQ(0, total_video_delay_ms); + EXPECT_EQ(last_total_audio_delay_ms + + MaxAudioDelayChangeMs(current_audio_delay_ms, kVideoDelayMs), + total_audio_delay_ms); +} + +TEST_F(StreamSynchronizationTest, NoAudioIncomingUnboundedIncrease) { + // Test how audio delay can grow unbounded when audio stops coming in. + // This is handled in caller of RtpStreamsSynchronizer, for example in + // RtpStreamsSynchronizer by not updating delays when audio samples stop + // coming in. + const int kVideoDelayMs = 300; + const int kAudioDelayMs = 100; + int current_audio_delay_ms = kAudioDelayMs; + int total_audio_delay_ms = 0; + int total_video_delay_ms = 0; + + EXPECT_TRUE(DelayedStreams(/*audio_delay_ms=*/0, kVideoDelayMs, + current_audio_delay_ms, &total_audio_delay_ms, + &total_video_delay_ms)); + EXPECT_EQ(0, total_video_delay_ms); + // The delay is not allowed to change more than this. + EXPECT_EQ((kVideoDelayMs - kAudioDelayMs) / kSmoothingFilter, + total_audio_delay_ms); + int last_total_audio_delay_ms = total_audio_delay_ms; + + // Set new current audio delay: simulate audio samples are flowing in. + current_audio_delay_ms = total_audio_delay_ms; + + clock_sender_.AdvanceTimeMilliseconds(1000); + clock_receiver_.AdvanceTimeMilliseconds(1000); + EXPECT_TRUE(DelayedStreams(/*audio_delay_ms=*/0, kVideoDelayMs, + current_audio_delay_ms, &total_audio_delay_ms, + &total_video_delay_ms)); + EXPECT_EQ(0, total_video_delay_ms); + EXPECT_EQ(last_total_audio_delay_ms + + MaxAudioDelayChangeMs(current_audio_delay_ms, kVideoDelayMs), + total_audio_delay_ms); + last_total_audio_delay_ms = total_audio_delay_ms; + + // Simulate no incoming audio by not update audio delay. + const int kSimulationSecs = 300; // 5min + const int kMaxDeltaDelayMs = 10000; // max delay for audio in webrtc + for (auto time_secs = 0; time_secs < kSimulationSecs; time_secs++) { + clock_sender_.AdvanceTimeMilliseconds(1000); + clock_receiver_.AdvanceTimeMilliseconds(1000); + EXPECT_TRUE(DelayedStreams(/*audio_delay_ms=*/0, kVideoDelayMs, + current_audio_delay_ms, &total_audio_delay_ms, + &total_video_delay_ms)); + EXPECT_EQ(0, total_video_delay_ms); + + // Audio delay does not go above kMaxDeltaDelayMs. + EXPECT_EQ(std::min(kMaxDeltaDelayMs, + last_total_audio_delay_ms + + MaxAudioDelayChangeMs(current_audio_delay_ms, + kVideoDelayMs)), + total_audio_delay_ms); + last_total_audio_delay_ms = total_audio_delay_ms; + } + // By now the audio delay has grown unbounded to kMaxDeltaDelayMs. + EXPECT_EQ(kMaxDeltaDelayMs, last_total_audio_delay_ms); +} + +TEST_F(StreamSynchronizationTest, BothDelayedVideoLater) { + BothDelayedVideoLaterTest(0); +} + +TEST_F(StreamSynchronizationTest, BothDelayedVideoLaterAudioClockDrift) { + audio_clock_drift_ = 1.05; + BothDelayedVideoLaterTest(0); +} + +TEST_F(StreamSynchronizationTest, BothDelayedVideoLaterVideoClockDrift) { + video_clock_drift_ = 1.05; + BothDelayedVideoLaterTest(0); +} + +TEST_F(StreamSynchronizationTest, BothDelayedAudioLater) { + BothDelayedAudioLaterTest(0); +} + +TEST_F(StreamSynchronizationTest, BothDelayedAudioClockDrift) { + audio_clock_drift_ = 1.05; + BothDelayedAudioLaterTest(0); +} + +TEST_F(StreamSynchronizationTest, BothDelayedVideoClockDrift) { + video_clock_drift_ = 1.05; + BothDelayedAudioLaterTest(0); +} + +TEST_F(StreamSynchronizationTest, BothEquallyDelayed) { + const int kDelayMs = 2000; + int current_audio_delay_ms = kDelayMs; + int total_audio_delay_ms = 0; + int total_video_delay_ms = kDelayMs; + // In sync, expect no change. + EXPECT_FALSE(DelayedStreams(kDelayMs, kDelayMs, current_audio_delay_ms, + &total_audio_delay_ms, &total_video_delay_ms)); + // Trigger another call with the same values, delay should not be modified. + total_video_delay_ms = kDelayMs; + EXPECT_FALSE(DelayedStreams(kDelayMs, kDelayMs, current_audio_delay_ms, + &total_audio_delay_ms, &total_video_delay_ms)); + // Change delay value, delay should not be modified. + const int kDelayMs2 = 5000; + current_audio_delay_ms = kDelayMs2; + total_video_delay_ms = kDelayMs2; + EXPECT_FALSE(DelayedStreams(kDelayMs2, kDelayMs2, current_audio_delay_ms, + &total_audio_delay_ms, &total_video_delay_ms)); +} + +TEST_F(StreamSynchronizationTest, BothDelayedAudioLaterWithBaseDelay) { + const int kBaseTargetDelayMs = 3000; + sync_.SetTargetBufferingDelay(kBaseTargetDelayMs); + BothDelayedAudioLaterTest(kBaseTargetDelayMs); +} + +TEST_F(StreamSynchronizationTest, BothDelayedAudioClockDriftWithBaseDelay) { + const int kBaseTargetDelayMs = 3000; + sync_.SetTargetBufferingDelay(kBaseTargetDelayMs); + audio_clock_drift_ = 1.05; + BothDelayedAudioLaterTest(kBaseTargetDelayMs); +} + +TEST_F(StreamSynchronizationTest, BothDelayedVideoClockDriftWithBaseDelay) { + const int kBaseTargetDelayMs = 3000; + sync_.SetTargetBufferingDelay(kBaseTargetDelayMs); + video_clock_drift_ = 1.05; + BothDelayedAudioLaterTest(kBaseTargetDelayMs); +} + +TEST_F(StreamSynchronizationTest, BothDelayedVideoLaterWithBaseDelay) { + const int kBaseTargetDelayMs = 2000; + sync_.SetTargetBufferingDelay(kBaseTargetDelayMs); + BothDelayedVideoLaterTest(kBaseTargetDelayMs); +} + +TEST_F(StreamSynchronizationTest, + BothDelayedVideoLaterAudioClockDriftWithBaseDelay) { + const int kBaseTargetDelayMs = 2000; + audio_clock_drift_ = 1.05; + sync_.SetTargetBufferingDelay(kBaseTargetDelayMs); + BothDelayedVideoLaterTest(kBaseTargetDelayMs); +} + +TEST_F(StreamSynchronizationTest, + BothDelayedVideoLaterVideoClockDriftWithBaseDelay) { + const int kBaseTargetDelayMs = 2000; + video_clock_drift_ = 1.05; + sync_.SetTargetBufferingDelay(kBaseTargetDelayMs); + BothDelayedVideoLaterTest(kBaseTargetDelayMs); +} + +} // namespace webrtc |