blob: 42cc9ac0a88237e8efffb213c10cbf47d1775445 [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
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,
philipel9d3ab612015-12-21 04:12:39 -0800118 receiver_.RenderBufferSizeMs());
stefan@webrtc.orgef144882013-05-07 19:16:33 +0000119}
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,
philipel9d3ab612015-12-21 04:12:39 -0800134 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;
perkj796cfaf2015-12-10 09:27:38 -0800144 VCMEncodedFrame* frame =
philipel9d3ab612015-12-21 04:12:39 -0800145 receiver_.FrameForDecoding(10, &next_render_time_ms, false);
mikhal@webrtc.org759b0412013-05-07 16:36:00 +0000146 EXPECT_TRUE(frame == NULL);
147 receiver_.ReleaseFrame(frame);
mikhal@webrtc.org381da4b2013-04-25 21:45:29 +0000148 EXPECT_GE(InsertFrame(kVideoFrameDelta, false), kNoError);
149 for (int i = 0; i < num_of_frames; ++i) {
150 EXPECT_GE(InsertFrame(kVideoFrameDelta, true), kNoError);
151 }
152 EXPECT_EQ(0, receiver_.RenderBufferSizeMs());
153}
154
stefan@webrtc.orgef144882013-05-07 19:16:33 +0000155TEST_F(TestVCMReceiver, NonDecodableDuration_Empty) {
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;
161 const int kMinDelayMs = 500;
162 receiver_.SetNackSettings(kMaxNackListSize, kMaxPacketAgeToNack,
philipel9d3ab612015-12-21 04:12:39 -0800163 kMaxNonDecodableDuration);
stefan@webrtc.orgef144882013-05-07 19:16:33 +0000164 EXPECT_GE(InsertFrame(kVideoFrameKey, true), kNoError);
165 // Advance time until it's time to decode the key frame.
166 clock_->AdvanceTimeMilliseconds(kMinDelayMs);
167 EXPECT_TRUE(DecodeNextFrame());
Wan-Teh Changb1825a42015-06-03 15:03:35 -0700168 bool request_key_frame = false;
169 std::vector<uint16_t> nack_list = receiver_.NackList(&request_key_frame);
170 EXPECT_FALSE(request_key_frame);
stefan@webrtc.orgef144882013-05-07 19:16:33 +0000171}
172
173TEST_F(TestVCMReceiver, NonDecodableDuration_NoKeyFrame) {
174 // Enable NACK and with no RTT thresholds for disabling retransmission delay.
175 receiver_.SetNackMode(kNack, -1, -1);
176 const size_t kMaxNackListSize = 1000;
177 const int kMaxPacketAgeToNack = 1000;
178 const int kMaxNonDecodableDuration = 500;
179 receiver_.SetNackSettings(kMaxNackListSize, kMaxPacketAgeToNack,
philipel9d3ab612015-12-21 04:12:39 -0800180 kMaxNonDecodableDuration);
stefan@webrtc.orgef144882013-05-07 19:16:33 +0000181 const int kNumFrames = kDefaultFrameRate * kMaxNonDecodableDuration / 1000;
182 for (int i = 0; i < kNumFrames; ++i) {
183 EXPECT_GE(InsertFrame(kVideoFrameDelta, true), kNoError);
184 }
Wan-Teh Changb1825a42015-06-03 15:03:35 -0700185 bool request_key_frame = false;
186 std::vector<uint16_t> nack_list = receiver_.NackList(&request_key_frame);
187 EXPECT_TRUE(request_key_frame);
stefan@webrtc.orgef144882013-05-07 19:16:33 +0000188}
189
190TEST_F(TestVCMReceiver, NonDecodableDuration_OneIncomplete) {
191 // Enable NACK and with no RTT thresholds for disabling retransmission delay.
192 receiver_.SetNackMode(kNack, -1, -1);
193 const size_t kMaxNackListSize = 1000;
194 const int kMaxPacketAgeToNack = 1000;
195 const int kMaxNonDecodableDuration = 500;
philipel9d3ab612015-12-21 04:12:39 -0800196 const int kMaxNonDecodableDurationFrames =
197 (kDefaultFrameRate * kMaxNonDecodableDuration + 500) / 1000;
stefan@webrtc.orgef144882013-05-07 19:16:33 +0000198 const int kMinDelayMs = 500;
199 receiver_.SetNackSettings(kMaxNackListSize, kMaxPacketAgeToNack,
philipel9d3ab612015-12-21 04:12:39 -0800200 kMaxNonDecodableDuration);
stefan@webrtc.orgef144882013-05-07 19:16:33 +0000201 receiver_.SetMinReceiverDelay(kMinDelayMs);
202 int64_t key_frame_inserted = clock_->TimeInMilliseconds();
203 EXPECT_GE(InsertFrame(kVideoFrameKey, true), kNoError);
204 // Insert an incomplete frame.
205 EXPECT_GE(InsertFrame(kVideoFrameDelta, false), kNoError);
206 // Insert enough frames to have too long non-decodable sequence.
philipel9d3ab612015-12-21 04:12:39 -0800207 for (int i = 0; i < kMaxNonDecodableDurationFrames; ++i) {
stefan@webrtc.orgef144882013-05-07 19:16:33 +0000208 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() -
philipel9d3ab612015-12-21 04:12:39 -0800212 key_frame_inserted);
stefan@webrtc.orgef144882013-05-07 19:16:33 +0000213 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;
philipel9d3ab612015-12-21 04:12:39 -0800226 const int kMaxNonDecodableDurationFrames =
227 (kDefaultFrameRate * kMaxNonDecodableDuration + 500) / 1000;
stefan@webrtc.orgef144882013-05-07 19:16:33 +0000228 const int kMinDelayMs = 500;
229 receiver_.SetNackSettings(kMaxNackListSize, kMaxPacketAgeToNack,
philipel9d3ab612015-12-21 04:12:39 -0800230 kMaxNonDecodableDuration);
stefan@webrtc.orgef144882013-05-07 19:16:33 +0000231 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.
philipel9d3ab612015-12-21 04:12:39 -0800238 for (int i = 0; i < kMaxNonDecodableDurationFrames - 1; ++i) {
stefan@webrtc.orgef144882013-05-07 19:16:33 +0000239 EXPECT_GE(InsertFrame(kVideoFrameDelta, true), kNoError);
240 }
241 // Advance time until it's time to decode the key frame.
242 clock_->AdvanceTimeMilliseconds(kMinDelayMs - clock_->TimeInMilliseconds() -
philipel9d3ab612015-12-21 04:12:39 -0800243 key_frame_inserted);
stefan@webrtc.orgef144882013-05-07 19:16:33 +0000244 EXPECT_TRUE(DecodeNextFrame());
245 // Make sure we don't get a key frame request since we haven't generated
246 // enough frames.
Wan-Teh Changb1825a42015-06-03 15:03:35 -0700247 bool request_key_frame = false;
248 std::vector<uint16_t> nack_list = receiver_.NackList(&request_key_frame);
249 EXPECT_FALSE(request_key_frame);
stefan@webrtc.orgef144882013-05-07 19:16:33 +0000250}
251
stefan@webrtc.org16734812013-05-14 12:00:47 +0000252TEST_F(TestVCMReceiver, NonDecodableDuration_NoTrigger2) {
253 // Enable NACK and with no RTT thresholds for disabling retransmission delay.
254 receiver_.SetNackMode(kNack, -1, -1);
255 const size_t kMaxNackListSize = 1000;
256 const int kMaxPacketAgeToNack = 1000;
257 const int kMaxNonDecodableDuration = 500;
philipel9d3ab612015-12-21 04:12:39 -0800258 const int kMaxNonDecodableDurationFrames =
259 (kDefaultFrameRate * kMaxNonDecodableDuration + 500) / 1000;
stefan@webrtc.org16734812013-05-14 12:00:47 +0000260 const int kMinDelayMs = 500;
261 receiver_.SetNackSettings(kMaxNackListSize, kMaxPacketAgeToNack,
philipel9d3ab612015-12-21 04:12:39 -0800262 kMaxNonDecodableDuration);
stefan@webrtc.org16734812013-05-14 12:00:47 +0000263 receiver_.SetMinReceiverDelay(kMinDelayMs);
264 int64_t key_frame_inserted = clock_->TimeInMilliseconds();
265 EXPECT_GE(InsertFrame(kVideoFrameKey, true), kNoError);
266 // Insert enough frames to have too long non-decodable sequence, except that
267 // we don't have any losses.
philipel9d3ab612015-12-21 04:12:39 -0800268 for (int i = 0; i < kMaxNonDecodableDurationFrames; ++i) {
stefan@webrtc.org16734812013-05-14 12:00:47 +0000269 EXPECT_GE(InsertFrame(kVideoFrameDelta, true), kNoError);
270 }
271 // Insert an incomplete frame.
272 EXPECT_GE(InsertFrame(kVideoFrameDelta, false), kNoError);
273 // Advance time until it's time to decode the key frame.
274 clock_->AdvanceTimeMilliseconds(kMinDelayMs - clock_->TimeInMilliseconds() -
philipel9d3ab612015-12-21 04:12:39 -0800275 key_frame_inserted);
stefan@webrtc.org16734812013-05-14 12:00:47 +0000276 EXPECT_TRUE(DecodeNextFrame());
277 // Make sure we don't get a key frame request since the non-decodable duration
278 // is only one frame.
Wan-Teh Changb1825a42015-06-03 15:03:35 -0700279 bool request_key_frame = false;
280 std::vector<uint16_t> nack_list = receiver_.NackList(&request_key_frame);
281 EXPECT_FALSE(request_key_frame);
stefan@webrtc.org16734812013-05-14 12:00:47 +0000282}
283
stefan@webrtc.orgef144882013-05-07 19:16:33 +0000284TEST_F(TestVCMReceiver, NonDecodableDuration_KeyFrameAfterIncompleteFrames) {
285 // Enable NACK and with no RTT thresholds for disabling retransmission delay.
286 receiver_.SetNackMode(kNack, -1, -1);
287 const size_t kMaxNackListSize = 1000;
288 const int kMaxPacketAgeToNack = 1000;
289 const int kMaxNonDecodableDuration = 500;
philipel9d3ab612015-12-21 04:12:39 -0800290 const int kMaxNonDecodableDurationFrames =
291 (kDefaultFrameRate * kMaxNonDecodableDuration + 500) / 1000;
stefan@webrtc.orgef144882013-05-07 19:16:33 +0000292 const int kMinDelayMs = 500;
293 receiver_.SetNackSettings(kMaxNackListSize, kMaxPacketAgeToNack,
philipel9d3ab612015-12-21 04:12:39 -0800294 kMaxNonDecodableDuration);
stefan@webrtc.orgef144882013-05-07 19:16:33 +0000295 receiver_.SetMinReceiverDelay(kMinDelayMs);
296 int64_t key_frame_inserted = clock_->TimeInMilliseconds();
297 EXPECT_GE(InsertFrame(kVideoFrameKey, true), kNoError);
298 // Insert an incomplete frame.
299 EXPECT_GE(InsertFrame(kVideoFrameDelta, false), kNoError);
300 // Insert enough frames to have too long non-decodable sequence.
philipel9d3ab612015-12-21 04:12:39 -0800301 for (int i = 0; i < kMaxNonDecodableDurationFrames; ++i) {
stefan@webrtc.orgef144882013-05-07 19:16:33 +0000302 EXPECT_GE(InsertFrame(kVideoFrameDelta, true), kNoError);
303 }
304 EXPECT_GE(InsertFrame(kVideoFrameKey, true), kNoError);
305 // Advance time until it's time to decode the key frame.
306 clock_->AdvanceTimeMilliseconds(kMinDelayMs - clock_->TimeInMilliseconds() -
philipel9d3ab612015-12-21 04:12:39 -0800307 key_frame_inserted);
stefan@webrtc.orgef144882013-05-07 19:16:33 +0000308 EXPECT_TRUE(DecodeNextFrame());
309 // Make sure we don't get a key frame request since we have a key frame
310 // in the list.
Wan-Teh Changb1825a42015-06-03 15:03:35 -0700311 bool request_key_frame = false;
312 std::vector<uint16_t> nack_list = receiver_.NackList(&request_key_frame);
313 EXPECT_FALSE(request_key_frame);
stefan@webrtc.orgef144882013-05-07 19:16:33 +0000314}
Qiang Chend4cec152015-06-19 09:17:00 -0700315
316// A simulated clock, when time elapses, will insert frames into the jitter
317// buffer, based on initial settings.
318class SimulatedClockWithFrames : public SimulatedClock {
319 public:
320 SimulatedClockWithFrames(StreamGenerator* stream_generator,
321 VCMReceiver* receiver)
322 : SimulatedClock(0),
323 stream_generator_(stream_generator),
324 receiver_(receiver) {}
325 virtual ~SimulatedClockWithFrames() {}
326
327 // If |stop_on_frame| is true and next frame arrives between now and
328 // now+|milliseconds|, the clock will be advanced to the arrival time of next
329 // frame.
330 // Otherwise, the clock will be advanced by |milliseconds|.
331 //
332 // For both cases, a frame will be inserted into the jitter buffer at the
333 // instant when the clock time is timestamps_.front().arrive_time.
334 //
335 // Return true if some frame arrives between now and now+|milliseconds|.
336 bool AdvanceTimeMilliseconds(int64_t milliseconds, bool stop_on_frame) {
337 return AdvanceTimeMicroseconds(milliseconds * 1000, stop_on_frame);
philipel9d3ab612015-12-21 04:12:39 -0800338 }
Qiang Chend4cec152015-06-19 09:17:00 -0700339
340 bool AdvanceTimeMicroseconds(int64_t microseconds, bool stop_on_frame) {
341 int64_t start_time = TimeInMicroseconds();
342 int64_t end_time = start_time + microseconds;
343 bool frame_injected = false;
344 while (!timestamps_.empty() &&
345 timestamps_.front().arrive_time <= end_time) {
henrikg91d6ede2015-09-17 00:24:34 -0700346 RTC_DCHECK(timestamps_.front().arrive_time >= start_time);
Qiang Chend4cec152015-06-19 09:17:00 -0700347
348 SimulatedClock::AdvanceTimeMicroseconds(timestamps_.front().arrive_time -
349 TimeInMicroseconds());
350 GenerateAndInsertFrame((timestamps_.front().render_time + 500) / 1000);
351 timestamps_.pop();
352 frame_injected = true;
353
354 if (stop_on_frame)
355 return frame_injected;
356 }
357
358 if (TimeInMicroseconds() < end_time) {
359 SimulatedClock::AdvanceTimeMicroseconds(end_time - TimeInMicroseconds());
360 }
361 return frame_injected;
philipel9d3ab612015-12-21 04:12:39 -0800362 }
Qiang Chend4cec152015-06-19 09:17:00 -0700363
364 // Input timestamps are in unit Milliseconds.
365 // And |arrive_timestamps| must be positive and in increasing order.
366 // |arrive_timestamps| determine when we are going to insert frames into the
367 // jitter buffer.
368 // |render_timestamps| are the timestamps on the frame.
369 void SetFrames(const int64_t* arrive_timestamps,
370 const int64_t* render_timestamps,
371 size_t size) {
372 int64_t previous_arrive_timestamp = 0;
373 for (size_t i = 0; i < size; i++) {
henrikg91d6ede2015-09-17 00:24:34 -0700374 RTC_CHECK(arrive_timestamps[i] >= previous_arrive_timestamp);
Qiang Chend4cec152015-06-19 09:17:00 -0700375 timestamps_.push(TimestampPair(arrive_timestamps[i] * 1000,
376 render_timestamps[i] * 1000));
377 previous_arrive_timestamp = arrive_timestamps[i];
378 }
379 }
380
381 private:
382 struct TimestampPair {
383 TimestampPair(int64_t arrive_timestamp, int64_t render_timestamp)
384 : arrive_time(arrive_timestamp), render_time(render_timestamp) {}
385
386 int64_t arrive_time;
387 int64_t render_time;
388 };
389
390 void GenerateAndInsertFrame(int64_t render_timestamp_ms) {
391 VCMPacket packet;
392 stream_generator_->GenerateFrame(FrameType::kVideoFrameKey,
393 1, // media packets
394 0, // empty packets
395 render_timestamp_ms);
396
397 bool packet_available = stream_generator_->PopPacket(&packet, 0);
398 EXPECT_TRUE(packet_available);
399 if (!packet_available)
400 return; // Return here to avoid crashes below.
401 receiver_->InsertPacket(packet, 640, 480);
402 }
403
404 std::queue<TimestampPair> timestamps_;
405 StreamGenerator* stream_generator_;
406 VCMReceiver* receiver_;
407};
408
409// Use a SimulatedClockWithFrames
410// Wait call will do either of these:
411// 1. If |stop_on_frame| is true, the clock will be turned to the exact instant
412// that the first frame comes and the frame will be inserted into the jitter
413// buffer, or the clock will be turned to now + |max_time| if no frame comes in
414// the window.
415// 2. If |stop_on_frame| is false, the clock will be turn to now + |max_time|,
416// and all the frames arriving between now and now + |max_time| will be
417// inserted into the jitter buffer.
418//
419// This is used to simulate the JitterBuffer getting packets from internet as
420// time elapses.
421
422class FrameInjectEvent : public EventWrapper {
423 public:
424 FrameInjectEvent(SimulatedClockWithFrames* clock, bool stop_on_frame)
425 : clock_(clock), stop_on_frame_(stop_on_frame) {}
426
427 bool Set() override { return true; }
428
philipel9d3ab612015-12-21 04:12:39 -0800429 EventTypeWrapper Wait(unsigned long max_time) override { // NOLINT
Qiang Chend4cec152015-06-19 09:17:00 -0700430 if (clock_->AdvanceTimeMilliseconds(max_time, stop_on_frame_) &&
431 stop_on_frame_) {
432 return EventTypeWrapper::kEventSignaled;
433 } else {
434 return EventTypeWrapper::kEventTimeout;
435 }
436 }
437
438 private:
439 SimulatedClockWithFrames* clock_;
440 bool stop_on_frame_;
441};
442
443class VCMReceiverTimingTest : public ::testing::Test {
444 protected:
Qiang Chend4cec152015-06-19 09:17:00 -0700445 VCMReceiverTimingTest()
446
447 : clock_(&stream_generator_, &receiver_),
448 stream_generator_(0, clock_.TimeInMilliseconds()),
449 timing_(&clock_),
450 receiver_(
451 &timing_,
452 &clock_,
kwiberg3f55dea2016-02-29 05:51:59 -0800453 std::unique_ptr<EventWrapper>(new FrameInjectEvent(&clock_, false)),
454 std::unique_ptr<EventWrapper>(
Qiang Chend4cec152015-06-19 09:17:00 -0700455 new FrameInjectEvent(&clock_, true))) {}
456
Qiang Chend4cec152015-06-19 09:17:00 -0700457 virtual void SetUp() { receiver_.Reset(); }
458
459 SimulatedClockWithFrames clock_;
460 StreamGenerator stream_generator_;
461 VCMTiming timing_;
462 VCMReceiver receiver_;
463};
464
465// Test whether VCMReceiver::FrameForDecoding handles parameter
466// |max_wait_time_ms| correctly:
467// 1. The function execution should never take more than |max_wait_time_ms|.
468// 2. If the function exit before now + |max_wait_time_ms|, a frame must be
469// returned.
470TEST_F(VCMReceiverTimingTest, FrameForDecoding) {
471 const size_t kNumFrames = 100;
472 const int kFramePeriod = 40;
473 int64_t arrive_timestamps[kNumFrames];
474 int64_t render_timestamps[kNumFrames];
475 int64_t next_render_time;
476
477 // Construct test samples.
478 // render_timestamps are the timestamps stored in the Frame;
479 // arrive_timestamps controls when the Frame packet got received.
480 for (size_t i = 0; i < kNumFrames; i++) {
481 // Preset frame rate to 25Hz.
482 // But we add a reasonable deviation to arrive_timestamps to mimic Internet
483 // fluctuation.
484 arrive_timestamps[i] =
485 (i + 1) * kFramePeriod + (i % 10) * ((i % 2) ? 1 : -1);
486 render_timestamps[i] = (i + 1) * kFramePeriod;
487 }
488
489 clock_.SetFrames(arrive_timestamps, render_timestamps, kNumFrames);
490
491 // Record how many frames we finally get out of the receiver.
492 size_t num_frames_return = 0;
493
494 const int64_t kMaxWaitTime = 30;
495
496 // Ideally, we should get all frames that we input in InitializeFrames.
497 // In the case that FrameForDecoding kills frames by error, we rely on the
498 // build bot to kill the test.
499 while (num_frames_return < kNumFrames) {
500 int64_t start_time = clock_.TimeInMilliseconds();
501 VCMEncodedFrame* frame =
philipel9d3ab612015-12-21 04:12:39 -0800502 receiver_.FrameForDecoding(kMaxWaitTime, &next_render_time, false);
Qiang Chend4cec152015-06-19 09:17:00 -0700503 int64_t end_time = clock_.TimeInMilliseconds();
504
505 // In any case the FrameForDecoding should not wait longer than
506 // max_wait_time.
507 // In the case that we did not get a frame, it should have been waiting for
508 // exactly max_wait_time. (By the testing samples we constructed above, we
509 // are sure there is no timing error, so the only case it returns with NULL
510 // is that it runs out of time.)
511 if (frame) {
512 receiver_.ReleaseFrame(frame);
513 ++num_frames_return;
514 EXPECT_GE(kMaxWaitTime, end_time - start_time);
515 } else {
516 EXPECT_EQ(kMaxWaitTime, end_time - start_time);
517 }
518 }
519}
520
perkj796cfaf2015-12-10 09:27:38 -0800521// Test whether VCMReceiver::FrameForDecoding handles parameter
522// |prefer_late_decoding| and |max_wait_time_ms| correctly:
523// 1. The function execution should never take more than |max_wait_time_ms|.
524// 2. If the function exit before now + |max_wait_time_ms|, a frame must be
525// returned and the end time must be equal to the render timestamp - delay
526// for decoding and rendering.
527TEST_F(VCMReceiverTimingTest, FrameForDecodingPreferLateDecoding) {
528 const size_t kNumFrames = 100;
529 const int kFramePeriod = 40;
530
531 int64_t arrive_timestamps[kNumFrames];
532 int64_t render_timestamps[kNumFrames];
533 int64_t next_render_time;
534
535 int render_delay_ms;
536 int max_decode_ms;
537 int dummy;
538 timing_.GetTimings(&dummy, &max_decode_ms, &dummy, &dummy, &dummy, &dummy,
539 &render_delay_ms);
540
541 // Construct test samples.
542 // render_timestamps are the timestamps stored in the Frame;
543 // arrive_timestamps controls when the Frame packet got received.
544 for (size_t i = 0; i < kNumFrames; i++) {
545 // Preset frame rate to 25Hz.
546 // But we add a reasonable deviation to arrive_timestamps to mimic Internet
547 // fluctuation.
548 arrive_timestamps[i] =
549 (i + 1) * kFramePeriod + (i % 10) * ((i % 2) ? 1 : -1);
550 render_timestamps[i] = (i + 1) * kFramePeriod;
551 }
552
553 clock_.SetFrames(arrive_timestamps, render_timestamps, kNumFrames);
554
555 // Record how many frames we finally get out of the receiver.
556 size_t num_frames_return = 0;
557 const int64_t kMaxWaitTime = 30;
558 bool prefer_late_decoding = true;
559 while (num_frames_return < kNumFrames) {
560 int64_t start_time = clock_.TimeInMilliseconds();
561
philipel9d3ab612015-12-21 04:12:39 -0800562 VCMEncodedFrame* frame = receiver_.FrameForDecoding(
563 kMaxWaitTime, &next_render_time, prefer_late_decoding);
perkj796cfaf2015-12-10 09:27:38 -0800564 int64_t end_time = clock_.TimeInMilliseconds();
565 if (frame) {
566 EXPECT_EQ(frame->RenderTimeMs() - max_decode_ms - render_delay_ms,
567 end_time);
568 receiver_.ReleaseFrame(frame);
569 ++num_frames_return;
570 } else {
571 EXPECT_EQ(kMaxWaitTime, end_time - start_time);
572 }
573 }
574}
575
mikhal@webrtc.org381da4b2013-04-25 21:45:29 +0000576} // namespace webrtc