blob: 863dac344e3b569a9254f092c24e8a955745e669 [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
17#include "testing/gtest/include/gtest/gtest.h"
Qiang Chend4cec152015-06-19 09:17:00 -070018#include "webrtc/base/checks.h"
perkj796cfaf2015-12-10 09:27:38 -080019#include "webrtc/modules/video_coding/encoded_frame.h"
Henrik Kjellander2557b862015-11-18 22:00:21 +010020#include "webrtc/modules/video_coding/packet.h"
21#include "webrtc/modules/video_coding/receiver.h"
22#include "webrtc/modules/video_coding/test/stream_generator.h"
23#include "webrtc/modules/video_coding/timing.h"
24#include "webrtc/modules/video_coding/test/test_util.h"
Henrik Kjellander98f53512015-10-28 18:17:40 +010025#include "webrtc/system_wrappers/include/clock.h"
26#include "webrtc/system_wrappers/include/critical_section_wrapper.h"
mikhal@webrtc.org381da4b2013-04-25 21:45:29 +000027
28namespace webrtc {
29
30class TestVCMReceiver : public ::testing::Test {
31 protected:
mikhal@webrtc.org381da4b2013-04-25 21:45:29 +000032 TestVCMReceiver()
33 : clock_(new SimulatedClock(0)),
34 timing_(clock_.get()),
Wan-Teh Chang92d94892015-05-28 13:36:06 -070035 receiver_(&timing_, clock_.get(), &event_factory_) {
philipel9d3ab612015-12-21 04:12:39 -080036 stream_generator_.reset(
37 new StreamGenerator(0, clock_->TimeInMilliseconds()));
mikhal@webrtc.org381da4b2013-04-25 21:45:29 +000038 }
39
philipel9d3ab612015-12-21 04:12:39 -080040 virtual void SetUp() { receiver_.Reset(); }
mikhal@webrtc.org381da4b2013-04-25 21:45:29 +000041
42 int32_t InsertPacket(int index) {
43 VCMPacket packet;
mikhal@webrtc.org381da4b2013-04-25 21:45:29 +000044 bool packet_available = stream_generator_->GetPacket(&packet, index);
45 EXPECT_TRUE(packet_available);
46 if (!packet_available)
stefan@webrtc.org3417eb42013-05-21 15:25:53 +000047 return kGeneralError; // Return here to avoid crashes below.
Johan Ahlers95348f72016-06-28 11:11:28 +020048 return receiver_.InsertPacket(packet);
mikhal@webrtc.org381da4b2013-04-25 21:45:29 +000049 }
50
51 int32_t InsertPacketAndPop(int index) {
52 VCMPacket packet;
mikhal@webrtc.org381da4b2013-04-25 21:45:29 +000053 bool packet_available = stream_generator_->PopPacket(&packet, index);
54 EXPECT_TRUE(packet_available);
55 if (!packet_available)
stefan@webrtc.org3417eb42013-05-21 15:25:53 +000056 return kGeneralError; // Return here to avoid crashes below.
Johan Ahlers95348f72016-06-28 11:11:28 +020057 return receiver_.InsertPacket(packet);
mikhal@webrtc.org381da4b2013-04-25 21:45:29 +000058 }
59
60 int32_t InsertFrame(FrameType frame_type, bool complete) {
61 int num_of_packets = complete ? 1 : 2;
62 stream_generator_->GenerateFrame(
pbos22993e12015-10-19 02:39:06 -070063 frame_type, (frame_type != kEmptyFrame) ? num_of_packets : 0,
64 (frame_type == kEmptyFrame) ? 1 : 0, clock_->TimeInMilliseconds());
mikhal@webrtc.org381da4b2013-04-25 21:45:29 +000065 int32_t ret = InsertPacketAndPop(0);
stefan@webrtc.orgef144882013-05-07 19:16:33 +000066 if (!complete) {
67 // Drop the second packet.
68 VCMPacket packet;
69 stream_generator_->PopPacket(&packet, 0);
70 }
mikhal@webrtc.org381da4b2013-04-25 21:45:29 +000071 clock_->AdvanceTimeMilliseconds(kDefaultFramePeriodMs);
72 return ret;
73 }
74
stefan@webrtc.orgef144882013-05-07 19:16:33 +000075 bool DecodeNextFrame() {
76 int64_t render_time_ms = 0;
pbos@webrtc.org4f16c872014-11-24 09:06:48 +000077 VCMEncodedFrame* frame =
philipel9d3ab612015-12-21 04:12:39 -080078 receiver_.FrameForDecoding(0, &render_time_ms, false);
stefan@webrtc.orgef144882013-05-07 19:16:33 +000079 if (!frame)
80 return false;
81 receiver_.ReleaseFrame(frame);
82 return true;
83 }
84
kwiberg3f55dea2016-02-29 05:51:59 -080085 std::unique_ptr<SimulatedClock> clock_;
mikhal@webrtc.org381da4b2013-04-25 21:45:29 +000086 VCMTiming timing_;
87 NullEventFactory event_factory_;
88 VCMReceiver receiver_;
kwiberg3f55dea2016-02-29 05:51:59 -080089 std::unique_ptr<StreamGenerator> stream_generator_;
mikhal@webrtc.org381da4b2013-04-25 21:45:29 +000090};
91
stefan@webrtc.orgef144882013-05-07 19:16:33 +000092TEST_F(TestVCMReceiver, NonDecodableDuration_Empty) {
93 // Enable NACK and with no RTT thresholds for disabling retransmission delay.
94 receiver_.SetNackMode(kNack, -1, -1);
95 const size_t kMaxNackListSize = 1000;
96 const int kMaxPacketAgeToNack = 1000;
97 const int kMaxNonDecodableDuration = 500;
98 const int kMinDelayMs = 500;
99 receiver_.SetNackSettings(kMaxNackListSize, kMaxPacketAgeToNack,
philipel9d3ab612015-12-21 04:12:39 -0800100 kMaxNonDecodableDuration);
stefan@webrtc.orgef144882013-05-07 19:16:33 +0000101 EXPECT_GE(InsertFrame(kVideoFrameKey, true), kNoError);
102 // Advance time until it's time to decode the key frame.
103 clock_->AdvanceTimeMilliseconds(kMinDelayMs);
104 EXPECT_TRUE(DecodeNextFrame());
Wan-Teh Changb1825a42015-06-03 15:03:35 -0700105 bool request_key_frame = false;
106 std::vector<uint16_t> nack_list = receiver_.NackList(&request_key_frame);
107 EXPECT_FALSE(request_key_frame);
stefan@webrtc.orgef144882013-05-07 19:16:33 +0000108}
109
110TEST_F(TestVCMReceiver, NonDecodableDuration_NoKeyFrame) {
111 // Enable NACK and with no RTT thresholds for disabling retransmission delay.
112 receiver_.SetNackMode(kNack, -1, -1);
113 const size_t kMaxNackListSize = 1000;
114 const int kMaxPacketAgeToNack = 1000;
115 const int kMaxNonDecodableDuration = 500;
116 receiver_.SetNackSettings(kMaxNackListSize, kMaxPacketAgeToNack,
philipel9d3ab612015-12-21 04:12:39 -0800117 kMaxNonDecodableDuration);
stefan@webrtc.orgef144882013-05-07 19:16:33 +0000118 const int kNumFrames = kDefaultFrameRate * kMaxNonDecodableDuration / 1000;
119 for (int i = 0; i < kNumFrames; ++i) {
120 EXPECT_GE(InsertFrame(kVideoFrameDelta, true), kNoError);
121 }
Wan-Teh Changb1825a42015-06-03 15:03:35 -0700122 bool request_key_frame = false;
123 std::vector<uint16_t> nack_list = receiver_.NackList(&request_key_frame);
124 EXPECT_TRUE(request_key_frame);
stefan@webrtc.orgef144882013-05-07 19:16:33 +0000125}
126
127TEST_F(TestVCMReceiver, NonDecodableDuration_OneIncomplete) {
128 // Enable NACK and with no RTT thresholds for disabling retransmission delay.
129 receiver_.SetNackMode(kNack, -1, -1);
130 const size_t kMaxNackListSize = 1000;
131 const int kMaxPacketAgeToNack = 1000;
132 const int kMaxNonDecodableDuration = 500;
philipel9d3ab612015-12-21 04:12:39 -0800133 const int kMaxNonDecodableDurationFrames =
134 (kDefaultFrameRate * kMaxNonDecodableDuration + 500) / 1000;
stefan@webrtc.orgef144882013-05-07 19:16:33 +0000135 const int kMinDelayMs = 500;
136 receiver_.SetNackSettings(kMaxNackListSize, kMaxPacketAgeToNack,
philipel9d3ab612015-12-21 04:12:39 -0800137 kMaxNonDecodableDuration);
stefan@webrtc.orgef144882013-05-07 19:16:33 +0000138 receiver_.SetMinReceiverDelay(kMinDelayMs);
139 int64_t key_frame_inserted = clock_->TimeInMilliseconds();
140 EXPECT_GE(InsertFrame(kVideoFrameKey, true), kNoError);
141 // Insert an incomplete frame.
142 EXPECT_GE(InsertFrame(kVideoFrameDelta, false), kNoError);
143 // Insert enough frames to have too long non-decodable sequence.
philipel9d3ab612015-12-21 04:12:39 -0800144 for (int i = 0; i < kMaxNonDecodableDurationFrames; ++i) {
stefan@webrtc.orgef144882013-05-07 19:16:33 +0000145 EXPECT_GE(InsertFrame(kVideoFrameDelta, true), kNoError);
146 }
147 // Advance time until it's time to decode the key frame.
148 clock_->AdvanceTimeMilliseconds(kMinDelayMs - clock_->TimeInMilliseconds() -
philipel9d3ab612015-12-21 04:12:39 -0800149 key_frame_inserted);
stefan@webrtc.orgef144882013-05-07 19:16:33 +0000150 EXPECT_TRUE(DecodeNextFrame());
151 // Make sure we get a key frame request.
Wan-Teh Changb1825a42015-06-03 15:03:35 -0700152 bool request_key_frame = false;
153 std::vector<uint16_t> nack_list = receiver_.NackList(&request_key_frame);
154 EXPECT_TRUE(request_key_frame);
stefan@webrtc.orgef144882013-05-07 19:16:33 +0000155}
156
157TEST_F(TestVCMReceiver, NonDecodableDuration_NoTrigger) {
158 // Enable NACK and with no RTT thresholds for disabling retransmission delay.
159 receiver_.SetNackMode(kNack, -1, -1);
160 const size_t kMaxNackListSize = 1000;
161 const int kMaxPacketAgeToNack = 1000;
162 const int kMaxNonDecodableDuration = 500;
philipel9d3ab612015-12-21 04:12:39 -0800163 const int kMaxNonDecodableDurationFrames =
164 (kDefaultFrameRate * kMaxNonDecodableDuration + 500) / 1000;
stefan@webrtc.orgef144882013-05-07 19:16:33 +0000165 const int kMinDelayMs = 500;
166 receiver_.SetNackSettings(kMaxNackListSize, kMaxPacketAgeToNack,
philipel9d3ab612015-12-21 04:12:39 -0800167 kMaxNonDecodableDuration);
stefan@webrtc.orgef144882013-05-07 19:16:33 +0000168 receiver_.SetMinReceiverDelay(kMinDelayMs);
169 int64_t key_frame_inserted = clock_->TimeInMilliseconds();
170 EXPECT_GE(InsertFrame(kVideoFrameKey, true), kNoError);
171 // Insert an incomplete frame.
172 EXPECT_GE(InsertFrame(kVideoFrameDelta, false), kNoError);
173 // Insert all but one frame to not trigger a key frame request due to
174 // too long duration of non-decodable frames.
philipel9d3ab612015-12-21 04:12:39 -0800175 for (int i = 0; i < kMaxNonDecodableDurationFrames - 1; ++i) {
stefan@webrtc.orgef144882013-05-07 19:16:33 +0000176 EXPECT_GE(InsertFrame(kVideoFrameDelta, true), kNoError);
177 }
178 // Advance time until it's time to decode the key frame.
179 clock_->AdvanceTimeMilliseconds(kMinDelayMs - clock_->TimeInMilliseconds() -
philipel9d3ab612015-12-21 04:12:39 -0800180 key_frame_inserted);
stefan@webrtc.orgef144882013-05-07 19:16:33 +0000181 EXPECT_TRUE(DecodeNextFrame());
182 // Make sure we don't get a key frame request since we haven't generated
183 // enough frames.
Wan-Teh Changb1825a42015-06-03 15:03:35 -0700184 bool request_key_frame = false;
185 std::vector<uint16_t> nack_list = receiver_.NackList(&request_key_frame);
186 EXPECT_FALSE(request_key_frame);
stefan@webrtc.orgef144882013-05-07 19:16:33 +0000187}
188
stefan@webrtc.org16734812013-05-14 12:00:47 +0000189TEST_F(TestVCMReceiver, NonDecodableDuration_NoTrigger2) {
190 // Enable NACK and with no RTT thresholds for disabling retransmission delay.
191 receiver_.SetNackMode(kNack, -1, -1);
192 const size_t kMaxNackListSize = 1000;
193 const int kMaxPacketAgeToNack = 1000;
194 const int kMaxNonDecodableDuration = 500;
philipel9d3ab612015-12-21 04:12:39 -0800195 const int kMaxNonDecodableDurationFrames =
196 (kDefaultFrameRate * kMaxNonDecodableDuration + 500) / 1000;
stefan@webrtc.org16734812013-05-14 12:00:47 +0000197 const int kMinDelayMs = 500;
198 receiver_.SetNackSettings(kMaxNackListSize, kMaxPacketAgeToNack,
philipel9d3ab612015-12-21 04:12:39 -0800199 kMaxNonDecodableDuration);
stefan@webrtc.org16734812013-05-14 12:00:47 +0000200 receiver_.SetMinReceiverDelay(kMinDelayMs);
201 int64_t key_frame_inserted = clock_->TimeInMilliseconds();
202 EXPECT_GE(InsertFrame(kVideoFrameKey, true), kNoError);
203 // Insert enough frames to have too long non-decodable sequence, except that
204 // we don't have any losses.
philipel9d3ab612015-12-21 04:12:39 -0800205 for (int i = 0; i < kMaxNonDecodableDurationFrames; ++i) {
stefan@webrtc.org16734812013-05-14 12:00:47 +0000206 EXPECT_GE(InsertFrame(kVideoFrameDelta, true), kNoError);
207 }
208 // Insert an incomplete frame.
209 EXPECT_GE(InsertFrame(kVideoFrameDelta, false), kNoError);
210 // Advance time until it's time to decode the key frame.
211 clock_->AdvanceTimeMilliseconds(kMinDelayMs - clock_->TimeInMilliseconds() -
philipel9d3ab612015-12-21 04:12:39 -0800212 key_frame_inserted);
stefan@webrtc.org16734812013-05-14 12:00:47 +0000213 EXPECT_TRUE(DecodeNextFrame());
214 // Make sure we don't get a key frame request since the non-decodable duration
215 // is only one frame.
Wan-Teh Changb1825a42015-06-03 15:03:35 -0700216 bool request_key_frame = false;
217 std::vector<uint16_t> nack_list = receiver_.NackList(&request_key_frame);
218 EXPECT_FALSE(request_key_frame);
stefan@webrtc.org16734812013-05-14 12:00:47 +0000219}
220
stefan@webrtc.orgef144882013-05-07 19:16:33 +0000221TEST_F(TestVCMReceiver, NonDecodableDuration_KeyFrameAfterIncompleteFrames) {
222 // Enable NACK and with no RTT thresholds for disabling retransmission delay.
223 receiver_.SetNackMode(kNack, -1, -1);
224 const size_t kMaxNackListSize = 1000;
225 const int kMaxPacketAgeToNack = 1000;
226 const int kMaxNonDecodableDuration = 500;
philipel9d3ab612015-12-21 04:12:39 -0800227 const int kMaxNonDecodableDurationFrames =
228 (kDefaultFrameRate * kMaxNonDecodableDuration + 500) / 1000;
stefan@webrtc.orgef144882013-05-07 19:16:33 +0000229 const int kMinDelayMs = 500;
230 receiver_.SetNackSettings(kMaxNackListSize, kMaxPacketAgeToNack,
philipel9d3ab612015-12-21 04:12:39 -0800231 kMaxNonDecodableDuration);
stefan@webrtc.orgef144882013-05-07 19:16:33 +0000232 receiver_.SetMinReceiverDelay(kMinDelayMs);
233 int64_t key_frame_inserted = clock_->TimeInMilliseconds();
234 EXPECT_GE(InsertFrame(kVideoFrameKey, true), kNoError);
235 // Insert an incomplete frame.
236 EXPECT_GE(InsertFrame(kVideoFrameDelta, false), kNoError);
237 // Insert enough frames to have too long non-decodable sequence.
philipel9d3ab612015-12-21 04:12:39 -0800238 for (int i = 0; i < kMaxNonDecodableDurationFrames; ++i) {
stefan@webrtc.orgef144882013-05-07 19:16:33 +0000239 EXPECT_GE(InsertFrame(kVideoFrameDelta, true), kNoError);
240 }
241 EXPECT_GE(InsertFrame(kVideoFrameKey, true), kNoError);
242 // Advance time until it's time to decode the key frame.
243 clock_->AdvanceTimeMilliseconds(kMinDelayMs - clock_->TimeInMilliseconds() -
philipel9d3ab612015-12-21 04:12:39 -0800244 key_frame_inserted);
stefan@webrtc.orgef144882013-05-07 19:16:33 +0000245 EXPECT_TRUE(DecodeNextFrame());
246 // Make sure we don't get a key frame request since we have a key frame
247 // in the list.
Wan-Teh Changb1825a42015-06-03 15:03:35 -0700248 bool request_key_frame = false;
249 std::vector<uint16_t> nack_list = receiver_.NackList(&request_key_frame);
250 EXPECT_FALSE(request_key_frame);
stefan@webrtc.orgef144882013-05-07 19:16:33 +0000251}
Qiang Chend4cec152015-06-19 09:17:00 -0700252
253// A simulated clock, when time elapses, will insert frames into the jitter
254// buffer, based on initial settings.
255class SimulatedClockWithFrames : public SimulatedClock {
256 public:
257 SimulatedClockWithFrames(StreamGenerator* stream_generator,
258 VCMReceiver* receiver)
259 : SimulatedClock(0),
260 stream_generator_(stream_generator),
261 receiver_(receiver) {}
262 virtual ~SimulatedClockWithFrames() {}
263
264 // If |stop_on_frame| is true and next frame arrives between now and
265 // now+|milliseconds|, the clock will be advanced to the arrival time of next
266 // frame.
267 // Otherwise, the clock will be advanced by |milliseconds|.
268 //
269 // For both cases, a frame will be inserted into the jitter buffer at the
270 // instant when the clock time is timestamps_.front().arrive_time.
271 //
272 // Return true if some frame arrives between now and now+|milliseconds|.
273 bool AdvanceTimeMilliseconds(int64_t milliseconds, bool stop_on_frame) {
274 return AdvanceTimeMicroseconds(milliseconds * 1000, stop_on_frame);
philipel9d3ab612015-12-21 04:12:39 -0800275 }
Qiang Chend4cec152015-06-19 09:17:00 -0700276
277 bool AdvanceTimeMicroseconds(int64_t microseconds, bool stop_on_frame) {
278 int64_t start_time = TimeInMicroseconds();
279 int64_t end_time = start_time + microseconds;
280 bool frame_injected = false;
281 while (!timestamps_.empty() &&
282 timestamps_.front().arrive_time <= end_time) {
henrikg91d6ede2015-09-17 00:24:34 -0700283 RTC_DCHECK(timestamps_.front().arrive_time >= start_time);
Qiang Chend4cec152015-06-19 09:17:00 -0700284
285 SimulatedClock::AdvanceTimeMicroseconds(timestamps_.front().arrive_time -
286 TimeInMicroseconds());
287 GenerateAndInsertFrame((timestamps_.front().render_time + 500) / 1000);
288 timestamps_.pop();
289 frame_injected = true;
290
291 if (stop_on_frame)
292 return frame_injected;
293 }
294
295 if (TimeInMicroseconds() < end_time) {
296 SimulatedClock::AdvanceTimeMicroseconds(end_time - TimeInMicroseconds());
297 }
298 return frame_injected;
philipel9d3ab612015-12-21 04:12:39 -0800299 }
Qiang Chend4cec152015-06-19 09:17:00 -0700300
301 // Input timestamps are in unit Milliseconds.
302 // And |arrive_timestamps| must be positive and in increasing order.
303 // |arrive_timestamps| determine when we are going to insert frames into the
304 // jitter buffer.
305 // |render_timestamps| are the timestamps on the frame.
306 void SetFrames(const int64_t* arrive_timestamps,
307 const int64_t* render_timestamps,
308 size_t size) {
309 int64_t previous_arrive_timestamp = 0;
310 for (size_t i = 0; i < size; i++) {
henrikg91d6ede2015-09-17 00:24:34 -0700311 RTC_CHECK(arrive_timestamps[i] >= previous_arrive_timestamp);
Qiang Chend4cec152015-06-19 09:17:00 -0700312 timestamps_.push(TimestampPair(arrive_timestamps[i] * 1000,
313 render_timestamps[i] * 1000));
314 previous_arrive_timestamp = arrive_timestamps[i];
315 }
316 }
317
318 private:
319 struct TimestampPair {
320 TimestampPair(int64_t arrive_timestamp, int64_t render_timestamp)
321 : arrive_time(arrive_timestamp), render_time(render_timestamp) {}
322
323 int64_t arrive_time;
324 int64_t render_time;
325 };
326
327 void GenerateAndInsertFrame(int64_t render_timestamp_ms) {
328 VCMPacket packet;
329 stream_generator_->GenerateFrame(FrameType::kVideoFrameKey,
330 1, // media packets
331 0, // empty packets
332 render_timestamp_ms);
333
334 bool packet_available = stream_generator_->PopPacket(&packet, 0);
335 EXPECT_TRUE(packet_available);
336 if (!packet_available)
337 return; // Return here to avoid crashes below.
Johan Ahlers95348f72016-06-28 11:11:28 +0200338 receiver_->InsertPacket(packet);
Qiang Chend4cec152015-06-19 09:17:00 -0700339 }
340
341 std::queue<TimestampPair> timestamps_;
342 StreamGenerator* stream_generator_;
343 VCMReceiver* receiver_;
344};
345
346// Use a SimulatedClockWithFrames
347// Wait call will do either of these:
348// 1. If |stop_on_frame| is true, the clock will be turned to the exact instant
349// that the first frame comes and the frame will be inserted into the jitter
350// buffer, or the clock will be turned to now + |max_time| if no frame comes in
351// the window.
352// 2. If |stop_on_frame| is false, the clock will be turn to now + |max_time|,
353// and all the frames arriving between now and now + |max_time| will be
354// inserted into the jitter buffer.
355//
356// This is used to simulate the JitterBuffer getting packets from internet as
357// time elapses.
358
359class FrameInjectEvent : public EventWrapper {
360 public:
361 FrameInjectEvent(SimulatedClockWithFrames* clock, bool stop_on_frame)
362 : clock_(clock), stop_on_frame_(stop_on_frame) {}
363
364 bool Set() override { return true; }
365
philipel9d3ab612015-12-21 04:12:39 -0800366 EventTypeWrapper Wait(unsigned long max_time) override { // NOLINT
Qiang Chend4cec152015-06-19 09:17:00 -0700367 if (clock_->AdvanceTimeMilliseconds(max_time, stop_on_frame_) &&
368 stop_on_frame_) {
369 return EventTypeWrapper::kEventSignaled;
370 } else {
371 return EventTypeWrapper::kEventTimeout;
372 }
373 }
374
375 private:
376 SimulatedClockWithFrames* clock_;
377 bool stop_on_frame_;
378};
379
380class VCMReceiverTimingTest : public ::testing::Test {
381 protected:
Qiang Chend4cec152015-06-19 09:17:00 -0700382 VCMReceiverTimingTest()
383
384 : clock_(&stream_generator_, &receiver_),
385 stream_generator_(0, clock_.TimeInMilliseconds()),
386 timing_(&clock_),
387 receiver_(
388 &timing_,
389 &clock_,
kwiberg3f55dea2016-02-29 05:51:59 -0800390 std::unique_ptr<EventWrapper>(new FrameInjectEvent(&clock_, false)),
391 std::unique_ptr<EventWrapper>(
Qiang Chend4cec152015-06-19 09:17:00 -0700392 new FrameInjectEvent(&clock_, true))) {}
393
Qiang Chend4cec152015-06-19 09:17:00 -0700394 virtual void SetUp() { receiver_.Reset(); }
395
396 SimulatedClockWithFrames clock_;
397 StreamGenerator stream_generator_;
398 VCMTiming timing_;
399 VCMReceiver receiver_;
400};
401
402// Test whether VCMReceiver::FrameForDecoding handles parameter
403// |max_wait_time_ms| correctly:
404// 1. The function execution should never take more than |max_wait_time_ms|.
405// 2. If the function exit before now + |max_wait_time_ms|, a frame must be
406// returned.
407TEST_F(VCMReceiverTimingTest, FrameForDecoding) {
408 const size_t kNumFrames = 100;
409 const int kFramePeriod = 40;
410 int64_t arrive_timestamps[kNumFrames];
411 int64_t render_timestamps[kNumFrames];
412 int64_t next_render_time;
413
414 // Construct test samples.
415 // render_timestamps are the timestamps stored in the Frame;
416 // arrive_timestamps controls when the Frame packet got received.
417 for (size_t i = 0; i < kNumFrames; i++) {
418 // Preset frame rate to 25Hz.
419 // But we add a reasonable deviation to arrive_timestamps to mimic Internet
420 // fluctuation.
421 arrive_timestamps[i] =
422 (i + 1) * kFramePeriod + (i % 10) * ((i % 2) ? 1 : -1);
423 render_timestamps[i] = (i + 1) * kFramePeriod;
424 }
425
426 clock_.SetFrames(arrive_timestamps, render_timestamps, kNumFrames);
427
428 // Record how many frames we finally get out of the receiver.
429 size_t num_frames_return = 0;
430
431 const int64_t kMaxWaitTime = 30;
432
433 // Ideally, we should get all frames that we input in InitializeFrames.
434 // In the case that FrameForDecoding kills frames by error, we rely on the
435 // build bot to kill the test.
436 while (num_frames_return < kNumFrames) {
437 int64_t start_time = clock_.TimeInMilliseconds();
438 VCMEncodedFrame* frame =
philipel9d3ab612015-12-21 04:12:39 -0800439 receiver_.FrameForDecoding(kMaxWaitTime, &next_render_time, false);
Qiang Chend4cec152015-06-19 09:17:00 -0700440 int64_t end_time = clock_.TimeInMilliseconds();
441
442 // In any case the FrameForDecoding should not wait longer than
443 // max_wait_time.
444 // In the case that we did not get a frame, it should have been waiting for
445 // exactly max_wait_time. (By the testing samples we constructed above, we
446 // are sure there is no timing error, so the only case it returns with NULL
447 // is that it runs out of time.)
448 if (frame) {
449 receiver_.ReleaseFrame(frame);
450 ++num_frames_return;
451 EXPECT_GE(kMaxWaitTime, end_time - start_time);
452 } else {
453 EXPECT_EQ(kMaxWaitTime, end_time - start_time);
454 }
455 }
456}
457
perkj796cfaf2015-12-10 09:27:38 -0800458// Test whether VCMReceiver::FrameForDecoding handles parameter
459// |prefer_late_decoding| and |max_wait_time_ms| correctly:
460// 1. The function execution should never take more than |max_wait_time_ms|.
461// 2. If the function exit before now + |max_wait_time_ms|, a frame must be
462// returned and the end time must be equal to the render timestamp - delay
463// for decoding and rendering.
464TEST_F(VCMReceiverTimingTest, FrameForDecodingPreferLateDecoding) {
465 const size_t kNumFrames = 100;
466 const int kFramePeriod = 40;
467
468 int64_t arrive_timestamps[kNumFrames];
469 int64_t render_timestamps[kNumFrames];
470 int64_t next_render_time;
471
472 int render_delay_ms;
473 int max_decode_ms;
474 int dummy;
475 timing_.GetTimings(&dummy, &max_decode_ms, &dummy, &dummy, &dummy, &dummy,
476 &render_delay_ms);
477
478 // Construct test samples.
479 // render_timestamps are the timestamps stored in the Frame;
480 // arrive_timestamps controls when the Frame packet got received.
481 for (size_t i = 0; i < kNumFrames; i++) {
482 // Preset frame rate to 25Hz.
483 // But we add a reasonable deviation to arrive_timestamps to mimic Internet
484 // fluctuation.
485 arrive_timestamps[i] =
486 (i + 1) * kFramePeriod + (i % 10) * ((i % 2) ? 1 : -1);
487 render_timestamps[i] = (i + 1) * kFramePeriod;
488 }
489
490 clock_.SetFrames(arrive_timestamps, render_timestamps, kNumFrames);
491
492 // Record how many frames we finally get out of the receiver.
493 size_t num_frames_return = 0;
494 const int64_t kMaxWaitTime = 30;
495 bool prefer_late_decoding = true;
496 while (num_frames_return < kNumFrames) {
497 int64_t start_time = clock_.TimeInMilliseconds();
498
philipel9d3ab612015-12-21 04:12:39 -0800499 VCMEncodedFrame* frame = receiver_.FrameForDecoding(
500 kMaxWaitTime, &next_render_time, prefer_late_decoding);
perkj796cfaf2015-12-10 09:27:38 -0800501 int64_t end_time = clock_.TimeInMilliseconds();
502 if (frame) {
503 EXPECT_EQ(frame->RenderTimeMs() - max_decode_ms - render_delay_ms,
504 end_time);
505 receiver_.ReleaseFrame(frame);
506 ++num_frames_return;
507 } else {
508 EXPECT_EQ(kMaxWaitTime, end_time - start_time);
509 }
510 }
511}
512
mikhal@webrtc.org381da4b2013-04-25 21:45:29 +0000513} // namespace webrtc