blob: 82345c8d59a54b52bd9676cadf8625af84a08f0f [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>
Qiang Chend4cec152015-06-19 09:17:00 -070013#include <queue>
mikhal@webrtc.org381da4b2013-04-25 21:45:29 +000014
15#include "testing/gtest/include/gtest/gtest.h"
Qiang Chend4cec152015-06-19 09:17:00 -070016#include "webrtc/base/checks.h"
Henrik Kjellander2557b862015-11-18 22:00:21 +010017#include "webrtc/modules/video_coding/packet.h"
18#include "webrtc/modules/video_coding/receiver.h"
19#include "webrtc/modules/video_coding/test/stream_generator.h"
20#include "webrtc/modules/video_coding/timing.h"
21#include "webrtc/modules/video_coding/test/test_util.h"
Henrik Kjellander98f53512015-10-28 18:17:40 +010022#include "webrtc/system_wrappers/include/clock.h"
23#include "webrtc/system_wrappers/include/critical_section_wrapper.h"
mikhal@webrtc.org381da4b2013-04-25 21:45:29 +000024
25namespace webrtc {
26
27class TestVCMReceiver : public ::testing::Test {
28 protected:
mikhal@webrtc.org381da4b2013-04-25 21:45:29 +000029 enum { kWidth = 640 };
30 enum { kHeight = 480 };
31
32 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_) {
Qiang Chend4cec152015-06-19 09:17:00 -070036
37 stream_generator_.reset(new
38 StreamGenerator(0, clock_->TimeInMilliseconds()));
mikhal@webrtc.org381da4b2013-04-25 21:45:29 +000039 }
40
41 virtual void SetUp() {
42 receiver_.Reset();
43 }
44
45 int32_t InsertPacket(int index) {
46 VCMPacket packet;
mikhal@webrtc.org381da4b2013-04-25 21:45:29 +000047 bool packet_available = stream_generator_->GetPacket(&packet, index);
48 EXPECT_TRUE(packet_available);
49 if (!packet_available)
stefan@webrtc.org3417eb42013-05-21 15:25:53 +000050 return kGeneralError; // Return here to avoid crashes below.
Wan-Teh Chang92d94892015-05-28 13:36:06 -070051 return receiver_.InsertPacket(packet, kWidth, kHeight);
mikhal@webrtc.org381da4b2013-04-25 21:45:29 +000052 }
53
54 int32_t InsertPacketAndPop(int index) {
55 VCMPacket packet;
mikhal@webrtc.org381da4b2013-04-25 21:45:29 +000056 bool packet_available = stream_generator_->PopPacket(&packet, index);
57 EXPECT_TRUE(packet_available);
58 if (!packet_available)
stefan@webrtc.org3417eb42013-05-21 15:25:53 +000059 return kGeneralError; // Return here to avoid crashes below.
mikhal@webrtc.org381da4b2013-04-25 21:45:29 +000060 return receiver_.InsertPacket(packet, kWidth, kHeight);
61 }
62
63 int32_t InsertFrame(FrameType frame_type, bool complete) {
64 int num_of_packets = complete ? 1 : 2;
65 stream_generator_->GenerateFrame(
pbos22993e12015-10-19 02:39:06 -070066 frame_type, (frame_type != kEmptyFrame) ? num_of_packets : 0,
67 (frame_type == kEmptyFrame) ? 1 : 0, clock_->TimeInMilliseconds());
mikhal@webrtc.org381da4b2013-04-25 21:45:29 +000068 int32_t ret = InsertPacketAndPop(0);
stefan@webrtc.orgef144882013-05-07 19:16:33 +000069 if (!complete) {
70 // Drop the second packet.
71 VCMPacket packet;
72 stream_generator_->PopPacket(&packet, 0);
73 }
mikhal@webrtc.org381da4b2013-04-25 21:45:29 +000074 clock_->AdvanceTimeMilliseconds(kDefaultFramePeriodMs);
75 return ret;
76 }
77
stefan@webrtc.orgef144882013-05-07 19:16:33 +000078 bool DecodeNextFrame() {
79 int64_t render_time_ms = 0;
pbos@webrtc.org4f16c872014-11-24 09:06:48 +000080 VCMEncodedFrame* frame =
81 receiver_.FrameForDecoding(0, render_time_ms, false);
stefan@webrtc.orgef144882013-05-07 19:16:33 +000082 if (!frame)
83 return false;
84 receiver_.ReleaseFrame(frame);
85 return true;
86 }
87
kwiberg@webrtc.org00b8f6b2015-02-26 14:34:55 +000088 rtc::scoped_ptr<SimulatedClock> clock_;
mikhal@webrtc.org381da4b2013-04-25 21:45:29 +000089 VCMTiming timing_;
90 NullEventFactory event_factory_;
91 VCMReceiver receiver_;
kwiberg@webrtc.org00b8f6b2015-02-26 14:34:55 +000092 rtc::scoped_ptr<StreamGenerator> stream_generator_;
mikhal@webrtc.org381da4b2013-04-25 21:45:29 +000093};
94
95TEST_F(TestVCMReceiver, RenderBufferSize_AllComplete) {
96 EXPECT_EQ(0, receiver_.RenderBufferSizeMs());
97 EXPECT_GE(InsertFrame(kVideoFrameKey, true), kNoError);
stefan@webrtc.orgef144882013-05-07 19:16:33 +000098 int num_of_frames = 10;
99 for (int i = 0; i < num_of_frames; ++i) {
mikhal@webrtc.org381da4b2013-04-25 21:45:29 +0000100 EXPECT_GE(InsertFrame(kVideoFrameDelta, true), kNoError);
101 }
stefan@webrtc.orgef144882013-05-07 19:16:33 +0000102 EXPECT_EQ(num_of_frames * kDefaultFramePeriodMs,
pbos@webrtc.org3004c792013-05-07 12:36:21 +0000103 receiver_.RenderBufferSizeMs());
mikhal@webrtc.org381da4b2013-04-25 21:45:29 +0000104}
105
stefan@webrtc.orgef144882013-05-07 19:16:33 +0000106TEST_F(TestVCMReceiver, RenderBufferSize_SkipToKeyFrame) {
107 EXPECT_EQ(0, receiver_.RenderBufferSizeMs());
108 const int kNumOfNonDecodableFrames = 2;
109 for (int i = 0; i < kNumOfNonDecodableFrames; ++i) {
110 EXPECT_GE(InsertFrame(kVideoFrameDelta, true), kNoError);
111 }
112 const int kNumOfFrames = 10;
113 EXPECT_GE(InsertFrame(kVideoFrameKey, true), kNoError);
114 for (int i = 0; i < kNumOfFrames - 1; ++i) {
115 EXPECT_GE(InsertFrame(kVideoFrameDelta, true), kNoError);
116 }
117 EXPECT_EQ((kNumOfFrames - 1) * kDefaultFramePeriodMs,
118 receiver_.RenderBufferSizeMs());
119}
120
mikhal@webrtc.org381da4b2013-04-25 21:45:29 +0000121TEST_F(TestVCMReceiver, RenderBufferSize_NotAllComplete) {
122 EXPECT_EQ(0, receiver_.RenderBufferSizeMs());
123 EXPECT_GE(InsertFrame(kVideoFrameKey, true), kNoError);
stefan@webrtc.orgef144882013-05-07 19:16:33 +0000124 int num_of_frames = 10;
125 for (int i = 0; i < num_of_frames; ++i) {
mikhal@webrtc.org381da4b2013-04-25 21:45:29 +0000126 EXPECT_GE(InsertFrame(kVideoFrameDelta, true), kNoError);
127 }
stefan@webrtc.org4ce19b12013-05-06 13:16:51 +0000128 num_of_frames++;
mikhal@webrtc.org381da4b2013-04-25 21:45:29 +0000129 EXPECT_GE(InsertFrame(kVideoFrameDelta, false), kNoError);
stefan@webrtc.orgef144882013-05-07 19:16:33 +0000130 for (int i = 0; i < num_of_frames; ++i) {
mikhal@webrtc.org381da4b2013-04-25 21:45:29 +0000131 EXPECT_GE(InsertFrame(kVideoFrameDelta, true), kNoError);
132 }
stefan@webrtc.orgef144882013-05-07 19:16:33 +0000133 EXPECT_EQ((num_of_frames - 1) * kDefaultFramePeriodMs,
134 receiver_.RenderBufferSizeMs());
mikhal@webrtc.org381da4b2013-04-25 21:45:29 +0000135}
136
137TEST_F(TestVCMReceiver, RenderBufferSize_NoKeyFrame) {
138 EXPECT_EQ(0, receiver_.RenderBufferSizeMs());
139 int num_of_frames = 10;
140 for (int i = 0; i < num_of_frames; ++i) {
141 EXPECT_GE(InsertFrame(kVideoFrameDelta, true), kNoError);
142 }
mikhal@webrtc.org759b0412013-05-07 16:36:00 +0000143 int64_t next_render_time_ms = 0;
144 VCMEncodedFrame* frame = receiver_.FrameForDecoding(10, next_render_time_ms);
145 EXPECT_TRUE(frame == NULL);
146 receiver_.ReleaseFrame(frame);
mikhal@webrtc.org381da4b2013-04-25 21:45:29 +0000147 EXPECT_GE(InsertFrame(kVideoFrameDelta, false), kNoError);
148 for (int i = 0; i < num_of_frames; ++i) {
149 EXPECT_GE(InsertFrame(kVideoFrameDelta, true), kNoError);
150 }
151 EXPECT_EQ(0, receiver_.RenderBufferSizeMs());
152}
153
stefan@webrtc.orgef144882013-05-07 19:16:33 +0000154TEST_F(TestVCMReceiver, NonDecodableDuration_Empty) {
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;
160 const int kMinDelayMs = 500;
161 receiver_.SetNackSettings(kMaxNackListSize, kMaxPacketAgeToNack,
162 kMaxNonDecodableDuration);
163 EXPECT_GE(InsertFrame(kVideoFrameKey, true), kNoError);
164 // Advance time until it's time to decode the key frame.
165 clock_->AdvanceTimeMilliseconds(kMinDelayMs);
166 EXPECT_TRUE(DecodeNextFrame());
Wan-Teh Changb1825a42015-06-03 15:03:35 -0700167 bool request_key_frame = false;
168 std::vector<uint16_t> nack_list = receiver_.NackList(&request_key_frame);
169 EXPECT_FALSE(request_key_frame);
stefan@webrtc.orgef144882013-05-07 19:16:33 +0000170}
171
172TEST_F(TestVCMReceiver, NonDecodableDuration_NoKeyFrame) {
173 // Enable NACK and with no RTT thresholds for disabling retransmission delay.
174 receiver_.SetNackMode(kNack, -1, -1);
175 const size_t kMaxNackListSize = 1000;
176 const int kMaxPacketAgeToNack = 1000;
177 const int kMaxNonDecodableDuration = 500;
178 receiver_.SetNackSettings(kMaxNackListSize, kMaxPacketAgeToNack,
179 kMaxNonDecodableDuration);
180 const int kNumFrames = kDefaultFrameRate * kMaxNonDecodableDuration / 1000;
181 for (int i = 0; i < kNumFrames; ++i) {
182 EXPECT_GE(InsertFrame(kVideoFrameDelta, true), kNoError);
183 }
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_TRUE(request_key_frame);
stefan@webrtc.orgef144882013-05-07 19:16:33 +0000187}
188
189TEST_F(TestVCMReceiver, NonDecodableDuration_OneIncomplete) {
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;
195 const int kMaxNonDecodableDurationFrames = (kDefaultFrameRate *
196 kMaxNonDecodableDuration + 500) / 1000;
197 const int kMinDelayMs = 500;
198 receiver_.SetNackSettings(kMaxNackListSize, kMaxPacketAgeToNack,
199 kMaxNonDecodableDuration);
200 receiver_.SetMinReceiverDelay(kMinDelayMs);
201 int64_t key_frame_inserted = clock_->TimeInMilliseconds();
202 EXPECT_GE(InsertFrame(kVideoFrameKey, true), kNoError);
203 // Insert an incomplete frame.
204 EXPECT_GE(InsertFrame(kVideoFrameDelta, false), kNoError);
205 // Insert enough frames to have too long non-decodable sequence.
206 for (int i = 0; i < kMaxNonDecodableDurationFrames;
207 ++i) {
208 EXPECT_GE(InsertFrame(kVideoFrameDelta, true), kNoError);
209 }
210 // Advance time until it's time to decode the key frame.
211 clock_->AdvanceTimeMilliseconds(kMinDelayMs - clock_->TimeInMilliseconds() -
212 key_frame_inserted);
213 EXPECT_TRUE(DecodeNextFrame());
214 // Make sure we get a key frame request.
Wan-Teh Changb1825a42015-06-03 15:03:35 -0700215 bool request_key_frame = false;
216 std::vector<uint16_t> nack_list = receiver_.NackList(&request_key_frame);
217 EXPECT_TRUE(request_key_frame);
stefan@webrtc.orgef144882013-05-07 19:16:33 +0000218}
219
220TEST_F(TestVCMReceiver, NonDecodableDuration_NoTrigger) {
221 // Enable NACK and with no RTT thresholds for disabling retransmission delay.
222 receiver_.SetNackMode(kNack, -1, -1);
223 const size_t kMaxNackListSize = 1000;
224 const int kMaxPacketAgeToNack = 1000;
225 const int kMaxNonDecodableDuration = 500;
226 const int kMaxNonDecodableDurationFrames = (kDefaultFrameRate *
227 kMaxNonDecodableDuration + 500) / 1000;
228 const int kMinDelayMs = 500;
229 receiver_.SetNackSettings(kMaxNackListSize, kMaxPacketAgeToNack,
230 kMaxNonDecodableDuration);
231 receiver_.SetMinReceiverDelay(kMinDelayMs);
232 int64_t key_frame_inserted = clock_->TimeInMilliseconds();
233 EXPECT_GE(InsertFrame(kVideoFrameKey, true), kNoError);
234 // Insert an incomplete frame.
235 EXPECT_GE(InsertFrame(kVideoFrameDelta, false), kNoError);
236 // Insert all but one frame to not trigger a key frame request due to
237 // too long duration of non-decodable frames.
238 for (int i = 0; i < kMaxNonDecodableDurationFrames - 1;
239 ++i) {
240 EXPECT_GE(InsertFrame(kVideoFrameDelta, true), kNoError);
241 }
242 // Advance time until it's time to decode the key frame.
243 clock_->AdvanceTimeMilliseconds(kMinDelayMs - clock_->TimeInMilliseconds() -
244 key_frame_inserted);
245 EXPECT_TRUE(DecodeNextFrame());
246 // Make sure we don't get a key frame request since we haven't generated
247 // enough frames.
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}
252
stefan@webrtc.org16734812013-05-14 12:00:47 +0000253TEST_F(TestVCMReceiver, NonDecodableDuration_NoTrigger2) {
254 // Enable NACK and with no RTT thresholds for disabling retransmission delay.
255 receiver_.SetNackMode(kNack, -1, -1);
256 const size_t kMaxNackListSize = 1000;
257 const int kMaxPacketAgeToNack = 1000;
258 const int kMaxNonDecodableDuration = 500;
259 const int kMaxNonDecodableDurationFrames = (kDefaultFrameRate *
260 kMaxNonDecodableDuration + 500) / 1000;
261 const int kMinDelayMs = 500;
262 receiver_.SetNackSettings(kMaxNackListSize, kMaxPacketAgeToNack,
263 kMaxNonDecodableDuration);
264 receiver_.SetMinReceiverDelay(kMinDelayMs);
265 int64_t key_frame_inserted = clock_->TimeInMilliseconds();
266 EXPECT_GE(InsertFrame(kVideoFrameKey, true), kNoError);
267 // Insert enough frames to have too long non-decodable sequence, except that
268 // we don't have any losses.
269 for (int i = 0; i < kMaxNonDecodableDurationFrames;
270 ++i) {
271 EXPECT_GE(InsertFrame(kVideoFrameDelta, true), kNoError);
272 }
273 // Insert an incomplete frame.
274 EXPECT_GE(InsertFrame(kVideoFrameDelta, false), kNoError);
275 // Advance time until it's time to decode the key frame.
276 clock_->AdvanceTimeMilliseconds(kMinDelayMs - clock_->TimeInMilliseconds() -
277 key_frame_inserted);
278 EXPECT_TRUE(DecodeNextFrame());
279 // Make sure we don't get a key frame request since the non-decodable duration
280 // is only one frame.
Wan-Teh Changb1825a42015-06-03 15:03:35 -0700281 bool request_key_frame = false;
282 std::vector<uint16_t> nack_list = receiver_.NackList(&request_key_frame);
283 EXPECT_FALSE(request_key_frame);
stefan@webrtc.org16734812013-05-14 12:00:47 +0000284}
285
stefan@webrtc.orgef144882013-05-07 19:16:33 +0000286TEST_F(TestVCMReceiver, NonDecodableDuration_KeyFrameAfterIncompleteFrames) {
287 // Enable NACK and with no RTT thresholds for disabling retransmission delay.
288 receiver_.SetNackMode(kNack, -1, -1);
289 const size_t kMaxNackListSize = 1000;
290 const int kMaxPacketAgeToNack = 1000;
291 const int kMaxNonDecodableDuration = 500;
292 const int kMaxNonDecodableDurationFrames = (kDefaultFrameRate *
293 kMaxNonDecodableDuration + 500) / 1000;
294 const int kMinDelayMs = 500;
295 receiver_.SetNackSettings(kMaxNackListSize, kMaxPacketAgeToNack,
296 kMaxNonDecodableDuration);
297 receiver_.SetMinReceiverDelay(kMinDelayMs);
298 int64_t key_frame_inserted = clock_->TimeInMilliseconds();
299 EXPECT_GE(InsertFrame(kVideoFrameKey, true), kNoError);
300 // Insert an incomplete frame.
301 EXPECT_GE(InsertFrame(kVideoFrameDelta, false), kNoError);
302 // Insert enough frames to have too long non-decodable sequence.
303 for (int i = 0; i < kMaxNonDecodableDurationFrames;
304 ++i) {
305 EXPECT_GE(InsertFrame(kVideoFrameDelta, true), kNoError);
306 }
307 EXPECT_GE(InsertFrame(kVideoFrameKey, true), kNoError);
308 // Advance time until it's time to decode the key frame.
309 clock_->AdvanceTimeMilliseconds(kMinDelayMs - clock_->TimeInMilliseconds() -
310 key_frame_inserted);
311 EXPECT_TRUE(DecodeNextFrame());
312 // Make sure we don't get a key frame request since we have a key frame
313 // in the list.
Wan-Teh Changb1825a42015-06-03 15:03:35 -0700314 bool request_key_frame = false;
315 std::vector<uint16_t> nack_list = receiver_.NackList(&request_key_frame);
316 EXPECT_FALSE(request_key_frame);
stefan@webrtc.orgef144882013-05-07 19:16:33 +0000317}
Qiang Chend4cec152015-06-19 09:17:00 -0700318
319// A simulated clock, when time elapses, will insert frames into the jitter
320// buffer, based on initial settings.
321class SimulatedClockWithFrames : public SimulatedClock {
322 public:
323 SimulatedClockWithFrames(StreamGenerator* stream_generator,
324 VCMReceiver* receiver)
325 : SimulatedClock(0),
326 stream_generator_(stream_generator),
327 receiver_(receiver) {}
328 virtual ~SimulatedClockWithFrames() {}
329
330 // If |stop_on_frame| is true and next frame arrives between now and
331 // now+|milliseconds|, the clock will be advanced to the arrival time of next
332 // frame.
333 // Otherwise, the clock will be advanced by |milliseconds|.
334 //
335 // For both cases, a frame will be inserted into the jitter buffer at the
336 // instant when the clock time is timestamps_.front().arrive_time.
337 //
338 // Return true if some frame arrives between now and now+|milliseconds|.
339 bool AdvanceTimeMilliseconds(int64_t milliseconds, bool stop_on_frame) {
340 return AdvanceTimeMicroseconds(milliseconds * 1000, stop_on_frame);
341 };
342
343 bool AdvanceTimeMicroseconds(int64_t microseconds, bool stop_on_frame) {
344 int64_t start_time = TimeInMicroseconds();
345 int64_t end_time = start_time + microseconds;
346 bool frame_injected = false;
347 while (!timestamps_.empty() &&
348 timestamps_.front().arrive_time <= end_time) {
henrikg91d6ede2015-09-17 00:24:34 -0700349 RTC_DCHECK(timestamps_.front().arrive_time >= start_time);
Qiang Chend4cec152015-06-19 09:17:00 -0700350
351 SimulatedClock::AdvanceTimeMicroseconds(timestamps_.front().arrive_time -
352 TimeInMicroseconds());
353 GenerateAndInsertFrame((timestamps_.front().render_time + 500) / 1000);
354 timestamps_.pop();
355 frame_injected = true;
356
357 if (stop_on_frame)
358 return frame_injected;
359 }
360
361 if (TimeInMicroseconds() < end_time) {
362 SimulatedClock::AdvanceTimeMicroseconds(end_time - TimeInMicroseconds());
363 }
364 return frame_injected;
365 };
366
367 // Input timestamps are in unit Milliseconds.
368 // And |arrive_timestamps| must be positive and in increasing order.
369 // |arrive_timestamps| determine when we are going to insert frames into the
370 // jitter buffer.
371 // |render_timestamps| are the timestamps on the frame.
372 void SetFrames(const int64_t* arrive_timestamps,
373 const int64_t* render_timestamps,
374 size_t size) {
375 int64_t previous_arrive_timestamp = 0;
376 for (size_t i = 0; i < size; i++) {
henrikg91d6ede2015-09-17 00:24:34 -0700377 RTC_CHECK(arrive_timestamps[i] >= previous_arrive_timestamp);
Qiang Chend4cec152015-06-19 09:17:00 -0700378 timestamps_.push(TimestampPair(arrive_timestamps[i] * 1000,
379 render_timestamps[i] * 1000));
380 previous_arrive_timestamp = arrive_timestamps[i];
381 }
382 }
383
384 private:
385 struct TimestampPair {
386 TimestampPair(int64_t arrive_timestamp, int64_t render_timestamp)
387 : arrive_time(arrive_timestamp), render_time(render_timestamp) {}
388
389 int64_t arrive_time;
390 int64_t render_time;
391 };
392
393 void GenerateAndInsertFrame(int64_t render_timestamp_ms) {
394 VCMPacket packet;
395 stream_generator_->GenerateFrame(FrameType::kVideoFrameKey,
396 1, // media packets
397 0, // empty packets
398 render_timestamp_ms);
399
400 bool packet_available = stream_generator_->PopPacket(&packet, 0);
401 EXPECT_TRUE(packet_available);
402 if (!packet_available)
403 return; // Return here to avoid crashes below.
404 receiver_->InsertPacket(packet, 640, 480);
405 }
406
407 std::queue<TimestampPair> timestamps_;
408 StreamGenerator* stream_generator_;
409 VCMReceiver* receiver_;
410};
411
412// Use a SimulatedClockWithFrames
413// Wait call will do either of these:
414// 1. If |stop_on_frame| is true, the clock will be turned to the exact instant
415// that the first frame comes and the frame will be inserted into the jitter
416// buffer, or the clock will be turned to now + |max_time| if no frame comes in
417// the window.
418// 2. If |stop_on_frame| is false, the clock will be turn to now + |max_time|,
419// and all the frames arriving between now and now + |max_time| will be
420// inserted into the jitter buffer.
421//
422// This is used to simulate the JitterBuffer getting packets from internet as
423// time elapses.
424
425class FrameInjectEvent : public EventWrapper {
426 public:
427 FrameInjectEvent(SimulatedClockWithFrames* clock, bool stop_on_frame)
428 : clock_(clock), stop_on_frame_(stop_on_frame) {}
429
430 bool Set() override { return true; }
431
432 EventTypeWrapper Wait(unsigned long max_time) override {
433 if (clock_->AdvanceTimeMilliseconds(max_time, stop_on_frame_) &&
434 stop_on_frame_) {
435 return EventTypeWrapper::kEventSignaled;
436 } else {
437 return EventTypeWrapper::kEventTimeout;
438 }
439 }
440
441 private:
442 SimulatedClockWithFrames* clock_;
443 bool stop_on_frame_;
444};
445
446class VCMReceiverTimingTest : public ::testing::Test {
447 protected:
448
449 VCMReceiverTimingTest()
450
451 : clock_(&stream_generator_, &receiver_),
452 stream_generator_(0, clock_.TimeInMilliseconds()),
453 timing_(&clock_),
454 receiver_(
455 &timing_,
456 &clock_,
457 rtc::scoped_ptr<EventWrapper>(new FrameInjectEvent(&clock_, false)),
458 rtc::scoped_ptr<EventWrapper>(
459 new FrameInjectEvent(&clock_, true))) {}
460
461
462 virtual void SetUp() { receiver_.Reset(); }
463
464 SimulatedClockWithFrames clock_;
465 StreamGenerator stream_generator_;
466 VCMTiming timing_;
467 VCMReceiver receiver_;
468};
469
470// Test whether VCMReceiver::FrameForDecoding handles parameter
471// |max_wait_time_ms| correctly:
472// 1. The function execution should never take more than |max_wait_time_ms|.
473// 2. If the function exit before now + |max_wait_time_ms|, a frame must be
474// returned.
475TEST_F(VCMReceiverTimingTest, FrameForDecoding) {
476 const size_t kNumFrames = 100;
477 const int kFramePeriod = 40;
478 int64_t arrive_timestamps[kNumFrames];
479 int64_t render_timestamps[kNumFrames];
480 int64_t next_render_time;
481
482 // Construct test samples.
483 // render_timestamps are the timestamps stored in the Frame;
484 // arrive_timestamps controls when the Frame packet got received.
485 for (size_t i = 0; i < kNumFrames; i++) {
486 // Preset frame rate to 25Hz.
487 // But we add a reasonable deviation to arrive_timestamps to mimic Internet
488 // fluctuation.
489 arrive_timestamps[i] =
490 (i + 1) * kFramePeriod + (i % 10) * ((i % 2) ? 1 : -1);
491 render_timestamps[i] = (i + 1) * kFramePeriod;
492 }
493
494 clock_.SetFrames(arrive_timestamps, render_timestamps, kNumFrames);
495
496 // Record how many frames we finally get out of the receiver.
497 size_t num_frames_return = 0;
498
499 const int64_t kMaxWaitTime = 30;
500
501 // Ideally, we should get all frames that we input in InitializeFrames.
502 // In the case that FrameForDecoding kills frames by error, we rely on the
503 // build bot to kill the test.
504 while (num_frames_return < kNumFrames) {
505 int64_t start_time = clock_.TimeInMilliseconds();
506 VCMEncodedFrame* frame =
507 receiver_.FrameForDecoding(kMaxWaitTime, next_render_time, false);
508 int64_t end_time = clock_.TimeInMilliseconds();
509
510 // In any case the FrameForDecoding should not wait longer than
511 // max_wait_time.
512 // In the case that we did not get a frame, it should have been waiting for
513 // exactly max_wait_time. (By the testing samples we constructed above, we
514 // are sure there is no timing error, so the only case it returns with NULL
515 // is that it runs out of time.)
516 if (frame) {
517 receiver_.ReleaseFrame(frame);
518 ++num_frames_return;
519 EXPECT_GE(kMaxWaitTime, end_time - start_time);
520 } else {
521 EXPECT_EQ(kMaxWaitTime, end_time - start_time);
522 }
523 }
524}
525
mikhal@webrtc.org381da4b2013-04-25 21:45:29 +0000526} // namespace webrtc