blob: b2a3a361e7c252ad819608e9373fa53da43b2e44 [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() {
Johan Ahlers31b2ec42016-06-28 13:32:49 +020076 VCMEncodedFrame* frame = receiver_.FrameForDecoding(0, false);
stefan@webrtc.orgef144882013-05-07 19:16:33 +000077 if (!frame)
78 return false;
79 receiver_.ReleaseFrame(frame);
80 return true;
81 }
82
kwiberg3f55dea2016-02-29 05:51:59 -080083 std::unique_ptr<SimulatedClock> clock_;
mikhal@webrtc.org381da4b2013-04-25 21:45:29 +000084 VCMTiming timing_;
85 NullEventFactory event_factory_;
86 VCMReceiver receiver_;
kwiberg3f55dea2016-02-29 05:51:59 -080087 std::unique_ptr<StreamGenerator> stream_generator_;
mikhal@webrtc.org381da4b2013-04-25 21:45:29 +000088};
89
stefan@webrtc.orgef144882013-05-07 19:16:33 +000090TEST_F(TestVCMReceiver, NonDecodableDuration_Empty) {
91 // Enable NACK and with no RTT thresholds for disabling retransmission delay.
92 receiver_.SetNackMode(kNack, -1, -1);
93 const size_t kMaxNackListSize = 1000;
94 const int kMaxPacketAgeToNack = 1000;
95 const int kMaxNonDecodableDuration = 500;
96 const int kMinDelayMs = 500;
97 receiver_.SetNackSettings(kMaxNackListSize, kMaxPacketAgeToNack,
philipel9d3ab612015-12-21 04:12:39 -080098 kMaxNonDecodableDuration);
stefan@webrtc.orgef144882013-05-07 19:16:33 +000099 EXPECT_GE(InsertFrame(kVideoFrameKey, true), kNoError);
100 // Advance time until it's time to decode the key frame.
101 clock_->AdvanceTimeMilliseconds(kMinDelayMs);
102 EXPECT_TRUE(DecodeNextFrame());
Wan-Teh Changb1825a42015-06-03 15:03:35 -0700103 bool request_key_frame = false;
104 std::vector<uint16_t> nack_list = receiver_.NackList(&request_key_frame);
105 EXPECT_FALSE(request_key_frame);
stefan@webrtc.orgef144882013-05-07 19:16:33 +0000106}
107
108TEST_F(TestVCMReceiver, NonDecodableDuration_NoKeyFrame) {
109 // Enable NACK and with no RTT thresholds for disabling retransmission delay.
110 receiver_.SetNackMode(kNack, -1, -1);
111 const size_t kMaxNackListSize = 1000;
112 const int kMaxPacketAgeToNack = 1000;
113 const int kMaxNonDecodableDuration = 500;
114 receiver_.SetNackSettings(kMaxNackListSize, kMaxPacketAgeToNack,
philipel9d3ab612015-12-21 04:12:39 -0800115 kMaxNonDecodableDuration);
stefan@webrtc.orgef144882013-05-07 19:16:33 +0000116 const int kNumFrames = kDefaultFrameRate * kMaxNonDecodableDuration / 1000;
117 for (int i = 0; i < kNumFrames; ++i) {
118 EXPECT_GE(InsertFrame(kVideoFrameDelta, true), kNoError);
119 }
Wan-Teh Changb1825a42015-06-03 15:03:35 -0700120 bool request_key_frame = false;
121 std::vector<uint16_t> nack_list = receiver_.NackList(&request_key_frame);
122 EXPECT_TRUE(request_key_frame);
stefan@webrtc.orgef144882013-05-07 19:16:33 +0000123}
124
125TEST_F(TestVCMReceiver, NonDecodableDuration_OneIncomplete) {
126 // Enable NACK and with no RTT thresholds for disabling retransmission delay.
127 receiver_.SetNackMode(kNack, -1, -1);
128 const size_t kMaxNackListSize = 1000;
129 const int kMaxPacketAgeToNack = 1000;
130 const int kMaxNonDecodableDuration = 500;
philipel9d3ab612015-12-21 04:12:39 -0800131 const int kMaxNonDecodableDurationFrames =
132 (kDefaultFrameRate * kMaxNonDecodableDuration + 500) / 1000;
stefan@webrtc.orgef144882013-05-07 19:16:33 +0000133 const int kMinDelayMs = 500;
134 receiver_.SetNackSettings(kMaxNackListSize, kMaxPacketAgeToNack,
philipel9d3ab612015-12-21 04:12:39 -0800135 kMaxNonDecodableDuration);
stefan@webrtc.orgef144882013-05-07 19:16:33 +0000136 receiver_.SetMinReceiverDelay(kMinDelayMs);
137 int64_t key_frame_inserted = clock_->TimeInMilliseconds();
138 EXPECT_GE(InsertFrame(kVideoFrameKey, true), kNoError);
139 // Insert an incomplete frame.
140 EXPECT_GE(InsertFrame(kVideoFrameDelta, false), kNoError);
141 // Insert enough frames to have too long non-decodable sequence.
philipel9d3ab612015-12-21 04:12:39 -0800142 for (int i = 0; i < kMaxNonDecodableDurationFrames; ++i) {
stefan@webrtc.orgef144882013-05-07 19:16:33 +0000143 EXPECT_GE(InsertFrame(kVideoFrameDelta, true), kNoError);
144 }
145 // Advance time until it's time to decode the key frame.
146 clock_->AdvanceTimeMilliseconds(kMinDelayMs - clock_->TimeInMilliseconds() -
philipel9d3ab612015-12-21 04:12:39 -0800147 key_frame_inserted);
stefan@webrtc.orgef144882013-05-07 19:16:33 +0000148 EXPECT_TRUE(DecodeNextFrame());
149 // Make sure we get a key frame request.
Wan-Teh Changb1825a42015-06-03 15:03:35 -0700150 bool request_key_frame = false;
151 std::vector<uint16_t> nack_list = receiver_.NackList(&request_key_frame);
152 EXPECT_TRUE(request_key_frame);
stefan@webrtc.orgef144882013-05-07 19:16:33 +0000153}
154
155TEST_F(TestVCMReceiver, NonDecodableDuration_NoTrigger) {
156 // Enable NACK and with no RTT thresholds for disabling retransmission delay.
157 receiver_.SetNackMode(kNack, -1, -1);
158 const size_t kMaxNackListSize = 1000;
159 const int kMaxPacketAgeToNack = 1000;
160 const int kMaxNonDecodableDuration = 500;
philipel9d3ab612015-12-21 04:12:39 -0800161 const int kMaxNonDecodableDurationFrames =
162 (kDefaultFrameRate * kMaxNonDecodableDuration + 500) / 1000;
stefan@webrtc.orgef144882013-05-07 19:16:33 +0000163 const int kMinDelayMs = 500;
164 receiver_.SetNackSettings(kMaxNackListSize, kMaxPacketAgeToNack,
philipel9d3ab612015-12-21 04:12:39 -0800165 kMaxNonDecodableDuration);
stefan@webrtc.orgef144882013-05-07 19:16:33 +0000166 receiver_.SetMinReceiverDelay(kMinDelayMs);
167 int64_t key_frame_inserted = clock_->TimeInMilliseconds();
168 EXPECT_GE(InsertFrame(kVideoFrameKey, true), kNoError);
169 // Insert an incomplete frame.
170 EXPECT_GE(InsertFrame(kVideoFrameDelta, false), kNoError);
171 // Insert all but one frame to not trigger a key frame request due to
172 // too long duration of non-decodable frames.
philipel9d3ab612015-12-21 04:12:39 -0800173 for (int i = 0; i < kMaxNonDecodableDurationFrames - 1; ++i) {
stefan@webrtc.orgef144882013-05-07 19:16:33 +0000174 EXPECT_GE(InsertFrame(kVideoFrameDelta, true), kNoError);
175 }
176 // Advance time until it's time to decode the key frame.
177 clock_->AdvanceTimeMilliseconds(kMinDelayMs - clock_->TimeInMilliseconds() -
philipel9d3ab612015-12-21 04:12:39 -0800178 key_frame_inserted);
stefan@webrtc.orgef144882013-05-07 19:16:33 +0000179 EXPECT_TRUE(DecodeNextFrame());
180 // Make sure we don't get a key frame request since we haven't generated
181 // enough frames.
Wan-Teh Changb1825a42015-06-03 15:03:35 -0700182 bool request_key_frame = false;
183 std::vector<uint16_t> nack_list = receiver_.NackList(&request_key_frame);
184 EXPECT_FALSE(request_key_frame);
stefan@webrtc.orgef144882013-05-07 19:16:33 +0000185}
186
stefan@webrtc.org16734812013-05-14 12:00:47 +0000187TEST_F(TestVCMReceiver, NonDecodableDuration_NoTrigger2) {
188 // Enable NACK and with no RTT thresholds for disabling retransmission delay.
189 receiver_.SetNackMode(kNack, -1, -1);
190 const size_t kMaxNackListSize = 1000;
191 const int kMaxPacketAgeToNack = 1000;
192 const int kMaxNonDecodableDuration = 500;
philipel9d3ab612015-12-21 04:12:39 -0800193 const int kMaxNonDecodableDurationFrames =
194 (kDefaultFrameRate * kMaxNonDecodableDuration + 500) / 1000;
stefan@webrtc.org16734812013-05-14 12:00:47 +0000195 const int kMinDelayMs = 500;
196 receiver_.SetNackSettings(kMaxNackListSize, kMaxPacketAgeToNack,
philipel9d3ab612015-12-21 04:12:39 -0800197 kMaxNonDecodableDuration);
stefan@webrtc.org16734812013-05-14 12:00:47 +0000198 receiver_.SetMinReceiverDelay(kMinDelayMs);
199 int64_t key_frame_inserted = clock_->TimeInMilliseconds();
200 EXPECT_GE(InsertFrame(kVideoFrameKey, true), kNoError);
201 // Insert enough frames to have too long non-decodable sequence, except that
202 // we don't have any losses.
philipel9d3ab612015-12-21 04:12:39 -0800203 for (int i = 0; i < kMaxNonDecodableDurationFrames; ++i) {
stefan@webrtc.org16734812013-05-14 12:00:47 +0000204 EXPECT_GE(InsertFrame(kVideoFrameDelta, true), kNoError);
205 }
206 // Insert an incomplete frame.
207 EXPECT_GE(InsertFrame(kVideoFrameDelta, false), kNoError);
208 // Advance time until it's time to decode the key frame.
209 clock_->AdvanceTimeMilliseconds(kMinDelayMs - clock_->TimeInMilliseconds() -
philipel9d3ab612015-12-21 04:12:39 -0800210 key_frame_inserted);
stefan@webrtc.org16734812013-05-14 12:00:47 +0000211 EXPECT_TRUE(DecodeNextFrame());
212 // Make sure we don't get a key frame request since the non-decodable duration
213 // is only one frame.
Wan-Teh Changb1825a42015-06-03 15:03:35 -0700214 bool request_key_frame = false;
215 std::vector<uint16_t> nack_list = receiver_.NackList(&request_key_frame);
216 EXPECT_FALSE(request_key_frame);
stefan@webrtc.org16734812013-05-14 12:00:47 +0000217}
218
stefan@webrtc.orgef144882013-05-07 19:16:33 +0000219TEST_F(TestVCMReceiver, NonDecodableDuration_KeyFrameAfterIncompleteFrames) {
220 // Enable NACK and with no RTT thresholds for disabling retransmission delay.
221 receiver_.SetNackMode(kNack, -1, -1);
222 const size_t kMaxNackListSize = 1000;
223 const int kMaxPacketAgeToNack = 1000;
224 const int kMaxNonDecodableDuration = 500;
philipel9d3ab612015-12-21 04:12:39 -0800225 const int kMaxNonDecodableDurationFrames =
226 (kDefaultFrameRate * kMaxNonDecodableDuration + 500) / 1000;
stefan@webrtc.orgef144882013-05-07 19:16:33 +0000227 const int kMinDelayMs = 500;
228 receiver_.SetNackSettings(kMaxNackListSize, kMaxPacketAgeToNack,
philipel9d3ab612015-12-21 04:12:39 -0800229 kMaxNonDecodableDuration);
stefan@webrtc.orgef144882013-05-07 19:16:33 +0000230 receiver_.SetMinReceiverDelay(kMinDelayMs);
231 int64_t key_frame_inserted = clock_->TimeInMilliseconds();
232 EXPECT_GE(InsertFrame(kVideoFrameKey, true), kNoError);
233 // Insert an incomplete frame.
234 EXPECT_GE(InsertFrame(kVideoFrameDelta, false), kNoError);
235 // Insert enough frames to have too long non-decodable sequence.
philipel9d3ab612015-12-21 04:12:39 -0800236 for (int i = 0; i < kMaxNonDecodableDurationFrames; ++i) {
stefan@webrtc.orgef144882013-05-07 19:16:33 +0000237 EXPECT_GE(InsertFrame(kVideoFrameDelta, true), kNoError);
238 }
239 EXPECT_GE(InsertFrame(kVideoFrameKey, true), kNoError);
240 // Advance time until it's time to decode the key frame.
241 clock_->AdvanceTimeMilliseconds(kMinDelayMs - clock_->TimeInMilliseconds() -
philipel9d3ab612015-12-21 04:12:39 -0800242 key_frame_inserted);
stefan@webrtc.orgef144882013-05-07 19:16:33 +0000243 EXPECT_TRUE(DecodeNextFrame());
244 // Make sure we don't get a key frame request since we have a key frame
245 // in the list.
Wan-Teh Changb1825a42015-06-03 15:03:35 -0700246 bool request_key_frame = false;
247 std::vector<uint16_t> nack_list = receiver_.NackList(&request_key_frame);
248 EXPECT_FALSE(request_key_frame);
stefan@webrtc.orgef144882013-05-07 19:16:33 +0000249}
Qiang Chend4cec152015-06-19 09:17:00 -0700250
251// A simulated clock, when time elapses, will insert frames into the jitter
252// buffer, based on initial settings.
253class SimulatedClockWithFrames : public SimulatedClock {
254 public:
255 SimulatedClockWithFrames(StreamGenerator* stream_generator,
256 VCMReceiver* receiver)
257 : SimulatedClock(0),
258 stream_generator_(stream_generator),
259 receiver_(receiver) {}
260 virtual ~SimulatedClockWithFrames() {}
261
262 // If |stop_on_frame| is true and next frame arrives between now and
263 // now+|milliseconds|, the clock will be advanced to the arrival time of next
264 // frame.
265 // Otherwise, the clock will be advanced by |milliseconds|.
266 //
267 // For both cases, a frame will be inserted into the jitter buffer at the
268 // instant when the clock time is timestamps_.front().arrive_time.
269 //
270 // Return true if some frame arrives between now and now+|milliseconds|.
271 bool AdvanceTimeMilliseconds(int64_t milliseconds, bool stop_on_frame) {
272 return AdvanceTimeMicroseconds(milliseconds * 1000, stop_on_frame);
philipel9d3ab612015-12-21 04:12:39 -0800273 }
Qiang Chend4cec152015-06-19 09:17:00 -0700274
275 bool AdvanceTimeMicroseconds(int64_t microseconds, bool stop_on_frame) {
276 int64_t start_time = TimeInMicroseconds();
277 int64_t end_time = start_time + microseconds;
278 bool frame_injected = false;
279 while (!timestamps_.empty() &&
280 timestamps_.front().arrive_time <= end_time) {
henrikg91d6ede2015-09-17 00:24:34 -0700281 RTC_DCHECK(timestamps_.front().arrive_time >= start_time);
Qiang Chend4cec152015-06-19 09:17:00 -0700282
283 SimulatedClock::AdvanceTimeMicroseconds(timestamps_.front().arrive_time -
284 TimeInMicroseconds());
285 GenerateAndInsertFrame((timestamps_.front().render_time + 500) / 1000);
286 timestamps_.pop();
287 frame_injected = true;
288
289 if (stop_on_frame)
290 return frame_injected;
291 }
292
293 if (TimeInMicroseconds() < end_time) {
294 SimulatedClock::AdvanceTimeMicroseconds(end_time - TimeInMicroseconds());
295 }
296 return frame_injected;
philipel9d3ab612015-12-21 04:12:39 -0800297 }
Qiang Chend4cec152015-06-19 09:17:00 -0700298
299 // Input timestamps are in unit Milliseconds.
300 // And |arrive_timestamps| must be positive and in increasing order.
301 // |arrive_timestamps| determine when we are going to insert frames into the
302 // jitter buffer.
303 // |render_timestamps| are the timestamps on the frame.
304 void SetFrames(const int64_t* arrive_timestamps,
305 const int64_t* render_timestamps,
306 size_t size) {
307 int64_t previous_arrive_timestamp = 0;
308 for (size_t i = 0; i < size; i++) {
henrikg91d6ede2015-09-17 00:24:34 -0700309 RTC_CHECK(arrive_timestamps[i] >= previous_arrive_timestamp);
Qiang Chend4cec152015-06-19 09:17:00 -0700310 timestamps_.push(TimestampPair(arrive_timestamps[i] * 1000,
311 render_timestamps[i] * 1000));
312 previous_arrive_timestamp = arrive_timestamps[i];
313 }
314 }
315
316 private:
317 struct TimestampPair {
318 TimestampPair(int64_t arrive_timestamp, int64_t render_timestamp)
319 : arrive_time(arrive_timestamp), render_time(render_timestamp) {}
320
321 int64_t arrive_time;
322 int64_t render_time;
323 };
324
325 void GenerateAndInsertFrame(int64_t render_timestamp_ms) {
326 VCMPacket packet;
327 stream_generator_->GenerateFrame(FrameType::kVideoFrameKey,
328 1, // media packets
329 0, // empty packets
330 render_timestamp_ms);
331
332 bool packet_available = stream_generator_->PopPacket(&packet, 0);
333 EXPECT_TRUE(packet_available);
334 if (!packet_available)
335 return; // Return here to avoid crashes below.
Johan Ahlers95348f72016-06-28 11:11:28 +0200336 receiver_->InsertPacket(packet);
Qiang Chend4cec152015-06-19 09:17:00 -0700337 }
338
339 std::queue<TimestampPair> timestamps_;
340 StreamGenerator* stream_generator_;
341 VCMReceiver* receiver_;
342};
343
344// Use a SimulatedClockWithFrames
345// Wait call will do either of these:
346// 1. If |stop_on_frame| is true, the clock will be turned to the exact instant
347// that the first frame comes and the frame will be inserted into the jitter
348// buffer, or the clock will be turned to now + |max_time| if no frame comes in
349// the window.
350// 2. If |stop_on_frame| is false, the clock will be turn to now + |max_time|,
351// and all the frames arriving between now and now + |max_time| will be
352// inserted into the jitter buffer.
353//
354// This is used to simulate the JitterBuffer getting packets from internet as
355// time elapses.
356
357class FrameInjectEvent : public EventWrapper {
358 public:
359 FrameInjectEvent(SimulatedClockWithFrames* clock, bool stop_on_frame)
360 : clock_(clock), stop_on_frame_(stop_on_frame) {}
361
362 bool Set() override { return true; }
363
philipel9d3ab612015-12-21 04:12:39 -0800364 EventTypeWrapper Wait(unsigned long max_time) override { // NOLINT
Qiang Chend4cec152015-06-19 09:17:00 -0700365 if (clock_->AdvanceTimeMilliseconds(max_time, stop_on_frame_) &&
366 stop_on_frame_) {
367 return EventTypeWrapper::kEventSignaled;
368 } else {
369 return EventTypeWrapper::kEventTimeout;
370 }
371 }
372
373 private:
374 SimulatedClockWithFrames* clock_;
375 bool stop_on_frame_;
376};
377
378class VCMReceiverTimingTest : public ::testing::Test {
379 protected:
Qiang Chend4cec152015-06-19 09:17:00 -0700380 VCMReceiverTimingTest()
381
382 : clock_(&stream_generator_, &receiver_),
383 stream_generator_(0, clock_.TimeInMilliseconds()),
384 timing_(&clock_),
385 receiver_(
386 &timing_,
387 &clock_,
kwiberg3f55dea2016-02-29 05:51:59 -0800388 std::unique_ptr<EventWrapper>(new FrameInjectEvent(&clock_, false)),
389 std::unique_ptr<EventWrapper>(
Qiang Chend4cec152015-06-19 09:17:00 -0700390 new FrameInjectEvent(&clock_, true))) {}
391
Qiang Chend4cec152015-06-19 09:17:00 -0700392 virtual void SetUp() { receiver_.Reset(); }
393
394 SimulatedClockWithFrames clock_;
395 StreamGenerator stream_generator_;
396 VCMTiming timing_;
397 VCMReceiver receiver_;
398};
399
400// Test whether VCMReceiver::FrameForDecoding handles parameter
401// |max_wait_time_ms| correctly:
402// 1. The function execution should never take more than |max_wait_time_ms|.
403// 2. If the function exit before now + |max_wait_time_ms|, a frame must be
404// returned.
405TEST_F(VCMReceiverTimingTest, FrameForDecoding) {
406 const size_t kNumFrames = 100;
407 const int kFramePeriod = 40;
408 int64_t arrive_timestamps[kNumFrames];
409 int64_t render_timestamps[kNumFrames];
Qiang Chend4cec152015-06-19 09:17:00 -0700410
411 // Construct test samples.
412 // render_timestamps are the timestamps stored in the Frame;
413 // arrive_timestamps controls when the Frame packet got received.
414 for (size_t i = 0; i < kNumFrames; i++) {
415 // Preset frame rate to 25Hz.
416 // But we add a reasonable deviation to arrive_timestamps to mimic Internet
417 // fluctuation.
418 arrive_timestamps[i] =
419 (i + 1) * kFramePeriod + (i % 10) * ((i % 2) ? 1 : -1);
420 render_timestamps[i] = (i + 1) * kFramePeriod;
421 }
422
423 clock_.SetFrames(arrive_timestamps, render_timestamps, kNumFrames);
424
425 // Record how many frames we finally get out of the receiver.
426 size_t num_frames_return = 0;
427
428 const int64_t kMaxWaitTime = 30;
429
430 // Ideally, we should get all frames that we input in InitializeFrames.
431 // In the case that FrameForDecoding kills frames by error, we rely on the
432 // build bot to kill the test.
433 while (num_frames_return < kNumFrames) {
434 int64_t start_time = clock_.TimeInMilliseconds();
Johan Ahlers31b2ec42016-06-28 13:32:49 +0200435 VCMEncodedFrame* frame = receiver_.FrameForDecoding(kMaxWaitTime, false);
Qiang Chend4cec152015-06-19 09:17:00 -0700436 int64_t end_time = clock_.TimeInMilliseconds();
437
438 // In any case the FrameForDecoding should not wait longer than
439 // max_wait_time.
440 // In the case that we did not get a frame, it should have been waiting for
441 // exactly max_wait_time. (By the testing samples we constructed above, we
442 // are sure there is no timing error, so the only case it returns with NULL
443 // is that it runs out of time.)
444 if (frame) {
445 receiver_.ReleaseFrame(frame);
446 ++num_frames_return;
447 EXPECT_GE(kMaxWaitTime, end_time - start_time);
448 } else {
449 EXPECT_EQ(kMaxWaitTime, end_time - start_time);
450 }
451 }
452}
453
perkj796cfaf2015-12-10 09:27:38 -0800454// Test whether VCMReceiver::FrameForDecoding handles parameter
455// |prefer_late_decoding| and |max_wait_time_ms| correctly:
456// 1. The function execution should never take more than |max_wait_time_ms|.
457// 2. If the function exit before now + |max_wait_time_ms|, a frame must be
458// returned and the end time must be equal to the render timestamp - delay
459// for decoding and rendering.
460TEST_F(VCMReceiverTimingTest, FrameForDecodingPreferLateDecoding) {
461 const size_t kNumFrames = 100;
462 const int kFramePeriod = 40;
463
464 int64_t arrive_timestamps[kNumFrames];
465 int64_t render_timestamps[kNumFrames];
perkj796cfaf2015-12-10 09:27:38 -0800466
467 int render_delay_ms;
468 int max_decode_ms;
469 int dummy;
470 timing_.GetTimings(&dummy, &max_decode_ms, &dummy, &dummy, &dummy, &dummy,
471 &render_delay_ms);
472
473 // Construct test samples.
474 // render_timestamps are the timestamps stored in the Frame;
475 // arrive_timestamps controls when the Frame packet got received.
476 for (size_t i = 0; i < kNumFrames; i++) {
477 // Preset frame rate to 25Hz.
478 // But we add a reasonable deviation to arrive_timestamps to mimic Internet
479 // fluctuation.
480 arrive_timestamps[i] =
481 (i + 1) * kFramePeriod + (i % 10) * ((i % 2) ? 1 : -1);
482 render_timestamps[i] = (i + 1) * kFramePeriod;
483 }
484
485 clock_.SetFrames(arrive_timestamps, render_timestamps, kNumFrames);
486
487 // Record how many frames we finally get out of the receiver.
488 size_t num_frames_return = 0;
489 const int64_t kMaxWaitTime = 30;
490 bool prefer_late_decoding = true;
491 while (num_frames_return < kNumFrames) {
492 int64_t start_time = clock_.TimeInMilliseconds();
493
Johan Ahlers31b2ec42016-06-28 13:32:49 +0200494 VCMEncodedFrame* frame =
495 receiver_.FrameForDecoding(kMaxWaitTime, prefer_late_decoding);
perkj796cfaf2015-12-10 09:27:38 -0800496 int64_t end_time = clock_.TimeInMilliseconds();
497 if (frame) {
498 EXPECT_EQ(frame->RenderTimeMs() - max_decode_ms - render_delay_ms,
499 end_time);
500 receiver_.ReleaseFrame(frame);
501 ++num_frames_return;
502 } else {
503 EXPECT_EQ(kMaxWaitTime, end_time - start_time);
504 }
505 }
506}
507
mikhal@webrtc.org381da4b2013-04-25 21:45:29 +0000508} // namespace webrtc