• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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