blob: d51b004a9bb3c8a4d2de0d1a66fb9bce05531d2a [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"
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"
21#include "webrtc/modules/video_coding/timing.h"
22#include "webrtc/modules/video_coding/test/test_util.h"
Henrik Kjellander98f53512015-10-28 18:17:40 +010023#include "webrtc/system_wrappers/include/clock.h"
24#include "webrtc/system_wrappers/include/critical_section_wrapper.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 enum { kWidth = 640 };
31 enum { kHeight = 480 };
32
33 TestVCMReceiver()
34 : clock_(new SimulatedClock(0)),
35 timing_(clock_.get()),
Wan-Teh Chang92d94892015-05-28 13:36:06 -070036 receiver_(&timing_, clock_.get(), &event_factory_) {
Qiang Chend4cec152015-06-19 09:17:00 -070037
38 stream_generator_.reset(new
39 StreamGenerator(0, clock_->TimeInMilliseconds()));
mikhal@webrtc.org381da4b2013-04-25 21:45:29 +000040 }
41
42 virtual void SetUp() {
43 receiver_.Reset();
44 }
45
46 int32_t InsertPacket(int index) {
47 VCMPacket packet;
mikhal@webrtc.org381da4b2013-04-25 21:45:29 +000048 bool packet_available = stream_generator_->GetPacket(&packet, index);
49 EXPECT_TRUE(packet_available);
50 if (!packet_available)
stefan@webrtc.org3417eb42013-05-21 15:25:53 +000051 return kGeneralError; // Return here to avoid crashes below.
Wan-Teh Chang92d94892015-05-28 13:36:06 -070052 return receiver_.InsertPacket(packet, kWidth, kHeight);
mikhal@webrtc.org381da4b2013-04-25 21:45:29 +000053 }
54
55 int32_t InsertPacketAndPop(int index) {
56 VCMPacket packet;
mikhal@webrtc.org381da4b2013-04-25 21:45:29 +000057 bool packet_available = stream_generator_->PopPacket(&packet, index);
58 EXPECT_TRUE(packet_available);
59 if (!packet_available)
stefan@webrtc.org3417eb42013-05-21 15:25:53 +000060 return kGeneralError; // Return here to avoid crashes below.
mikhal@webrtc.org381da4b2013-04-25 21:45:29 +000061 return receiver_.InsertPacket(packet, kWidth, kHeight);
62 }
63
64 int32_t InsertFrame(FrameType frame_type, bool complete) {
65 int num_of_packets = complete ? 1 : 2;
66 stream_generator_->GenerateFrame(
pbos22993e12015-10-19 02:39:06 -070067 frame_type, (frame_type != kEmptyFrame) ? num_of_packets : 0,
68 (frame_type == kEmptyFrame) ? 1 : 0, clock_->TimeInMilliseconds());
mikhal@webrtc.org381da4b2013-04-25 21:45:29 +000069 int32_t ret = InsertPacketAndPop(0);
stefan@webrtc.orgef144882013-05-07 19:16:33 +000070 if (!complete) {
71 // Drop the second packet.
72 VCMPacket packet;
73 stream_generator_->PopPacket(&packet, 0);
74 }
mikhal@webrtc.org381da4b2013-04-25 21:45:29 +000075 clock_->AdvanceTimeMilliseconds(kDefaultFramePeriodMs);
76 return ret;
77 }
78
stefan@webrtc.orgef144882013-05-07 19:16:33 +000079 bool DecodeNextFrame() {
80 int64_t render_time_ms = 0;
pbos@webrtc.org4f16c872014-11-24 09:06:48 +000081 VCMEncodedFrame* frame =
82 receiver_.FrameForDecoding(0, render_time_ms, false);
stefan@webrtc.orgef144882013-05-07 19:16:33 +000083 if (!frame)
84 return false;
85 receiver_.ReleaseFrame(frame);
86 return true;
87 }
88
kwiberg@webrtc.org00b8f6b2015-02-26 14:34:55 +000089 rtc::scoped_ptr<SimulatedClock> clock_;
mikhal@webrtc.org381da4b2013-04-25 21:45:29 +000090 VCMTiming timing_;
91 NullEventFactory event_factory_;
92 VCMReceiver receiver_;
kwiberg@webrtc.org00b8f6b2015-02-26 14:34:55 +000093 rtc::scoped_ptr<StreamGenerator> stream_generator_;
mikhal@webrtc.org381da4b2013-04-25 21:45:29 +000094};
95
96TEST_F(TestVCMReceiver, RenderBufferSize_AllComplete) {
97 EXPECT_EQ(0, receiver_.RenderBufferSizeMs());
98 EXPECT_GE(InsertFrame(kVideoFrameKey, true), kNoError);
stefan@webrtc.orgef144882013-05-07 19:16:33 +000099 int num_of_frames = 10;
100 for (int i = 0; i < num_of_frames; ++i) {
mikhal@webrtc.org381da4b2013-04-25 21:45:29 +0000101 EXPECT_GE(InsertFrame(kVideoFrameDelta, true), kNoError);
102 }
stefan@webrtc.orgef144882013-05-07 19:16:33 +0000103 EXPECT_EQ(num_of_frames * kDefaultFramePeriodMs,
pbos@webrtc.org3004c792013-05-07 12:36:21 +0000104 receiver_.RenderBufferSizeMs());
mikhal@webrtc.org381da4b2013-04-25 21:45:29 +0000105}
106
stefan@webrtc.orgef144882013-05-07 19:16:33 +0000107TEST_F(TestVCMReceiver, RenderBufferSize_SkipToKeyFrame) {
108 EXPECT_EQ(0, receiver_.RenderBufferSizeMs());
109 const int kNumOfNonDecodableFrames = 2;
110 for (int i = 0; i < kNumOfNonDecodableFrames; ++i) {
111 EXPECT_GE(InsertFrame(kVideoFrameDelta, true), kNoError);
112 }
113 const int kNumOfFrames = 10;
114 EXPECT_GE(InsertFrame(kVideoFrameKey, true), kNoError);
115 for (int i = 0; i < kNumOfFrames - 1; ++i) {
116 EXPECT_GE(InsertFrame(kVideoFrameDelta, true), kNoError);
117 }
118 EXPECT_EQ((kNumOfFrames - 1) * kDefaultFramePeriodMs,
119 receiver_.RenderBufferSizeMs());
120}
121
mikhal@webrtc.org381da4b2013-04-25 21:45:29 +0000122TEST_F(TestVCMReceiver, RenderBufferSize_NotAllComplete) {
123 EXPECT_EQ(0, receiver_.RenderBufferSizeMs());
124 EXPECT_GE(InsertFrame(kVideoFrameKey, true), kNoError);
stefan@webrtc.orgef144882013-05-07 19:16:33 +0000125 int num_of_frames = 10;
126 for (int i = 0; i < num_of_frames; ++i) {
mikhal@webrtc.org381da4b2013-04-25 21:45:29 +0000127 EXPECT_GE(InsertFrame(kVideoFrameDelta, true), kNoError);
128 }
stefan@webrtc.org4ce19b12013-05-06 13:16:51 +0000129 num_of_frames++;
mikhal@webrtc.org381da4b2013-04-25 21:45:29 +0000130 EXPECT_GE(InsertFrame(kVideoFrameDelta, false), kNoError);
stefan@webrtc.orgef144882013-05-07 19:16:33 +0000131 for (int i = 0; i < num_of_frames; ++i) {
mikhal@webrtc.org381da4b2013-04-25 21:45:29 +0000132 EXPECT_GE(InsertFrame(kVideoFrameDelta, true), kNoError);
133 }
stefan@webrtc.orgef144882013-05-07 19:16:33 +0000134 EXPECT_EQ((num_of_frames - 1) * kDefaultFramePeriodMs,
135 receiver_.RenderBufferSizeMs());
mikhal@webrtc.org381da4b2013-04-25 21:45:29 +0000136}
137
138TEST_F(TestVCMReceiver, RenderBufferSize_NoKeyFrame) {
139 EXPECT_EQ(0, receiver_.RenderBufferSizeMs());
140 int num_of_frames = 10;
141 for (int i = 0; i < num_of_frames; ++i) {
142 EXPECT_GE(InsertFrame(kVideoFrameDelta, true), kNoError);
143 }
mikhal@webrtc.org759b0412013-05-07 16:36:00 +0000144 int64_t next_render_time_ms = 0;
perkj796cfaf2015-12-10 09:27:38 -0800145 VCMEncodedFrame* frame =
146 receiver_.FrameForDecoding(10, next_render_time_ms, false);
mikhal@webrtc.org759b0412013-05-07 16:36:00 +0000147 EXPECT_TRUE(frame == NULL);
148 receiver_.ReleaseFrame(frame);
mikhal@webrtc.org381da4b2013-04-25 21:45:29 +0000149 EXPECT_GE(InsertFrame(kVideoFrameDelta, false), kNoError);
150 for (int i = 0; i < num_of_frames; ++i) {
151 EXPECT_GE(InsertFrame(kVideoFrameDelta, true), kNoError);
152 }
153 EXPECT_EQ(0, receiver_.RenderBufferSizeMs());
154}
155
stefan@webrtc.orgef144882013-05-07 19:16:33 +0000156TEST_F(TestVCMReceiver, NonDecodableDuration_Empty) {
157 // Enable NACK and with no RTT thresholds for disabling retransmission delay.
158 receiver_.SetNackMode(kNack, -1, -1);
159 const size_t kMaxNackListSize = 1000;
160 const int kMaxPacketAgeToNack = 1000;
161 const int kMaxNonDecodableDuration = 500;
162 const int kMinDelayMs = 500;
163 receiver_.SetNackSettings(kMaxNackListSize, kMaxPacketAgeToNack,
164 kMaxNonDecodableDuration);
165 EXPECT_GE(InsertFrame(kVideoFrameKey, true), kNoError);
166 // Advance time until it's time to decode the key frame.
167 clock_->AdvanceTimeMilliseconds(kMinDelayMs);
168 EXPECT_TRUE(DecodeNextFrame());
Wan-Teh Changb1825a42015-06-03 15:03:35 -0700169 bool request_key_frame = false;
170 std::vector<uint16_t> nack_list = receiver_.NackList(&request_key_frame);
171 EXPECT_FALSE(request_key_frame);
stefan@webrtc.orgef144882013-05-07 19:16:33 +0000172}
173
174TEST_F(TestVCMReceiver, NonDecodableDuration_NoKeyFrame) {
175 // Enable NACK and with no RTT thresholds for disabling retransmission delay.
176 receiver_.SetNackMode(kNack, -1, -1);
177 const size_t kMaxNackListSize = 1000;
178 const int kMaxPacketAgeToNack = 1000;
179 const int kMaxNonDecodableDuration = 500;
180 receiver_.SetNackSettings(kMaxNackListSize, kMaxPacketAgeToNack,
181 kMaxNonDecodableDuration);
182 const int kNumFrames = kDefaultFrameRate * kMaxNonDecodableDuration / 1000;
183 for (int i = 0; i < kNumFrames; ++i) {
184 EXPECT_GE(InsertFrame(kVideoFrameDelta, true), kNoError);
185 }
Wan-Teh Changb1825a42015-06-03 15:03:35 -0700186 bool request_key_frame = false;
187 std::vector<uint16_t> nack_list = receiver_.NackList(&request_key_frame);
188 EXPECT_TRUE(request_key_frame);
stefan@webrtc.orgef144882013-05-07 19:16:33 +0000189}
190
191TEST_F(TestVCMReceiver, NonDecodableDuration_OneIncomplete) {
192 // Enable NACK and with no RTT thresholds for disabling retransmission delay.
193 receiver_.SetNackMode(kNack, -1, -1);
194 const size_t kMaxNackListSize = 1000;
195 const int kMaxPacketAgeToNack = 1000;
196 const int kMaxNonDecodableDuration = 500;
197 const int kMaxNonDecodableDurationFrames = (kDefaultFrameRate *
198 kMaxNonDecodableDuration + 500) / 1000;
199 const int kMinDelayMs = 500;
200 receiver_.SetNackSettings(kMaxNackListSize, kMaxPacketAgeToNack,
201 kMaxNonDecodableDuration);
202 receiver_.SetMinReceiverDelay(kMinDelayMs);
203 int64_t key_frame_inserted = clock_->TimeInMilliseconds();
204 EXPECT_GE(InsertFrame(kVideoFrameKey, true), kNoError);
205 // Insert an incomplete frame.
206 EXPECT_GE(InsertFrame(kVideoFrameDelta, false), kNoError);
207 // Insert enough frames to have too long non-decodable sequence.
208 for (int i = 0; i < kMaxNonDecodableDurationFrames;
209 ++i) {
210 EXPECT_GE(InsertFrame(kVideoFrameDelta, true), kNoError);
211 }
212 // Advance time until it's time to decode the key frame.
213 clock_->AdvanceTimeMilliseconds(kMinDelayMs - clock_->TimeInMilliseconds() -
214 key_frame_inserted);
215 EXPECT_TRUE(DecodeNextFrame());
216 // Make sure we get a key frame request.
Wan-Teh Changb1825a42015-06-03 15:03:35 -0700217 bool request_key_frame = false;
218 std::vector<uint16_t> nack_list = receiver_.NackList(&request_key_frame);
219 EXPECT_TRUE(request_key_frame);
stefan@webrtc.orgef144882013-05-07 19:16:33 +0000220}
221
222TEST_F(TestVCMReceiver, NonDecodableDuration_NoTrigger) {
223 // Enable NACK and with no RTT thresholds for disabling retransmission delay.
224 receiver_.SetNackMode(kNack, -1, -1);
225 const size_t kMaxNackListSize = 1000;
226 const int kMaxPacketAgeToNack = 1000;
227 const int kMaxNonDecodableDuration = 500;
228 const int kMaxNonDecodableDurationFrames = (kDefaultFrameRate *
229 kMaxNonDecodableDuration + 500) / 1000;
230 const int kMinDelayMs = 500;
231 receiver_.SetNackSettings(kMaxNackListSize, kMaxPacketAgeToNack,
232 kMaxNonDecodableDuration);
233 receiver_.SetMinReceiverDelay(kMinDelayMs);
234 int64_t key_frame_inserted = clock_->TimeInMilliseconds();
235 EXPECT_GE(InsertFrame(kVideoFrameKey, true), kNoError);
236 // Insert an incomplete frame.
237 EXPECT_GE(InsertFrame(kVideoFrameDelta, false), kNoError);
238 // Insert all but one frame to not trigger a key frame request due to
239 // too long duration of non-decodable frames.
240 for (int i = 0; i < kMaxNonDecodableDurationFrames - 1;
241 ++i) {
242 EXPECT_GE(InsertFrame(kVideoFrameDelta, true), kNoError);
243 }
244 // Advance time until it's time to decode the key frame.
245 clock_->AdvanceTimeMilliseconds(kMinDelayMs - clock_->TimeInMilliseconds() -
246 key_frame_inserted);
247 EXPECT_TRUE(DecodeNextFrame());
248 // Make sure we don't get a key frame request since we haven't generated
249 // enough frames.
Wan-Teh Changb1825a42015-06-03 15:03:35 -0700250 bool request_key_frame = false;
251 std::vector<uint16_t> nack_list = receiver_.NackList(&request_key_frame);
252 EXPECT_FALSE(request_key_frame);
stefan@webrtc.orgef144882013-05-07 19:16:33 +0000253}
254
stefan@webrtc.org16734812013-05-14 12:00:47 +0000255TEST_F(TestVCMReceiver, NonDecodableDuration_NoTrigger2) {
256 // Enable NACK and with no RTT thresholds for disabling retransmission delay.
257 receiver_.SetNackMode(kNack, -1, -1);
258 const size_t kMaxNackListSize = 1000;
259 const int kMaxPacketAgeToNack = 1000;
260 const int kMaxNonDecodableDuration = 500;
261 const int kMaxNonDecodableDurationFrames = (kDefaultFrameRate *
262 kMaxNonDecodableDuration + 500) / 1000;
263 const int kMinDelayMs = 500;
264 receiver_.SetNackSettings(kMaxNackListSize, kMaxPacketAgeToNack,
265 kMaxNonDecodableDuration);
266 receiver_.SetMinReceiverDelay(kMinDelayMs);
267 int64_t key_frame_inserted = clock_->TimeInMilliseconds();
268 EXPECT_GE(InsertFrame(kVideoFrameKey, true), kNoError);
269 // Insert enough frames to have too long non-decodable sequence, except that
270 // we don't have any losses.
271 for (int i = 0; i < kMaxNonDecodableDurationFrames;
272 ++i) {
273 EXPECT_GE(InsertFrame(kVideoFrameDelta, true), kNoError);
274 }
275 // Insert an incomplete frame.
276 EXPECT_GE(InsertFrame(kVideoFrameDelta, false), kNoError);
277 // Advance time until it's time to decode the key frame.
278 clock_->AdvanceTimeMilliseconds(kMinDelayMs - clock_->TimeInMilliseconds() -
279 key_frame_inserted);
280 EXPECT_TRUE(DecodeNextFrame());
281 // Make sure we don't get a key frame request since the non-decodable duration
282 // is only one frame.
Wan-Teh Changb1825a42015-06-03 15:03:35 -0700283 bool request_key_frame = false;
284 std::vector<uint16_t> nack_list = receiver_.NackList(&request_key_frame);
285 EXPECT_FALSE(request_key_frame);
stefan@webrtc.org16734812013-05-14 12:00:47 +0000286}
287
stefan@webrtc.orgef144882013-05-07 19:16:33 +0000288TEST_F(TestVCMReceiver, NonDecodableDuration_KeyFrameAfterIncompleteFrames) {
289 // Enable NACK and with no RTT thresholds for disabling retransmission delay.
290 receiver_.SetNackMode(kNack, -1, -1);
291 const size_t kMaxNackListSize = 1000;
292 const int kMaxPacketAgeToNack = 1000;
293 const int kMaxNonDecodableDuration = 500;
294 const int kMaxNonDecodableDurationFrames = (kDefaultFrameRate *
295 kMaxNonDecodableDuration + 500) / 1000;
296 const int kMinDelayMs = 500;
297 receiver_.SetNackSettings(kMaxNackListSize, kMaxPacketAgeToNack,
298 kMaxNonDecodableDuration);
299 receiver_.SetMinReceiverDelay(kMinDelayMs);
300 int64_t key_frame_inserted = clock_->TimeInMilliseconds();
301 EXPECT_GE(InsertFrame(kVideoFrameKey, true), kNoError);
302 // Insert an incomplete frame.
303 EXPECT_GE(InsertFrame(kVideoFrameDelta, false), kNoError);
304 // Insert enough frames to have too long non-decodable sequence.
305 for (int i = 0; i < kMaxNonDecodableDurationFrames;
306 ++i) {
307 EXPECT_GE(InsertFrame(kVideoFrameDelta, true), kNoError);
308 }
309 EXPECT_GE(InsertFrame(kVideoFrameKey, true), kNoError);
310 // Advance time until it's time to decode the key frame.
311 clock_->AdvanceTimeMilliseconds(kMinDelayMs - clock_->TimeInMilliseconds() -
312 key_frame_inserted);
313 EXPECT_TRUE(DecodeNextFrame());
314 // Make sure we don't get a key frame request since we have a key frame
315 // in the list.
Wan-Teh Changb1825a42015-06-03 15:03:35 -0700316 bool request_key_frame = false;
317 std::vector<uint16_t> nack_list = receiver_.NackList(&request_key_frame);
318 EXPECT_FALSE(request_key_frame);
stefan@webrtc.orgef144882013-05-07 19:16:33 +0000319}
Qiang Chend4cec152015-06-19 09:17:00 -0700320
321// A simulated clock, when time elapses, will insert frames into the jitter
322// buffer, based on initial settings.
323class SimulatedClockWithFrames : public SimulatedClock {
324 public:
325 SimulatedClockWithFrames(StreamGenerator* stream_generator,
326 VCMReceiver* receiver)
327 : SimulatedClock(0),
328 stream_generator_(stream_generator),
329 receiver_(receiver) {}
330 virtual ~SimulatedClockWithFrames() {}
331
332 // If |stop_on_frame| is true and next frame arrives between now and
333 // now+|milliseconds|, the clock will be advanced to the arrival time of next
334 // frame.
335 // Otherwise, the clock will be advanced by |milliseconds|.
336 //
337 // For both cases, a frame will be inserted into the jitter buffer at the
338 // instant when the clock time is timestamps_.front().arrive_time.
339 //
340 // Return true if some frame arrives between now and now+|milliseconds|.
341 bool AdvanceTimeMilliseconds(int64_t milliseconds, bool stop_on_frame) {
342 return AdvanceTimeMicroseconds(milliseconds * 1000, stop_on_frame);
343 };
344
345 bool AdvanceTimeMicroseconds(int64_t microseconds, bool stop_on_frame) {
346 int64_t start_time = TimeInMicroseconds();
347 int64_t end_time = start_time + microseconds;
348 bool frame_injected = false;
349 while (!timestamps_.empty() &&
350 timestamps_.front().arrive_time <= end_time) {
henrikg91d6ede2015-09-17 00:24:34 -0700351 RTC_DCHECK(timestamps_.front().arrive_time >= start_time);
Qiang Chend4cec152015-06-19 09:17:00 -0700352
353 SimulatedClock::AdvanceTimeMicroseconds(timestamps_.front().arrive_time -
354 TimeInMicroseconds());
355 GenerateAndInsertFrame((timestamps_.front().render_time + 500) / 1000);
356 timestamps_.pop();
357 frame_injected = true;
358
359 if (stop_on_frame)
360 return frame_injected;
361 }
362
363 if (TimeInMicroseconds() < end_time) {
364 SimulatedClock::AdvanceTimeMicroseconds(end_time - TimeInMicroseconds());
365 }
366 return frame_injected;
367 };
368
369 // Input timestamps are in unit Milliseconds.
370 // And |arrive_timestamps| must be positive and in increasing order.
371 // |arrive_timestamps| determine when we are going to insert frames into the
372 // jitter buffer.
373 // |render_timestamps| are the timestamps on the frame.
374 void SetFrames(const int64_t* arrive_timestamps,
375 const int64_t* render_timestamps,
376 size_t size) {
377 int64_t previous_arrive_timestamp = 0;
378 for (size_t i = 0; i < size; i++) {
henrikg91d6ede2015-09-17 00:24:34 -0700379 RTC_CHECK(arrive_timestamps[i] >= previous_arrive_timestamp);
Qiang Chend4cec152015-06-19 09:17:00 -0700380 timestamps_.push(TimestampPair(arrive_timestamps[i] * 1000,
381 render_timestamps[i] * 1000));
382 previous_arrive_timestamp = arrive_timestamps[i];
383 }
384 }
385
386 private:
387 struct TimestampPair {
388 TimestampPair(int64_t arrive_timestamp, int64_t render_timestamp)
389 : arrive_time(arrive_timestamp), render_time(render_timestamp) {}
390
391 int64_t arrive_time;
392 int64_t render_time;
393 };
394
395 void GenerateAndInsertFrame(int64_t render_timestamp_ms) {
396 VCMPacket packet;
397 stream_generator_->GenerateFrame(FrameType::kVideoFrameKey,
398 1, // media packets
399 0, // empty packets
400 render_timestamp_ms);
401
402 bool packet_available = stream_generator_->PopPacket(&packet, 0);
403 EXPECT_TRUE(packet_available);
404 if (!packet_available)
405 return; // Return here to avoid crashes below.
406 receiver_->InsertPacket(packet, 640, 480);
407 }
408
409 std::queue<TimestampPair> timestamps_;
410 StreamGenerator* stream_generator_;
411 VCMReceiver* receiver_;
412};
413
414// Use a SimulatedClockWithFrames
415// Wait call will do either of these:
416// 1. If |stop_on_frame| is true, the clock will be turned to the exact instant
417// that the first frame comes and the frame will be inserted into the jitter
418// buffer, or the clock will be turned to now + |max_time| if no frame comes in
419// the window.
420// 2. If |stop_on_frame| is false, the clock will be turn to now + |max_time|,
421// and all the frames arriving between now and now + |max_time| will be
422// inserted into the jitter buffer.
423//
424// This is used to simulate the JitterBuffer getting packets from internet as
425// time elapses.
426
427class FrameInjectEvent : public EventWrapper {
428 public:
429 FrameInjectEvent(SimulatedClockWithFrames* clock, bool stop_on_frame)
430 : clock_(clock), stop_on_frame_(stop_on_frame) {}
431
432 bool Set() override { return true; }
433
434 EventTypeWrapper Wait(unsigned long max_time) override {
435 if (clock_->AdvanceTimeMilliseconds(max_time, stop_on_frame_) &&
436 stop_on_frame_) {
437 return EventTypeWrapper::kEventSignaled;
438 } else {
439 return EventTypeWrapper::kEventTimeout;
440 }
441 }
442
443 private:
444 SimulatedClockWithFrames* clock_;
445 bool stop_on_frame_;
446};
447
448class VCMReceiverTimingTest : public ::testing::Test {
449 protected:
450
451 VCMReceiverTimingTest()
452
453 : clock_(&stream_generator_, &receiver_),
454 stream_generator_(0, clock_.TimeInMilliseconds()),
455 timing_(&clock_),
456 receiver_(
457 &timing_,
458 &clock_,
459 rtc::scoped_ptr<EventWrapper>(new FrameInjectEvent(&clock_, false)),
460 rtc::scoped_ptr<EventWrapper>(
461 new FrameInjectEvent(&clock_, true))) {}
462
463
464 virtual void SetUp() { receiver_.Reset(); }
465
466 SimulatedClockWithFrames clock_;
467 StreamGenerator stream_generator_;
468 VCMTiming timing_;
469 VCMReceiver receiver_;
470};
471
472// Test whether VCMReceiver::FrameForDecoding handles parameter
473// |max_wait_time_ms| correctly:
474// 1. The function execution should never take more than |max_wait_time_ms|.
475// 2. If the function exit before now + |max_wait_time_ms|, a frame must be
476// returned.
477TEST_F(VCMReceiverTimingTest, FrameForDecoding) {
478 const size_t kNumFrames = 100;
479 const int kFramePeriod = 40;
480 int64_t arrive_timestamps[kNumFrames];
481 int64_t render_timestamps[kNumFrames];
482 int64_t next_render_time;
483
484 // Construct test samples.
485 // render_timestamps are the timestamps stored in the Frame;
486 // arrive_timestamps controls when the Frame packet got received.
487 for (size_t i = 0; i < kNumFrames; i++) {
488 // Preset frame rate to 25Hz.
489 // But we add a reasonable deviation to arrive_timestamps to mimic Internet
490 // fluctuation.
491 arrive_timestamps[i] =
492 (i + 1) * kFramePeriod + (i % 10) * ((i % 2) ? 1 : -1);
493 render_timestamps[i] = (i + 1) * kFramePeriod;
494 }
495
496 clock_.SetFrames(arrive_timestamps, render_timestamps, kNumFrames);
497
498 // Record how many frames we finally get out of the receiver.
499 size_t num_frames_return = 0;
500
501 const int64_t kMaxWaitTime = 30;
502
503 // Ideally, we should get all frames that we input in InitializeFrames.
504 // In the case that FrameForDecoding kills frames by error, we rely on the
505 // build bot to kill the test.
506 while (num_frames_return < kNumFrames) {
507 int64_t start_time = clock_.TimeInMilliseconds();
508 VCMEncodedFrame* frame =
509 receiver_.FrameForDecoding(kMaxWaitTime, next_render_time, false);
510 int64_t end_time = clock_.TimeInMilliseconds();
511
512 // In any case the FrameForDecoding should not wait longer than
513 // max_wait_time.
514 // In the case that we did not get a frame, it should have been waiting for
515 // exactly max_wait_time. (By the testing samples we constructed above, we
516 // are sure there is no timing error, so the only case it returns with NULL
517 // is that it runs out of time.)
518 if (frame) {
519 receiver_.ReleaseFrame(frame);
520 ++num_frames_return;
521 EXPECT_GE(kMaxWaitTime, end_time - start_time);
522 } else {
523 EXPECT_EQ(kMaxWaitTime, end_time - start_time);
524 }
525 }
526}
527
perkj796cfaf2015-12-10 09:27:38 -0800528// Test whether VCMReceiver::FrameForDecoding handles parameter
529// |prefer_late_decoding| and |max_wait_time_ms| correctly:
530// 1. The function execution should never take more than |max_wait_time_ms|.
531// 2. If the function exit before now + |max_wait_time_ms|, a frame must be
532// returned and the end time must be equal to the render timestamp - delay
533// for decoding and rendering.
534TEST_F(VCMReceiverTimingTest, FrameForDecodingPreferLateDecoding) {
535 const size_t kNumFrames = 100;
536 const int kFramePeriod = 40;
537
538 int64_t arrive_timestamps[kNumFrames];
539 int64_t render_timestamps[kNumFrames];
540 int64_t next_render_time;
541
542 int render_delay_ms;
543 int max_decode_ms;
544 int dummy;
545 timing_.GetTimings(&dummy, &max_decode_ms, &dummy, &dummy, &dummy, &dummy,
546 &render_delay_ms);
547
548 // Construct test samples.
549 // render_timestamps are the timestamps stored in the Frame;
550 // arrive_timestamps controls when the Frame packet got received.
551 for (size_t i = 0; i < kNumFrames; i++) {
552 // Preset frame rate to 25Hz.
553 // But we add a reasonable deviation to arrive_timestamps to mimic Internet
554 // fluctuation.
555 arrive_timestamps[i] =
556 (i + 1) * kFramePeriod + (i % 10) * ((i % 2) ? 1 : -1);
557 render_timestamps[i] = (i + 1) * kFramePeriod;
558 }
559
560 clock_.SetFrames(arrive_timestamps, render_timestamps, kNumFrames);
561
562 // Record how many frames we finally get out of the receiver.
563 size_t num_frames_return = 0;
564 const int64_t kMaxWaitTime = 30;
565 bool prefer_late_decoding = true;
566 while (num_frames_return < kNumFrames) {
567 int64_t start_time = clock_.TimeInMilliseconds();
568
569 VCMEncodedFrame* frame =
570 receiver_.FrameForDecoding(kMaxWaitTime, next_render_time,
571 prefer_late_decoding);
572 int64_t end_time = clock_.TimeInMilliseconds();
573 if (frame) {
574 EXPECT_EQ(frame->RenderTimeMs() - max_decode_ms - render_delay_ms,
575 end_time);
576 receiver_.ReleaseFrame(frame);
577 ++num_frames_return;
578 } else {
579 EXPECT_EQ(kMaxWaitTime, end_time - start_time);
580 }
581 }
582}
583
mikhal@webrtc.org381da4b2013-04-25 21:45:29 +0000584} // namespace webrtc