xref: /aosp_15_r20/external/webrtc/video/decode_synchronizer_unittest.cc (revision d9f758449e529ab9291ac668be2861e7a55c2422)
1*d9f75844SAndroid Build Coastguard Worker /*
2*d9f75844SAndroid Build Coastguard Worker  *  Copyright (c) 2022 The WebRTC project authors. All Rights Reserved.
3*d9f75844SAndroid Build Coastguard Worker  *
4*d9f75844SAndroid Build Coastguard Worker  *  Use of this source code is governed by a BSD-style license
5*d9f75844SAndroid Build Coastguard Worker  *  that can be found in the LICENSE file in the root of the source
6*d9f75844SAndroid Build Coastguard Worker  *  tree. An additional intellectual property rights grant can be found
7*d9f75844SAndroid Build Coastguard Worker  *  in the file PATENTS.  All contributing project authors may
8*d9f75844SAndroid Build Coastguard Worker  *  be found in the AUTHORS file in the root of the source tree.
9*d9f75844SAndroid Build Coastguard Worker  */
10*d9f75844SAndroid Build Coastguard Worker 
11*d9f75844SAndroid Build Coastguard Worker #include "video/decode_synchronizer.h"
12*d9f75844SAndroid Build Coastguard Worker 
13*d9f75844SAndroid Build Coastguard Worker #include <stddef.h>
14*d9f75844SAndroid Build Coastguard Worker 
15*d9f75844SAndroid Build Coastguard Worker #include <memory>
16*d9f75844SAndroid Build Coastguard Worker #include <utility>
17*d9f75844SAndroid Build Coastguard Worker 
18*d9f75844SAndroid Build Coastguard Worker #include "absl/functional/any_invocable.h"
19*d9f75844SAndroid Build Coastguard Worker #include "api/metronome/test/fake_metronome.h"
20*d9f75844SAndroid Build Coastguard Worker #include "api/units/time_delta.h"
21*d9f75844SAndroid Build Coastguard Worker #include "test/gmock.h"
22*d9f75844SAndroid Build Coastguard Worker #include "test/gtest.h"
23*d9f75844SAndroid Build Coastguard Worker #include "test/time_controller/simulated_time_controller.h"
24*d9f75844SAndroid Build Coastguard Worker #include "video/frame_decode_scheduler.h"
25*d9f75844SAndroid Build Coastguard Worker #include "video/frame_decode_timing.h"
26*d9f75844SAndroid Build Coastguard Worker 
27*d9f75844SAndroid Build Coastguard Worker using ::testing::_;
28*d9f75844SAndroid Build Coastguard Worker using ::testing::Eq;
29*d9f75844SAndroid Build Coastguard Worker using ::testing::Invoke;
30*d9f75844SAndroid Build Coastguard Worker using ::testing::Return;
31*d9f75844SAndroid Build Coastguard Worker 
32*d9f75844SAndroid Build Coastguard Worker namespace webrtc {
33*d9f75844SAndroid Build Coastguard Worker 
34*d9f75844SAndroid Build Coastguard Worker class MockMetronome : public Metronome {
35*d9f75844SAndroid Build Coastguard Worker  public:
36*d9f75844SAndroid Build Coastguard Worker   MOCK_METHOD(void,
37*d9f75844SAndroid Build Coastguard Worker               RequestCallOnNextTick,
38*d9f75844SAndroid Build Coastguard Worker               (absl::AnyInvocable<void() &&> callback),
39*d9f75844SAndroid Build Coastguard Worker               (override));
40*d9f75844SAndroid Build Coastguard Worker   MOCK_METHOD(TimeDelta, TickPeriod, (), (const override));
41*d9f75844SAndroid Build Coastguard Worker };
42*d9f75844SAndroid Build Coastguard Worker 
43*d9f75844SAndroid Build Coastguard Worker class DecodeSynchronizerTest : public ::testing::Test {
44*d9f75844SAndroid Build Coastguard Worker  public:
45*d9f75844SAndroid Build Coastguard Worker   static constexpr TimeDelta kTickPeriod = TimeDelta::Millis(33);
46*d9f75844SAndroid Build Coastguard Worker 
DecodeSynchronizerTest()47*d9f75844SAndroid Build Coastguard Worker   DecodeSynchronizerTest()
48*d9f75844SAndroid Build Coastguard Worker       : time_controller_(Timestamp::Millis(1337)),
49*d9f75844SAndroid Build Coastguard Worker         clock_(time_controller_.GetClock()),
50*d9f75844SAndroid Build Coastguard Worker         metronome_(kTickPeriod),
51*d9f75844SAndroid Build Coastguard Worker         decode_synchronizer_(clock_,
52*d9f75844SAndroid Build Coastguard Worker                              &metronome_,
53*d9f75844SAndroid Build Coastguard Worker                              time_controller_.GetMainThread()) {}
54*d9f75844SAndroid Build Coastguard Worker 
55*d9f75844SAndroid Build Coastguard Worker  protected:
56*d9f75844SAndroid Build Coastguard Worker   GlobalSimulatedTimeController time_controller_;
57*d9f75844SAndroid Build Coastguard Worker   Clock* clock_;
58*d9f75844SAndroid Build Coastguard Worker   test::ForcedTickMetronome metronome_;
59*d9f75844SAndroid Build Coastguard Worker   DecodeSynchronizer decode_synchronizer_;
60*d9f75844SAndroid Build Coastguard Worker };
61*d9f75844SAndroid Build Coastguard Worker 
TEST_F(DecodeSynchronizerTest,AllFramesReadyBeforeNextTickDecoded)62*d9f75844SAndroid Build Coastguard Worker TEST_F(DecodeSynchronizerTest, AllFramesReadyBeforeNextTickDecoded) {
63*d9f75844SAndroid Build Coastguard Worker   ::testing::MockFunction<void(uint32_t, Timestamp)> mock_callback1;
64*d9f75844SAndroid Build Coastguard Worker   auto scheduler1 = decode_synchronizer_.CreateSynchronizedFrameScheduler();
65*d9f75844SAndroid Build Coastguard Worker 
66*d9f75844SAndroid Build Coastguard Worker   testing::MockFunction<void(unsigned int, Timestamp)> mock_callback2;
67*d9f75844SAndroid Build Coastguard Worker   auto scheduler2 = decode_synchronizer_.CreateSynchronizedFrameScheduler();
68*d9f75844SAndroid Build Coastguard Worker 
69*d9f75844SAndroid Build Coastguard Worker   {
70*d9f75844SAndroid Build Coastguard Worker     uint32_t frame_rtp = 90000;
71*d9f75844SAndroid Build Coastguard Worker     FrameDecodeTiming::FrameSchedule frame_sched{
72*d9f75844SAndroid Build Coastguard Worker         .latest_decode_time =
73*d9f75844SAndroid Build Coastguard Worker             clock_->CurrentTime() + kTickPeriod - TimeDelta::Millis(3),
74*d9f75844SAndroid Build Coastguard Worker         .render_time = clock_->CurrentTime() + TimeDelta::Millis(60)};
75*d9f75844SAndroid Build Coastguard Worker     scheduler1->ScheduleFrame(frame_rtp, frame_sched,
76*d9f75844SAndroid Build Coastguard Worker                               mock_callback1.AsStdFunction());
77*d9f75844SAndroid Build Coastguard Worker     EXPECT_CALL(mock_callback1,
78*d9f75844SAndroid Build Coastguard Worker                 Call(Eq(frame_rtp), Eq(frame_sched.render_time)));
79*d9f75844SAndroid Build Coastguard Worker   }
80*d9f75844SAndroid Build Coastguard Worker   {
81*d9f75844SAndroid Build Coastguard Worker     uint32_t frame_rtp = 123456;
82*d9f75844SAndroid Build Coastguard Worker     FrameDecodeTiming::FrameSchedule frame_sched{
83*d9f75844SAndroid Build Coastguard Worker         .latest_decode_time =
84*d9f75844SAndroid Build Coastguard Worker             clock_->CurrentTime() + kTickPeriod - TimeDelta::Millis(2),
85*d9f75844SAndroid Build Coastguard Worker         .render_time = clock_->CurrentTime() + TimeDelta::Millis(70)};
86*d9f75844SAndroid Build Coastguard Worker     scheduler2->ScheduleFrame(frame_rtp, frame_sched,
87*d9f75844SAndroid Build Coastguard Worker                               mock_callback2.AsStdFunction());
88*d9f75844SAndroid Build Coastguard Worker     EXPECT_CALL(mock_callback2,
89*d9f75844SAndroid Build Coastguard Worker                 Call(Eq(frame_rtp), Eq(frame_sched.render_time)));
90*d9f75844SAndroid Build Coastguard Worker   }
91*d9f75844SAndroid Build Coastguard Worker   metronome_.Tick();
92*d9f75844SAndroid Build Coastguard Worker   time_controller_.AdvanceTime(TimeDelta::Zero());
93*d9f75844SAndroid Build Coastguard Worker 
94*d9f75844SAndroid Build Coastguard Worker   // Cleanup
95*d9f75844SAndroid Build Coastguard Worker   scheduler1->Stop();
96*d9f75844SAndroid Build Coastguard Worker   scheduler2->Stop();
97*d9f75844SAndroid Build Coastguard Worker }
98*d9f75844SAndroid Build Coastguard Worker 
TEST_F(DecodeSynchronizerTest,FramesNotDecodedIfDecodeTimeIsInNextInterval)99*d9f75844SAndroid Build Coastguard Worker TEST_F(DecodeSynchronizerTest, FramesNotDecodedIfDecodeTimeIsInNextInterval) {
100*d9f75844SAndroid Build Coastguard Worker   ::testing::MockFunction<void(unsigned int, Timestamp)> mock_callback;
101*d9f75844SAndroid Build Coastguard Worker   auto scheduler = decode_synchronizer_.CreateSynchronizedFrameScheduler();
102*d9f75844SAndroid Build Coastguard Worker 
103*d9f75844SAndroid Build Coastguard Worker   uint32_t frame_rtp = 90000;
104*d9f75844SAndroid Build Coastguard Worker   FrameDecodeTiming::FrameSchedule frame_sched{
105*d9f75844SAndroid Build Coastguard Worker       .latest_decode_time =
106*d9f75844SAndroid Build Coastguard Worker           clock_->CurrentTime() + kTickPeriod + TimeDelta::Millis(10),
107*d9f75844SAndroid Build Coastguard Worker       .render_time =
108*d9f75844SAndroid Build Coastguard Worker           clock_->CurrentTime() + kTickPeriod + TimeDelta::Millis(30)};
109*d9f75844SAndroid Build Coastguard Worker   scheduler->ScheduleFrame(frame_rtp, frame_sched,
110*d9f75844SAndroid Build Coastguard Worker                            mock_callback.AsStdFunction());
111*d9f75844SAndroid Build Coastguard Worker 
112*d9f75844SAndroid Build Coastguard Worker   metronome_.Tick();
113*d9f75844SAndroid Build Coastguard Worker   time_controller_.AdvanceTime(TimeDelta::Zero());
114*d9f75844SAndroid Build Coastguard Worker   // No decodes should have happened in this tick.
115*d9f75844SAndroid Build Coastguard Worker   ::testing::Mock::VerifyAndClearExpectations(&mock_callback);
116*d9f75844SAndroid Build Coastguard Worker 
117*d9f75844SAndroid Build Coastguard Worker   // Decode should happen on next tick.
118*d9f75844SAndroid Build Coastguard Worker   EXPECT_CALL(mock_callback, Call(Eq(frame_rtp), Eq(frame_sched.render_time)));
119*d9f75844SAndroid Build Coastguard Worker   time_controller_.AdvanceTime(kTickPeriod);
120*d9f75844SAndroid Build Coastguard Worker   metronome_.Tick();
121*d9f75844SAndroid Build Coastguard Worker   time_controller_.AdvanceTime(TimeDelta::Zero());
122*d9f75844SAndroid Build Coastguard Worker 
123*d9f75844SAndroid Build Coastguard Worker   // Cleanup
124*d9f75844SAndroid Build Coastguard Worker   scheduler->Stop();
125*d9f75844SAndroid Build Coastguard Worker }
126*d9f75844SAndroid Build Coastguard Worker 
TEST_F(DecodeSynchronizerTest,FrameDecodedOnce)127*d9f75844SAndroid Build Coastguard Worker TEST_F(DecodeSynchronizerTest, FrameDecodedOnce) {
128*d9f75844SAndroid Build Coastguard Worker   ::testing::MockFunction<void(unsigned int, Timestamp)> mock_callback;
129*d9f75844SAndroid Build Coastguard Worker   auto scheduler = decode_synchronizer_.CreateSynchronizedFrameScheduler();
130*d9f75844SAndroid Build Coastguard Worker 
131*d9f75844SAndroid Build Coastguard Worker   uint32_t frame_rtp = 90000;
132*d9f75844SAndroid Build Coastguard Worker   FrameDecodeTiming::FrameSchedule frame_sched{
133*d9f75844SAndroid Build Coastguard Worker       .latest_decode_time = clock_->CurrentTime() + TimeDelta::Millis(30),
134*d9f75844SAndroid Build Coastguard Worker       .render_time = clock_->CurrentTime() + TimeDelta::Millis(60)};
135*d9f75844SAndroid Build Coastguard Worker   scheduler->ScheduleFrame(frame_rtp, frame_sched,
136*d9f75844SAndroid Build Coastguard Worker                            mock_callback.AsStdFunction());
137*d9f75844SAndroid Build Coastguard Worker   EXPECT_CALL(mock_callback, Call(_, _)).Times(1);
138*d9f75844SAndroid Build Coastguard Worker   metronome_.Tick();
139*d9f75844SAndroid Build Coastguard Worker   time_controller_.AdvanceTime(TimeDelta::Zero());
140*d9f75844SAndroid Build Coastguard Worker   ::testing::Mock::VerifyAndClearExpectations(&mock_callback);
141*d9f75844SAndroid Build Coastguard Worker 
142*d9f75844SAndroid Build Coastguard Worker   // Trigger tick again. No frame should be decoded now.
143*d9f75844SAndroid Build Coastguard Worker   time_controller_.AdvanceTime(kTickPeriod);
144*d9f75844SAndroid Build Coastguard Worker   metronome_.Tick();
145*d9f75844SAndroid Build Coastguard Worker   time_controller_.AdvanceTime(TimeDelta::Zero());
146*d9f75844SAndroid Build Coastguard Worker 
147*d9f75844SAndroid Build Coastguard Worker   // Cleanup
148*d9f75844SAndroid Build Coastguard Worker   scheduler->Stop();
149*d9f75844SAndroid Build Coastguard Worker }
150*d9f75844SAndroid Build Coastguard Worker 
TEST_F(DecodeSynchronizerTest,FrameWithDecodeTimeInPastDecodedImmediately)151*d9f75844SAndroid Build Coastguard Worker TEST_F(DecodeSynchronizerTest, FrameWithDecodeTimeInPastDecodedImmediately) {
152*d9f75844SAndroid Build Coastguard Worker   ::testing::MockFunction<void(unsigned int, Timestamp)> mock_callback;
153*d9f75844SAndroid Build Coastguard Worker   auto scheduler = decode_synchronizer_.CreateSynchronizedFrameScheduler();
154*d9f75844SAndroid Build Coastguard Worker 
155*d9f75844SAndroid Build Coastguard Worker   uint32_t frame_rtp = 90000;
156*d9f75844SAndroid Build Coastguard Worker   FrameDecodeTiming::FrameSchedule frame_sched{
157*d9f75844SAndroid Build Coastguard Worker       .latest_decode_time = clock_->CurrentTime() - TimeDelta::Millis(5),
158*d9f75844SAndroid Build Coastguard Worker       .render_time = clock_->CurrentTime() + TimeDelta::Millis(30)};
159*d9f75844SAndroid Build Coastguard Worker   EXPECT_CALL(mock_callback, Call(Eq(90000u), _)).Times(1);
160*d9f75844SAndroid Build Coastguard Worker   scheduler->ScheduleFrame(frame_rtp, frame_sched,
161*d9f75844SAndroid Build Coastguard Worker                            mock_callback.AsStdFunction());
162*d9f75844SAndroid Build Coastguard Worker   // Verify the callback was invoked already.
163*d9f75844SAndroid Build Coastguard Worker   ::testing::Mock::VerifyAndClearExpectations(&mock_callback);
164*d9f75844SAndroid Build Coastguard Worker 
165*d9f75844SAndroid Build Coastguard Worker   metronome_.Tick();
166*d9f75844SAndroid Build Coastguard Worker   time_controller_.AdvanceTime(TimeDelta::Zero());
167*d9f75844SAndroid Build Coastguard Worker 
168*d9f75844SAndroid Build Coastguard Worker   // Cleanup
169*d9f75844SAndroid Build Coastguard Worker   scheduler->Stop();
170*d9f75844SAndroid Build Coastguard Worker }
171*d9f75844SAndroid Build Coastguard Worker 
TEST_F(DecodeSynchronizerTest,FrameWithDecodeTimeFarBeforeNextTickDecodedImmediately)172*d9f75844SAndroid Build Coastguard Worker TEST_F(DecodeSynchronizerTest,
173*d9f75844SAndroid Build Coastguard Worker        FrameWithDecodeTimeFarBeforeNextTickDecodedImmediately) {
174*d9f75844SAndroid Build Coastguard Worker   ::testing::MockFunction<void(unsigned int, Timestamp)> mock_callback;
175*d9f75844SAndroid Build Coastguard Worker   auto scheduler = decode_synchronizer_.CreateSynchronizedFrameScheduler();
176*d9f75844SAndroid Build Coastguard Worker 
177*d9f75844SAndroid Build Coastguard Worker   // Frame which would be behind by more than kMaxAllowedFrameDelay after
178*d9f75844SAndroid Build Coastguard Worker   // the next tick.
179*d9f75844SAndroid Build Coastguard Worker   FrameDecodeTiming::FrameSchedule frame_sched{
180*d9f75844SAndroid Build Coastguard Worker       .latest_decode_time = clock_->CurrentTime() + kTickPeriod -
181*d9f75844SAndroid Build Coastguard Worker                             FrameDecodeTiming::kMaxAllowedFrameDelay -
182*d9f75844SAndroid Build Coastguard Worker                             TimeDelta::Millis(1),
183*d9f75844SAndroid Build Coastguard Worker       .render_time = clock_->CurrentTime() + TimeDelta::Millis(30)};
184*d9f75844SAndroid Build Coastguard Worker   EXPECT_CALL(mock_callback, Call(Eq(90000u), _)).Times(1);
185*d9f75844SAndroid Build Coastguard Worker   scheduler->ScheduleFrame(90000, frame_sched, mock_callback.AsStdFunction());
186*d9f75844SAndroid Build Coastguard Worker   // Verify the callback was invoked already.
187*d9f75844SAndroid Build Coastguard Worker   ::testing::Mock::VerifyAndClearExpectations(&mock_callback);
188*d9f75844SAndroid Build Coastguard Worker 
189*d9f75844SAndroid Build Coastguard Worker   time_controller_.AdvanceTime(kTickPeriod);
190*d9f75844SAndroid Build Coastguard Worker   metronome_.Tick();
191*d9f75844SAndroid Build Coastguard Worker   time_controller_.AdvanceTime(TimeDelta::Zero());
192*d9f75844SAndroid Build Coastguard Worker 
193*d9f75844SAndroid Build Coastguard Worker   // A frame that would be behind by exactly kMaxAllowedFrameDelay after next
194*d9f75844SAndroid Build Coastguard Worker   // tick should decode at the next tick.
195*d9f75844SAndroid Build Coastguard Worker   FrameDecodeTiming::FrameSchedule queued_frame{
196*d9f75844SAndroid Build Coastguard Worker       .latest_decode_time = clock_->CurrentTime() + kTickPeriod -
197*d9f75844SAndroid Build Coastguard Worker                             FrameDecodeTiming::kMaxAllowedFrameDelay,
198*d9f75844SAndroid Build Coastguard Worker       .render_time = clock_->CurrentTime() + TimeDelta::Millis(30)};
199*d9f75844SAndroid Build Coastguard Worker   scheduler->ScheduleFrame(180000, queued_frame, mock_callback.AsStdFunction());
200*d9f75844SAndroid Build Coastguard Worker   // Verify the callback was invoked already.
201*d9f75844SAndroid Build Coastguard Worker   ::testing::Mock::VerifyAndClearExpectations(&mock_callback);
202*d9f75844SAndroid Build Coastguard Worker 
203*d9f75844SAndroid Build Coastguard Worker   EXPECT_CALL(mock_callback, Call(Eq(180000u), _)).Times(1);
204*d9f75844SAndroid Build Coastguard Worker   time_controller_.AdvanceTime(kTickPeriod);
205*d9f75844SAndroid Build Coastguard Worker   metronome_.Tick();
206*d9f75844SAndroid Build Coastguard Worker   time_controller_.AdvanceTime(TimeDelta::Zero());
207*d9f75844SAndroid Build Coastguard Worker 
208*d9f75844SAndroid Build Coastguard Worker   // Cleanup
209*d9f75844SAndroid Build Coastguard Worker   scheduler->Stop();
210*d9f75844SAndroid Build Coastguard Worker }
211*d9f75844SAndroid Build Coastguard Worker 
TEST_F(DecodeSynchronizerTest,FramesNotReleasedAfterStop)212*d9f75844SAndroid Build Coastguard Worker TEST_F(DecodeSynchronizerTest, FramesNotReleasedAfterStop) {
213*d9f75844SAndroid Build Coastguard Worker   ::testing::MockFunction<void(unsigned int, Timestamp)> mock_callback;
214*d9f75844SAndroid Build Coastguard Worker   auto scheduler = decode_synchronizer_.CreateSynchronizedFrameScheduler();
215*d9f75844SAndroid Build Coastguard Worker 
216*d9f75844SAndroid Build Coastguard Worker   uint32_t frame_rtp = 90000;
217*d9f75844SAndroid Build Coastguard Worker   FrameDecodeTiming::FrameSchedule frame_sched{
218*d9f75844SAndroid Build Coastguard Worker       .latest_decode_time = clock_->CurrentTime() + TimeDelta::Millis(30),
219*d9f75844SAndroid Build Coastguard Worker       .render_time = clock_->CurrentTime() + TimeDelta::Millis(60)};
220*d9f75844SAndroid Build Coastguard Worker   scheduler->ScheduleFrame(frame_rtp, frame_sched,
221*d9f75844SAndroid Build Coastguard Worker                            mock_callback.AsStdFunction());
222*d9f75844SAndroid Build Coastguard Worker   // Cleanup
223*d9f75844SAndroid Build Coastguard Worker   scheduler->Stop();
224*d9f75844SAndroid Build Coastguard Worker 
225*d9f75844SAndroid Build Coastguard Worker   // No callback should occur on this tick since Stop() was called before.
226*d9f75844SAndroid Build Coastguard Worker   metronome_.Tick();
227*d9f75844SAndroid Build Coastguard Worker   time_controller_.AdvanceTime(TimeDelta::Zero());
228*d9f75844SAndroid Build Coastguard Worker }
229*d9f75844SAndroid Build Coastguard Worker 
TEST(DecodeSynchronizerStandaloneTest,MetronomeNotListenedWhenNoStreamsAreActive)230*d9f75844SAndroid Build Coastguard Worker TEST(DecodeSynchronizerStandaloneTest,
231*d9f75844SAndroid Build Coastguard Worker      MetronomeNotListenedWhenNoStreamsAreActive) {
232*d9f75844SAndroid Build Coastguard Worker   GlobalSimulatedTimeController time_controller(Timestamp::Millis(4711));
233*d9f75844SAndroid Build Coastguard Worker   Clock* clock(time_controller.GetClock());
234*d9f75844SAndroid Build Coastguard Worker   MockMetronome metronome;
235*d9f75844SAndroid Build Coastguard Worker   ON_CALL(metronome, TickPeriod).WillByDefault(Return(TimeDelta::Seconds(1)));
236*d9f75844SAndroid Build Coastguard Worker   DecodeSynchronizer decode_synchronizer_(clock, &metronome,
237*d9f75844SAndroid Build Coastguard Worker                                           time_controller.GetMainThread());
238*d9f75844SAndroid Build Coastguard Worker   absl::AnyInvocable<void() &&> callback;
239*d9f75844SAndroid Build Coastguard Worker   EXPECT_CALL(metronome, RequestCallOnNextTick)
240*d9f75844SAndroid Build Coastguard Worker       .WillOnce(Invoke([&callback](absl::AnyInvocable<void() &&> cb) {
241*d9f75844SAndroid Build Coastguard Worker         callback = std::move(cb);
242*d9f75844SAndroid Build Coastguard Worker       }));
243*d9f75844SAndroid Build Coastguard Worker   auto scheduler = decode_synchronizer_.CreateSynchronizedFrameScheduler();
244*d9f75844SAndroid Build Coastguard Worker   auto scheduler2 = decode_synchronizer_.CreateSynchronizedFrameScheduler();
245*d9f75844SAndroid Build Coastguard Worker   scheduler->Stop();
246*d9f75844SAndroid Build Coastguard Worker   scheduler2->Stop();
247*d9f75844SAndroid Build Coastguard Worker   time_controller.AdvanceTime(TimeDelta::Seconds(1));
248*d9f75844SAndroid Build Coastguard Worker   ASSERT_TRUE(callback);
249*d9f75844SAndroid Build Coastguard Worker   (std::move)(callback)();
250*d9f75844SAndroid Build Coastguard Worker }
251*d9f75844SAndroid Build Coastguard Worker 
252*d9f75844SAndroid Build Coastguard Worker }  // namespace webrtc
253