blob: 320d466095e6e25f93c73cc1edcacb794a6bf994 [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>
11
12#include <list>
kwiberg3f55dea2016-02-29 05:51:59 -080013#include <memory>
Qiang Chend4cec152015-06-19 09:17:00 -070014#include <queue>
philipel9d3ab612015-12-21 04:12:39 -080015#include <vector>
mikhal@webrtc.org381da4b2013-04-25 21:45:29 +000016
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020017#include "modules/video_coding/encoded_frame.h"
18#include "modules/video_coding/packet.h"
19#include "modules/video_coding/receiver.h"
20#include "modules/video_coding/test/stream_generator.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020021#include "modules/video_coding/timing.h"
22#include "rtc_base/checks.h"
23#include "system_wrappers/include/clock.h"
24#include "test/gtest.h"
mikhal@webrtc.org381da4b2013-04-25 21:45:29 +000025
26namespace webrtc {
27
28class TestVCMReceiver : public ::testing::Test {
29 protected:
mikhal@webrtc.org381da4b2013-04-25 21:45:29 +000030 TestVCMReceiver()
31 : clock_(new SimulatedClock(0)),
32 timing_(clock_.get()),
Niels Möllerd5659182018-11-07 13:40:24 +010033 receiver_(&timing_, clock_.get(), nullptr) {
philipel9d3ab612015-12-21 04:12:39 -080034 stream_generator_.reset(
35 new StreamGenerator(0, clock_->TimeInMilliseconds()));
mikhal@webrtc.org381da4b2013-04-25 21:45:29 +000036 }
37
philipel9d3ab612015-12-21 04:12:39 -080038 virtual void SetUp() { receiver_.Reset(); }
mikhal@webrtc.org381da4b2013-04-25 21:45:29 +000039
40 int32_t InsertPacket(int index) {
41 VCMPacket packet;
mikhal@webrtc.org381da4b2013-04-25 21:45:29 +000042 bool packet_available = stream_generator_->GetPacket(&packet, index);
43 EXPECT_TRUE(packet_available);
44 if (!packet_available)
stefan@webrtc.org3417eb42013-05-21 15:25:53 +000045 return kGeneralError; // Return here to avoid crashes below.
Johan Ahlers95348f72016-06-28 11:11:28 +020046 return receiver_.InsertPacket(packet);
mikhal@webrtc.org381da4b2013-04-25 21:45:29 +000047 }
48
49 int32_t InsertPacketAndPop(int index) {
50 VCMPacket packet;
mikhal@webrtc.org381da4b2013-04-25 21:45:29 +000051 bool packet_available = stream_generator_->PopPacket(&packet, index);
52 EXPECT_TRUE(packet_available);
53 if (!packet_available)
stefan@webrtc.org3417eb42013-05-21 15:25:53 +000054 return kGeneralError; // Return here to avoid crashes below.
Johan Ahlers95348f72016-06-28 11:11:28 +020055 return receiver_.InsertPacket(packet);
mikhal@webrtc.org381da4b2013-04-25 21:45:29 +000056 }
57
58 int32_t InsertFrame(FrameType frame_type, bool complete) {
59 int num_of_packets = complete ? 1 : 2;
60 stream_generator_->GenerateFrame(
pbos22993e12015-10-19 02:39:06 -070061 frame_type, (frame_type != kEmptyFrame) ? num_of_packets : 0,
62 (frame_type == kEmptyFrame) ? 1 : 0, clock_->TimeInMilliseconds());
mikhal@webrtc.org381da4b2013-04-25 21:45:29 +000063 int32_t ret = InsertPacketAndPop(0);
stefan@webrtc.orgef144882013-05-07 19:16:33 +000064 if (!complete) {
65 // Drop the second packet.
66 VCMPacket packet;
67 stream_generator_->PopPacket(&packet, 0);
68 }
mikhal@webrtc.org381da4b2013-04-25 21:45:29 +000069 clock_->AdvanceTimeMilliseconds(kDefaultFramePeriodMs);
70 return ret;
71 }
72
stefan@webrtc.orgef144882013-05-07 19:16:33 +000073 bool DecodeNextFrame() {
Johan Ahlers31b2ec42016-06-28 13:32:49 +020074 VCMEncodedFrame* frame = receiver_.FrameForDecoding(0, false);
stefan@webrtc.orgef144882013-05-07 19:16:33 +000075 if (!frame)
76 return false;
77 receiver_.ReleaseFrame(frame);
78 return true;
79 }
80
kwiberg3f55dea2016-02-29 05:51:59 -080081 std::unique_ptr<SimulatedClock> clock_;
mikhal@webrtc.org381da4b2013-04-25 21:45:29 +000082 VCMTiming timing_;
mikhal@webrtc.org381da4b2013-04-25 21:45:29 +000083 VCMReceiver receiver_;
kwiberg3f55dea2016-02-29 05:51:59 -080084 std::unique_ptr<StreamGenerator> stream_generator_;
mikhal@webrtc.org381da4b2013-04-25 21:45:29 +000085};
86
stefan@webrtc.orgef144882013-05-07 19:16:33 +000087TEST_F(TestVCMReceiver, NonDecodableDuration_Empty) {
88 // Enable NACK and with no RTT thresholds for disabling retransmission delay.
89 receiver_.SetNackMode(kNack, -1, -1);
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,
philipel9d3ab612015-12-21 04:12:39 -080095 kMaxNonDecodableDuration);
stefan@webrtc.orgef144882013-05-07 19:16:33 +000096 EXPECT_GE(InsertFrame(kVideoFrameKey, true), kNoError);
97 // Advance time until it's time to decode the key frame.
98 clock_->AdvanceTimeMilliseconds(kMinDelayMs);
99 EXPECT_TRUE(DecodeNextFrame());
Wan-Teh Changb1825a42015-06-03 15:03:35 -0700100 bool request_key_frame = false;
101 std::vector<uint16_t> nack_list = receiver_.NackList(&request_key_frame);
102 EXPECT_FALSE(request_key_frame);
stefan@webrtc.orgef144882013-05-07 19:16:33 +0000103}
104
105TEST_F(TestVCMReceiver, NonDecodableDuration_NoKeyFrame) {
106 // Enable NACK and with no RTT thresholds for disabling retransmission delay.
107 receiver_.SetNackMode(kNack, -1, -1);
108 const size_t kMaxNackListSize = 1000;
109 const int kMaxPacketAgeToNack = 1000;
110 const int kMaxNonDecodableDuration = 500;
111 receiver_.SetNackSettings(kMaxNackListSize, kMaxPacketAgeToNack,
philipel9d3ab612015-12-21 04:12:39 -0800112 kMaxNonDecodableDuration);
stefan@webrtc.orgef144882013-05-07 19:16:33 +0000113 const int kNumFrames = kDefaultFrameRate * kMaxNonDecodableDuration / 1000;
114 for (int i = 0; i < kNumFrames; ++i) {
115 EXPECT_GE(InsertFrame(kVideoFrameDelta, true), kNoError);
116 }
Wan-Teh Changb1825a42015-06-03 15:03:35 -0700117 bool request_key_frame = false;
118 std::vector<uint16_t> nack_list = receiver_.NackList(&request_key_frame);
119 EXPECT_TRUE(request_key_frame);
stefan@webrtc.orgef144882013-05-07 19:16:33 +0000120}
121
122TEST_F(TestVCMReceiver, NonDecodableDuration_OneIncomplete) {
123 // Enable NACK and with no RTT thresholds for disabling retransmission delay.
124 receiver_.SetNackMode(kNack, -1, -1);
125 const size_t kMaxNackListSize = 1000;
126 const int kMaxPacketAgeToNack = 1000;
127 const int kMaxNonDecodableDuration = 500;
philipel9d3ab612015-12-21 04:12:39 -0800128 const int kMaxNonDecodableDurationFrames =
129 (kDefaultFrameRate * kMaxNonDecodableDuration + 500) / 1000;
stefan@webrtc.orgef144882013-05-07 19:16:33 +0000130 const int kMinDelayMs = 500;
131 receiver_.SetNackSettings(kMaxNackListSize, kMaxPacketAgeToNack,
philipel9d3ab612015-12-21 04:12:39 -0800132 kMaxNonDecodableDuration);
Niels Möller4eb4b052018-08-14 10:31:58 +0200133 timing_.set_min_playout_delay(kMinDelayMs);
stefan@webrtc.orgef144882013-05-07 19:16:33 +0000134 int64_t key_frame_inserted = clock_->TimeInMilliseconds();
135 EXPECT_GE(InsertFrame(kVideoFrameKey, true), kNoError);
136 // Insert an incomplete frame.
137 EXPECT_GE(InsertFrame(kVideoFrameDelta, false), kNoError);
138 // Insert enough frames to have too long non-decodable sequence.
philipel9d3ab612015-12-21 04:12:39 -0800139 for (int i = 0; i < kMaxNonDecodableDurationFrames; ++i) {
stefan@webrtc.orgef144882013-05-07 19:16:33 +0000140 EXPECT_GE(InsertFrame(kVideoFrameDelta, true), kNoError);
141 }
142 // Advance time until it's time to decode the key frame.
143 clock_->AdvanceTimeMilliseconds(kMinDelayMs - clock_->TimeInMilliseconds() -
philipel9d3ab612015-12-21 04:12:39 -0800144 key_frame_inserted);
stefan@webrtc.orgef144882013-05-07 19:16:33 +0000145 EXPECT_TRUE(DecodeNextFrame());
146 // Make sure we get a key frame request.
Wan-Teh Changb1825a42015-06-03 15:03:35 -0700147 bool request_key_frame = false;
148 std::vector<uint16_t> nack_list = receiver_.NackList(&request_key_frame);
149 EXPECT_TRUE(request_key_frame);
stefan@webrtc.orgef144882013-05-07 19:16:33 +0000150}
151
152TEST_F(TestVCMReceiver, NonDecodableDuration_NoTrigger) {
153 // Enable NACK and with no RTT thresholds for disabling retransmission delay.
154 receiver_.SetNackMode(kNack, -1, -1);
155 const size_t kMaxNackListSize = 1000;
156 const int kMaxPacketAgeToNack = 1000;
157 const int kMaxNonDecodableDuration = 500;
philipel9d3ab612015-12-21 04:12:39 -0800158 const int kMaxNonDecodableDurationFrames =
159 (kDefaultFrameRate * kMaxNonDecodableDuration + 500) / 1000;
stefan@webrtc.orgef144882013-05-07 19:16:33 +0000160 const int kMinDelayMs = 500;
161 receiver_.SetNackSettings(kMaxNackListSize, kMaxPacketAgeToNack,
philipel9d3ab612015-12-21 04:12:39 -0800162 kMaxNonDecodableDuration);
Niels Möller4eb4b052018-08-14 10:31:58 +0200163 timing_.set_min_playout_delay(kMinDelayMs);
stefan@webrtc.orgef144882013-05-07 19:16:33 +0000164 int64_t key_frame_inserted = clock_->TimeInMilliseconds();
165 EXPECT_GE(InsertFrame(kVideoFrameKey, true), kNoError);
166 // Insert an incomplete frame.
167 EXPECT_GE(InsertFrame(kVideoFrameDelta, false), kNoError);
168 // Insert all but one frame to not trigger a key frame request due to
169 // too long duration of non-decodable frames.
philipel9d3ab612015-12-21 04:12:39 -0800170 for (int i = 0; i < kMaxNonDecodableDurationFrames - 1; ++i) {
stefan@webrtc.orgef144882013-05-07 19:16:33 +0000171 EXPECT_GE(InsertFrame(kVideoFrameDelta, true), kNoError);
172 }
173 // Advance time until it's time to decode the key frame.
174 clock_->AdvanceTimeMilliseconds(kMinDelayMs - clock_->TimeInMilliseconds() -
philipel9d3ab612015-12-21 04:12:39 -0800175 key_frame_inserted);
stefan@webrtc.orgef144882013-05-07 19:16:33 +0000176 EXPECT_TRUE(DecodeNextFrame());
177 // Make sure we don't get a key frame request since we haven't generated
178 // enough frames.
Wan-Teh Changb1825a42015-06-03 15:03:35 -0700179 bool request_key_frame = false;
180 std::vector<uint16_t> nack_list = receiver_.NackList(&request_key_frame);
181 EXPECT_FALSE(request_key_frame);
stefan@webrtc.orgef144882013-05-07 19:16:33 +0000182}
183
stefan@webrtc.org16734812013-05-14 12:00:47 +0000184TEST_F(TestVCMReceiver, NonDecodableDuration_NoTrigger2) {
185 // Enable NACK and with no RTT thresholds for disabling retransmission delay.
186 receiver_.SetNackMode(kNack, -1, -1);
187 const size_t kMaxNackListSize = 1000;
188 const int kMaxPacketAgeToNack = 1000;
189 const int kMaxNonDecodableDuration = 500;
philipel9d3ab612015-12-21 04:12:39 -0800190 const int kMaxNonDecodableDurationFrames =
191 (kDefaultFrameRate * kMaxNonDecodableDuration + 500) / 1000;
stefan@webrtc.org16734812013-05-14 12:00:47 +0000192 const int kMinDelayMs = 500;
193 receiver_.SetNackSettings(kMaxNackListSize, kMaxPacketAgeToNack,
philipel9d3ab612015-12-21 04:12:39 -0800194 kMaxNonDecodableDuration);
Niels Möller4eb4b052018-08-14 10:31:58 +0200195 timing_.set_min_playout_delay(kMinDelayMs);
stefan@webrtc.org16734812013-05-14 12:00:47 +0000196 int64_t key_frame_inserted = clock_->TimeInMilliseconds();
197 EXPECT_GE(InsertFrame(kVideoFrameKey, true), kNoError);
198 // Insert enough frames to have too long non-decodable sequence, except that
199 // we don't have any losses.
philipel9d3ab612015-12-21 04:12:39 -0800200 for (int i = 0; i < kMaxNonDecodableDurationFrames; ++i) {
stefan@webrtc.org16734812013-05-14 12:00:47 +0000201 EXPECT_GE(InsertFrame(kVideoFrameDelta, true), kNoError);
202 }
203 // Insert an incomplete frame.
204 EXPECT_GE(InsertFrame(kVideoFrameDelta, false), kNoError);
205 // Advance time until it's time to decode the key frame.
206 clock_->AdvanceTimeMilliseconds(kMinDelayMs - clock_->TimeInMilliseconds() -
philipel9d3ab612015-12-21 04:12:39 -0800207 key_frame_inserted);
stefan@webrtc.org16734812013-05-14 12:00:47 +0000208 EXPECT_TRUE(DecodeNextFrame());
209 // Make sure we don't get a key frame request since the non-decodable duration
210 // is only one frame.
Wan-Teh Changb1825a42015-06-03 15:03:35 -0700211 bool request_key_frame = false;
212 std::vector<uint16_t> nack_list = receiver_.NackList(&request_key_frame);
213 EXPECT_FALSE(request_key_frame);
stefan@webrtc.org16734812013-05-14 12:00:47 +0000214}
215
stefan@webrtc.orgef144882013-05-07 19:16:33 +0000216TEST_F(TestVCMReceiver, NonDecodableDuration_KeyFrameAfterIncompleteFrames) {
217 // Enable NACK and with no RTT thresholds for disabling retransmission delay.
218 receiver_.SetNackMode(kNack, -1, -1);
219 const size_t kMaxNackListSize = 1000;
220 const int kMaxPacketAgeToNack = 1000;
221 const int kMaxNonDecodableDuration = 500;
philipel9d3ab612015-12-21 04:12:39 -0800222 const int kMaxNonDecodableDurationFrames =
223 (kDefaultFrameRate * kMaxNonDecodableDuration + 500) / 1000;
stefan@webrtc.orgef144882013-05-07 19:16:33 +0000224 const int kMinDelayMs = 500;
225 receiver_.SetNackSettings(kMaxNackListSize, kMaxPacketAgeToNack,
philipel9d3ab612015-12-21 04:12:39 -0800226 kMaxNonDecodableDuration);
Niels Möller4eb4b052018-08-14 10:31:58 +0200227 timing_.set_min_playout_delay(kMinDelayMs);
stefan@webrtc.orgef144882013-05-07 19:16:33 +0000228 int64_t key_frame_inserted = clock_->TimeInMilliseconds();
229 EXPECT_GE(InsertFrame(kVideoFrameKey, true), kNoError);
230 // Insert an incomplete frame.
231 EXPECT_GE(InsertFrame(kVideoFrameDelta, false), kNoError);
232 // Insert enough frames to have too long non-decodable sequence.
philipel9d3ab612015-12-21 04:12:39 -0800233 for (int i = 0; i < kMaxNonDecodableDurationFrames; ++i) {
stefan@webrtc.orgef144882013-05-07 19:16:33 +0000234 EXPECT_GE(InsertFrame(kVideoFrameDelta, true), kNoError);
235 }
236 EXPECT_GE(InsertFrame(kVideoFrameKey, true), kNoError);
237 // Advance time until it's time to decode the key frame.
238 clock_->AdvanceTimeMilliseconds(kMinDelayMs - clock_->TimeInMilliseconds() -
philipel9d3ab612015-12-21 04:12:39 -0800239 key_frame_inserted);
stefan@webrtc.orgef144882013-05-07 19:16:33 +0000240 EXPECT_TRUE(DecodeNextFrame());
241 // Make sure we don't get a key frame request since we have a key frame
242 // in the list.
Wan-Teh Changb1825a42015-06-03 15:03:35 -0700243 bool request_key_frame = false;
244 std::vector<uint16_t> nack_list = receiver_.NackList(&request_key_frame);
245 EXPECT_FALSE(request_key_frame);
stefan@webrtc.orgef144882013-05-07 19:16:33 +0000246}
Qiang Chend4cec152015-06-19 09:17:00 -0700247
248// A simulated clock, when time elapses, will insert frames into the jitter
249// buffer, based on initial settings.
250class SimulatedClockWithFrames : public SimulatedClock {
251 public:
252 SimulatedClockWithFrames(StreamGenerator* stream_generator,
253 VCMReceiver* receiver)
254 : SimulatedClock(0),
255 stream_generator_(stream_generator),
256 receiver_(receiver) {}
257 virtual ~SimulatedClockWithFrames() {}
258
259 // If |stop_on_frame| is true and next frame arrives between now and
260 // now+|milliseconds|, the clock will be advanced to the arrival time of next
261 // frame.
262 // Otherwise, the clock will be advanced by |milliseconds|.
263 //
264 // For both cases, a frame will be inserted into the jitter buffer at the
265 // instant when the clock time is timestamps_.front().arrive_time.
266 //
267 // Return true if some frame arrives between now and now+|milliseconds|.
268 bool AdvanceTimeMilliseconds(int64_t milliseconds, bool stop_on_frame) {
269 return AdvanceTimeMicroseconds(milliseconds * 1000, stop_on_frame);
philipel9d3ab612015-12-21 04:12:39 -0800270 }
Qiang Chend4cec152015-06-19 09:17:00 -0700271
272 bool AdvanceTimeMicroseconds(int64_t microseconds, bool stop_on_frame) {
273 int64_t start_time = TimeInMicroseconds();
274 int64_t end_time = start_time + microseconds;
275 bool frame_injected = false;
276 while (!timestamps_.empty() &&
277 timestamps_.front().arrive_time <= end_time) {
henrikg91d6ede2015-09-17 00:24:34 -0700278 RTC_DCHECK(timestamps_.front().arrive_time >= start_time);
Qiang Chend4cec152015-06-19 09:17:00 -0700279
280 SimulatedClock::AdvanceTimeMicroseconds(timestamps_.front().arrive_time -
281 TimeInMicroseconds());
282 GenerateAndInsertFrame((timestamps_.front().render_time + 500) / 1000);
283 timestamps_.pop();
284 frame_injected = true;
285
286 if (stop_on_frame)
287 return frame_injected;
288 }
289
290 if (TimeInMicroseconds() < end_time) {
291 SimulatedClock::AdvanceTimeMicroseconds(end_time - TimeInMicroseconds());
292 }
293 return frame_injected;
philipel9d3ab612015-12-21 04:12:39 -0800294 }
Qiang Chend4cec152015-06-19 09:17:00 -0700295
296 // Input timestamps are in unit Milliseconds.
297 // And |arrive_timestamps| must be positive and in increasing order.
298 // |arrive_timestamps| determine when we are going to insert frames into the
299 // jitter buffer.
300 // |render_timestamps| are the timestamps on the frame.
301 void SetFrames(const int64_t* arrive_timestamps,
302 const int64_t* render_timestamps,
303 size_t size) {
304 int64_t previous_arrive_timestamp = 0;
305 for (size_t i = 0; i < size; i++) {
henrikg91d6ede2015-09-17 00:24:34 -0700306 RTC_CHECK(arrive_timestamps[i] >= previous_arrive_timestamp);
Qiang Chend4cec152015-06-19 09:17:00 -0700307 timestamps_.push(TimestampPair(arrive_timestamps[i] * 1000,
308 render_timestamps[i] * 1000));
309 previous_arrive_timestamp = arrive_timestamps[i];
310 }
311 }
312
313 private:
314 struct TimestampPair {
315 TimestampPair(int64_t arrive_timestamp, int64_t render_timestamp)
316 : arrive_time(arrive_timestamp), render_time(render_timestamp) {}
317
318 int64_t arrive_time;
319 int64_t render_time;
320 };
321
322 void GenerateAndInsertFrame(int64_t render_timestamp_ms) {
323 VCMPacket packet;
324 stream_generator_->GenerateFrame(FrameType::kVideoFrameKey,
325 1, // media packets
326 0, // empty packets
327 render_timestamp_ms);
328
329 bool packet_available = stream_generator_->PopPacket(&packet, 0);
330 EXPECT_TRUE(packet_available);
331 if (!packet_available)
332 return; // Return here to avoid crashes below.
Johan Ahlers95348f72016-06-28 11:11:28 +0200333 receiver_->InsertPacket(packet);
Qiang Chend4cec152015-06-19 09:17:00 -0700334 }
335
336 std::queue<TimestampPair> timestamps_;
337 StreamGenerator* stream_generator_;
338 VCMReceiver* receiver_;
339};
340
341// Use a SimulatedClockWithFrames
342// Wait call will do either of these:
343// 1. If |stop_on_frame| is true, the clock will be turned to the exact instant
344// that the first frame comes and the frame will be inserted into the jitter
345// buffer, or the clock will be turned to now + |max_time| if no frame comes in
346// the window.
347// 2. If |stop_on_frame| is false, the clock will be turn to now + |max_time|,
348// and all the frames arriving between now and now + |max_time| will be
349// inserted into the jitter buffer.
350//
351// This is used to simulate the JitterBuffer getting packets from internet as
352// time elapses.
353
354class FrameInjectEvent : public EventWrapper {
355 public:
356 FrameInjectEvent(SimulatedClockWithFrames* clock, bool stop_on_frame)
357 : clock_(clock), stop_on_frame_(stop_on_frame) {}
358
359 bool Set() override { return true; }
360
philipel9d3ab612015-12-21 04:12:39 -0800361 EventTypeWrapper Wait(unsigned long max_time) override { // NOLINT
Qiang Chend4cec152015-06-19 09:17:00 -0700362 if (clock_->AdvanceTimeMilliseconds(max_time, stop_on_frame_) &&
363 stop_on_frame_) {
364 return EventTypeWrapper::kEventSignaled;
365 } else {
366 return EventTypeWrapper::kEventTimeout;
367 }
368 }
369
370 private:
371 SimulatedClockWithFrames* clock_;
372 bool stop_on_frame_;
373};
374
375class VCMReceiverTimingTest : public ::testing::Test {
376 protected:
Qiang Chend4cec152015-06-19 09:17:00 -0700377 VCMReceiverTimingTest()
378
379 : clock_(&stream_generator_, &receiver_),
380 stream_generator_(0, clock_.TimeInMilliseconds()),
381 timing_(&clock_),
382 receiver_(
383 &timing_,
384 &clock_,
kwiberg3f55dea2016-02-29 05:51:59 -0800385 std::unique_ptr<EventWrapper>(new FrameInjectEvent(&clock_, false)),
386 std::unique_ptr<EventWrapper>(
Qiang Chend4cec152015-06-19 09:17:00 -0700387 new FrameInjectEvent(&clock_, true))) {}
388
Qiang Chend4cec152015-06-19 09:17:00 -0700389 virtual void SetUp() { receiver_.Reset(); }
390
391 SimulatedClockWithFrames clock_;
392 StreamGenerator stream_generator_;
393 VCMTiming timing_;
394 VCMReceiver receiver_;
395};
396
397// Test whether VCMReceiver::FrameForDecoding handles parameter
398// |max_wait_time_ms| correctly:
399// 1. The function execution should never take more than |max_wait_time_ms|.
400// 2. If the function exit before now + |max_wait_time_ms|, a frame must be
401// returned.
402TEST_F(VCMReceiverTimingTest, FrameForDecoding) {
403 const size_t kNumFrames = 100;
404 const int kFramePeriod = 40;
405 int64_t arrive_timestamps[kNumFrames];
406 int64_t render_timestamps[kNumFrames];
Qiang Chend4cec152015-06-19 09:17:00 -0700407
408 // Construct test samples.
409 // render_timestamps are the timestamps stored in the Frame;
410 // arrive_timestamps controls when the Frame packet got received.
411 for (size_t i = 0; i < kNumFrames; i++) {
412 // Preset frame rate to 25Hz.
413 // But we add a reasonable deviation to arrive_timestamps to mimic Internet
414 // fluctuation.
415 arrive_timestamps[i] =
416 (i + 1) * kFramePeriod + (i % 10) * ((i % 2) ? 1 : -1);
417 render_timestamps[i] = (i + 1) * kFramePeriod;
418 }
419
420 clock_.SetFrames(arrive_timestamps, render_timestamps, kNumFrames);
421
422 // Record how many frames we finally get out of the receiver.
423 size_t num_frames_return = 0;
424
425 const int64_t kMaxWaitTime = 30;
426
427 // Ideally, we should get all frames that we input in InitializeFrames.
428 // In the case that FrameForDecoding kills frames by error, we rely on the
429 // build bot to kill the test.
430 while (num_frames_return < kNumFrames) {
431 int64_t start_time = clock_.TimeInMilliseconds();
Johan Ahlers31b2ec42016-06-28 13:32:49 +0200432 VCMEncodedFrame* frame = receiver_.FrameForDecoding(kMaxWaitTime, false);
Qiang Chend4cec152015-06-19 09:17:00 -0700433 int64_t end_time = clock_.TimeInMilliseconds();
434
435 // In any case the FrameForDecoding should not wait longer than
436 // max_wait_time.
437 // In the case that we did not get a frame, it should have been waiting for
438 // exactly max_wait_time. (By the testing samples we constructed above, we
439 // are sure there is no timing error, so the only case it returns with NULL
440 // is that it runs out of time.)
441 if (frame) {
442 receiver_.ReleaseFrame(frame);
443 ++num_frames_return;
444 EXPECT_GE(kMaxWaitTime, end_time - start_time);
445 } else {
446 EXPECT_EQ(kMaxWaitTime, end_time - start_time);
447 }
448 }
449}
450
perkj796cfaf2015-12-10 09:27:38 -0800451// Test whether VCMReceiver::FrameForDecoding handles parameter
452// |prefer_late_decoding| and |max_wait_time_ms| correctly:
453// 1. The function execution should never take more than |max_wait_time_ms|.
454// 2. If the function exit before now + |max_wait_time_ms|, a frame must be
455// returned and the end time must be equal to the render timestamp - delay
456// for decoding and rendering.
457TEST_F(VCMReceiverTimingTest, FrameForDecodingPreferLateDecoding) {
458 const size_t kNumFrames = 100;
459 const int kFramePeriod = 40;
460
461 int64_t arrive_timestamps[kNumFrames];
462 int64_t render_timestamps[kNumFrames];
perkj796cfaf2015-12-10 09:27:38 -0800463
464 int render_delay_ms;
465 int max_decode_ms;
466 int dummy;
467 timing_.GetTimings(&dummy, &max_decode_ms, &dummy, &dummy, &dummy, &dummy,
468 &render_delay_ms);
469
470 // Construct test samples.
471 // render_timestamps are the timestamps stored in the Frame;
472 // arrive_timestamps controls when the Frame packet got received.
473 for (size_t i = 0; i < kNumFrames; i++) {
474 // Preset frame rate to 25Hz.
475 // But we add a reasonable deviation to arrive_timestamps to mimic Internet
476 // fluctuation.
477 arrive_timestamps[i] =
478 (i + 1) * kFramePeriod + (i % 10) * ((i % 2) ? 1 : -1);
479 render_timestamps[i] = (i + 1) * kFramePeriod;
480 }
481
482 clock_.SetFrames(arrive_timestamps, render_timestamps, kNumFrames);
483
484 // Record how many frames we finally get out of the receiver.
485 size_t num_frames_return = 0;
486 const int64_t kMaxWaitTime = 30;
487 bool prefer_late_decoding = true;
488 while (num_frames_return < kNumFrames) {
489 int64_t start_time = clock_.TimeInMilliseconds();
490
Johan Ahlers31b2ec42016-06-28 13:32:49 +0200491 VCMEncodedFrame* frame =
492 receiver_.FrameForDecoding(kMaxWaitTime, prefer_late_decoding);
perkj796cfaf2015-12-10 09:27:38 -0800493 int64_t end_time = clock_.TimeInMilliseconds();
494 if (frame) {
495 EXPECT_EQ(frame->RenderTimeMs() - max_decode_ms - render_delay_ms,
496 end_time);
497 receiver_.ReleaseFrame(frame);
498 ++num_frames_return;
499 } else {
500 EXPECT_EQ(kMaxWaitTime, end_time - start_time);
501 }
502 }
503}
504
mikhal@webrtc.org381da4b2013-04-25 21:45:29 +0000505} // namespace webrtc