1 /*
2 * Copyright (c) 2022 The WebRTC project authors. All Rights Reserved.
3 *
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10
11 #include "video/task_queue_frame_decode_scheduler.h"
12
13 #include <stddef.h>
14
15 #include <memory>
16 #include <utility>
17
18 #include "absl/types/optional.h"
19 #include "api/units/time_delta.h"
20 #include "api/units/timestamp.h"
21 #include "test/gmock.h"
22 #include "test/gtest.h"
23 #include "test/time_controller/simulated_time_controller.h"
24
25 namespace webrtc {
26
27 using ::testing::_;
28 using ::testing::Eq;
29 using ::testing::MockFunction;
30 using ::testing::Optional;
31
TEST(TaskQueueFrameDecodeSchedulerTest,FrameYieldedAfterSpecifiedPeriod)32 TEST(TaskQueueFrameDecodeSchedulerTest, FrameYieldedAfterSpecifiedPeriod) {
33 GlobalSimulatedTimeController time_controller_(Timestamp::Seconds(2000));
34 TaskQueueFrameDecodeScheduler scheduler(time_controller_.GetClock(),
35 time_controller_.GetMainThread());
36 constexpr TimeDelta decode_delay = TimeDelta::Millis(5);
37
38 const Timestamp now = time_controller_.GetClock()->CurrentTime();
39 const uint32_t rtp = 90000;
40 const Timestamp render_time = now + TimeDelta::Millis(15);
41 FrameDecodeTiming::FrameSchedule schedule = {
42 .latest_decode_time = now + decode_delay, .render_time = render_time};
43
44 MockFunction<void(uint32_t, Timestamp)> ready_cb;
45 scheduler.ScheduleFrame(rtp, schedule, ready_cb.AsStdFunction());
46 EXPECT_CALL(ready_cb, Call(_, _)).Times(0);
47 EXPECT_THAT(scheduler.ScheduledRtpTimestamp(), Optional(rtp));
48 time_controller_.AdvanceTime(TimeDelta::Zero());
49 // Check that `ready_cb` has not been invoked yet.
50 ::testing::Mock::VerifyAndClearExpectations(&ready_cb);
51
52 EXPECT_CALL(ready_cb, Call(rtp, render_time)).Times(1);
53 time_controller_.AdvanceTime(decode_delay);
54
55 scheduler.Stop();
56 }
57
TEST(TaskQueueFrameDecodeSchedulerTest,NegativeDecodeDelayIsRoundedToZero)58 TEST(TaskQueueFrameDecodeSchedulerTest, NegativeDecodeDelayIsRoundedToZero) {
59 GlobalSimulatedTimeController time_controller_(Timestamp::Seconds(2000));
60 TaskQueueFrameDecodeScheduler scheduler(time_controller_.GetClock(),
61 time_controller_.GetMainThread());
62 constexpr TimeDelta decode_delay = TimeDelta::Millis(-5);
63 const Timestamp now = time_controller_.GetClock()->CurrentTime();
64 const uint32_t rtp = 90000;
65 const Timestamp render_time = now + TimeDelta::Millis(15);
66 FrameDecodeTiming::FrameSchedule schedule = {
67 .latest_decode_time = now + decode_delay, .render_time = render_time};
68
69 MockFunction<void(uint32_t, Timestamp)> ready_cb;
70 EXPECT_CALL(ready_cb, Call(rtp, render_time)).Times(1);
71 scheduler.ScheduleFrame(rtp, schedule, ready_cb.AsStdFunction());
72 EXPECT_THAT(scheduler.ScheduledRtpTimestamp(), Optional(rtp));
73 time_controller_.AdvanceTime(TimeDelta::Zero());
74
75 scheduler.Stop();
76 }
77
TEST(TaskQueueFrameDecodeSchedulerTest,CancelOutstanding)78 TEST(TaskQueueFrameDecodeSchedulerTest, CancelOutstanding) {
79 GlobalSimulatedTimeController time_controller_(Timestamp::Seconds(2000));
80 TaskQueueFrameDecodeScheduler scheduler(time_controller_.GetClock(),
81 time_controller_.GetMainThread());
82 constexpr TimeDelta decode_delay = TimeDelta::Millis(50);
83 const Timestamp now = time_controller_.GetClock()->CurrentTime();
84 const uint32_t rtp = 90000;
85 FrameDecodeTiming::FrameSchedule schedule = {
86 .latest_decode_time = now + decode_delay,
87 .render_time = now + TimeDelta::Millis(75)};
88
89 MockFunction<void(uint32_t, Timestamp)> ready_cb;
90 EXPECT_CALL(ready_cb, Call).Times(0);
91 scheduler.ScheduleFrame(rtp, schedule, ready_cb.AsStdFunction());
92 EXPECT_THAT(scheduler.ScheduledRtpTimestamp(), Optional(rtp));
93 time_controller_.AdvanceTime(decode_delay / 2);
94 EXPECT_THAT(scheduler.ScheduledRtpTimestamp(), Optional(rtp));
95 scheduler.CancelOutstanding();
96 EXPECT_THAT(scheduler.ScheduledRtpTimestamp(), Eq(absl::nullopt));
97 time_controller_.AdvanceTime(decode_delay / 2);
98
99 scheduler.Stop();
100 }
101
102 } // namespace webrtc
103