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