1 /* Copyright (c) 2013 The WebRTC project authors. All Rights Reserved.
2 *
3 * Use of this source code is governed by a BSD-style license
4 * that can be found in the LICENSE file in the root of the source
5 * tree. An additional intellectual property rights grant can be found
6 * in the file PATENTS. All contributing project authors may
7 * be found in the AUTHORS file in the root of the source tree.
8 */
9
10 #include "modules/video_coding/receiver.h"
11
12 #include <string.h>
13
14 #include <cstdint>
15 #include <memory>
16 #include <queue>
17 #include <vector>
18
19 #include "modules/video_coding/encoded_frame.h"
20 #include "modules/video_coding/jitter_buffer_common.h"
21 #include "modules/video_coding/packet.h"
22 #include "modules/video_coding/test/stream_generator.h"
23 #include "modules/video_coding/timing/timing.h"
24 #include "rtc_base/checks.h"
25 #include "system_wrappers/include/clock.h"
26 #include "test/gtest.h"
27 #include "test/scoped_key_value_config.h"
28
29 namespace webrtc {
30
31 class TestVCMReceiver : public ::testing::Test {
32 protected:
TestVCMReceiver()33 TestVCMReceiver()
34 : clock_(0),
35 timing_(&clock_, field_trials_),
36 receiver_(&timing_, &clock_, field_trials_),
37 stream_generator_(0, clock_.TimeInMilliseconds()) {}
38
InsertPacket(int index)39 int32_t InsertPacket(int index) {
40 VCMPacket packet;
41 bool packet_available = stream_generator_.GetPacket(&packet, index);
42 EXPECT_TRUE(packet_available);
43 if (!packet_available)
44 return kGeneralError; // Return here to avoid crashes below.
45 return receiver_.InsertPacket(packet);
46 }
47
InsertPacketAndPop(int index)48 int32_t InsertPacketAndPop(int index) {
49 VCMPacket packet;
50 bool packet_available = stream_generator_.PopPacket(&packet, index);
51 EXPECT_TRUE(packet_available);
52 if (!packet_available)
53 return kGeneralError; // Return here to avoid crashes below.
54 return receiver_.InsertPacket(packet);
55 }
56
InsertFrame(VideoFrameType frame_type,bool complete)57 int32_t InsertFrame(VideoFrameType frame_type, bool complete) {
58 int num_of_packets = complete ? 1 : 2;
59 stream_generator_.GenerateFrame(
60 frame_type,
61 (frame_type != VideoFrameType::kEmptyFrame) ? num_of_packets : 0,
62 (frame_type == VideoFrameType::kEmptyFrame) ? 1 : 0,
63 clock_.TimeInMilliseconds());
64 int32_t ret = InsertPacketAndPop(0);
65 if (!complete) {
66 // Drop the second packet.
67 VCMPacket packet;
68 stream_generator_.PopPacket(&packet, 0);
69 }
70 clock_.AdvanceTimeMilliseconds(kDefaultFramePeriodMs);
71 return ret;
72 }
73
DecodeNextFrame()74 bool DecodeNextFrame() {
75 VCMEncodedFrame* frame = receiver_.FrameForDecoding(0, false);
76 if (!frame)
77 return false;
78 receiver_.ReleaseFrame(frame);
79 return true;
80 }
81
82 test::ScopedKeyValueConfig field_trials_;
83 SimulatedClock clock_;
84 VCMTiming timing_;
85 VCMReceiver receiver_;
86 StreamGenerator stream_generator_;
87 };
88
TEST_F(TestVCMReceiver,NonDecodableDuration_Empty)89 TEST_F(TestVCMReceiver, NonDecodableDuration_Empty) {
90 const size_t kMaxNackListSize = 1000;
91 const int kMaxPacketAgeToNack = 1000;
92 const int kMaxNonDecodableDuration = 500;
93 const int kMinDelayMs = 500;
94 receiver_.SetNackSettings(kMaxNackListSize, kMaxPacketAgeToNack,
95 kMaxNonDecodableDuration);
96 EXPECT_GE(InsertFrame(VideoFrameType::kVideoFrameKey, true), kNoError);
97 // Advance time until it's time to decode the key frame.
98 clock_.AdvanceTimeMilliseconds(kMinDelayMs);
99 EXPECT_TRUE(DecodeNextFrame());
100 bool request_key_frame = false;
101 std::vector<uint16_t> nack_list = receiver_.NackList(&request_key_frame);
102 EXPECT_FALSE(request_key_frame);
103 }
104
TEST_F(TestVCMReceiver,NonDecodableDuration_NoKeyFrame)105 TEST_F(TestVCMReceiver, NonDecodableDuration_NoKeyFrame) {
106 const size_t kMaxNackListSize = 1000;
107 const int kMaxPacketAgeToNack = 1000;
108 const int kMaxNonDecodableDuration = 500;
109 receiver_.SetNackSettings(kMaxNackListSize, kMaxPacketAgeToNack,
110 kMaxNonDecodableDuration);
111 const int kNumFrames = kDefaultFrameRate * kMaxNonDecodableDuration / 1000;
112 for (int i = 0; i < kNumFrames; ++i) {
113 EXPECT_GE(InsertFrame(VideoFrameType::kVideoFrameDelta, true), kNoError);
114 }
115 bool request_key_frame = false;
116 std::vector<uint16_t> nack_list = receiver_.NackList(&request_key_frame);
117 EXPECT_TRUE(request_key_frame);
118 }
119
TEST_F(TestVCMReceiver,NonDecodableDuration_OneIncomplete)120 TEST_F(TestVCMReceiver, NonDecodableDuration_OneIncomplete) {
121 const size_t kMaxNackListSize = 1000;
122 const int kMaxPacketAgeToNack = 1000;
123 const int kMaxNonDecodableDuration = 500;
124 const int kMaxNonDecodableDurationFrames =
125 (kDefaultFrameRate * kMaxNonDecodableDuration + 500) / 1000;
126 const int kMinDelayMs = 500;
127 receiver_.SetNackSettings(kMaxNackListSize, kMaxPacketAgeToNack,
128 kMaxNonDecodableDuration);
129 timing_.set_min_playout_delay(TimeDelta::Millis(kMinDelayMs));
130 int64_t key_frame_inserted = clock_.TimeInMilliseconds();
131 EXPECT_GE(InsertFrame(VideoFrameType::kVideoFrameKey, true), kNoError);
132 // Insert an incomplete frame.
133 EXPECT_GE(InsertFrame(VideoFrameType::kVideoFrameDelta, false), kNoError);
134 // Insert enough frames to have too long non-decodable sequence.
135 for (int i = 0; i < kMaxNonDecodableDurationFrames; ++i) {
136 EXPECT_GE(InsertFrame(VideoFrameType::kVideoFrameDelta, true), kNoError);
137 }
138 // Advance time until it's time to decode the key frame.
139 clock_.AdvanceTimeMilliseconds(kMinDelayMs - clock_.TimeInMilliseconds() -
140 key_frame_inserted);
141 EXPECT_TRUE(DecodeNextFrame());
142 // Make sure we get a key frame request.
143 bool request_key_frame = false;
144 std::vector<uint16_t> nack_list = receiver_.NackList(&request_key_frame);
145 EXPECT_TRUE(request_key_frame);
146 }
147
TEST_F(TestVCMReceiver,NonDecodableDuration_NoTrigger)148 TEST_F(TestVCMReceiver, NonDecodableDuration_NoTrigger) {
149 const size_t kMaxNackListSize = 1000;
150 const int kMaxPacketAgeToNack = 1000;
151 const int kMaxNonDecodableDuration = 500;
152 const int kMaxNonDecodableDurationFrames =
153 (kDefaultFrameRate * kMaxNonDecodableDuration + 500) / 1000;
154 const int kMinDelayMs = 500;
155 receiver_.SetNackSettings(kMaxNackListSize, kMaxPacketAgeToNack,
156 kMaxNonDecodableDuration);
157 timing_.set_min_playout_delay(TimeDelta::Millis(kMinDelayMs));
158 int64_t key_frame_inserted = clock_.TimeInMilliseconds();
159 EXPECT_GE(InsertFrame(VideoFrameType::kVideoFrameKey, true), kNoError);
160 // Insert an incomplete frame.
161 EXPECT_GE(InsertFrame(VideoFrameType::kVideoFrameDelta, false), kNoError);
162 // Insert all but one frame to not trigger a key frame request due to
163 // too long duration of non-decodable frames.
164 for (int i = 0; i < kMaxNonDecodableDurationFrames - 1; ++i) {
165 EXPECT_GE(InsertFrame(VideoFrameType::kVideoFrameDelta, true), kNoError);
166 }
167 // Advance time until it's time to decode the key frame.
168 clock_.AdvanceTimeMilliseconds(kMinDelayMs - clock_.TimeInMilliseconds() -
169 key_frame_inserted);
170 EXPECT_TRUE(DecodeNextFrame());
171 // Make sure we don't get a key frame request since we haven't generated
172 // enough frames.
173 bool request_key_frame = false;
174 std::vector<uint16_t> nack_list = receiver_.NackList(&request_key_frame);
175 EXPECT_FALSE(request_key_frame);
176 }
177
TEST_F(TestVCMReceiver,NonDecodableDuration_NoTrigger2)178 TEST_F(TestVCMReceiver, NonDecodableDuration_NoTrigger2) {
179 const size_t kMaxNackListSize = 1000;
180 const int kMaxPacketAgeToNack = 1000;
181 const int kMaxNonDecodableDuration = 500;
182 const int kMaxNonDecodableDurationFrames =
183 (kDefaultFrameRate * kMaxNonDecodableDuration + 500) / 1000;
184 const int kMinDelayMs = 500;
185 receiver_.SetNackSettings(kMaxNackListSize, kMaxPacketAgeToNack,
186 kMaxNonDecodableDuration);
187 timing_.set_min_playout_delay(TimeDelta::Millis(kMinDelayMs));
188 int64_t key_frame_inserted = clock_.TimeInMilliseconds();
189 EXPECT_GE(InsertFrame(VideoFrameType::kVideoFrameKey, true), kNoError);
190 // Insert enough frames to have too long non-decodable sequence, except that
191 // we don't have any losses.
192 for (int i = 0; i < kMaxNonDecodableDurationFrames; ++i) {
193 EXPECT_GE(InsertFrame(VideoFrameType::kVideoFrameDelta, true), kNoError);
194 }
195 // Insert an incomplete frame.
196 EXPECT_GE(InsertFrame(VideoFrameType::kVideoFrameDelta, false), kNoError);
197 // Advance time until it's time to decode the key frame.
198 clock_.AdvanceTimeMilliseconds(kMinDelayMs - clock_.TimeInMilliseconds() -
199 key_frame_inserted);
200 EXPECT_TRUE(DecodeNextFrame());
201 // Make sure we don't get a key frame request since the non-decodable duration
202 // is only one frame.
203 bool request_key_frame = false;
204 std::vector<uint16_t> nack_list = receiver_.NackList(&request_key_frame);
205 EXPECT_FALSE(request_key_frame);
206 }
207
TEST_F(TestVCMReceiver,NonDecodableDuration_KeyFrameAfterIncompleteFrames)208 TEST_F(TestVCMReceiver, NonDecodableDuration_KeyFrameAfterIncompleteFrames) {
209 const size_t kMaxNackListSize = 1000;
210 const int kMaxPacketAgeToNack = 1000;
211 const int kMaxNonDecodableDuration = 500;
212 const int kMaxNonDecodableDurationFrames =
213 (kDefaultFrameRate * kMaxNonDecodableDuration + 500) / 1000;
214 const int kMinDelayMs = 500;
215 receiver_.SetNackSettings(kMaxNackListSize, kMaxPacketAgeToNack,
216 kMaxNonDecodableDuration);
217 timing_.set_min_playout_delay(TimeDelta::Millis(kMinDelayMs));
218 int64_t key_frame_inserted = clock_.TimeInMilliseconds();
219 EXPECT_GE(InsertFrame(VideoFrameType::kVideoFrameKey, true), kNoError);
220 // Insert an incomplete frame.
221 EXPECT_GE(InsertFrame(VideoFrameType::kVideoFrameDelta, false), kNoError);
222 // Insert enough frames to have too long non-decodable sequence.
223 for (int i = 0; i < kMaxNonDecodableDurationFrames; ++i) {
224 EXPECT_GE(InsertFrame(VideoFrameType::kVideoFrameDelta, true), kNoError);
225 }
226 EXPECT_GE(InsertFrame(VideoFrameType::kVideoFrameKey, true), kNoError);
227 // Advance time until it's time to decode the key frame.
228 clock_.AdvanceTimeMilliseconds(kMinDelayMs - clock_.TimeInMilliseconds() -
229 key_frame_inserted);
230 EXPECT_TRUE(DecodeNextFrame());
231 // Make sure we don't get a key frame request since we have a key frame
232 // in the list.
233 bool request_key_frame = false;
234 std::vector<uint16_t> nack_list = receiver_.NackList(&request_key_frame);
235 EXPECT_FALSE(request_key_frame);
236 }
237
238 // A simulated clock, when time elapses, will insert frames into the jitter
239 // buffer, based on initial settings.
240 class SimulatedClockWithFrames : public SimulatedClock {
241 public:
SimulatedClockWithFrames(StreamGenerator * stream_generator,VCMReceiver * receiver)242 SimulatedClockWithFrames(StreamGenerator* stream_generator,
243 VCMReceiver* receiver)
244 : SimulatedClock(0),
245 stream_generator_(stream_generator),
246 receiver_(receiver) {}
~SimulatedClockWithFrames()247 virtual ~SimulatedClockWithFrames() {}
248
249 // If `stop_on_frame` is true and next frame arrives between now and
250 // now+`milliseconds`, the clock will be advanced to the arrival time of next
251 // frame.
252 // Otherwise, the clock will be advanced by `milliseconds`.
253 //
254 // For both cases, a frame will be inserted into the jitter buffer at the
255 // instant when the clock time is timestamps_.front().arrive_time.
256 //
257 // Return true if some frame arrives between now and now+`milliseconds`.
AdvanceTimeMilliseconds(int64_t milliseconds,bool stop_on_frame)258 bool AdvanceTimeMilliseconds(int64_t milliseconds, bool stop_on_frame) {
259 return AdvanceTimeMicroseconds(milliseconds * 1000, stop_on_frame);
260 }
261
AdvanceTimeMicroseconds(int64_t microseconds,bool stop_on_frame)262 bool AdvanceTimeMicroseconds(int64_t microseconds, bool stop_on_frame) {
263 int64_t start_time = TimeInMicroseconds();
264 int64_t end_time = start_time + microseconds;
265 bool frame_injected = false;
266 while (!timestamps_.empty() &&
267 timestamps_.front().arrive_time <= end_time) {
268 RTC_DCHECK_GE(timestamps_.front().arrive_time, start_time);
269
270 SimulatedClock::AdvanceTimeMicroseconds(timestamps_.front().arrive_time -
271 TimeInMicroseconds());
272 GenerateAndInsertFrame((timestamps_.front().render_time + 500) / 1000);
273 timestamps_.pop();
274 frame_injected = true;
275
276 if (stop_on_frame)
277 return frame_injected;
278 }
279
280 if (TimeInMicroseconds() < end_time) {
281 SimulatedClock::AdvanceTimeMicroseconds(end_time - TimeInMicroseconds());
282 }
283 return frame_injected;
284 }
285
286 // Input timestamps are in unit Milliseconds.
287 // And `arrive_timestamps` must be positive and in increasing order.
288 // `arrive_timestamps` determine when we are going to insert frames into the
289 // jitter buffer.
290 // `render_timestamps` are the timestamps on the frame.
SetFrames(const int64_t * arrive_timestamps,const int64_t * render_timestamps,size_t size)291 void SetFrames(const int64_t* arrive_timestamps,
292 const int64_t* render_timestamps,
293 size_t size) {
294 int64_t previous_arrive_timestamp = 0;
295 for (size_t i = 0; i < size; i++) {
296 RTC_CHECK_GE(arrive_timestamps[i], previous_arrive_timestamp);
297 timestamps_.push(TimestampPair(arrive_timestamps[i] * 1000,
298 render_timestamps[i] * 1000));
299 previous_arrive_timestamp = arrive_timestamps[i];
300 }
301 }
302
303 private:
304 struct TimestampPair {
TimestampPairwebrtc::SimulatedClockWithFrames::TimestampPair305 TimestampPair(int64_t arrive_timestamp, int64_t render_timestamp)
306 : arrive_time(arrive_timestamp), render_time(render_timestamp) {}
307
308 int64_t arrive_time;
309 int64_t render_time;
310 };
311
GenerateAndInsertFrame(int64_t render_timestamp_ms)312 void GenerateAndInsertFrame(int64_t render_timestamp_ms) {
313 VCMPacket packet;
314 stream_generator_->GenerateFrame(VideoFrameType::kVideoFrameKey,
315 1, // media packets
316 0, // empty packets
317 render_timestamp_ms);
318
319 bool packet_available = stream_generator_->PopPacket(&packet, 0);
320 EXPECT_TRUE(packet_available);
321 if (!packet_available)
322 return; // Return here to avoid crashes below.
323 receiver_->InsertPacket(packet);
324 }
325
326 std::queue<TimestampPair> timestamps_;
327 StreamGenerator* stream_generator_;
328 VCMReceiver* receiver_;
329 };
330
331 // Use a SimulatedClockWithFrames
332 // Wait call will do either of these:
333 // 1. If `stop_on_frame` is true, the clock will be turned to the exact instant
334 // that the first frame comes and the frame will be inserted into the jitter
335 // buffer, or the clock will be turned to now + `max_time` if no frame comes in
336 // the window.
337 // 2. If `stop_on_frame` is false, the clock will be turn to now + `max_time`,
338 // and all the frames arriving between now and now + `max_time` will be
339 // inserted into the jitter buffer.
340 //
341 // This is used to simulate the JitterBuffer getting packets from internet as
342 // time elapses.
343
344 class FrameInjectEvent : public EventWrapper {
345 public:
FrameInjectEvent(SimulatedClockWithFrames * clock,bool stop_on_frame)346 FrameInjectEvent(SimulatedClockWithFrames* clock, bool stop_on_frame)
347 : clock_(clock), stop_on_frame_(stop_on_frame) {}
348
Set()349 bool Set() override { return true; }
350
Wait(int max_time_ms)351 EventTypeWrapper Wait(int max_time_ms) override {
352 if (clock_->AdvanceTimeMilliseconds(max_time_ms, stop_on_frame_) &&
353 stop_on_frame_) {
354 return EventTypeWrapper::kEventSignaled;
355 } else {
356 return EventTypeWrapper::kEventTimeout;
357 }
358 }
359
360 private:
361 SimulatedClockWithFrames* clock_;
362 bool stop_on_frame_;
363 };
364
365 class VCMReceiverTimingTest : public ::testing::Test {
366 protected:
VCMReceiverTimingTest()367 VCMReceiverTimingTest()
368 : clock_(&stream_generator_, &receiver_),
369 stream_generator_(0, clock_.TimeInMilliseconds()),
370 timing_(&clock_, field_trials_),
371 receiver_(
372 &timing_,
373 &clock_,
374 std::unique_ptr<EventWrapper>(new FrameInjectEvent(&clock_, false)),
375 std::unique_ptr<EventWrapper>(new FrameInjectEvent(&clock_, true)),
376 field_trials_) {}
377
SetUp()378 virtual void SetUp() {}
379
380 test::ScopedKeyValueConfig field_trials_;
381 SimulatedClockWithFrames clock_;
382 StreamGenerator stream_generator_;
383 VCMTiming timing_;
384 VCMReceiver receiver_;
385 };
386
387 // Test whether VCMReceiver::FrameForDecoding handles parameter
388 // `max_wait_time_ms` correctly:
389 // 1. The function execution should never take more than `max_wait_time_ms`.
390 // 2. If the function exit before now + `max_wait_time_ms`, a frame must be
391 // returned.
TEST_F(VCMReceiverTimingTest,FrameForDecoding)392 TEST_F(VCMReceiverTimingTest, FrameForDecoding) {
393 const size_t kNumFrames = 100;
394 const int kFramePeriod = 40;
395 int64_t arrive_timestamps[kNumFrames];
396 int64_t render_timestamps[kNumFrames];
397
398 // Construct test samples.
399 // render_timestamps are the timestamps stored in the Frame;
400 // arrive_timestamps controls when the Frame packet got received.
401 for (size_t i = 0; i < kNumFrames; i++) {
402 // Preset frame rate to 25Hz.
403 // But we add a reasonable deviation to arrive_timestamps to mimic Internet
404 // fluctuation.
405 arrive_timestamps[i] =
406 (i + 1) * kFramePeriod + (i % 10) * ((i % 2) ? 1 : -1);
407 render_timestamps[i] = (i + 1) * kFramePeriod;
408 }
409
410 clock_.SetFrames(arrive_timestamps, render_timestamps, kNumFrames);
411
412 // Record how many frames we finally get out of the receiver.
413 size_t num_frames_return = 0;
414
415 const int64_t kMaxWaitTime = 30;
416
417 // Ideally, we should get all frames that we input in InitializeFrames.
418 // In the case that FrameForDecoding kills frames by error, we rely on the
419 // build bot to kill the test.
420 while (num_frames_return < kNumFrames) {
421 int64_t start_time = clock_.TimeInMilliseconds();
422 VCMEncodedFrame* frame = receiver_.FrameForDecoding(kMaxWaitTime, false);
423 int64_t end_time = clock_.TimeInMilliseconds();
424
425 // In any case the FrameForDecoding should not wait longer than
426 // max_wait_time.
427 // In the case that we did not get a frame, it should have been waiting for
428 // exactly max_wait_time. (By the testing samples we constructed above, we
429 // are sure there is no timing error, so the only case it returns with NULL
430 // is that it runs out of time.)
431 if (frame) {
432 receiver_.ReleaseFrame(frame);
433 ++num_frames_return;
434 EXPECT_GE(kMaxWaitTime, end_time - start_time);
435 } else {
436 EXPECT_EQ(kMaxWaitTime, end_time - start_time);
437 }
438 }
439 }
440
441 // Test whether VCMReceiver::FrameForDecoding handles parameter
442 // `prefer_late_decoding` and `max_wait_time_ms` correctly:
443 // 1. The function execution should never take more than `max_wait_time_ms`.
444 // 2. If the function exit before now + `max_wait_time_ms`, a frame must be
445 // returned and the end time must be equal to the render timestamp - delay
446 // for decoding and rendering.
TEST_F(VCMReceiverTimingTest,FrameForDecodingPreferLateDecoding)447 TEST_F(VCMReceiverTimingTest, FrameForDecodingPreferLateDecoding) {
448 const size_t kNumFrames = 100;
449 const int kFramePeriod = 40;
450
451 int64_t arrive_timestamps[kNumFrames];
452 int64_t render_timestamps[kNumFrames];
453
454 auto timings = timing_.GetTimings();
455 TimeDelta render_delay = timings.render_delay;
456 TimeDelta max_decode = timings.max_decode_duration;
457
458 // Construct test samples.
459 // render_timestamps are the timestamps stored in the Frame;
460 // arrive_timestamps controls when the Frame packet got received.
461 for (size_t i = 0; i < kNumFrames; i++) {
462 // Preset frame rate to 25Hz.
463 // But we add a reasonable deviation to arrive_timestamps to mimic Internet
464 // fluctuation.
465 arrive_timestamps[i] =
466 (i + 1) * kFramePeriod + (i % 10) * ((i % 2) ? 1 : -1);
467 render_timestamps[i] = (i + 1) * kFramePeriod;
468 }
469
470 clock_.SetFrames(arrive_timestamps, render_timestamps, kNumFrames);
471
472 // Record how many frames we finally get out of the receiver.
473 size_t num_frames_return = 0;
474 const int64_t kMaxWaitTime = 30;
475 bool prefer_late_decoding = true;
476 while (num_frames_return < kNumFrames) {
477 int64_t start_time = clock_.TimeInMilliseconds();
478
479 VCMEncodedFrame* frame =
480 receiver_.FrameForDecoding(kMaxWaitTime, prefer_late_decoding);
481 int64_t end_time = clock_.TimeInMilliseconds();
482 if (frame) {
483 EXPECT_EQ(frame->RenderTimeMs() - max_decode.ms() - render_delay.ms(),
484 end_time);
485 receiver_.ReleaseFrame(frame);
486 ++num_frames_return;
487 } else {
488 EXPECT_EQ(kMaxWaitTime, end_time - start_time);
489 }
490 }
491 }
492
493 } // namespace webrtc
494