blob: cb45d709f1e0e018dfe34321fd634da87c405b1e [file] [log] [blame]
Evan Shrubsole9a999052021-12-12 14:27:001/*
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
Florent Castelli8037fc62024-08-29 13:00:4015#include <optional>
16
Evan Shrubsole9a999052021-12-12 14:27:0017#include "api/units/time_delta.h"
Rasmus Brandtc4d253c2022-05-25 10:03:3518#include "modules/video_coding/timing/timing.h"
Evan Shrubsole9a999052021-12-12 14:27:0019#include "rtc_base/containers/flat_map.h"
20#include "test/gmock.h"
21#include "test/gtest.h"
Jonas Orelande02f9ee2022-03-25 11:43:1422#include "test/scoped_key_value_config.h"
Evan Shrubsole3fa9a662022-06-13 14:19:1023#include "video/video_receive_stream2.h"
Evan Shrubsole9a999052021-12-12 14:27:0024
25namespace webrtc {
26
27using ::testing::AllOf;
28using ::testing::Eq;
29using ::testing::Field;
30using ::testing::Optional;
31
32namespace {
33
34class FakeVCMTiming : public webrtc::VCMTiming {
35 public:
Jonas Orelande62c2f22022-03-29 09:04:4836 explicit FakeVCMTiming(Clock* clock, const FieldTrialsView& field_trials)
Jonas Orelande02f9ee2022-03-25 11:43:1437 : webrtc::VCMTiming(clock, field_trials) {}
Evan Shrubsole9a999052021-12-12 14:27:0038
Evan Shrubsoled6cdf802022-03-02 14:13:5539 Timestamp RenderTime(uint32_t frame_timestamp, Timestamp now) const override {
Evan Shrubsole9a999052021-12-12 14:27:0040 RTC_DCHECK(render_time_map_.contains(frame_timestamp));
41 auto it = render_time_map_.find(frame_timestamp);
Evan Shrubsoled6cdf802022-03-02 14:13:5542 return it->second;
Evan Shrubsole9a999052021-12-12 14:27:0043 }
44
Evan Shrubsoled6cdf802022-03-02 14:13:5545 TimeDelta MaxWaitingTime(Timestamp render_time,
46 Timestamp now,
47 bool too_many_frames_queued) const override {
Evan Shrubsole9a999052021-12-12 14:27:0048 RTC_DCHECK(wait_time_map_.contains(render_time));
49 auto it = wait_time_map_.find(render_time);
Evan Shrubsoled6cdf802022-03-02 14:13:5550 return it->second;
Evan Shrubsole9a999052021-12-12 14:27:0051 }
52
53 void SetTimes(uint32_t frame_timestamp,
54 Timestamp render_time,
55 TimeDelta max_decode_wait) {
56 render_time_map_.insert_or_assign(frame_timestamp, render_time);
57 wait_time_map_.insert_or_assign(render_time, max_decode_wait);
58 }
59
60 protected:
61 flat_map<uint32_t, Timestamp> render_time_map_;
62 flat_map<Timestamp, TimeDelta> wait_time_map_;
63};
64} // namespace
65
66class FrameDecodeTimingTest : public ::testing::Test {
67 public:
68 FrameDecodeTimingTest()
69 : clock_(Timestamp::Millis(1000)),
Jonas Orelande02f9ee2022-03-25 11:43:1470 timing_(&clock_, field_trials_),
Evan Shrubsole9a999052021-12-12 14:27:0071 frame_decode_scheduler_(&clock_, &timing_) {}
72
73 protected:
Jonas Orelande02f9ee2022-03-25 11:43:1474 test::ScopedKeyValueConfig field_trials_;
Evan Shrubsole9a999052021-12-12 14:27:0075 SimulatedClock clock_;
76 FakeVCMTiming timing_;
77 FrameDecodeTiming frame_decode_scheduler_;
78};
79
80TEST_F(FrameDecodeTimingTest, ReturnsWaitTimesWhenValid) {
81 const TimeDelta decode_delay = TimeDelta::Millis(42);
82 const Timestamp render_time = clock_.CurrentTime() + TimeDelta::Millis(60);
83 timing_.SetTimes(90000, render_time, decode_delay);
84
Evan Shrubsole3fa9a662022-06-13 14:19:1085 EXPECT_THAT(frame_decode_scheduler_.OnFrameBufferUpdated(
86 90000, 180000, kMaxWaitForFrame, false),
87 Optional(AllOf(
88 Field(&FrameDecodeTiming::FrameSchedule::latest_decode_time,
89 Eq(clock_.CurrentTime() + decode_delay)),
90 Field(&FrameDecodeTiming::FrameSchedule::render_time,
91 Eq(render_time)))));
Evan Shrubsole9a999052021-12-12 14:27:0092}
93
94TEST_F(FrameDecodeTimingTest, FastForwardsFrameTooFarInThePast) {
Evan Shrubsolef7a19372022-02-14 13:05:1095 const TimeDelta decode_delay =
96 -FrameDecodeTiming::kMaxAllowedFrameDelay - TimeDelta::Millis(1);
Evan Shrubsole9a999052021-12-12 14:27:0097 const Timestamp render_time = clock_.CurrentTime();
98 timing_.SetTimes(90000, render_time, decode_delay);
99
Evan Shrubsole3fa9a662022-06-13 14:19:10100 EXPECT_THAT(frame_decode_scheduler_.OnFrameBufferUpdated(
101 90000, 180000, kMaxWaitForFrame, false),
Florent Castelli8037fc62024-08-29 13:00:40102 Eq(std::nullopt));
Evan Shrubsole9a999052021-12-12 14:27:00103}
104
105TEST_F(FrameDecodeTimingTest, NoFastForwardIfOnlyFrameToDecode) {
Evan Shrubsolef7a19372022-02-14 13:05:10106 const TimeDelta decode_delay =
107 -FrameDecodeTiming::kMaxAllowedFrameDelay - TimeDelta::Millis(1);
Evan Shrubsole9a999052021-12-12 14:27:00108 const Timestamp render_time = clock_.CurrentTime();
109 timing_.SetTimes(90000, render_time, decode_delay);
110
Evan Shrubsolef7a19372022-02-14 13:05:10111 // Negative `decode_delay` means that `latest_decode_time` is now.
Evan Shrubsole3fa9a662022-06-13 14:19:10112 EXPECT_THAT(frame_decode_scheduler_.OnFrameBufferUpdated(
113 90000, 90000, kMaxWaitForFrame, false),
Evan Shrubsole6cd6d8e2022-02-11 14:30:26114 Optional(AllOf(
115 Field(&FrameDecodeTiming::FrameSchedule::latest_decode_time,
Evan Shrubsolef7a19372022-02-14 13:05:10116 Eq(clock_.CurrentTime())),
Evan Shrubsole6cd6d8e2022-02-11 14:30:26117 Field(&FrameDecodeTiming::FrameSchedule::render_time,
118 Eq(render_time)))));
Evan Shrubsole9a999052021-12-12 14:27:00119}
120
Evan Shrubsole3fa9a662022-06-13 14:19:10121TEST_F(FrameDecodeTimingTest, MaxWaitCapped) {
122 TimeDelta frame_delay = TimeDelta::Millis(30);
123 const TimeDelta decode_delay = TimeDelta::Seconds(3);
124 const Timestamp render_time = clock_.CurrentTime() + TimeDelta::Seconds(3);
125 timing_.SetTimes(90000, render_time, decode_delay);
126 timing_.SetTimes(180000, render_time + frame_delay,
127 decode_delay + frame_delay);
128
129 EXPECT_THAT(frame_decode_scheduler_.OnFrameBufferUpdated(
130 90000, 270000, kMaxWaitForFrame, false),
131 Optional(AllOf(
132 Field(&FrameDecodeTiming::FrameSchedule::latest_decode_time,
133 Eq(clock_.CurrentTime() + kMaxWaitForFrame)),
134 Field(&FrameDecodeTiming::FrameSchedule::render_time,
135 Eq(render_time)))));
136
137 // Test cap keyframe.
138 clock_.AdvanceTime(frame_delay);
139 EXPECT_THAT(frame_decode_scheduler_.OnFrameBufferUpdated(
140 180000, 270000, kMaxWaitForKeyFrame, false),
141 Optional(AllOf(
142 Field(&FrameDecodeTiming::FrameSchedule::latest_decode_time,
143 Eq(clock_.CurrentTime() + kMaxWaitForKeyFrame)),
144 Field(&FrameDecodeTiming::FrameSchedule::render_time,
145 Eq(render_time + frame_delay)))));
146}
147
Evan Shrubsole9a999052021-12-12 14:27:00148} // namespace webrtc