blob: 83fdff28963624cd3d952182d1f3f8e0b676e6de [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
perkj796cfaf2015-12-10 09:27:38 -080017#include "webrtc/modules/video_coding/encoded_frame.h"
Henrik Kjellander2557b862015-11-18 22:00:21 +010018#include "webrtc/modules/video_coding/packet.h"
19#include "webrtc/modules/video_coding/receiver.h"
20#include "webrtc/modules/video_coding/test/stream_generator.h"
Henrik Kjellander2557b862015-11-18 22:00:21 +010021#include "webrtc/modules/video_coding/test/test_util.h"
kwibergac9f8762016-09-30 22:29:43 -070022#include "webrtc/modules/video_coding/timing.h"
kjellanderc8fa6922017-06-30 14:02:00 -070023#include "webrtc/rtc_base/checks.h"
Henrik Kjellander98f53512015-10-28 18:17:40 +010024#include "webrtc/system_wrappers/include/clock.h"
kwibergac9f8762016-09-30 22:29:43 -070025#include "webrtc/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()),
Wan-Teh Chang92d94892015-05-28 13:36:06 -070034 receiver_(&timing_, clock_.get(), &event_factory_) {
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
59 int32_t InsertFrame(FrameType frame_type, bool complete) {
60 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_;
84 NullEventFactory event_factory_;
85 VCMReceiver receiver_;
kwiberg3f55dea2016-02-29 05:51:59 -080086 std::unique_ptr<StreamGenerator> stream_generator_;
mikhal@webrtc.org381da4b2013-04-25 21:45:29 +000087};
88
stefan@webrtc.orgef144882013-05-07 19:16:33 +000089TEST_F(TestVCMReceiver, NonDecodableDuration_Empty) {
90 // Enable NACK and with no RTT thresholds for disabling retransmission delay.
91 receiver_.SetNackMode(kNack, -1, -1);
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,
philipel9d3ab612015-12-21 04:12:39 -080097 kMaxNonDecodableDuration);
stefan@webrtc.orgef144882013-05-07 19:16:33 +000098 EXPECT_GE(InsertFrame(kVideoFrameKey, true), kNoError);
99 // Advance time until it's time to decode the key frame.
100 clock_->AdvanceTimeMilliseconds(kMinDelayMs);
101 EXPECT_TRUE(DecodeNextFrame());
Wan-Teh Changb1825a42015-06-03 15:03:35 -0700102 bool request_key_frame = false;
103 std::vector<uint16_t> nack_list = receiver_.NackList(&request_key_frame);
104 EXPECT_FALSE(request_key_frame);
stefan@webrtc.orgef144882013-05-07 19:16:33 +0000105}
106
107TEST_F(TestVCMReceiver, NonDecodableDuration_NoKeyFrame) {
108 // Enable NACK and with no RTT thresholds for disabling retransmission delay.
109 receiver_.SetNackMode(kNack, -1, -1);
110 const size_t kMaxNackListSize = 1000;
111 const int kMaxPacketAgeToNack = 1000;
112 const int kMaxNonDecodableDuration = 500;
113 receiver_.SetNackSettings(kMaxNackListSize, kMaxPacketAgeToNack,
philipel9d3ab612015-12-21 04:12:39 -0800114 kMaxNonDecodableDuration);
stefan@webrtc.orgef144882013-05-07 19:16:33 +0000115 const int kNumFrames = kDefaultFrameRate * kMaxNonDecodableDuration / 1000;
116 for (int i = 0; i < kNumFrames; ++i) {
117 EXPECT_GE(InsertFrame(kVideoFrameDelta, true), kNoError);
118 }
Wan-Teh Changb1825a42015-06-03 15:03:35 -0700119 bool request_key_frame = false;
120 std::vector<uint16_t> nack_list = receiver_.NackList(&request_key_frame);
121 EXPECT_TRUE(request_key_frame);
stefan@webrtc.orgef144882013-05-07 19:16:33 +0000122}
123
124TEST_F(TestVCMReceiver, NonDecodableDuration_OneIncomplete) {
125 // Enable NACK and with no RTT thresholds for disabling retransmission delay.
126 receiver_.SetNackMode(kNack, -1, -1);
127 const size_t kMaxNackListSize = 1000;
128 const int kMaxPacketAgeToNack = 1000;
129 const int kMaxNonDecodableDuration = 500;
philipel9d3ab612015-12-21 04:12:39 -0800130 const int kMaxNonDecodableDurationFrames =
131 (kDefaultFrameRate * kMaxNonDecodableDuration + 500) / 1000;
stefan@webrtc.orgef144882013-05-07 19:16:33 +0000132 const int kMinDelayMs = 500;
133 receiver_.SetNackSettings(kMaxNackListSize, kMaxPacketAgeToNack,
philipel9d3ab612015-12-21 04:12:39 -0800134 kMaxNonDecodableDuration);
stefan@webrtc.orgef144882013-05-07 19:16:33 +0000135 receiver_.SetMinReceiverDelay(kMinDelayMs);
136 int64_t key_frame_inserted = clock_->TimeInMilliseconds();
137 EXPECT_GE(InsertFrame(kVideoFrameKey, true), kNoError);
138 // Insert an incomplete frame.
139 EXPECT_GE(InsertFrame(kVideoFrameDelta, false), kNoError);
140 // Insert enough frames to have too long non-decodable sequence.
philipel9d3ab612015-12-21 04:12:39 -0800141 for (int i = 0; i < kMaxNonDecodableDurationFrames; ++i) {
stefan@webrtc.orgef144882013-05-07 19:16:33 +0000142 EXPECT_GE(InsertFrame(kVideoFrameDelta, true), kNoError);
143 }
144 // Advance time until it's time to decode the key frame.
145 clock_->AdvanceTimeMilliseconds(kMinDelayMs - clock_->TimeInMilliseconds() -
philipel9d3ab612015-12-21 04:12:39 -0800146 key_frame_inserted);
stefan@webrtc.orgef144882013-05-07 19:16:33 +0000147 EXPECT_TRUE(DecodeNextFrame());
148 // Make sure we get a key frame request.
Wan-Teh Changb1825a42015-06-03 15:03:35 -0700149 bool request_key_frame = false;
150 std::vector<uint16_t> nack_list = receiver_.NackList(&request_key_frame);
151 EXPECT_TRUE(request_key_frame);
stefan@webrtc.orgef144882013-05-07 19:16:33 +0000152}
153
154TEST_F(TestVCMReceiver, NonDecodableDuration_NoTrigger) {
155 // Enable NACK and with no RTT thresholds for disabling retransmission delay.
156 receiver_.SetNackMode(kNack, -1, -1);
157 const size_t kMaxNackListSize = 1000;
158 const int kMaxPacketAgeToNack = 1000;
159 const int kMaxNonDecodableDuration = 500;
philipel9d3ab612015-12-21 04:12:39 -0800160 const int kMaxNonDecodableDurationFrames =
161 (kDefaultFrameRate * kMaxNonDecodableDuration + 500) / 1000;
stefan@webrtc.orgef144882013-05-07 19:16:33 +0000162 const int kMinDelayMs = 500;
163 receiver_.SetNackSettings(kMaxNackListSize, kMaxPacketAgeToNack,
philipel9d3ab612015-12-21 04:12:39 -0800164 kMaxNonDecodableDuration);
stefan@webrtc.orgef144882013-05-07 19:16:33 +0000165 receiver_.SetMinReceiverDelay(kMinDelayMs);
166 int64_t key_frame_inserted = clock_->TimeInMilliseconds();
167 EXPECT_GE(InsertFrame(kVideoFrameKey, true), kNoError);
168 // Insert an incomplete frame.
169 EXPECT_GE(InsertFrame(kVideoFrameDelta, false), kNoError);
170 // Insert all but one frame to not trigger a key frame request due to
171 // too long duration of non-decodable frames.
philipel9d3ab612015-12-21 04:12:39 -0800172 for (int i = 0; i < kMaxNonDecodableDurationFrames - 1; ++i) {
stefan@webrtc.orgef144882013-05-07 19:16:33 +0000173 EXPECT_GE(InsertFrame(kVideoFrameDelta, true), kNoError);
174 }
175 // Advance time until it's time to decode the key frame.
176 clock_->AdvanceTimeMilliseconds(kMinDelayMs - clock_->TimeInMilliseconds() -
philipel9d3ab612015-12-21 04:12:39 -0800177 key_frame_inserted);
stefan@webrtc.orgef144882013-05-07 19:16:33 +0000178 EXPECT_TRUE(DecodeNextFrame());
179 // Make sure we don't get a key frame request since we haven't generated
180 // enough frames.
Wan-Teh Changb1825a42015-06-03 15:03:35 -0700181 bool request_key_frame = false;
182 std::vector<uint16_t> nack_list = receiver_.NackList(&request_key_frame);
183 EXPECT_FALSE(request_key_frame);
stefan@webrtc.orgef144882013-05-07 19:16:33 +0000184}
185
stefan@webrtc.org16734812013-05-14 12:00:47 +0000186TEST_F(TestVCMReceiver, NonDecodableDuration_NoTrigger2) {
187 // Enable NACK and with no RTT thresholds for disabling retransmission delay.
188 receiver_.SetNackMode(kNack, -1, -1);
189 const size_t kMaxNackListSize = 1000;
190 const int kMaxPacketAgeToNack = 1000;
191 const int kMaxNonDecodableDuration = 500;
philipel9d3ab612015-12-21 04:12:39 -0800192 const int kMaxNonDecodableDurationFrames =
193 (kDefaultFrameRate * kMaxNonDecodableDuration + 500) / 1000;
stefan@webrtc.org16734812013-05-14 12:00:47 +0000194 const int kMinDelayMs = 500;
195 receiver_.SetNackSettings(kMaxNackListSize, kMaxPacketAgeToNack,
philipel9d3ab612015-12-21 04:12:39 -0800196 kMaxNonDecodableDuration);
stefan@webrtc.org16734812013-05-14 12:00:47 +0000197 receiver_.SetMinReceiverDelay(kMinDelayMs);
198 int64_t key_frame_inserted = clock_->TimeInMilliseconds();
199 EXPECT_GE(InsertFrame(kVideoFrameKey, true), kNoError);
200 // Insert enough frames to have too long non-decodable sequence, except that
201 // we don't have any losses.
philipel9d3ab612015-12-21 04:12:39 -0800202 for (int i = 0; i < kMaxNonDecodableDurationFrames; ++i) {
stefan@webrtc.org16734812013-05-14 12:00:47 +0000203 EXPECT_GE(InsertFrame(kVideoFrameDelta, true), kNoError);
204 }
205 // Insert an incomplete frame.
206 EXPECT_GE(InsertFrame(kVideoFrameDelta, false), kNoError);
207 // Advance time until it's time to decode the key frame.
208 clock_->AdvanceTimeMilliseconds(kMinDelayMs - clock_->TimeInMilliseconds() -
philipel9d3ab612015-12-21 04:12:39 -0800209 key_frame_inserted);
stefan@webrtc.org16734812013-05-14 12:00:47 +0000210 EXPECT_TRUE(DecodeNextFrame());
211 // Make sure we don't get a key frame request since the non-decodable duration
212 // is only one frame.
Wan-Teh Changb1825a42015-06-03 15:03:35 -0700213 bool request_key_frame = false;
214 std::vector<uint16_t> nack_list = receiver_.NackList(&request_key_frame);
215 EXPECT_FALSE(request_key_frame);
stefan@webrtc.org16734812013-05-14 12:00:47 +0000216}
217
stefan@webrtc.orgef144882013-05-07 19:16:33 +0000218TEST_F(TestVCMReceiver, NonDecodableDuration_KeyFrameAfterIncompleteFrames) {
219 // Enable NACK and with no RTT thresholds for disabling retransmission delay.
220 receiver_.SetNackMode(kNack, -1, -1);
221 const size_t kMaxNackListSize = 1000;
222 const int kMaxPacketAgeToNack = 1000;
223 const int kMaxNonDecodableDuration = 500;
philipel9d3ab612015-12-21 04:12:39 -0800224 const int kMaxNonDecodableDurationFrames =
225 (kDefaultFrameRate * kMaxNonDecodableDuration + 500) / 1000;
stefan@webrtc.orgef144882013-05-07 19:16:33 +0000226 const int kMinDelayMs = 500;
227 receiver_.SetNackSettings(kMaxNackListSize, kMaxPacketAgeToNack,
philipel9d3ab612015-12-21 04:12:39 -0800228 kMaxNonDecodableDuration);
stefan@webrtc.orgef144882013-05-07 19:16:33 +0000229 receiver_.SetMinReceiverDelay(kMinDelayMs);
230 int64_t key_frame_inserted = clock_->TimeInMilliseconds();
231 EXPECT_GE(InsertFrame(kVideoFrameKey, true), kNoError);
232 // Insert an incomplete frame.
233 EXPECT_GE(InsertFrame(kVideoFrameDelta, false), kNoError);
234 // Insert enough frames to have too long non-decodable sequence.
philipel9d3ab612015-12-21 04:12:39 -0800235 for (int i = 0; i < kMaxNonDecodableDurationFrames; ++i) {
stefan@webrtc.orgef144882013-05-07 19:16:33 +0000236 EXPECT_GE(InsertFrame(kVideoFrameDelta, true), kNoError);
237 }
238 EXPECT_GE(InsertFrame(kVideoFrameKey, true), kNoError);
239 // Advance time until it's time to decode the key frame.
240 clock_->AdvanceTimeMilliseconds(kMinDelayMs - clock_->TimeInMilliseconds() -
philipel9d3ab612015-12-21 04:12:39 -0800241 key_frame_inserted);
stefan@webrtc.orgef144882013-05-07 19:16:33 +0000242 EXPECT_TRUE(DecodeNextFrame());
243 // Make sure we don't get a key frame request since we have a key frame
244 // in the list.
Wan-Teh Changb1825a42015-06-03 15:03:35 -0700245 bool request_key_frame = false;
246 std::vector<uint16_t> nack_list = receiver_.NackList(&request_key_frame);
247 EXPECT_FALSE(request_key_frame);
stefan@webrtc.orgef144882013-05-07 19:16:33 +0000248}
Qiang Chend4cec152015-06-19 09:17:00 -0700249
250// A simulated clock, when time elapses, will insert frames into the jitter
251// buffer, based on initial settings.
252class SimulatedClockWithFrames : public SimulatedClock {
253 public:
254 SimulatedClockWithFrames(StreamGenerator* stream_generator,
255 VCMReceiver* receiver)
256 : SimulatedClock(0),
257 stream_generator_(stream_generator),
258 receiver_(receiver) {}
259 virtual ~SimulatedClockWithFrames() {}
260
261 // If |stop_on_frame| is true and next frame arrives between now and
262 // now+|milliseconds|, the clock will be advanced to the arrival time of next
263 // frame.
264 // Otherwise, the clock will be advanced by |milliseconds|.
265 //
266 // For both cases, a frame will be inserted into the jitter buffer at the
267 // instant when the clock time is timestamps_.front().arrive_time.
268 //
269 // Return true if some frame arrives between now and now+|milliseconds|.
270 bool AdvanceTimeMilliseconds(int64_t milliseconds, bool stop_on_frame) {
271 return AdvanceTimeMicroseconds(milliseconds * 1000, stop_on_frame);
philipel9d3ab612015-12-21 04:12:39 -0800272 }
Qiang Chend4cec152015-06-19 09:17:00 -0700273
274 bool AdvanceTimeMicroseconds(int64_t microseconds, bool stop_on_frame) {
275 int64_t start_time = TimeInMicroseconds();
276 int64_t end_time = start_time + microseconds;
277 bool frame_injected = false;
278 while (!timestamps_.empty() &&
279 timestamps_.front().arrive_time <= end_time) {
henrikg91d6ede2015-09-17 00:24:34 -0700280 RTC_DCHECK(timestamps_.front().arrive_time >= start_time);
Qiang Chend4cec152015-06-19 09:17:00 -0700281
282 SimulatedClock::AdvanceTimeMicroseconds(timestamps_.front().arrive_time -
283 TimeInMicroseconds());
284 GenerateAndInsertFrame((timestamps_.front().render_time + 500) / 1000);
285 timestamps_.pop();
286 frame_injected = true;
287
288 if (stop_on_frame)
289 return frame_injected;
290 }
291
292 if (TimeInMicroseconds() < end_time) {
293 SimulatedClock::AdvanceTimeMicroseconds(end_time - TimeInMicroseconds());
294 }
295 return frame_injected;
philipel9d3ab612015-12-21 04:12:39 -0800296 }
Qiang Chend4cec152015-06-19 09:17:00 -0700297
298 // Input timestamps are in unit Milliseconds.
299 // And |arrive_timestamps| must be positive and in increasing order.
300 // |arrive_timestamps| determine when we are going to insert frames into the
301 // jitter buffer.
302 // |render_timestamps| are the timestamps on the frame.
303 void SetFrames(const int64_t* arrive_timestamps,
304 const int64_t* render_timestamps,
305 size_t size) {
306 int64_t previous_arrive_timestamp = 0;
307 for (size_t i = 0; i < size; i++) {
henrikg91d6ede2015-09-17 00:24:34 -0700308 RTC_CHECK(arrive_timestamps[i] >= previous_arrive_timestamp);
Qiang Chend4cec152015-06-19 09:17:00 -0700309 timestamps_.push(TimestampPair(arrive_timestamps[i] * 1000,
310 render_timestamps[i] * 1000));
311 previous_arrive_timestamp = arrive_timestamps[i];
312 }
313 }
314
315 private:
316 struct TimestampPair {
317 TimestampPair(int64_t arrive_timestamp, int64_t render_timestamp)
318 : arrive_time(arrive_timestamp), render_time(render_timestamp) {}
319
320 int64_t arrive_time;
321 int64_t render_time;
322 };
323
324 void GenerateAndInsertFrame(int64_t render_timestamp_ms) {
325 VCMPacket packet;
326 stream_generator_->GenerateFrame(FrameType::kVideoFrameKey,
327 1, // media packets
328 0, // empty packets
329 render_timestamp_ms);
330
331 bool packet_available = stream_generator_->PopPacket(&packet, 0);
332 EXPECT_TRUE(packet_available);
333 if (!packet_available)
334 return; // Return here to avoid crashes below.
Johan Ahlers95348f72016-06-28 11:11:28 +0200335 receiver_->InsertPacket(packet);
Qiang Chend4cec152015-06-19 09:17:00 -0700336 }
337
338 std::queue<TimestampPair> timestamps_;
339 StreamGenerator* stream_generator_;
340 VCMReceiver* receiver_;
341};
342
343// Use a SimulatedClockWithFrames
344// Wait call will do either of these:
345// 1. If |stop_on_frame| is true, the clock will be turned to the exact instant
346// that the first frame comes and the frame will be inserted into the jitter
347// buffer, or the clock will be turned to now + |max_time| if no frame comes in
348// the window.
349// 2. If |stop_on_frame| is false, the clock will be turn to now + |max_time|,
350// and all the frames arriving between now and now + |max_time| will be
351// inserted into the jitter buffer.
352//
353// This is used to simulate the JitterBuffer getting packets from internet as
354// time elapses.
355
356class FrameInjectEvent : public EventWrapper {
357 public:
358 FrameInjectEvent(SimulatedClockWithFrames* clock, bool stop_on_frame)
359 : clock_(clock), stop_on_frame_(stop_on_frame) {}
360
361 bool Set() override { return true; }
362
philipel9d3ab612015-12-21 04:12:39 -0800363 EventTypeWrapper Wait(unsigned long max_time) override { // NOLINT
Qiang Chend4cec152015-06-19 09:17:00 -0700364 if (clock_->AdvanceTimeMilliseconds(max_time, stop_on_frame_) &&
365 stop_on_frame_) {
366 return EventTypeWrapper::kEventSignaled;
367 } else {
368 return EventTypeWrapper::kEventTimeout;
369 }
370 }
371
372 private:
373 SimulatedClockWithFrames* clock_;
374 bool stop_on_frame_;
375};
376
377class VCMReceiverTimingTest : public ::testing::Test {
378 protected:
Qiang Chend4cec152015-06-19 09:17:00 -0700379 VCMReceiverTimingTest()
380
381 : clock_(&stream_generator_, &receiver_),
382 stream_generator_(0, clock_.TimeInMilliseconds()),
383 timing_(&clock_),
384 receiver_(
385 &timing_,
386 &clock_,
kwiberg3f55dea2016-02-29 05:51:59 -0800387 std::unique_ptr<EventWrapper>(new FrameInjectEvent(&clock_, false)),
388 std::unique_ptr<EventWrapper>(
Qiang Chend4cec152015-06-19 09:17:00 -0700389 new FrameInjectEvent(&clock_, true))) {}
390
Qiang Chend4cec152015-06-19 09:17:00 -0700391 virtual void SetUp() { receiver_.Reset(); }
392
393 SimulatedClockWithFrames clock_;
394 StreamGenerator stream_generator_;
395 VCMTiming timing_;
396 VCMReceiver receiver_;
397};
398
399// Test whether VCMReceiver::FrameForDecoding handles parameter
400// |max_wait_time_ms| correctly:
401// 1. The function execution should never take more than |max_wait_time_ms|.
402// 2. If the function exit before now + |max_wait_time_ms|, a frame must be
403// returned.
404TEST_F(VCMReceiverTimingTest, FrameForDecoding) {
405 const size_t kNumFrames = 100;
406 const int kFramePeriod = 40;
407 int64_t arrive_timestamps[kNumFrames];
408 int64_t render_timestamps[kNumFrames];
Qiang Chend4cec152015-06-19 09:17:00 -0700409
410 // Construct test samples.
411 // render_timestamps are the timestamps stored in the Frame;
412 // arrive_timestamps controls when the Frame packet got received.
413 for (size_t i = 0; i < kNumFrames; i++) {
414 // Preset frame rate to 25Hz.
415 // But we add a reasonable deviation to arrive_timestamps to mimic Internet
416 // fluctuation.
417 arrive_timestamps[i] =
418 (i + 1) * kFramePeriod + (i % 10) * ((i % 2) ? 1 : -1);
419 render_timestamps[i] = (i + 1) * kFramePeriod;
420 }
421
422 clock_.SetFrames(arrive_timestamps, render_timestamps, kNumFrames);
423
424 // Record how many frames we finally get out of the receiver.
425 size_t num_frames_return = 0;
426
427 const int64_t kMaxWaitTime = 30;
428
429 // Ideally, we should get all frames that we input in InitializeFrames.
430 // In the case that FrameForDecoding kills frames by error, we rely on the
431 // build bot to kill the test.
432 while (num_frames_return < kNumFrames) {
433 int64_t start_time = clock_.TimeInMilliseconds();
Johan Ahlers31b2ec42016-06-28 13:32:49 +0200434 VCMEncodedFrame* frame = receiver_.FrameForDecoding(kMaxWaitTime, false);
Qiang Chend4cec152015-06-19 09:17:00 -0700435 int64_t end_time = clock_.TimeInMilliseconds();
436
437 // In any case the FrameForDecoding should not wait longer than
438 // max_wait_time.
439 // In the case that we did not get a frame, it should have been waiting for
440 // exactly max_wait_time. (By the testing samples we constructed above, we
441 // are sure there is no timing error, so the only case it returns with NULL
442 // is that it runs out of time.)
443 if (frame) {
444 receiver_.ReleaseFrame(frame);
445 ++num_frames_return;
446 EXPECT_GE(kMaxWaitTime, end_time - start_time);
447 } else {
448 EXPECT_EQ(kMaxWaitTime, end_time - start_time);
449 }
450 }
451}
452
perkj796cfaf2015-12-10 09:27:38 -0800453// Test whether VCMReceiver::FrameForDecoding handles parameter
454// |prefer_late_decoding| and |max_wait_time_ms| correctly:
455// 1. The function execution should never take more than |max_wait_time_ms|.
456// 2. If the function exit before now + |max_wait_time_ms|, a frame must be
457// returned and the end time must be equal to the render timestamp - delay
458// for decoding and rendering.
459TEST_F(VCMReceiverTimingTest, FrameForDecodingPreferLateDecoding) {
460 const size_t kNumFrames = 100;
461 const int kFramePeriod = 40;
462
463 int64_t arrive_timestamps[kNumFrames];
464 int64_t render_timestamps[kNumFrames];
perkj796cfaf2015-12-10 09:27:38 -0800465
466 int render_delay_ms;
467 int max_decode_ms;
468 int dummy;
469 timing_.GetTimings(&dummy, &max_decode_ms, &dummy, &dummy, &dummy, &dummy,
470 &render_delay_ms);
471
472 // Construct test samples.
473 // render_timestamps are the timestamps stored in the Frame;
474 // arrive_timestamps controls when the Frame packet got received.
475 for (size_t i = 0; i < kNumFrames; i++) {
476 // Preset frame rate to 25Hz.
477 // But we add a reasonable deviation to arrive_timestamps to mimic Internet
478 // fluctuation.
479 arrive_timestamps[i] =
480 (i + 1) * kFramePeriod + (i % 10) * ((i % 2) ? 1 : -1);
481 render_timestamps[i] = (i + 1) * kFramePeriod;
482 }
483
484 clock_.SetFrames(arrive_timestamps, render_timestamps, kNumFrames);
485
486 // Record how many frames we finally get out of the receiver.
487 size_t num_frames_return = 0;
488 const int64_t kMaxWaitTime = 30;
489 bool prefer_late_decoding = true;
490 while (num_frames_return < kNumFrames) {
491 int64_t start_time = clock_.TimeInMilliseconds();
492
Johan Ahlers31b2ec42016-06-28 13:32:49 +0200493 VCMEncodedFrame* frame =
494 receiver_.FrameForDecoding(kMaxWaitTime, prefer_late_decoding);
perkj796cfaf2015-12-10 09:27:38 -0800495 int64_t end_time = clock_.TimeInMilliseconds();
496 if (frame) {
497 EXPECT_EQ(frame->RenderTimeMs() - max_decode_ms - render_delay_ms,
498 end_time);
499 receiver_.ReleaseFrame(frame);
500 ++num_frames_return;
501 } else {
502 EXPECT_EQ(kMaxWaitTime, end_time - start_time);
503 }
504 }
505}
506
mikhal@webrtc.org381da4b2013-04-25 21:45:29 +0000507} // namespace webrtc