blob: d05957f6f0df69d87ba2456164e25ce13e10a04e [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 enum { kWidth = 640 };
33 enum { kHeight = 480 };
34
35 TestVCMReceiver()
36 : clock_(new SimulatedClock(0)),
37 timing_(clock_.get()),
Wan-Teh Chang92d94892015-05-28 13:36:06 -070038 receiver_(&timing_, clock_.get(), &event_factory_) {
philipel9d3ab612015-12-21 04:12:39 -080039 stream_generator_.reset(
40 new StreamGenerator(0, clock_->TimeInMilliseconds()));
mikhal@webrtc.org381da4b2013-04-25 21:45:29 +000041 }
42
philipel9d3ab612015-12-21 04:12:39 -080043 virtual void SetUp() { receiver_.Reset(); }
mikhal@webrtc.org381da4b2013-04-25 21:45:29 +000044
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 =
philipel9d3ab612015-12-21 04:12:39 -080081 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
kwiberg3f55dea2016-02-29 05:51:59 -080088 std::unique_ptr<SimulatedClock> clock_;
mikhal@webrtc.org381da4b2013-04-25 21:45:29 +000089 VCMTiming timing_;
90 NullEventFactory event_factory_;
91 VCMReceiver receiver_;
kwiberg3f55dea2016-02-29 05:51:59 -080092 std::unique_ptr<StreamGenerator> stream_generator_;
mikhal@webrtc.org381da4b2013-04-25 21:45:29 +000093};
94
stefan@webrtc.orgef144882013-05-07 19:16:33 +000095TEST_F(TestVCMReceiver, NonDecodableDuration_Empty) {
96 // Enable NACK and with no RTT thresholds for disabling retransmission delay.
97 receiver_.SetNackMode(kNack, -1, -1);
98 const size_t kMaxNackListSize = 1000;
99 const int kMaxPacketAgeToNack = 1000;
100 const int kMaxNonDecodableDuration = 500;
101 const int kMinDelayMs = 500;
102 receiver_.SetNackSettings(kMaxNackListSize, kMaxPacketAgeToNack,
philipel9d3ab612015-12-21 04:12:39 -0800103 kMaxNonDecodableDuration);
stefan@webrtc.orgef144882013-05-07 19:16:33 +0000104 EXPECT_GE(InsertFrame(kVideoFrameKey, true), kNoError);
105 // Advance time until it's time to decode the key frame.
106 clock_->AdvanceTimeMilliseconds(kMinDelayMs);
107 EXPECT_TRUE(DecodeNextFrame());
Wan-Teh Changb1825a42015-06-03 15:03:35 -0700108 bool request_key_frame = false;
109 std::vector<uint16_t> nack_list = receiver_.NackList(&request_key_frame);
110 EXPECT_FALSE(request_key_frame);
stefan@webrtc.orgef144882013-05-07 19:16:33 +0000111}
112
113TEST_F(TestVCMReceiver, NonDecodableDuration_NoKeyFrame) {
114 // Enable NACK and with no RTT thresholds for disabling retransmission delay.
115 receiver_.SetNackMode(kNack, -1, -1);
116 const size_t kMaxNackListSize = 1000;
117 const int kMaxPacketAgeToNack = 1000;
118 const int kMaxNonDecodableDuration = 500;
119 receiver_.SetNackSettings(kMaxNackListSize, kMaxPacketAgeToNack,
philipel9d3ab612015-12-21 04:12:39 -0800120 kMaxNonDecodableDuration);
stefan@webrtc.orgef144882013-05-07 19:16:33 +0000121 const int kNumFrames = kDefaultFrameRate * kMaxNonDecodableDuration / 1000;
122 for (int i = 0; i < kNumFrames; ++i) {
123 EXPECT_GE(InsertFrame(kVideoFrameDelta, true), kNoError);
124 }
Wan-Teh Changb1825a42015-06-03 15:03:35 -0700125 bool request_key_frame = false;
126 std::vector<uint16_t> nack_list = receiver_.NackList(&request_key_frame);
127 EXPECT_TRUE(request_key_frame);
stefan@webrtc.orgef144882013-05-07 19:16:33 +0000128}
129
130TEST_F(TestVCMReceiver, NonDecodableDuration_OneIncomplete) {
131 // Enable NACK and with no RTT thresholds for disabling retransmission delay.
132 receiver_.SetNackMode(kNack, -1, -1);
133 const size_t kMaxNackListSize = 1000;
134 const int kMaxPacketAgeToNack = 1000;
135 const int kMaxNonDecodableDuration = 500;
philipel9d3ab612015-12-21 04:12:39 -0800136 const int kMaxNonDecodableDurationFrames =
137 (kDefaultFrameRate * kMaxNonDecodableDuration + 500) / 1000;
stefan@webrtc.orgef144882013-05-07 19:16:33 +0000138 const int kMinDelayMs = 500;
139 receiver_.SetNackSettings(kMaxNackListSize, kMaxPacketAgeToNack,
philipel9d3ab612015-12-21 04:12:39 -0800140 kMaxNonDecodableDuration);
stefan@webrtc.orgef144882013-05-07 19:16:33 +0000141 receiver_.SetMinReceiverDelay(kMinDelayMs);
142 int64_t key_frame_inserted = clock_->TimeInMilliseconds();
143 EXPECT_GE(InsertFrame(kVideoFrameKey, true), kNoError);
144 // Insert an incomplete frame.
145 EXPECT_GE(InsertFrame(kVideoFrameDelta, false), kNoError);
146 // Insert enough frames to have too long non-decodable sequence.
philipel9d3ab612015-12-21 04:12:39 -0800147 for (int i = 0; i < kMaxNonDecodableDurationFrames; ++i) {
stefan@webrtc.orgef144882013-05-07 19:16:33 +0000148 EXPECT_GE(InsertFrame(kVideoFrameDelta, true), kNoError);
149 }
150 // Advance time until it's time to decode the key frame.
151 clock_->AdvanceTimeMilliseconds(kMinDelayMs - clock_->TimeInMilliseconds() -
philipel9d3ab612015-12-21 04:12:39 -0800152 key_frame_inserted);
stefan@webrtc.orgef144882013-05-07 19:16:33 +0000153 EXPECT_TRUE(DecodeNextFrame());
154 // Make sure we get a key frame request.
Wan-Teh Changb1825a42015-06-03 15:03:35 -0700155 bool request_key_frame = false;
156 std::vector<uint16_t> nack_list = receiver_.NackList(&request_key_frame);
157 EXPECT_TRUE(request_key_frame);
stefan@webrtc.orgef144882013-05-07 19:16:33 +0000158}
159
160TEST_F(TestVCMReceiver, NonDecodableDuration_NoTrigger) {
161 // Enable NACK and with no RTT thresholds for disabling retransmission delay.
162 receiver_.SetNackMode(kNack, -1, -1);
163 const size_t kMaxNackListSize = 1000;
164 const int kMaxPacketAgeToNack = 1000;
165 const int kMaxNonDecodableDuration = 500;
philipel9d3ab612015-12-21 04:12:39 -0800166 const int kMaxNonDecodableDurationFrames =
167 (kDefaultFrameRate * kMaxNonDecodableDuration + 500) / 1000;
stefan@webrtc.orgef144882013-05-07 19:16:33 +0000168 const int kMinDelayMs = 500;
169 receiver_.SetNackSettings(kMaxNackListSize, kMaxPacketAgeToNack,
philipel9d3ab612015-12-21 04:12:39 -0800170 kMaxNonDecodableDuration);
stefan@webrtc.orgef144882013-05-07 19:16:33 +0000171 receiver_.SetMinReceiverDelay(kMinDelayMs);
172 int64_t key_frame_inserted = clock_->TimeInMilliseconds();
173 EXPECT_GE(InsertFrame(kVideoFrameKey, true), kNoError);
174 // Insert an incomplete frame.
175 EXPECT_GE(InsertFrame(kVideoFrameDelta, false), kNoError);
176 // Insert all but one frame to not trigger a key frame request due to
177 // too long duration of non-decodable frames.
philipel9d3ab612015-12-21 04:12:39 -0800178 for (int i = 0; i < kMaxNonDecodableDurationFrames - 1; ++i) {
stefan@webrtc.orgef144882013-05-07 19:16:33 +0000179 EXPECT_GE(InsertFrame(kVideoFrameDelta, true), kNoError);
180 }
181 // Advance time until it's time to decode the key frame.
182 clock_->AdvanceTimeMilliseconds(kMinDelayMs - clock_->TimeInMilliseconds() -
philipel9d3ab612015-12-21 04:12:39 -0800183 key_frame_inserted);
stefan@webrtc.orgef144882013-05-07 19:16:33 +0000184 EXPECT_TRUE(DecodeNextFrame());
185 // Make sure we don't get a key frame request since we haven't generated
186 // enough frames.
Wan-Teh Changb1825a42015-06-03 15:03:35 -0700187 bool request_key_frame = false;
188 std::vector<uint16_t> nack_list = receiver_.NackList(&request_key_frame);
189 EXPECT_FALSE(request_key_frame);
stefan@webrtc.orgef144882013-05-07 19:16:33 +0000190}
191
stefan@webrtc.org16734812013-05-14 12:00:47 +0000192TEST_F(TestVCMReceiver, NonDecodableDuration_NoTrigger2) {
193 // Enable NACK and with no RTT thresholds for disabling retransmission delay.
194 receiver_.SetNackMode(kNack, -1, -1);
195 const size_t kMaxNackListSize = 1000;
196 const int kMaxPacketAgeToNack = 1000;
197 const int kMaxNonDecodableDuration = 500;
philipel9d3ab612015-12-21 04:12:39 -0800198 const int kMaxNonDecodableDurationFrames =
199 (kDefaultFrameRate * kMaxNonDecodableDuration + 500) / 1000;
stefan@webrtc.org16734812013-05-14 12:00:47 +0000200 const int kMinDelayMs = 500;
201 receiver_.SetNackSettings(kMaxNackListSize, kMaxPacketAgeToNack,
philipel9d3ab612015-12-21 04:12:39 -0800202 kMaxNonDecodableDuration);
stefan@webrtc.org16734812013-05-14 12:00:47 +0000203 receiver_.SetMinReceiverDelay(kMinDelayMs);
204 int64_t key_frame_inserted = clock_->TimeInMilliseconds();
205 EXPECT_GE(InsertFrame(kVideoFrameKey, true), kNoError);
206 // Insert enough frames to have too long non-decodable sequence, except that
207 // we don't have any losses.
philipel9d3ab612015-12-21 04:12:39 -0800208 for (int i = 0; i < kMaxNonDecodableDurationFrames; ++i) {
stefan@webrtc.org16734812013-05-14 12:00:47 +0000209 EXPECT_GE(InsertFrame(kVideoFrameDelta, true), kNoError);
210 }
211 // Insert an incomplete frame.
212 EXPECT_GE(InsertFrame(kVideoFrameDelta, false), kNoError);
213 // Advance time until it's time to decode the key frame.
214 clock_->AdvanceTimeMilliseconds(kMinDelayMs - clock_->TimeInMilliseconds() -
philipel9d3ab612015-12-21 04:12:39 -0800215 key_frame_inserted);
stefan@webrtc.org16734812013-05-14 12:00:47 +0000216 EXPECT_TRUE(DecodeNextFrame());
217 // Make sure we don't get a key frame request since the non-decodable duration
218 // is only one frame.
Wan-Teh Changb1825a42015-06-03 15:03:35 -0700219 bool request_key_frame = false;
220 std::vector<uint16_t> nack_list = receiver_.NackList(&request_key_frame);
221 EXPECT_FALSE(request_key_frame);
stefan@webrtc.org16734812013-05-14 12:00:47 +0000222}
223
stefan@webrtc.orgef144882013-05-07 19:16:33 +0000224TEST_F(TestVCMReceiver, NonDecodableDuration_KeyFrameAfterIncompleteFrames) {
225 // Enable NACK and with no RTT thresholds for disabling retransmission delay.
226 receiver_.SetNackMode(kNack, -1, -1);
227 const size_t kMaxNackListSize = 1000;
228 const int kMaxPacketAgeToNack = 1000;
229 const int kMaxNonDecodableDuration = 500;
philipel9d3ab612015-12-21 04:12:39 -0800230 const int kMaxNonDecodableDurationFrames =
231 (kDefaultFrameRate * kMaxNonDecodableDuration + 500) / 1000;
stefan@webrtc.orgef144882013-05-07 19:16:33 +0000232 const int kMinDelayMs = 500;
233 receiver_.SetNackSettings(kMaxNackListSize, kMaxPacketAgeToNack,
philipel9d3ab612015-12-21 04:12:39 -0800234 kMaxNonDecodableDuration);
stefan@webrtc.orgef144882013-05-07 19:16:33 +0000235 receiver_.SetMinReceiverDelay(kMinDelayMs);
236 int64_t key_frame_inserted = clock_->TimeInMilliseconds();
237 EXPECT_GE(InsertFrame(kVideoFrameKey, true), kNoError);
238 // Insert an incomplete frame.
239 EXPECT_GE(InsertFrame(kVideoFrameDelta, false), kNoError);
240 // Insert enough frames to have too long non-decodable sequence.
philipel9d3ab612015-12-21 04:12:39 -0800241 for (int i = 0; i < kMaxNonDecodableDurationFrames; ++i) {
stefan@webrtc.orgef144882013-05-07 19:16:33 +0000242 EXPECT_GE(InsertFrame(kVideoFrameDelta, true), kNoError);
243 }
244 EXPECT_GE(InsertFrame(kVideoFrameKey, true), kNoError);
245 // Advance time until it's time to decode the key frame.
246 clock_->AdvanceTimeMilliseconds(kMinDelayMs - clock_->TimeInMilliseconds() -
philipel9d3ab612015-12-21 04:12:39 -0800247 key_frame_inserted);
stefan@webrtc.orgef144882013-05-07 19:16:33 +0000248 EXPECT_TRUE(DecodeNextFrame());
249 // Make sure we don't get a key frame request since we have a key frame
250 // in the list.
Wan-Teh Changb1825a42015-06-03 15:03:35 -0700251 bool request_key_frame = false;
252 std::vector<uint16_t> nack_list = receiver_.NackList(&request_key_frame);
253 EXPECT_FALSE(request_key_frame);
stefan@webrtc.orgef144882013-05-07 19:16:33 +0000254}
Qiang Chend4cec152015-06-19 09:17:00 -0700255
256// A simulated clock, when time elapses, will insert frames into the jitter
257// buffer, based on initial settings.
258class SimulatedClockWithFrames : public SimulatedClock {
259 public:
260 SimulatedClockWithFrames(StreamGenerator* stream_generator,
261 VCMReceiver* receiver)
262 : SimulatedClock(0),
263 stream_generator_(stream_generator),
264 receiver_(receiver) {}
265 virtual ~SimulatedClockWithFrames() {}
266
267 // If |stop_on_frame| is true and next frame arrives between now and
268 // now+|milliseconds|, the clock will be advanced to the arrival time of next
269 // frame.
270 // Otherwise, the clock will be advanced by |milliseconds|.
271 //
272 // For both cases, a frame will be inserted into the jitter buffer at the
273 // instant when the clock time is timestamps_.front().arrive_time.
274 //
275 // Return true if some frame arrives between now and now+|milliseconds|.
276 bool AdvanceTimeMilliseconds(int64_t milliseconds, bool stop_on_frame) {
277 return AdvanceTimeMicroseconds(milliseconds * 1000, stop_on_frame);
philipel9d3ab612015-12-21 04:12:39 -0800278 }
Qiang Chend4cec152015-06-19 09:17:00 -0700279
280 bool AdvanceTimeMicroseconds(int64_t microseconds, bool stop_on_frame) {
281 int64_t start_time = TimeInMicroseconds();
282 int64_t end_time = start_time + microseconds;
283 bool frame_injected = false;
284 while (!timestamps_.empty() &&
285 timestamps_.front().arrive_time <= end_time) {
henrikg91d6ede2015-09-17 00:24:34 -0700286 RTC_DCHECK(timestamps_.front().arrive_time >= start_time);
Qiang Chend4cec152015-06-19 09:17:00 -0700287
288 SimulatedClock::AdvanceTimeMicroseconds(timestamps_.front().arrive_time -
289 TimeInMicroseconds());
290 GenerateAndInsertFrame((timestamps_.front().render_time + 500) / 1000);
291 timestamps_.pop();
292 frame_injected = true;
293
294 if (stop_on_frame)
295 return frame_injected;
296 }
297
298 if (TimeInMicroseconds() < end_time) {
299 SimulatedClock::AdvanceTimeMicroseconds(end_time - TimeInMicroseconds());
300 }
301 return frame_injected;
philipel9d3ab612015-12-21 04:12:39 -0800302 }
Qiang Chend4cec152015-06-19 09:17:00 -0700303
304 // Input timestamps are in unit Milliseconds.
305 // And |arrive_timestamps| must be positive and in increasing order.
306 // |arrive_timestamps| determine when we are going to insert frames into the
307 // jitter buffer.
308 // |render_timestamps| are the timestamps on the frame.
309 void SetFrames(const int64_t* arrive_timestamps,
310 const int64_t* render_timestamps,
311 size_t size) {
312 int64_t previous_arrive_timestamp = 0;
313 for (size_t i = 0; i < size; i++) {
henrikg91d6ede2015-09-17 00:24:34 -0700314 RTC_CHECK(arrive_timestamps[i] >= previous_arrive_timestamp);
Qiang Chend4cec152015-06-19 09:17:00 -0700315 timestamps_.push(TimestampPair(arrive_timestamps[i] * 1000,
316 render_timestamps[i] * 1000));
317 previous_arrive_timestamp = arrive_timestamps[i];
318 }
319 }
320
321 private:
322 struct TimestampPair {
323 TimestampPair(int64_t arrive_timestamp, int64_t render_timestamp)
324 : arrive_time(arrive_timestamp), render_time(render_timestamp) {}
325
326 int64_t arrive_time;
327 int64_t render_time;
328 };
329
330 void GenerateAndInsertFrame(int64_t render_timestamp_ms) {
331 VCMPacket packet;
332 stream_generator_->GenerateFrame(FrameType::kVideoFrameKey,
333 1, // media packets
334 0, // empty packets
335 render_timestamp_ms);
336
337 bool packet_available = stream_generator_->PopPacket(&packet, 0);
338 EXPECT_TRUE(packet_available);
339 if (!packet_available)
340 return; // Return here to avoid crashes below.
341 receiver_->InsertPacket(packet, 640, 480);
342 }
343
344 std::queue<TimestampPair> timestamps_;
345 StreamGenerator* stream_generator_;
346 VCMReceiver* receiver_;
347};
348
349// Use a SimulatedClockWithFrames
350// Wait call will do either of these:
351// 1. If |stop_on_frame| is true, the clock will be turned to the exact instant
352// that the first frame comes and the frame will be inserted into the jitter
353// buffer, or the clock will be turned to now + |max_time| if no frame comes in
354// the window.
355// 2. If |stop_on_frame| is false, the clock will be turn to now + |max_time|,
356// and all the frames arriving between now and now + |max_time| will be
357// inserted into the jitter buffer.
358//
359// This is used to simulate the JitterBuffer getting packets from internet as
360// time elapses.
361
362class FrameInjectEvent : public EventWrapper {
363 public:
364 FrameInjectEvent(SimulatedClockWithFrames* clock, bool stop_on_frame)
365 : clock_(clock), stop_on_frame_(stop_on_frame) {}
366
367 bool Set() override { return true; }
368
philipel9d3ab612015-12-21 04:12:39 -0800369 EventTypeWrapper Wait(unsigned long max_time) override { // NOLINT
Qiang Chend4cec152015-06-19 09:17:00 -0700370 if (clock_->AdvanceTimeMilliseconds(max_time, stop_on_frame_) &&
371 stop_on_frame_) {
372 return EventTypeWrapper::kEventSignaled;
373 } else {
374 return EventTypeWrapper::kEventTimeout;
375 }
376 }
377
378 private:
379 SimulatedClockWithFrames* clock_;
380 bool stop_on_frame_;
381};
382
383class VCMReceiverTimingTest : public ::testing::Test {
384 protected:
Qiang Chend4cec152015-06-19 09:17:00 -0700385 VCMReceiverTimingTest()
386
387 : clock_(&stream_generator_, &receiver_),
388 stream_generator_(0, clock_.TimeInMilliseconds()),
389 timing_(&clock_),
390 receiver_(
391 &timing_,
392 &clock_,
kwiberg3f55dea2016-02-29 05:51:59 -0800393 std::unique_ptr<EventWrapper>(new FrameInjectEvent(&clock_, false)),
394 std::unique_ptr<EventWrapper>(
Qiang Chend4cec152015-06-19 09:17:00 -0700395 new FrameInjectEvent(&clock_, true))) {}
396
Qiang Chend4cec152015-06-19 09:17:00 -0700397 virtual void SetUp() { receiver_.Reset(); }
398
399 SimulatedClockWithFrames clock_;
400 StreamGenerator stream_generator_;
401 VCMTiming timing_;
402 VCMReceiver receiver_;
403};
404
405// Test whether VCMReceiver::FrameForDecoding handles parameter
406// |max_wait_time_ms| correctly:
407// 1. The function execution should never take more than |max_wait_time_ms|.
408// 2. If the function exit before now + |max_wait_time_ms|, a frame must be
409// returned.
410TEST_F(VCMReceiverTimingTest, FrameForDecoding) {
411 const size_t kNumFrames = 100;
412 const int kFramePeriod = 40;
413 int64_t arrive_timestamps[kNumFrames];
414 int64_t render_timestamps[kNumFrames];
415 int64_t next_render_time;
416
417 // Construct test samples.
418 // render_timestamps are the timestamps stored in the Frame;
419 // arrive_timestamps controls when the Frame packet got received.
420 for (size_t i = 0; i < kNumFrames; i++) {
421 // Preset frame rate to 25Hz.
422 // But we add a reasonable deviation to arrive_timestamps to mimic Internet
423 // fluctuation.
424 arrive_timestamps[i] =
425 (i + 1) * kFramePeriod + (i % 10) * ((i % 2) ? 1 : -1);
426 render_timestamps[i] = (i + 1) * kFramePeriod;
427 }
428
429 clock_.SetFrames(arrive_timestamps, render_timestamps, kNumFrames);
430
431 // Record how many frames we finally get out of the receiver.
432 size_t num_frames_return = 0;
433
434 const int64_t kMaxWaitTime = 30;
435
436 // Ideally, we should get all frames that we input in InitializeFrames.
437 // In the case that FrameForDecoding kills frames by error, we rely on the
438 // build bot to kill the test.
439 while (num_frames_return < kNumFrames) {
440 int64_t start_time = clock_.TimeInMilliseconds();
441 VCMEncodedFrame* frame =
philipel9d3ab612015-12-21 04:12:39 -0800442 receiver_.FrameForDecoding(kMaxWaitTime, &next_render_time, false);
Qiang Chend4cec152015-06-19 09:17:00 -0700443 int64_t end_time = clock_.TimeInMilliseconds();
444
445 // In any case the FrameForDecoding should not wait longer than
446 // max_wait_time.
447 // In the case that we did not get a frame, it should have been waiting for
448 // exactly max_wait_time. (By the testing samples we constructed above, we
449 // are sure there is no timing error, so the only case it returns with NULL
450 // is that it runs out of time.)
451 if (frame) {
452 receiver_.ReleaseFrame(frame);
453 ++num_frames_return;
454 EXPECT_GE(kMaxWaitTime, end_time - start_time);
455 } else {
456 EXPECT_EQ(kMaxWaitTime, end_time - start_time);
457 }
458 }
459}
460
perkj796cfaf2015-12-10 09:27:38 -0800461// Test whether VCMReceiver::FrameForDecoding handles parameter
462// |prefer_late_decoding| and |max_wait_time_ms| correctly:
463// 1. The function execution should never take more than |max_wait_time_ms|.
464// 2. If the function exit before now + |max_wait_time_ms|, a frame must be
465// returned and the end time must be equal to the render timestamp - delay
466// for decoding and rendering.
467TEST_F(VCMReceiverTimingTest, FrameForDecodingPreferLateDecoding) {
468 const size_t kNumFrames = 100;
469 const int kFramePeriod = 40;
470
471 int64_t arrive_timestamps[kNumFrames];
472 int64_t render_timestamps[kNumFrames];
473 int64_t next_render_time;
474
475 int render_delay_ms;
476 int max_decode_ms;
477 int dummy;
478 timing_.GetTimings(&dummy, &max_decode_ms, &dummy, &dummy, &dummy, &dummy,
479 &render_delay_ms);
480
481 // Construct test samples.
482 // render_timestamps are the timestamps stored in the Frame;
483 // arrive_timestamps controls when the Frame packet got received.
484 for (size_t i = 0; i < kNumFrames; i++) {
485 // Preset frame rate to 25Hz.
486 // But we add a reasonable deviation to arrive_timestamps to mimic Internet
487 // fluctuation.
488 arrive_timestamps[i] =
489 (i + 1) * kFramePeriod + (i % 10) * ((i % 2) ? 1 : -1);
490 render_timestamps[i] = (i + 1) * kFramePeriod;
491 }
492
493 clock_.SetFrames(arrive_timestamps, render_timestamps, kNumFrames);
494
495 // Record how many frames we finally get out of the receiver.
496 size_t num_frames_return = 0;
497 const int64_t kMaxWaitTime = 30;
498 bool prefer_late_decoding = true;
499 while (num_frames_return < kNumFrames) {
500 int64_t start_time = clock_.TimeInMilliseconds();
501
philipel9d3ab612015-12-21 04:12:39 -0800502 VCMEncodedFrame* frame = receiver_.FrameForDecoding(
503 kMaxWaitTime, &next_render_time, prefer_late_decoding);
perkj796cfaf2015-12-10 09:27:38 -0800504 int64_t end_time = clock_.TimeInMilliseconds();
505 if (frame) {
506 EXPECT_EQ(frame->RenderTimeMs() - max_decode_ms - render_delay_ms,
507 end_time);
508 receiver_.ReleaseFrame(frame);
509 ++num_frames_return;
510 } else {
511 EXPECT_EQ(kMaxWaitTime, end_time - start_time);
512 }
513 }
514}
515
mikhal@webrtc.org381da4b2013-04-25 21:45:29 +0000516} // namespace webrtc