blob: 83ea91692ceedce37ae737946c0cd75181f692c7 [file] [log] [blame]
Evan Shrubsole9a999052021-12-12 15:27:00 +01001/*
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"
Rasmus Brandtc4d253c2022-05-25 12:03:35 +020017#include "modules/video_coding/timing/timing.h"
Evan Shrubsole9a999052021-12-12 15:27:00 +010018#include "rtc_base/containers/flat_map.h"
19#include "test/gmock.h"
20#include "test/gtest.h"
Jonas Orelande02f9ee2022-03-25 12:43:14 +010021#include "test/scoped_key_value_config.h"
Evan Shrubsole3fa9a662022-06-13 14:19:10 +000022#include "video/video_receive_stream2.h"
Evan Shrubsole9a999052021-12-12 15:27:00 +010023
24namespace webrtc {
25
26using ::testing::AllOf;
27using ::testing::Eq;
28using ::testing::Field;
29using ::testing::Optional;
30
31namespace {
32
33class FakeVCMTiming : public webrtc::VCMTiming {
34 public:
Jonas Orelande62c2f22022-03-29 11:04:48 +020035 explicit FakeVCMTiming(Clock* clock, const FieldTrialsView& field_trials)
Jonas Orelande02f9ee2022-03-25 12:43:14 +010036 : webrtc::VCMTiming(clock, field_trials) {}
Evan Shrubsole9a999052021-12-12 15:27:00 +010037
Evan Shrubsoled6cdf802022-03-02 15:13:55 +010038 Timestamp RenderTime(uint32_t frame_timestamp, Timestamp now) const override {
Evan Shrubsole9a999052021-12-12 15:27:00 +010039 RTC_DCHECK(render_time_map_.contains(frame_timestamp));
40 auto it = render_time_map_.find(frame_timestamp);
Evan Shrubsoled6cdf802022-03-02 15:13:55 +010041 return it->second;
Evan Shrubsole9a999052021-12-12 15:27:00 +010042 }
43
Evan Shrubsoled6cdf802022-03-02 15:13:55 +010044 TimeDelta MaxWaitingTime(Timestamp render_time,
45 Timestamp now,
46 bool too_many_frames_queued) const override {
Evan Shrubsole9a999052021-12-12 15:27:00 +010047 RTC_DCHECK(wait_time_map_.contains(render_time));
48 auto it = wait_time_map_.find(render_time);
Evan Shrubsoled6cdf802022-03-02 15:13:55 +010049 return it->second;
Evan Shrubsole9a999052021-12-12 15:27:00 +010050 }
51
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
65class FrameDecodeTimingTest : public ::testing::Test {
66 public:
67 FrameDecodeTimingTest()
68 : clock_(Timestamp::Millis(1000)),
Jonas Orelande02f9ee2022-03-25 12:43:14 +010069 timing_(&clock_, field_trials_),
Evan Shrubsole9a999052021-12-12 15:27:00 +010070 frame_decode_scheduler_(&clock_, &timing_) {}
71
72 protected:
Jonas Orelande02f9ee2022-03-25 12:43:14 +010073 test::ScopedKeyValueConfig field_trials_;
Evan Shrubsole9a999052021-12-12 15:27:00 +010074 SimulatedClock clock_;
75 FakeVCMTiming timing_;
76 FrameDecodeTiming frame_decode_scheduler_;
77};
78
79TEST_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
Evan Shrubsole3fa9a662022-06-13 14:19:10 +000084 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)))));
Evan Shrubsole9a999052021-12-12 15:27:00 +010091}
92
93TEST_F(FrameDecodeTimingTest, FastForwardsFrameTooFarInThePast) {
Evan Shrubsolef7a19372022-02-14 14:05:10 +010094 const TimeDelta decode_delay =
95 -FrameDecodeTiming::kMaxAllowedFrameDelay - TimeDelta::Millis(1);
Evan Shrubsole9a999052021-12-12 15:27:00 +010096 const Timestamp render_time = clock_.CurrentTime();
97 timing_.SetTimes(90000, render_time, decode_delay);
98
Evan Shrubsole3fa9a662022-06-13 14:19:10 +000099 EXPECT_THAT(frame_decode_scheduler_.OnFrameBufferUpdated(
100 90000, 180000, kMaxWaitForFrame, false),
101 Eq(absl::nullopt));
Evan Shrubsole9a999052021-12-12 15:27:00 +0100102}
103
104TEST_F(FrameDecodeTimingTest, NoFastForwardIfOnlyFrameToDecode) {
Evan Shrubsolef7a19372022-02-14 14:05:10 +0100105 const TimeDelta decode_delay =
106 -FrameDecodeTiming::kMaxAllowedFrameDelay - TimeDelta::Millis(1);
Evan Shrubsole9a999052021-12-12 15:27:00 +0100107 const Timestamp render_time = clock_.CurrentTime();
108 timing_.SetTimes(90000, render_time, decode_delay);
109
Evan Shrubsolef7a19372022-02-14 14:05:10 +0100110 // Negative `decode_delay` means that `latest_decode_time` is now.
Evan Shrubsole3fa9a662022-06-13 14:19:10 +0000111 EXPECT_THAT(frame_decode_scheduler_.OnFrameBufferUpdated(
112 90000, 90000, kMaxWaitForFrame, false),
Evan Shrubsole6cd6d8e2022-02-11 15:30:26 +0100113 Optional(AllOf(
114 Field(&FrameDecodeTiming::FrameSchedule::latest_decode_time,
Evan Shrubsolef7a19372022-02-14 14:05:10 +0100115 Eq(clock_.CurrentTime())),
Evan Shrubsole6cd6d8e2022-02-11 15:30:26 +0100116 Field(&FrameDecodeTiming::FrameSchedule::render_time,
117 Eq(render_time)))));
Evan Shrubsole9a999052021-12-12 15:27:00 +0100118}
119
Evan Shrubsole3fa9a662022-06-13 14:19:10 +0000120TEST_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
Evan Shrubsole9a999052021-12-12 15:27:00 +0100147} // namespace webrtc