blob: 0d99847e7320435134df8acfb55c6b46516c4bec [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"
21
22namespace webrtc {
23
24using ::testing::AllOf;
25using ::testing::Eq;
26using ::testing::Field;
27using ::testing::Optional;
28
29namespace {
30
31class FakeVCMTiming : public webrtc::VCMTiming {
32 public:
33 explicit FakeVCMTiming(Clock* clock) : webrtc::VCMTiming(clock) {}
34
Evan Shrubsoled6cdf802022-03-02 15:13:55 +010035 Timestamp RenderTime(uint32_t frame_timestamp, Timestamp now) const override {
Evan Shrubsole9a999052021-12-12 15:27:00 +010036 RTC_DCHECK(render_time_map_.contains(frame_timestamp));
37 auto it = render_time_map_.find(frame_timestamp);
Evan Shrubsoled6cdf802022-03-02 15:13:55 +010038 return it->second;
Evan Shrubsole9a999052021-12-12 15:27:00 +010039 }
40
Evan Shrubsoled6cdf802022-03-02 15:13:55 +010041 TimeDelta MaxWaitingTime(Timestamp render_time,
42 Timestamp now,
43 bool too_many_frames_queued) const override {
Evan Shrubsole9a999052021-12-12 15:27:00 +010044 RTC_DCHECK(wait_time_map_.contains(render_time));
45 auto it = wait_time_map_.find(render_time);
Evan Shrubsoled6cdf802022-03-02 15:13:55 +010046 return it->second;
Evan Shrubsole9a999052021-12-12 15:27:00 +010047 }
48
49 void SetTimes(uint32_t frame_timestamp,
50 Timestamp render_time,
51 TimeDelta max_decode_wait) {
52 render_time_map_.insert_or_assign(frame_timestamp, render_time);
53 wait_time_map_.insert_or_assign(render_time, max_decode_wait);
54 }
55
56 protected:
57 flat_map<uint32_t, Timestamp> render_time_map_;
58 flat_map<Timestamp, TimeDelta> wait_time_map_;
59};
60} // namespace
61
62class FrameDecodeTimingTest : public ::testing::Test {
63 public:
64 FrameDecodeTimingTest()
65 : clock_(Timestamp::Millis(1000)),
66 timing_(&clock_),
67 frame_decode_scheduler_(&clock_, &timing_) {}
68
69 protected:
70 SimulatedClock clock_;
71 FakeVCMTiming timing_;
72 FrameDecodeTiming frame_decode_scheduler_;
73};
74
75TEST_F(FrameDecodeTimingTest, ReturnsWaitTimesWhenValid) {
76 const TimeDelta decode_delay = TimeDelta::Millis(42);
77 const Timestamp render_time = clock_.CurrentTime() + TimeDelta::Millis(60);
78 timing_.SetTimes(90000, render_time, decode_delay);
79
80 EXPECT_THAT(
81 frame_decode_scheduler_.OnFrameBufferUpdated(90000, 180000, false),
Evan Shrubsole6cd6d8e2022-02-11 15:30:26 +010082 Optional(
83 AllOf(Field(&FrameDecodeTiming::FrameSchedule::latest_decode_time,
84 Eq(clock_.CurrentTime() + decode_delay)),
85 Field(&FrameDecodeTiming::FrameSchedule::render_time,
86 Eq(render_time)))));
Evan Shrubsole9a999052021-12-12 15:27:00 +010087}
88
89TEST_F(FrameDecodeTimingTest, FastForwardsFrameTooFarInThePast) {
Evan Shrubsolef7a19372022-02-14 14:05:10 +010090 const TimeDelta decode_delay =
91 -FrameDecodeTiming::kMaxAllowedFrameDelay - TimeDelta::Millis(1);
Evan Shrubsole9a999052021-12-12 15:27:00 +010092 const Timestamp render_time = clock_.CurrentTime();
93 timing_.SetTimes(90000, render_time, decode_delay);
94
95 EXPECT_THAT(
96 frame_decode_scheduler_.OnFrameBufferUpdated(90000, 180000, false),
97 Eq(absl::nullopt));
98}
99
100TEST_F(FrameDecodeTimingTest, NoFastForwardIfOnlyFrameToDecode) {
Evan Shrubsolef7a19372022-02-14 14:05:10 +0100101 const TimeDelta decode_delay =
102 -FrameDecodeTiming::kMaxAllowedFrameDelay - TimeDelta::Millis(1);
Evan Shrubsole9a999052021-12-12 15:27:00 +0100103 const Timestamp render_time = clock_.CurrentTime();
104 timing_.SetTimes(90000, render_time, decode_delay);
105
Evan Shrubsolef7a19372022-02-14 14:05:10 +0100106 // Negative `decode_delay` means that `latest_decode_time` is now.
Evan Shrubsole6cd6d8e2022-02-11 15:30:26 +0100107 EXPECT_THAT(frame_decode_scheduler_.OnFrameBufferUpdated(90000, 90000, false),
108 Optional(AllOf(
109 Field(&FrameDecodeTiming::FrameSchedule::latest_decode_time,
Evan Shrubsolef7a19372022-02-14 14:05:10 +0100110 Eq(clock_.CurrentTime())),
Evan Shrubsole6cd6d8e2022-02-11 15:30:26 +0100111 Field(&FrameDecodeTiming::FrameSchedule::render_time,
112 Eq(render_time)))));
Evan Shrubsole9a999052021-12-12 15:27:00 +0100113}
114
115} // namespace webrtc