1 /*
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 "test/testsupport/fixed_fps_video_frame_writer_adapter.h"
12
13 #include <memory>
14 #include <utility>
15 #include <vector>
16
17 #include "api/units/time_delta.h"
18 #include "api/units/timestamp.h"
19 #include "api/video/i420_buffer.h"
20 #include "api/video/video_frame.h"
21 #include "rtc_base/synchronization/mutex.h"
22 #include "test/gmock.h"
23 #include "test/gtest.h"
24 #include "test/testsupport/video_frame_writer.h"
25 #include "test/time_controller/simulated_time_controller.h"
26
27 namespace webrtc {
28 namespace test {
29 namespace {
30
31 constexpr TimeDelta kOneSecond = TimeDelta::Seconds(1);
32
33 using ::testing::ElementsAre;
34
35 class InMemoryVideoWriter : public VideoFrameWriter {
36 public:
37 ~InMemoryVideoWriter() override = default;
38
WriteFrame(const webrtc::VideoFrame & frame)39 bool WriteFrame(const webrtc::VideoFrame& frame) override {
40 MutexLock lock(&mutex_);
41 received_frames_.push_back(frame);
42 return true;
43 }
44
Close()45 void Close() override {}
46
received_frames() const47 std::vector<VideoFrame> received_frames() const {
48 MutexLock lock(&mutex_);
49 return received_frames_;
50 }
51
52 private:
53 mutable Mutex mutex_;
54 std::vector<VideoFrame> received_frames_ RTC_GUARDED_BY(mutex_);
55 };
56
EmptyFrameWithId(uint16_t frame_id)57 VideoFrame EmptyFrameWithId(uint16_t frame_id) {
58 return VideoFrame::Builder()
59 .set_video_frame_buffer(I420Buffer::Create(1, 1))
60 .set_id(frame_id)
61 .build();
62 }
63
FrameIds(const std::vector<VideoFrame> & frames)64 std::vector<uint16_t> FrameIds(const std::vector<VideoFrame>& frames) {
65 std::vector<uint16_t> out;
66 for (const VideoFrame& frame : frames) {
67 out.push_back(frame.id());
68 }
69 return out;
70 }
71
CreateSimulatedTimeController()72 std::unique_ptr<TimeController> CreateSimulatedTimeController() {
73 // Using an offset of 100000 to get nice fixed width and readable
74 // timestamps in typical test scenarios.
75 const Timestamp kSimulatedStartTime = Timestamp::Seconds(100000);
76 return std::make_unique<GlobalSimulatedTimeController>(kSimulatedStartTime);
77 }
78
TEST(FixedFpsVideoFrameWriterAdapterTest,WhenWrittenWithSameFpsVideoIsCorrect)79 TEST(FixedFpsVideoFrameWriterAdapterTest,
80 WhenWrittenWithSameFpsVideoIsCorrect) {
81 auto time_controller = CreateSimulatedTimeController();
82 int fps = 25;
83
84 auto inmemory_writer = std::make_unique<InMemoryVideoWriter>();
85 InMemoryVideoWriter* inmemory_writer_ref = inmemory_writer.get();
86
87 FixedFpsVideoFrameWriterAdapter video_writer(fps, time_controller->GetClock(),
88 std::move(inmemory_writer));
89
90 for (int i = 1; i <= 30; ++i) {
91 video_writer.WriteFrame(EmptyFrameWithId(i));
92 time_controller->AdvanceTime(kOneSecond / fps);
93 }
94 video_writer.Close();
95
96 std::vector<VideoFrame> received_frames =
97 inmemory_writer_ref->received_frames();
98 EXPECT_THAT(
99 FrameIds(received_frames),
100 ElementsAre(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18,
101 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30));
102 }
103
TEST(FixedFpsVideoFrameWriterAdapterTest,FrameIsRepeatedWhenThereIsAFreeze)104 TEST(FixedFpsVideoFrameWriterAdapterTest, FrameIsRepeatedWhenThereIsAFreeze) {
105 auto time_controller = CreateSimulatedTimeController();
106 int fps = 25;
107
108 auto inmemory_writer = std::make_unique<InMemoryVideoWriter>();
109 InMemoryVideoWriter* inmemory_writer_ref = inmemory_writer.get();
110
111 FixedFpsVideoFrameWriterAdapter video_writer(fps, time_controller->GetClock(),
112 std::move(inmemory_writer));
113
114 // Write 10 frames
115 for (int i = 1; i <= 10; ++i) {
116 video_writer.WriteFrame(EmptyFrameWithId(i));
117 time_controller->AdvanceTime(kOneSecond / fps);
118 }
119
120 // Freeze for 4 frames
121 time_controller->AdvanceTime(4 * kOneSecond / fps);
122
123 // Write 10 more frames
124 for (int i = 11; i <= 20; ++i) {
125 video_writer.WriteFrame(EmptyFrameWithId(i));
126 time_controller->AdvanceTime(kOneSecond / fps);
127 }
128 video_writer.Close();
129
130 std::vector<VideoFrame> received_frames =
131 inmemory_writer_ref->received_frames();
132 EXPECT_THAT(FrameIds(received_frames),
133 ElementsAre(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 10, 10, 10, 10, 11, 12,
134 13, 14, 15, 16, 17, 18, 19, 20));
135 }
136
TEST(FixedFpsVideoFrameWriterAdapterTest,NoFramesWritten)137 TEST(FixedFpsVideoFrameWriterAdapterTest, NoFramesWritten) {
138 auto time_controller = CreateSimulatedTimeController();
139 int fps = 25;
140
141 auto inmemory_writer = std::make_unique<InMemoryVideoWriter>();
142 InMemoryVideoWriter* inmemory_writer_ref = inmemory_writer.get();
143
144 FixedFpsVideoFrameWriterAdapter video_writer(fps, time_controller->GetClock(),
145 std::move(inmemory_writer));
146 time_controller->AdvanceTime(TimeDelta::Millis(100));
147 video_writer.Close();
148
149 std::vector<VideoFrame> received_frames =
150 inmemory_writer_ref->received_frames();
151 ASSERT_TRUE(received_frames.empty());
152 }
153
TEST(FixedFpsVideoFrameWriterAdapterTest,FreezeInTheMiddleAndNewFrameReceivedBeforeMiddleOfExpectedInterval)154 TEST(FixedFpsVideoFrameWriterAdapterTest,
155 FreezeInTheMiddleAndNewFrameReceivedBeforeMiddleOfExpectedInterval) {
156 auto time_controller = CreateSimulatedTimeController();
157 constexpr int kFps = 10;
158 constexpr TimeDelta kInterval = kOneSecond / kFps;
159
160 auto inmemory_writer = std::make_unique<InMemoryVideoWriter>();
161 InMemoryVideoWriter* inmemory_writer_ref = inmemory_writer.get();
162
163 FixedFpsVideoFrameWriterAdapter video_writer(
164 kFps, time_controller->GetClock(), std::move(inmemory_writer));
165 video_writer.WriteFrame(EmptyFrameWithId(1));
166 time_controller->AdvanceTime(2.3 * kInterval);
167 video_writer.WriteFrame(EmptyFrameWithId(2));
168 video_writer.Close();
169
170 std::vector<VideoFrame> received_frames =
171 inmemory_writer_ref->received_frames();
172 EXPECT_THAT(FrameIds(received_frames), ElementsAre(1, 1, 2));
173 }
174
TEST(FixedFpsVideoFrameWriterAdapterTest,FreezeInTheMiddleAndNewFrameReceivedAfterMiddleOfExpectedInterval)175 TEST(FixedFpsVideoFrameWriterAdapterTest,
176 FreezeInTheMiddleAndNewFrameReceivedAfterMiddleOfExpectedInterval) {
177 auto time_controller = CreateSimulatedTimeController();
178 constexpr int kFps = 10;
179 constexpr TimeDelta kInterval = kOneSecond / kFps;
180
181 auto inmemory_writer = std::make_unique<InMemoryVideoWriter>();
182 InMemoryVideoWriter* inmemory_writer_ref = inmemory_writer.get();
183
184 FixedFpsVideoFrameWriterAdapter video_writer(
185 kFps, time_controller->GetClock(), std::move(inmemory_writer));
186 video_writer.WriteFrame(EmptyFrameWithId(1));
187 time_controller->AdvanceTime(2.5 * kInterval);
188 video_writer.WriteFrame(EmptyFrameWithId(2));
189 video_writer.Close();
190
191 std::vector<VideoFrame> received_frames =
192 inmemory_writer_ref->received_frames();
193 EXPECT_THAT(FrameIds(received_frames), ElementsAre(1, 1, 1, 2));
194 }
195
TEST(FixedFpsVideoFrameWriterAdapterTest,NewFrameReceivedBeforeMiddleOfExpectedInterval)196 TEST(FixedFpsVideoFrameWriterAdapterTest,
197 NewFrameReceivedBeforeMiddleOfExpectedInterval) {
198 auto time_controller = CreateSimulatedTimeController();
199 constexpr int kFps = 10;
200 constexpr TimeDelta kInterval = kOneSecond / kFps;
201
202 auto inmemory_writer = std::make_unique<InMemoryVideoWriter>();
203 InMemoryVideoWriter* inmemory_writer_ref = inmemory_writer.get();
204
205 FixedFpsVideoFrameWriterAdapter video_writer(
206 kFps, time_controller->GetClock(), std::move(inmemory_writer));
207 video_writer.WriteFrame(EmptyFrameWithId(1));
208 time_controller->AdvanceTime(0.3 * kInterval);
209 video_writer.WriteFrame(EmptyFrameWithId(2));
210 video_writer.Close();
211
212 std::vector<VideoFrame> received_frames =
213 inmemory_writer_ref->received_frames();
214 EXPECT_THAT(FrameIds(received_frames), ElementsAre(2));
215 }
216
TEST(FixedFpsVideoFrameWriterAdapterTest,NewFrameReceivedAfterMiddleOfExpectedInterval)217 TEST(FixedFpsVideoFrameWriterAdapterTest,
218 NewFrameReceivedAfterMiddleOfExpectedInterval) {
219 auto time_controller = CreateSimulatedTimeController();
220 constexpr int kFps = 10;
221 constexpr TimeDelta kInterval = kOneSecond / kFps;
222
223 auto inmemory_writer = std::make_unique<InMemoryVideoWriter>();
224 InMemoryVideoWriter* inmemory_writer_ref = inmemory_writer.get();
225
226 FixedFpsVideoFrameWriterAdapter video_writer(
227 kFps, time_controller->GetClock(), std::move(inmemory_writer));
228 video_writer.WriteFrame(EmptyFrameWithId(1));
229 time_controller->AdvanceTime(0.5 * kInterval);
230 video_writer.WriteFrame(EmptyFrameWithId(2));
231 video_writer.Close();
232
233 std::vector<VideoFrame> received_frames =
234 inmemory_writer_ref->received_frames();
235 EXPECT_THAT(FrameIds(received_frames), ElementsAre(1, 2));
236 }
237
TEST(FixedFpsVideoFrameWriterAdapterTest,FreeezeAtTheEndAndDestroyBeforeMiddleOfExpectedInterval)238 TEST(FixedFpsVideoFrameWriterAdapterTest,
239 FreeezeAtTheEndAndDestroyBeforeMiddleOfExpectedInterval) {
240 auto time_controller = CreateSimulatedTimeController();
241 constexpr int kFps = 10;
242 constexpr TimeDelta kInterval = kOneSecond / kFps;
243
244 auto inmemory_writer = std::make_unique<InMemoryVideoWriter>();
245 InMemoryVideoWriter* inmemory_writer_ref = inmemory_writer.get();
246
247 FixedFpsVideoFrameWriterAdapter video_writer(
248 kFps, time_controller->GetClock(), std::move(inmemory_writer));
249 video_writer.WriteFrame(EmptyFrameWithId(1));
250 time_controller->AdvanceTime(2.3 * kInterval);
251 video_writer.Close();
252
253 std::vector<VideoFrame> received_frames =
254 inmemory_writer_ref->received_frames();
255 EXPECT_THAT(FrameIds(received_frames), ElementsAre(1, 1, 1));
256 }
257
TEST(FixedFpsVideoFrameWriterAdapterTest,FreeezeAtTheEndAndDestroyAfterMiddleOfExpectedInterval)258 TEST(FixedFpsVideoFrameWriterAdapterTest,
259 FreeezeAtTheEndAndDestroyAfterMiddleOfExpectedInterval) {
260 auto time_controller = CreateSimulatedTimeController();
261 constexpr int kFps = 10;
262 constexpr TimeDelta kInterval = kOneSecond / kFps;
263
264 auto inmemory_writer = std::make_unique<InMemoryVideoWriter>();
265 InMemoryVideoWriter* inmemory_writer_ref = inmemory_writer.get();
266
267 FixedFpsVideoFrameWriterAdapter video_writer(
268 kFps, time_controller->GetClock(), std::move(inmemory_writer));
269 video_writer.WriteFrame(EmptyFrameWithId(1));
270 time_controller->AdvanceTime(2.5 * kInterval);
271 video_writer.Close();
272
273 std::vector<VideoFrame> received_frames =
274 inmemory_writer_ref->received_frames();
275 EXPECT_THAT(FrameIds(received_frames), ElementsAre(1, 1, 1));
276 }
277
TEST(FixedFpsVideoFrameWriterAdapterTest,DestroyBeforeMiddleOfExpectedInterval)278 TEST(FixedFpsVideoFrameWriterAdapterTest,
279 DestroyBeforeMiddleOfExpectedInterval) {
280 auto time_controller = CreateSimulatedTimeController();
281 constexpr int kFps = 10;
282 constexpr TimeDelta kInterval = kOneSecond / kFps;
283
284 auto inmemory_writer = std::make_unique<InMemoryVideoWriter>();
285 InMemoryVideoWriter* inmemory_writer_ref = inmemory_writer.get();
286
287 FixedFpsVideoFrameWriterAdapter video_writer(
288 kFps, time_controller->GetClock(), std::move(inmemory_writer));
289 video_writer.WriteFrame(EmptyFrameWithId(1));
290 time_controller->AdvanceTime(0.3 * kInterval);
291 video_writer.Close();
292
293 std::vector<VideoFrame> received_frames =
294 inmemory_writer_ref->received_frames();
295 EXPECT_THAT(FrameIds(received_frames), ElementsAre(1));
296 }
297
TEST(FixedFpsVideoFrameWriterAdapterTest,DestroyAfterMiddleOfExpectedInterval)298 TEST(FixedFpsVideoFrameWriterAdapterTest,
299 DestroyAfterMiddleOfExpectedInterval) {
300 auto time_controller = CreateSimulatedTimeController();
301 constexpr int kFps = 10;
302 constexpr TimeDelta kInterval = kOneSecond / kFps;
303
304 auto inmemory_writer = std::make_unique<InMemoryVideoWriter>();
305 InMemoryVideoWriter* inmemory_writer_ref = inmemory_writer.get();
306
307 FixedFpsVideoFrameWriterAdapter video_writer(
308 kFps, time_controller->GetClock(), std::move(inmemory_writer));
309 video_writer.WriteFrame(EmptyFrameWithId(1));
310 time_controller->AdvanceTime(0.5 * kInterval);
311 video_writer.Close();
312
313 std::vector<VideoFrame> received_frames =
314 inmemory_writer_ref->received_frames();
315 EXPECT_THAT(FrameIds(received_frames), ElementsAre(1));
316 }
317
318 } // namespace
319 } // namespace test
320 } // namespace webrtc
321