blob: 743e722ed980cc09936c1aae2d62bf95b1cdb1c8 [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"
17#include "modules/video_coding/timing.h"
18#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 Shrubsole9a999052021-12-12 15:27:00 +010022
23namespace webrtc {
24
25using ::testing::AllOf;
26using ::testing::Eq;
27using ::testing::Field;
28using ::testing::Optional;
29
30namespace {
31
32class FakeVCMTiming : public webrtc::VCMTiming {
33 public:
Jonas Orelande02f9ee2022-03-25 12:43:14 +010034 explicit FakeVCMTiming(Clock* clock, const WebRtcKeyValueConfig& field_trials)
35 : webrtc::VCMTiming(clock, field_trials) {}
Evan Shrubsole9a999052021-12-12 15:27:00 +010036
Evan Shrubsoled6cdf802022-03-02 15:13:55 +010037 Timestamp RenderTime(uint32_t frame_timestamp, Timestamp now) const override {
Evan Shrubsole9a999052021-12-12 15:27:00 +010038 RTC_DCHECK(render_time_map_.contains(frame_timestamp));
39 auto it = render_time_map_.find(frame_timestamp);
Evan Shrubsoled6cdf802022-03-02 15:13:55 +010040 return it->second;
Evan Shrubsole9a999052021-12-12 15:27:00 +010041 }
42
Evan Shrubsoled6cdf802022-03-02 15:13:55 +010043 TimeDelta MaxWaitingTime(Timestamp render_time,
44 Timestamp now,
45 bool too_many_frames_queued) const override {
Evan Shrubsole9a999052021-12-12 15:27:00 +010046 RTC_DCHECK(wait_time_map_.contains(render_time));
47 auto it = wait_time_map_.find(render_time);
Evan Shrubsoled6cdf802022-03-02 15:13:55 +010048 return it->second;
Evan Shrubsole9a999052021-12-12 15:27:00 +010049 }
50
51 void SetTimes(uint32_t frame_timestamp,
52 Timestamp render_time,
53 TimeDelta max_decode_wait) {
54 render_time_map_.insert_or_assign(frame_timestamp, render_time);
55 wait_time_map_.insert_or_assign(render_time, max_decode_wait);
56 }
57
58 protected:
59 flat_map<uint32_t, Timestamp> render_time_map_;
60 flat_map<Timestamp, TimeDelta> wait_time_map_;
61};
62} // namespace
63
64class FrameDecodeTimingTest : public ::testing::Test {
65 public:
66 FrameDecodeTimingTest()
67 : clock_(Timestamp::Millis(1000)),
Jonas Orelande02f9ee2022-03-25 12:43:14 +010068 timing_(&clock_, field_trials_),
Evan Shrubsole9a999052021-12-12 15:27:00 +010069 frame_decode_scheduler_(&clock_, &timing_) {}
70
71 protected:
Jonas Orelande02f9ee2022-03-25 12:43:14 +010072 test::ScopedKeyValueConfig field_trials_;
Evan Shrubsole9a999052021-12-12 15:27:00 +010073 SimulatedClock clock_;
74 FakeVCMTiming timing_;
75 FrameDecodeTiming frame_decode_scheduler_;
76};
77
78TEST_F(FrameDecodeTimingTest, ReturnsWaitTimesWhenValid) {
79 const TimeDelta decode_delay = TimeDelta::Millis(42);
80 const Timestamp render_time = clock_.CurrentTime() + TimeDelta::Millis(60);
81 timing_.SetTimes(90000, render_time, decode_delay);
82
83 EXPECT_THAT(
84 frame_decode_scheduler_.OnFrameBufferUpdated(90000, 180000, false),
Evan Shrubsole6cd6d8e2022-02-11 15:30:26 +010085 Optional(
86 AllOf(Field(&FrameDecodeTiming::FrameSchedule::latest_decode_time,
87 Eq(clock_.CurrentTime() + decode_delay)),
88 Field(&FrameDecodeTiming::FrameSchedule::render_time,
89 Eq(render_time)))));
Evan Shrubsole9a999052021-12-12 15:27:00 +010090}
91
92TEST_F(FrameDecodeTimingTest, FastForwardsFrameTooFarInThePast) {
Evan Shrubsolef7a19372022-02-14 14:05:10 +010093 const TimeDelta decode_delay =
94 -FrameDecodeTiming::kMaxAllowedFrameDelay - TimeDelta::Millis(1);
Evan Shrubsole9a999052021-12-12 15:27:00 +010095 const Timestamp render_time = clock_.CurrentTime();
96 timing_.SetTimes(90000, render_time, decode_delay);
97
98 EXPECT_THAT(
99 frame_decode_scheduler_.OnFrameBufferUpdated(90000, 180000, false),
100 Eq(absl::nullopt));
101}
102
103TEST_F(FrameDecodeTimingTest, NoFastForwardIfOnlyFrameToDecode) {
Evan Shrubsolef7a19372022-02-14 14:05:10 +0100104 const TimeDelta decode_delay =
105 -FrameDecodeTiming::kMaxAllowedFrameDelay - TimeDelta::Millis(1);
Evan Shrubsole9a999052021-12-12 15:27:00 +0100106 const Timestamp render_time = clock_.CurrentTime();
107 timing_.SetTimes(90000, render_time, decode_delay);
108
Evan Shrubsolef7a19372022-02-14 14:05:10 +0100109 // Negative `decode_delay` means that `latest_decode_time` is now.
Evan Shrubsole6cd6d8e2022-02-11 15:30:26 +0100110 EXPECT_THAT(frame_decode_scheduler_.OnFrameBufferUpdated(90000, 90000, false),
111 Optional(AllOf(
112 Field(&FrameDecodeTiming::FrameSchedule::latest_decode_time,
Evan Shrubsolef7a19372022-02-14 14:05:10 +0100113 Eq(clock_.CurrentTime())),
Evan Shrubsole6cd6d8e2022-02-11 15:30:26 +0100114 Field(&FrameDecodeTiming::FrameSchedule::render_time,
115 Eq(render_time)))));
Evan Shrubsole9a999052021-12-12 15:27:00 +0100116}
117
118} // namespace webrtc