blob: 29bb209a57f829a84588f55904720a332401f9c9 [file] [log] [blame]
mikhal@webrtc.org381da4b2013-04-25 21:45:29 +00001/* 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 <string.h>
Yves Gerey3e707812018-11-28 16:47:49 +010011#include <cstdint>
kwiberg3f55dea2016-02-29 05:51:59 -080012#include <memory>
Qiang Chend4cec152015-06-19 09:17:00 -070013#include <queue>
philipel9d3ab612015-12-21 04:12:39 -080014#include <vector>
mikhal@webrtc.org381da4b2013-04-25 21:45:29 +000015
Yves Gerey3e707812018-11-28 16:47:49 +010016#include "common_types.h" // NOLINT(build/include)
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020017#include "modules/video_coding/encoded_frame.h"
Yves Gerey3e707812018-11-28 16:47:49 +010018#include "modules/video_coding/jitter_buffer_common.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020019#include "modules/video_coding/packet.h"
20#include "modules/video_coding/receiver.h"
21#include "modules/video_coding/test/stream_generator.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020022#include "modules/video_coding/timing.h"
23#include "rtc_base/checks.h"
24#include "system_wrappers/include/clock.h"
25#include "test/gtest.h"
mikhal@webrtc.org381da4b2013-04-25 21:45:29 +000026
27namespace webrtc {
28
29class TestVCMReceiver : public ::testing::Test {
30 protected:
mikhal@webrtc.org381da4b2013-04-25 21:45:29 +000031 TestVCMReceiver()
32 : clock_(new SimulatedClock(0)),
33 timing_(clock_.get()),
Niels Möller689983f2018-11-07 16:36:22 +010034 receiver_(&timing_, clock_.get()) {
philipel9d3ab612015-12-21 04:12:39 -080035 stream_generator_.reset(
36 new StreamGenerator(0, clock_->TimeInMilliseconds()));
mikhal@webrtc.org381da4b2013-04-25 21:45:29 +000037 }
38
philipel9d3ab612015-12-21 04:12:39 -080039 virtual void SetUp() { receiver_.Reset(); }
mikhal@webrtc.org381da4b2013-04-25 21:45:29 +000040
41 int32_t InsertPacket(int index) {
42 VCMPacket packet;
mikhal@webrtc.org381da4b2013-04-25 21:45:29 +000043 bool packet_available = stream_generator_->GetPacket(&packet, index);
44 EXPECT_TRUE(packet_available);
45 if (!packet_available)
stefan@webrtc.org3417eb42013-05-21 15:25:53 +000046 return kGeneralError; // Return here to avoid crashes below.
Johan Ahlers95348f72016-06-28 11:11:28 +020047 return receiver_.InsertPacket(packet);
mikhal@webrtc.org381da4b2013-04-25 21:45:29 +000048 }
49
50 int32_t InsertPacketAndPop(int index) {
51 VCMPacket packet;
mikhal@webrtc.org381da4b2013-04-25 21:45:29 +000052 bool packet_available = stream_generator_->PopPacket(&packet, index);
53 EXPECT_TRUE(packet_available);
54 if (!packet_available)
stefan@webrtc.org3417eb42013-05-21 15:25:53 +000055 return kGeneralError; // Return here to avoid crashes below.
Johan Ahlers95348f72016-06-28 11:11:28 +020056 return receiver_.InsertPacket(packet);
mikhal@webrtc.org381da4b2013-04-25 21:45:29 +000057 }
58
Niels Möller87e2d782019-03-07 10:18:23 +010059 int32_t InsertFrame(VideoFrameType frame_type, bool complete) {
mikhal@webrtc.org381da4b2013-04-25 21:45:29 +000060 int num_of_packets = complete ? 1 : 2;
61 stream_generator_->GenerateFrame(
pbos22993e12015-10-19 02:39:06 -070062 frame_type, (frame_type != kEmptyFrame) ? num_of_packets : 0,
63 (frame_type == kEmptyFrame) ? 1 : 0, clock_->TimeInMilliseconds());
mikhal@webrtc.org381da4b2013-04-25 21:45:29 +000064 int32_t ret = InsertPacketAndPop(0);
stefan@webrtc.orgef144882013-05-07 19:16:33 +000065 if (!complete) {
66 // Drop the second packet.
67 VCMPacket packet;
68 stream_generator_->PopPacket(&packet, 0);
69 }
mikhal@webrtc.org381da4b2013-04-25 21:45:29 +000070 clock_->AdvanceTimeMilliseconds(kDefaultFramePeriodMs);
71 return ret;
72 }
73
stefan@webrtc.orgef144882013-05-07 19:16:33 +000074 bool DecodeNextFrame() {
Johan Ahlers31b2ec42016-06-28 13:32:49 +020075 VCMEncodedFrame* frame = receiver_.FrameForDecoding(0, false);
stefan@webrtc.orgef144882013-05-07 19:16:33 +000076 if (!frame)
77 return false;
78 receiver_.ReleaseFrame(frame);
79 return true;
80 }
81
kwiberg3f55dea2016-02-29 05:51:59 -080082 std::unique_ptr<SimulatedClock> clock_;
mikhal@webrtc.org381da4b2013-04-25 21:45:29 +000083 VCMTiming timing_;
mikhal@webrtc.org381da4b2013-04-25 21:45:29 +000084 VCMReceiver receiver_;
kwiberg3f55dea2016-02-29 05:51:59 -080085 std::unique_ptr<StreamGenerator> stream_generator_;
mikhal@webrtc.org381da4b2013-04-25 21:45:29 +000086};
87
stefan@webrtc.orgef144882013-05-07 19:16:33 +000088TEST_F(TestVCMReceiver, NonDecodableDuration_Empty) {
89 // Enable NACK and with no RTT thresholds for disabling retransmission delay.
90 receiver_.SetNackMode(kNack, -1, -1);
91 const size_t kMaxNackListSize = 1000;
92 const int kMaxPacketAgeToNack = 1000;
93 const int kMaxNonDecodableDuration = 500;
94 const int kMinDelayMs = 500;
95 receiver_.SetNackSettings(kMaxNackListSize, kMaxPacketAgeToNack,
philipel9d3ab612015-12-21 04:12:39 -080096 kMaxNonDecodableDuration);
stefan@webrtc.orgef144882013-05-07 19:16:33 +000097 EXPECT_GE(InsertFrame(kVideoFrameKey, true), kNoError);
98 // Advance time until it's time to decode the key frame.
99 clock_->AdvanceTimeMilliseconds(kMinDelayMs);
100 EXPECT_TRUE(DecodeNextFrame());
Wan-Teh Changb1825a42015-06-03 15:03:35 -0700101 bool request_key_frame = false;
102 std::vector<uint16_t> nack_list = receiver_.NackList(&request_key_frame);
103 EXPECT_FALSE(request_key_frame);
stefan@webrtc.orgef144882013-05-07 19:16:33 +0000104}
105
106TEST_F(TestVCMReceiver, NonDecodableDuration_NoKeyFrame) {
107 // Enable NACK and with no RTT thresholds for disabling retransmission delay.
108 receiver_.SetNackMode(kNack, -1, -1);
109 const size_t kMaxNackListSize = 1000;
110 const int kMaxPacketAgeToNack = 1000;
111 const int kMaxNonDecodableDuration = 500;
112 receiver_.SetNackSettings(kMaxNackListSize, kMaxPacketAgeToNack,
philipel9d3ab612015-12-21 04:12:39 -0800113 kMaxNonDecodableDuration);
stefan@webrtc.orgef144882013-05-07 19:16:33 +0000114 const int kNumFrames = kDefaultFrameRate * kMaxNonDecodableDuration / 1000;
115 for (int i = 0; i < kNumFrames; ++i) {
116 EXPECT_GE(InsertFrame(kVideoFrameDelta, true), kNoError);
117 }
Wan-Teh Changb1825a42015-06-03 15:03:35 -0700118 bool request_key_frame = false;
119 std::vector<uint16_t> nack_list = receiver_.NackList(&request_key_frame);
120 EXPECT_TRUE(request_key_frame);
stefan@webrtc.orgef144882013-05-07 19:16:33 +0000121}
122
123TEST_F(TestVCMReceiver, NonDecodableDuration_OneIncomplete) {
124 // Enable NACK and with no RTT thresholds for disabling retransmission delay.
125 receiver_.SetNackMode(kNack, -1, -1);
126 const size_t kMaxNackListSize = 1000;
127 const int kMaxPacketAgeToNack = 1000;
128 const int kMaxNonDecodableDuration = 500;
philipel9d3ab612015-12-21 04:12:39 -0800129 const int kMaxNonDecodableDurationFrames =
130 (kDefaultFrameRate * kMaxNonDecodableDuration + 500) / 1000;
stefan@webrtc.orgef144882013-05-07 19:16:33 +0000131 const int kMinDelayMs = 500;
132 receiver_.SetNackSettings(kMaxNackListSize, kMaxPacketAgeToNack,
philipel9d3ab612015-12-21 04:12:39 -0800133 kMaxNonDecodableDuration);
Niels Möller4eb4b052018-08-14 10:31:58 +0200134 timing_.set_min_playout_delay(kMinDelayMs);
stefan@webrtc.orgef144882013-05-07 19:16:33 +0000135 int64_t key_frame_inserted = clock_->TimeInMilliseconds();
136 EXPECT_GE(InsertFrame(kVideoFrameKey, true), kNoError);
137 // Insert an incomplete frame.
138 EXPECT_GE(InsertFrame(kVideoFrameDelta, false), kNoError);
139 // Insert enough frames to have too long non-decodable sequence.
philipel9d3ab612015-12-21 04:12:39 -0800140 for (int i = 0; i < kMaxNonDecodableDurationFrames; ++i) {
stefan@webrtc.orgef144882013-05-07 19:16:33 +0000141 EXPECT_GE(InsertFrame(kVideoFrameDelta, true), kNoError);
142 }
143 // Advance time until it's time to decode the key frame.
144 clock_->AdvanceTimeMilliseconds(kMinDelayMs - clock_->TimeInMilliseconds() -
philipel9d3ab612015-12-21 04:12:39 -0800145 key_frame_inserted);
stefan@webrtc.orgef144882013-05-07 19:16:33 +0000146 EXPECT_TRUE(DecodeNextFrame());
147 // Make sure we get a key frame request.
Wan-Teh Changb1825a42015-06-03 15:03:35 -0700148 bool request_key_frame = false;
149 std::vector<uint16_t> nack_list = receiver_.NackList(&request_key_frame);
150 EXPECT_TRUE(request_key_frame);
stefan@webrtc.orgef144882013-05-07 19:16:33 +0000151}
152
153TEST_F(TestVCMReceiver, NonDecodableDuration_NoTrigger) {
154 // Enable NACK and with no RTT thresholds for disabling retransmission delay.
155 receiver_.SetNackMode(kNack, -1, -1);
156 const size_t kMaxNackListSize = 1000;
157 const int kMaxPacketAgeToNack = 1000;
158 const int kMaxNonDecodableDuration = 500;
philipel9d3ab612015-12-21 04:12:39 -0800159 const int kMaxNonDecodableDurationFrames =
160 (kDefaultFrameRate * kMaxNonDecodableDuration + 500) / 1000;
stefan@webrtc.orgef144882013-05-07 19:16:33 +0000161 const int kMinDelayMs = 500;
162 receiver_.SetNackSettings(kMaxNackListSize, kMaxPacketAgeToNack,
philipel9d3ab612015-12-21 04:12:39 -0800163 kMaxNonDecodableDuration);
Niels Möller4eb4b052018-08-14 10:31:58 +0200164 timing_.set_min_playout_delay(kMinDelayMs);
stefan@webrtc.orgef144882013-05-07 19:16:33 +0000165 int64_t key_frame_inserted = clock_->TimeInMilliseconds();
166 EXPECT_GE(InsertFrame(kVideoFrameKey, true), kNoError);
167 // Insert an incomplete frame.
168 EXPECT_GE(InsertFrame(kVideoFrameDelta, false), kNoError);
169 // Insert all but one frame to not trigger a key frame request due to
170 // too long duration of non-decodable frames.
philipel9d3ab612015-12-21 04:12:39 -0800171 for (int i = 0; i < kMaxNonDecodableDurationFrames - 1; ++i) {
stefan@webrtc.orgef144882013-05-07 19:16:33 +0000172 EXPECT_GE(InsertFrame(kVideoFrameDelta, true), kNoError);
173 }
174 // Advance time until it's time to decode the key frame.
175 clock_->AdvanceTimeMilliseconds(kMinDelayMs - clock_->TimeInMilliseconds() -
philipel9d3ab612015-12-21 04:12:39 -0800176 key_frame_inserted);
stefan@webrtc.orgef144882013-05-07 19:16:33 +0000177 EXPECT_TRUE(DecodeNextFrame());
178 // Make sure we don't get a key frame request since we haven't generated
179 // enough frames.
Wan-Teh Changb1825a42015-06-03 15:03:35 -0700180 bool request_key_frame = false;
181 std::vector<uint16_t> nack_list = receiver_.NackList(&request_key_frame);
182 EXPECT_FALSE(request_key_frame);
stefan@webrtc.orgef144882013-05-07 19:16:33 +0000183}
184
stefan@webrtc.org16734812013-05-14 12:00:47 +0000185TEST_F(TestVCMReceiver, NonDecodableDuration_NoTrigger2) {
186 // Enable NACK and with no RTT thresholds for disabling retransmission delay.
187 receiver_.SetNackMode(kNack, -1, -1);
188 const size_t kMaxNackListSize = 1000;
189 const int kMaxPacketAgeToNack = 1000;
190 const int kMaxNonDecodableDuration = 500;
philipel9d3ab612015-12-21 04:12:39 -0800191 const int kMaxNonDecodableDurationFrames =
192 (kDefaultFrameRate * kMaxNonDecodableDuration + 500) / 1000;
stefan@webrtc.org16734812013-05-14 12:00:47 +0000193 const int kMinDelayMs = 500;
194 receiver_.SetNackSettings(kMaxNackListSize, kMaxPacketAgeToNack,
philipel9d3ab612015-12-21 04:12:39 -0800195 kMaxNonDecodableDuration);
Niels Möller4eb4b052018-08-14 10:31:58 +0200196 timing_.set_min_playout_delay(kMinDelayMs);
stefan@webrtc.org16734812013-05-14 12:00:47 +0000197 int64_t key_frame_inserted = clock_->TimeInMilliseconds();
198 EXPECT_GE(InsertFrame(kVideoFrameKey, true), kNoError);
199 // Insert enough frames to have too long non-decodable sequence, except that
200 // we don't have any losses.
philipel9d3ab612015-12-21 04:12:39 -0800201 for (int i = 0; i < kMaxNonDecodableDurationFrames; ++i) {
stefan@webrtc.org16734812013-05-14 12:00:47 +0000202 EXPECT_GE(InsertFrame(kVideoFrameDelta, true), kNoError);
203 }
204 // Insert an incomplete frame.
205 EXPECT_GE(InsertFrame(kVideoFrameDelta, false), kNoError);
206 // Advance time until it's time to decode the key frame.
207 clock_->AdvanceTimeMilliseconds(kMinDelayMs - clock_->TimeInMilliseconds() -
philipel9d3ab612015-12-21 04:12:39 -0800208 key_frame_inserted);
stefan@webrtc.org16734812013-05-14 12:00:47 +0000209 EXPECT_TRUE(DecodeNextFrame());
210 // Make sure we don't get a key frame request since the non-decodable duration
211 // is only one frame.
Wan-Teh Changb1825a42015-06-03 15:03:35 -0700212 bool request_key_frame = false;
213 std::vector<uint16_t> nack_list = receiver_.NackList(&request_key_frame);
214 EXPECT_FALSE(request_key_frame);
stefan@webrtc.org16734812013-05-14 12:00:47 +0000215}
216
stefan@webrtc.orgef144882013-05-07 19:16:33 +0000217TEST_F(TestVCMReceiver, NonDecodableDuration_KeyFrameAfterIncompleteFrames) {
218 // Enable NACK and with no RTT thresholds for disabling retransmission delay.
219 receiver_.SetNackMode(kNack, -1, -1);
220 const size_t kMaxNackListSize = 1000;
221 const int kMaxPacketAgeToNack = 1000;
222 const int kMaxNonDecodableDuration = 500;
philipel9d3ab612015-12-21 04:12:39 -0800223 const int kMaxNonDecodableDurationFrames =
224 (kDefaultFrameRate * kMaxNonDecodableDuration + 500) / 1000;
stefan@webrtc.orgef144882013-05-07 19:16:33 +0000225 const int kMinDelayMs = 500;
226 receiver_.SetNackSettings(kMaxNackListSize, kMaxPacketAgeToNack,
philipel9d3ab612015-12-21 04:12:39 -0800227 kMaxNonDecodableDuration);
Niels Möller4eb4b052018-08-14 10:31:58 +0200228 timing_.set_min_playout_delay(kMinDelayMs);
stefan@webrtc.orgef144882013-05-07 19:16:33 +0000229 int64_t key_frame_inserted = clock_->TimeInMilliseconds();
230 EXPECT_GE(InsertFrame(kVideoFrameKey, true), kNoError);
231 // Insert an incomplete frame.
232 EXPECT_GE(InsertFrame(kVideoFrameDelta, false), kNoError);
233 // Insert enough frames to have too long non-decodable sequence.
philipel9d3ab612015-12-21 04:12:39 -0800234 for (int i = 0; i < kMaxNonDecodableDurationFrames; ++i) {
stefan@webrtc.orgef144882013-05-07 19:16:33 +0000235 EXPECT_GE(InsertFrame(kVideoFrameDelta, true), kNoError);
236 }
237 EXPECT_GE(InsertFrame(kVideoFrameKey, true), kNoError);
238 // Advance time until it's time to decode the key frame.
239 clock_->AdvanceTimeMilliseconds(kMinDelayMs - clock_->TimeInMilliseconds() -
philipel9d3ab612015-12-21 04:12:39 -0800240 key_frame_inserted);
stefan@webrtc.orgef144882013-05-07 19:16:33 +0000241 EXPECT_TRUE(DecodeNextFrame());
242 // Make sure we don't get a key frame request since we have a key frame
243 // in the list.
Wan-Teh Changb1825a42015-06-03 15:03:35 -0700244 bool request_key_frame = false;
245 std::vector<uint16_t> nack_list = receiver_.NackList(&request_key_frame);
246 EXPECT_FALSE(request_key_frame);
stefan@webrtc.orgef144882013-05-07 19:16:33 +0000247}
Qiang Chend4cec152015-06-19 09:17:00 -0700248
249// A simulated clock, when time elapses, will insert frames into the jitter
250// buffer, based on initial settings.
251class SimulatedClockWithFrames : public SimulatedClock {
252 public:
253 SimulatedClockWithFrames(StreamGenerator* stream_generator,
254 VCMReceiver* receiver)
255 : SimulatedClock(0),
256 stream_generator_(stream_generator),
257 receiver_(receiver) {}
258 virtual ~SimulatedClockWithFrames() {}
259
260 // If |stop_on_frame| is true and next frame arrives between now and
261 // now+|milliseconds|, the clock will be advanced to the arrival time of next
262 // frame.
263 // Otherwise, the clock will be advanced by |milliseconds|.
264 //
265 // For both cases, a frame will be inserted into the jitter buffer at the
266 // instant when the clock time is timestamps_.front().arrive_time.
267 //
268 // Return true if some frame arrives between now and now+|milliseconds|.
269 bool AdvanceTimeMilliseconds(int64_t milliseconds, bool stop_on_frame) {
270 return AdvanceTimeMicroseconds(milliseconds * 1000, stop_on_frame);
philipel9d3ab612015-12-21 04:12:39 -0800271 }
Qiang Chend4cec152015-06-19 09:17:00 -0700272
273 bool AdvanceTimeMicroseconds(int64_t microseconds, bool stop_on_frame) {
274 int64_t start_time = TimeInMicroseconds();
275 int64_t end_time = start_time + microseconds;
276 bool frame_injected = false;
277 while (!timestamps_.empty() &&
278 timestamps_.front().arrive_time <= end_time) {
henrikg91d6ede2015-09-17 00:24:34 -0700279 RTC_DCHECK(timestamps_.front().arrive_time >= start_time);
Qiang Chend4cec152015-06-19 09:17:00 -0700280
281 SimulatedClock::AdvanceTimeMicroseconds(timestamps_.front().arrive_time -
282 TimeInMicroseconds());
283 GenerateAndInsertFrame((timestamps_.front().render_time + 500) / 1000);
284 timestamps_.pop();
285 frame_injected = true;
286
287 if (stop_on_frame)
288 return frame_injected;
289 }
290
291 if (TimeInMicroseconds() < end_time) {
292 SimulatedClock::AdvanceTimeMicroseconds(end_time - TimeInMicroseconds());
293 }
294 return frame_injected;
philipel9d3ab612015-12-21 04:12:39 -0800295 }
Qiang Chend4cec152015-06-19 09:17:00 -0700296
297 // Input timestamps are in unit Milliseconds.
298 // And |arrive_timestamps| must be positive and in increasing order.
299 // |arrive_timestamps| determine when we are going to insert frames into the
300 // jitter buffer.
301 // |render_timestamps| are the timestamps on the frame.
302 void SetFrames(const int64_t* arrive_timestamps,
303 const int64_t* render_timestamps,
304 size_t size) {
305 int64_t previous_arrive_timestamp = 0;
306 for (size_t i = 0; i < size; i++) {
henrikg91d6ede2015-09-17 00:24:34 -0700307 RTC_CHECK(arrive_timestamps[i] >= previous_arrive_timestamp);
Qiang Chend4cec152015-06-19 09:17:00 -0700308 timestamps_.push(TimestampPair(arrive_timestamps[i] * 1000,
309 render_timestamps[i] * 1000));
310 previous_arrive_timestamp = arrive_timestamps[i];
311 }
312 }
313
314 private:
315 struct TimestampPair {
316 TimestampPair(int64_t arrive_timestamp, int64_t render_timestamp)
317 : arrive_time(arrive_timestamp), render_time(render_timestamp) {}
318
319 int64_t arrive_time;
320 int64_t render_time;
321 };
322
323 void GenerateAndInsertFrame(int64_t render_timestamp_ms) {
324 VCMPacket packet;
Niels Möller87e2d782019-03-07 10:18:23 +0100325 stream_generator_->GenerateFrame(VideoFrameType::kVideoFrameKey,
Qiang Chend4cec152015-06-19 09:17:00 -0700326 1, // media packets
327 0, // empty packets
328 render_timestamp_ms);
329
330 bool packet_available = stream_generator_->PopPacket(&packet, 0);
331 EXPECT_TRUE(packet_available);
332 if (!packet_available)
333 return; // Return here to avoid crashes below.
Johan Ahlers95348f72016-06-28 11:11:28 +0200334 receiver_->InsertPacket(packet);
Qiang Chend4cec152015-06-19 09:17:00 -0700335 }
336
337 std::queue<TimestampPair> timestamps_;
338 StreamGenerator* stream_generator_;
339 VCMReceiver* receiver_;
340};
341
342// Use a SimulatedClockWithFrames
343// Wait call will do either of these:
344// 1. If |stop_on_frame| is true, the clock will be turned to the exact instant
345// that the first frame comes and the frame will be inserted into the jitter
346// buffer, or the clock will be turned to now + |max_time| if no frame comes in
347// the window.
348// 2. If |stop_on_frame| is false, the clock will be turn to now + |max_time|,
349// and all the frames arriving between now and now + |max_time| will be
350// inserted into the jitter buffer.
351//
352// This is used to simulate the JitterBuffer getting packets from internet as
353// time elapses.
354
355class FrameInjectEvent : public EventWrapper {
356 public:
357 FrameInjectEvent(SimulatedClockWithFrames* clock, bool stop_on_frame)
358 : clock_(clock), stop_on_frame_(stop_on_frame) {}
359
360 bool Set() override { return true; }
361
philipel9d3ab612015-12-21 04:12:39 -0800362 EventTypeWrapper Wait(unsigned long max_time) override { // NOLINT
Qiang Chend4cec152015-06-19 09:17:00 -0700363 if (clock_->AdvanceTimeMilliseconds(max_time, stop_on_frame_) &&
364 stop_on_frame_) {
365 return EventTypeWrapper::kEventSignaled;
366 } else {
367 return EventTypeWrapper::kEventTimeout;
368 }
369 }
370
371 private:
372 SimulatedClockWithFrames* clock_;
373 bool stop_on_frame_;
374};
375
376class VCMReceiverTimingTest : public ::testing::Test {
377 protected:
Qiang Chend4cec152015-06-19 09:17:00 -0700378 VCMReceiverTimingTest()
379
380 : clock_(&stream_generator_, &receiver_),
381 stream_generator_(0, clock_.TimeInMilliseconds()),
382 timing_(&clock_),
383 receiver_(
384 &timing_,
385 &clock_,
kwiberg3f55dea2016-02-29 05:51:59 -0800386 std::unique_ptr<EventWrapper>(new FrameInjectEvent(&clock_, false)),
387 std::unique_ptr<EventWrapper>(
Qiang Chend4cec152015-06-19 09:17:00 -0700388 new FrameInjectEvent(&clock_, true))) {}
389
Qiang Chend4cec152015-06-19 09:17:00 -0700390 virtual void SetUp() { receiver_.Reset(); }
391
392 SimulatedClockWithFrames clock_;
393 StreamGenerator stream_generator_;
394 VCMTiming timing_;
395 VCMReceiver receiver_;
396};
397
398// Test whether VCMReceiver::FrameForDecoding handles parameter
399// |max_wait_time_ms| correctly:
400// 1. The function execution should never take more than |max_wait_time_ms|.
401// 2. If the function exit before now + |max_wait_time_ms|, a frame must be
402// returned.
403TEST_F(VCMReceiverTimingTest, FrameForDecoding) {
404 const size_t kNumFrames = 100;
405 const int kFramePeriod = 40;
406 int64_t arrive_timestamps[kNumFrames];
407 int64_t render_timestamps[kNumFrames];
Qiang Chend4cec152015-06-19 09:17:00 -0700408
409 // Construct test samples.
410 // render_timestamps are the timestamps stored in the Frame;
411 // arrive_timestamps controls when the Frame packet got received.
412 for (size_t i = 0; i < kNumFrames; i++) {
413 // Preset frame rate to 25Hz.
414 // But we add a reasonable deviation to arrive_timestamps to mimic Internet
415 // fluctuation.
416 arrive_timestamps[i] =
417 (i + 1) * kFramePeriod + (i % 10) * ((i % 2) ? 1 : -1);
418 render_timestamps[i] = (i + 1) * kFramePeriod;
419 }
420
421 clock_.SetFrames(arrive_timestamps, render_timestamps, kNumFrames);
422
423 // Record how many frames we finally get out of the receiver.
424 size_t num_frames_return = 0;
425
426 const int64_t kMaxWaitTime = 30;
427
428 // Ideally, we should get all frames that we input in InitializeFrames.
429 // In the case that FrameForDecoding kills frames by error, we rely on the
430 // build bot to kill the test.
431 while (num_frames_return < kNumFrames) {
432 int64_t start_time = clock_.TimeInMilliseconds();
Johan Ahlers31b2ec42016-06-28 13:32:49 +0200433 VCMEncodedFrame* frame = receiver_.FrameForDecoding(kMaxWaitTime, false);
Qiang Chend4cec152015-06-19 09:17:00 -0700434 int64_t end_time = clock_.TimeInMilliseconds();
435
436 // In any case the FrameForDecoding should not wait longer than
437 // max_wait_time.
438 // In the case that we did not get a frame, it should have been waiting for
439 // exactly max_wait_time. (By the testing samples we constructed above, we
440 // are sure there is no timing error, so the only case it returns with NULL
441 // is that it runs out of time.)
442 if (frame) {
443 receiver_.ReleaseFrame(frame);
444 ++num_frames_return;
445 EXPECT_GE(kMaxWaitTime, end_time - start_time);
446 } else {
447 EXPECT_EQ(kMaxWaitTime, end_time - start_time);
448 }
449 }
450}
451
perkj796cfaf2015-12-10 09:27:38 -0800452// Test whether VCMReceiver::FrameForDecoding handles parameter
453// |prefer_late_decoding| and |max_wait_time_ms| correctly:
454// 1. The function execution should never take more than |max_wait_time_ms|.
455// 2. If the function exit before now + |max_wait_time_ms|, a frame must be
456// returned and the end time must be equal to the render timestamp - delay
457// for decoding and rendering.
458TEST_F(VCMReceiverTimingTest, FrameForDecodingPreferLateDecoding) {
459 const size_t kNumFrames = 100;
460 const int kFramePeriod = 40;
461
462 int64_t arrive_timestamps[kNumFrames];
463 int64_t render_timestamps[kNumFrames];
perkj796cfaf2015-12-10 09:27:38 -0800464
465 int render_delay_ms;
466 int max_decode_ms;
467 int dummy;
468 timing_.GetTimings(&dummy, &max_decode_ms, &dummy, &dummy, &dummy, &dummy,
469 &render_delay_ms);
470
471 // Construct test samples.
472 // render_timestamps are the timestamps stored in the Frame;
473 // arrive_timestamps controls when the Frame packet got received.
474 for (size_t i = 0; i < kNumFrames; i++) {
475 // Preset frame rate to 25Hz.
476 // But we add a reasonable deviation to arrive_timestamps to mimic Internet
477 // fluctuation.
478 arrive_timestamps[i] =
479 (i + 1) * kFramePeriod + (i % 10) * ((i % 2) ? 1 : -1);
480 render_timestamps[i] = (i + 1) * kFramePeriod;
481 }
482
483 clock_.SetFrames(arrive_timestamps, render_timestamps, kNumFrames);
484
485 // Record how many frames we finally get out of the receiver.
486 size_t num_frames_return = 0;
487 const int64_t kMaxWaitTime = 30;
488 bool prefer_late_decoding = true;
489 while (num_frames_return < kNumFrames) {
490 int64_t start_time = clock_.TimeInMilliseconds();
491
Johan Ahlers31b2ec42016-06-28 13:32:49 +0200492 VCMEncodedFrame* frame =
493 receiver_.FrameForDecoding(kMaxWaitTime, prefer_late_decoding);
perkj796cfaf2015-12-10 09:27:38 -0800494 int64_t end_time = clock_.TimeInMilliseconds();
495 if (frame) {
496 EXPECT_EQ(frame->RenderTimeMs() - max_decode_ms - render_delay_ms,
497 end_time);
498 receiver_.ReleaseFrame(frame);
499 ++num_frames_return;
500 } else {
501 EXPECT_EQ(kMaxWaitTime, end_time - start_time);
502 }
503 }
504}
505
mikhal@webrtc.org381da4b2013-04-25 21:45:29 +0000506} // namespace webrtc