blob: 1932e85246e7ad4e7a1a6ab3d77534ad4e2b40c4 [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
35 int64_t RenderTimeMs(uint32_t frame_timestamp,
36 int64_t now_ms) const override {
37 RTC_DCHECK(render_time_map_.contains(frame_timestamp));
38 auto it = render_time_map_.find(frame_timestamp);
39 return it->second.ms();
40 }
41
42 int64_t MaxWaitingTime(int64_t render_time_ms,
43 int64_t now_ms,
44 bool too_many_frames_queued) const override {
45 auto render_time = Timestamp::Millis(render_time_ms);
46 RTC_DCHECK(wait_time_map_.contains(render_time));
47 auto it = wait_time_map_.find(render_time);
48 return it->second.ms();
49 }
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)),
68 timing_(&clock_),
69 frame_decode_scheduler_(&clock_, &timing_) {}
70
71 protected:
72 SimulatedClock clock_;
73 FakeVCMTiming timing_;
74 FrameDecodeTiming frame_decode_scheduler_;
75};
76
77TEST_F(FrameDecodeTimingTest, ReturnsWaitTimesWhenValid) {
78 const TimeDelta decode_delay = TimeDelta::Millis(42);
79 const Timestamp render_time = clock_.CurrentTime() + TimeDelta::Millis(60);
80 timing_.SetTimes(90000, render_time, decode_delay);
81
82 EXPECT_THAT(
83 frame_decode_scheduler_.OnFrameBufferUpdated(90000, 180000, false),
Evan Shrubsole6cd6d8e2022-02-11 15:30:26 +010084 Optional(
85 AllOf(Field(&FrameDecodeTiming::FrameSchedule::latest_decode_time,
86 Eq(clock_.CurrentTime() + decode_delay)),
87 Field(&FrameDecodeTiming::FrameSchedule::render_time,
88 Eq(render_time)))));
Evan Shrubsole9a999052021-12-12 15:27:00 +010089}
90
91TEST_F(FrameDecodeTimingTest, FastForwardsFrameTooFarInThePast) {
92 const TimeDelta decode_delay = TimeDelta::Millis(-6);
93 const Timestamp render_time = clock_.CurrentTime();
94 timing_.SetTimes(90000, render_time, decode_delay);
95
96 EXPECT_THAT(
97 frame_decode_scheduler_.OnFrameBufferUpdated(90000, 180000, false),
98 Eq(absl::nullopt));
99}
100
101TEST_F(FrameDecodeTimingTest, NoFastForwardIfOnlyFrameToDecode) {
102 const TimeDelta decode_delay = TimeDelta::Millis(-6);
103 const Timestamp render_time = clock_.CurrentTime();
104 timing_.SetTimes(90000, render_time, decode_delay);
105
Evan Shrubsole6cd6d8e2022-02-11 15:30:26 +0100106 EXPECT_THAT(frame_decode_scheduler_.OnFrameBufferUpdated(90000, 90000, false),
107 Optional(AllOf(
108 Field(&FrameDecodeTiming::FrameSchedule::latest_decode_time,
109 Eq(clock_.CurrentTime() + decode_delay)),
110 Field(&FrameDecodeTiming::FrameSchedule::render_time,
111 Eq(render_time)))));
Evan Shrubsole9a999052021-12-12 15:27:00 +0100112}
113
114} // namespace webrtc