xref: /aosp_15_r20/external/webrtc/video/frame_decode_timing_unittest.cc (revision d9f758449e529ab9291ac668be2861e7a55c2422)
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/frame_decode_timing.h"
12 
13 #include <stdint.h>
14 
15 #include "absl/types/optional.h"
16 #include "api/units/time_delta.h"
17 #include "modules/video_coding/timing/timing.h"
18 #include "rtc_base/containers/flat_map.h"
19 #include "test/gmock.h"
20 #include "test/gtest.h"
21 #include "test/scoped_key_value_config.h"
22 #include "video/video_receive_stream2.h"
23 
24 namespace webrtc {
25 
26 using ::testing::AllOf;
27 using ::testing::Eq;
28 using ::testing::Field;
29 using ::testing::Optional;
30 
31 namespace {
32 
33 class FakeVCMTiming : public webrtc::VCMTiming {
34  public:
FakeVCMTiming(Clock * clock,const FieldTrialsView & field_trials)35   explicit FakeVCMTiming(Clock* clock, const FieldTrialsView& field_trials)
36       : webrtc::VCMTiming(clock, field_trials) {}
37 
RenderTime(uint32_t frame_timestamp,Timestamp now) const38   Timestamp RenderTime(uint32_t frame_timestamp, Timestamp now) const override {
39     RTC_DCHECK(render_time_map_.contains(frame_timestamp));
40     auto it = render_time_map_.find(frame_timestamp);
41     return it->second;
42   }
43 
MaxWaitingTime(Timestamp render_time,Timestamp now,bool too_many_frames_queued) const44   TimeDelta MaxWaitingTime(Timestamp render_time,
45                            Timestamp now,
46                            bool too_many_frames_queued) const override {
47     RTC_DCHECK(wait_time_map_.contains(render_time));
48     auto it = wait_time_map_.find(render_time);
49     return it->second;
50   }
51 
SetTimes(uint32_t frame_timestamp,Timestamp render_time,TimeDelta max_decode_wait)52   void SetTimes(uint32_t frame_timestamp,
53                 Timestamp render_time,
54                 TimeDelta max_decode_wait) {
55     render_time_map_.insert_or_assign(frame_timestamp, render_time);
56     wait_time_map_.insert_or_assign(render_time, max_decode_wait);
57   }
58 
59  protected:
60   flat_map<uint32_t, Timestamp> render_time_map_;
61   flat_map<Timestamp, TimeDelta> wait_time_map_;
62 };
63 }  // namespace
64 
65 class FrameDecodeTimingTest : public ::testing::Test {
66  public:
FrameDecodeTimingTest()67   FrameDecodeTimingTest()
68       : clock_(Timestamp::Millis(1000)),
69         timing_(&clock_, field_trials_),
70         frame_decode_scheduler_(&clock_, &timing_) {}
71 
72  protected:
73   test::ScopedKeyValueConfig field_trials_;
74   SimulatedClock clock_;
75   FakeVCMTiming timing_;
76   FrameDecodeTiming frame_decode_scheduler_;
77 };
78 
TEST_F(FrameDecodeTimingTest,ReturnsWaitTimesWhenValid)79 TEST_F(FrameDecodeTimingTest, ReturnsWaitTimesWhenValid) {
80   const TimeDelta decode_delay = TimeDelta::Millis(42);
81   const Timestamp render_time = clock_.CurrentTime() + TimeDelta::Millis(60);
82   timing_.SetTimes(90000, render_time, decode_delay);
83 
84   EXPECT_THAT(frame_decode_scheduler_.OnFrameBufferUpdated(
85                   90000, 180000, kMaxWaitForFrame, false),
86               Optional(AllOf(
87                   Field(&FrameDecodeTiming::FrameSchedule::latest_decode_time,
88                         Eq(clock_.CurrentTime() + decode_delay)),
89                   Field(&FrameDecodeTiming::FrameSchedule::render_time,
90                         Eq(render_time)))));
91 }
92 
TEST_F(FrameDecodeTimingTest,FastForwardsFrameTooFarInThePast)93 TEST_F(FrameDecodeTimingTest, FastForwardsFrameTooFarInThePast) {
94   const TimeDelta decode_delay =
95       -FrameDecodeTiming::kMaxAllowedFrameDelay - TimeDelta::Millis(1);
96   const Timestamp render_time = clock_.CurrentTime();
97   timing_.SetTimes(90000, render_time, decode_delay);
98 
99   EXPECT_THAT(frame_decode_scheduler_.OnFrameBufferUpdated(
100                   90000, 180000, kMaxWaitForFrame, false),
101               Eq(absl::nullopt));
102 }
103 
TEST_F(FrameDecodeTimingTest,NoFastForwardIfOnlyFrameToDecode)104 TEST_F(FrameDecodeTimingTest, NoFastForwardIfOnlyFrameToDecode) {
105   const TimeDelta decode_delay =
106       -FrameDecodeTiming::kMaxAllowedFrameDelay - TimeDelta::Millis(1);
107   const Timestamp render_time = clock_.CurrentTime();
108   timing_.SetTimes(90000, render_time, decode_delay);
109 
110   // Negative `decode_delay` means that `latest_decode_time` is now.
111   EXPECT_THAT(frame_decode_scheduler_.OnFrameBufferUpdated(
112                   90000, 90000, kMaxWaitForFrame, false),
113               Optional(AllOf(
114                   Field(&FrameDecodeTiming::FrameSchedule::latest_decode_time,
115                         Eq(clock_.CurrentTime())),
116                   Field(&FrameDecodeTiming::FrameSchedule::render_time,
117                         Eq(render_time)))));
118 }
119 
TEST_F(FrameDecodeTimingTest,MaxWaitCapped)120 TEST_F(FrameDecodeTimingTest, MaxWaitCapped) {
121   TimeDelta frame_delay = TimeDelta::Millis(30);
122   const TimeDelta decode_delay = TimeDelta::Seconds(3);
123   const Timestamp render_time = clock_.CurrentTime() + TimeDelta::Seconds(3);
124   timing_.SetTimes(90000, render_time, decode_delay);
125   timing_.SetTimes(180000, render_time + frame_delay,
126                    decode_delay + frame_delay);
127 
128   EXPECT_THAT(frame_decode_scheduler_.OnFrameBufferUpdated(
129                   90000, 270000, kMaxWaitForFrame, false),
130               Optional(AllOf(
131                   Field(&FrameDecodeTiming::FrameSchedule::latest_decode_time,
132                         Eq(clock_.CurrentTime() + kMaxWaitForFrame)),
133                   Field(&FrameDecodeTiming::FrameSchedule::render_time,
134                         Eq(render_time)))));
135 
136   // Test cap keyframe.
137   clock_.AdvanceTime(frame_delay);
138   EXPECT_THAT(frame_decode_scheduler_.OnFrameBufferUpdated(
139                   180000, 270000, kMaxWaitForKeyFrame, false),
140               Optional(AllOf(
141                   Field(&FrameDecodeTiming::FrameSchedule::latest_decode_time,
142                         Eq(clock_.CurrentTime() + kMaxWaitForKeyFrame)),
143                   Field(&FrameDecodeTiming::FrameSchedule::render_time,
144                         Eq(render_time + frame_delay)))));
145 }
146 
147 }  // namespace webrtc
148