blob: 1f3a144badd02ab5a943fe5c27e82fa6b2e7f4b2 [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>
philipel9d3ab612015-12-21 04:12:39 -080014#include <vector>
mikhal@webrtc.org381da4b2013-04-25 21:45:29 +000015
16#include "testing/gtest/include/gtest/gtest.h"
Qiang Chend4cec152015-06-19 09:17:00 -070017#include "webrtc/base/checks.h"
perkj796cfaf2015-12-10 09:27:38 -080018#include "webrtc/modules/video_coding/encoded_frame.h"
Henrik Kjellander2557b862015-11-18 22:00:21 +010019#include "webrtc/modules/video_coding/packet.h"
20#include "webrtc/modules/video_coding/receiver.h"
21#include "webrtc/modules/video_coding/test/stream_generator.h"
22#include "webrtc/modules/video_coding/timing.h"
23#include "webrtc/modules/video_coding/test/test_util.h"
Henrik Kjellander98f53512015-10-28 18:17:40 +010024#include "webrtc/system_wrappers/include/clock.h"
25#include "webrtc/system_wrappers/include/critical_section_wrapper.h"
mikhal@webrtc.org381da4b2013-04-25 21:45:29 +000026
27namespace webrtc {
28
29class TestVCMReceiver : public ::testing::Test {
30 protected:
mikhal@webrtc.org381da4b2013-04-25 21:45:29 +000031 enum { kWidth = 640 };
32 enum { kHeight = 480 };
33
34 TestVCMReceiver()
35 : clock_(new SimulatedClock(0)),
36 timing_(clock_.get()),
Wan-Teh Chang92d94892015-05-28 13:36:06 -070037 receiver_(&timing_, clock_.get(), &event_factory_) {
philipel9d3ab612015-12-21 04:12:39 -080038 stream_generator_.reset(
39 new StreamGenerator(0, clock_->TimeInMilliseconds()));
mikhal@webrtc.org381da4b2013-04-25 21:45:29 +000040 }
41
philipel9d3ab612015-12-21 04:12:39 -080042 virtual void SetUp() { receiver_.Reset(); }
mikhal@webrtc.org381da4b2013-04-25 21:45:29 +000043
44 int32_t InsertPacket(int index) {
45 VCMPacket packet;
mikhal@webrtc.org381da4b2013-04-25 21:45:29 +000046 bool packet_available = stream_generator_->GetPacket(&packet, index);
47 EXPECT_TRUE(packet_available);
48 if (!packet_available)
stefan@webrtc.org3417eb42013-05-21 15:25:53 +000049 return kGeneralError; // Return here to avoid crashes below.
Wan-Teh Chang92d94892015-05-28 13:36:06 -070050 return receiver_.InsertPacket(packet, kWidth, kHeight);
mikhal@webrtc.org381da4b2013-04-25 21:45:29 +000051 }
52
53 int32_t InsertPacketAndPop(int index) {
54 VCMPacket packet;
mikhal@webrtc.org381da4b2013-04-25 21:45:29 +000055 bool packet_available = stream_generator_->PopPacket(&packet, index);
56 EXPECT_TRUE(packet_available);
57 if (!packet_available)
stefan@webrtc.org3417eb42013-05-21 15:25:53 +000058 return kGeneralError; // Return here to avoid crashes below.
mikhal@webrtc.org381da4b2013-04-25 21:45:29 +000059 return receiver_.InsertPacket(packet, kWidth, kHeight);
60 }
61
62 int32_t InsertFrame(FrameType frame_type, bool complete) {
63 int num_of_packets = complete ? 1 : 2;
64 stream_generator_->GenerateFrame(
pbos22993e12015-10-19 02:39:06 -070065 frame_type, (frame_type != kEmptyFrame) ? num_of_packets : 0,
66 (frame_type == kEmptyFrame) ? 1 : 0, clock_->TimeInMilliseconds());
mikhal@webrtc.org381da4b2013-04-25 21:45:29 +000067 int32_t ret = InsertPacketAndPop(0);
stefan@webrtc.orgef144882013-05-07 19:16:33 +000068 if (!complete) {
69 // Drop the second packet.
70 VCMPacket packet;
71 stream_generator_->PopPacket(&packet, 0);
72 }
mikhal@webrtc.org381da4b2013-04-25 21:45:29 +000073 clock_->AdvanceTimeMilliseconds(kDefaultFramePeriodMs);
74 return ret;
75 }
76
stefan@webrtc.orgef144882013-05-07 19:16:33 +000077 bool DecodeNextFrame() {
78 int64_t render_time_ms = 0;
pbos@webrtc.org4f16c872014-11-24 09:06:48 +000079 VCMEncodedFrame* frame =
philipel9d3ab612015-12-21 04:12:39 -080080 receiver_.FrameForDecoding(0, &render_time_ms, false);
stefan@webrtc.orgef144882013-05-07 19:16:33 +000081 if (!frame)
82 return false;
83 receiver_.ReleaseFrame(frame);
84 return true;
85 }
86
kwiberg@webrtc.org00b8f6b2015-02-26 14:34:55 +000087 rtc::scoped_ptr<SimulatedClock> clock_;
mikhal@webrtc.org381da4b2013-04-25 21:45:29 +000088 VCMTiming timing_;
89 NullEventFactory event_factory_;
90 VCMReceiver receiver_;
kwiberg@webrtc.org00b8f6b2015-02-26 14:34:55 +000091 rtc::scoped_ptr<StreamGenerator> stream_generator_;
mikhal@webrtc.org381da4b2013-04-25 21:45:29 +000092};
93
94TEST_F(TestVCMReceiver, RenderBufferSize_AllComplete) {
95 EXPECT_EQ(0, receiver_.RenderBufferSizeMs());
96 EXPECT_GE(InsertFrame(kVideoFrameKey, true), kNoError);
stefan@webrtc.orgef144882013-05-07 19:16:33 +000097 int num_of_frames = 10;
98 for (int i = 0; i < num_of_frames; ++i) {
mikhal@webrtc.org381da4b2013-04-25 21:45:29 +000099 EXPECT_GE(InsertFrame(kVideoFrameDelta, true), kNoError);
100 }
stefan@webrtc.orgef144882013-05-07 19:16:33 +0000101 EXPECT_EQ(num_of_frames * kDefaultFramePeriodMs,
pbos@webrtc.org3004c792013-05-07 12:36:21 +0000102 receiver_.RenderBufferSizeMs());
mikhal@webrtc.org381da4b2013-04-25 21:45:29 +0000103}
104
stefan@webrtc.orgef144882013-05-07 19:16:33 +0000105TEST_F(TestVCMReceiver, RenderBufferSize_SkipToKeyFrame) {
106 EXPECT_EQ(0, receiver_.RenderBufferSizeMs());
107 const int kNumOfNonDecodableFrames = 2;
108 for (int i = 0; i < kNumOfNonDecodableFrames; ++i) {
109 EXPECT_GE(InsertFrame(kVideoFrameDelta, true), kNoError);
110 }
111 const int kNumOfFrames = 10;
112 EXPECT_GE(InsertFrame(kVideoFrameKey, true), kNoError);
113 for (int i = 0; i < kNumOfFrames - 1; ++i) {
114 EXPECT_GE(InsertFrame(kVideoFrameDelta, true), kNoError);
115 }
116 EXPECT_EQ((kNumOfFrames - 1) * kDefaultFramePeriodMs,
philipel9d3ab612015-12-21 04:12:39 -0800117 receiver_.RenderBufferSizeMs());
stefan@webrtc.orgef144882013-05-07 19:16:33 +0000118}
119
mikhal@webrtc.org381da4b2013-04-25 21:45:29 +0000120TEST_F(TestVCMReceiver, RenderBufferSize_NotAllComplete) {
121 EXPECT_EQ(0, receiver_.RenderBufferSizeMs());
122 EXPECT_GE(InsertFrame(kVideoFrameKey, true), kNoError);
stefan@webrtc.orgef144882013-05-07 19:16:33 +0000123 int num_of_frames = 10;
124 for (int i = 0; i < num_of_frames; ++i) {
mikhal@webrtc.org381da4b2013-04-25 21:45:29 +0000125 EXPECT_GE(InsertFrame(kVideoFrameDelta, true), kNoError);
126 }
stefan@webrtc.org4ce19b12013-05-06 13:16:51 +0000127 num_of_frames++;
mikhal@webrtc.org381da4b2013-04-25 21:45:29 +0000128 EXPECT_GE(InsertFrame(kVideoFrameDelta, false), kNoError);
stefan@webrtc.orgef144882013-05-07 19:16:33 +0000129 for (int i = 0; i < num_of_frames; ++i) {
mikhal@webrtc.org381da4b2013-04-25 21:45:29 +0000130 EXPECT_GE(InsertFrame(kVideoFrameDelta, true), kNoError);
131 }
stefan@webrtc.orgef144882013-05-07 19:16:33 +0000132 EXPECT_EQ((num_of_frames - 1) * kDefaultFramePeriodMs,
philipel9d3ab612015-12-21 04:12:39 -0800133 receiver_.RenderBufferSizeMs());
mikhal@webrtc.org381da4b2013-04-25 21:45:29 +0000134}
135
136TEST_F(TestVCMReceiver, RenderBufferSize_NoKeyFrame) {
137 EXPECT_EQ(0, receiver_.RenderBufferSizeMs());
138 int num_of_frames = 10;
139 for (int i = 0; i < num_of_frames; ++i) {
140 EXPECT_GE(InsertFrame(kVideoFrameDelta, true), kNoError);
141 }
mikhal@webrtc.org759b0412013-05-07 16:36:00 +0000142 int64_t next_render_time_ms = 0;
perkj796cfaf2015-12-10 09:27:38 -0800143 VCMEncodedFrame* frame =
philipel9d3ab612015-12-21 04:12:39 -0800144 receiver_.FrameForDecoding(10, &next_render_time_ms, false);
mikhal@webrtc.org759b0412013-05-07 16:36:00 +0000145 EXPECT_TRUE(frame == NULL);
146 receiver_.ReleaseFrame(frame);
mikhal@webrtc.org381da4b2013-04-25 21:45:29 +0000147 EXPECT_GE(InsertFrame(kVideoFrameDelta, false), kNoError);
148 for (int i = 0; i < num_of_frames; ++i) {
149 EXPECT_GE(InsertFrame(kVideoFrameDelta, true), kNoError);
150 }
151 EXPECT_EQ(0, receiver_.RenderBufferSizeMs());
152}
153
stefan@webrtc.orgef144882013-05-07 19:16:33 +0000154TEST_F(TestVCMReceiver, NonDecodableDuration_Empty) {
155 // Enable NACK and with no RTT thresholds for disabling retransmission delay.
156 receiver_.SetNackMode(kNack, -1, -1);
157 const size_t kMaxNackListSize = 1000;
158 const int kMaxPacketAgeToNack = 1000;
159 const int kMaxNonDecodableDuration = 500;
160 const int kMinDelayMs = 500;
161 receiver_.SetNackSettings(kMaxNackListSize, kMaxPacketAgeToNack,
philipel9d3ab612015-12-21 04:12:39 -0800162 kMaxNonDecodableDuration);
stefan@webrtc.orgef144882013-05-07 19:16:33 +0000163 EXPECT_GE(InsertFrame(kVideoFrameKey, true), kNoError);
164 // Advance time until it's time to decode the key frame.
165 clock_->AdvanceTimeMilliseconds(kMinDelayMs);
166 EXPECT_TRUE(DecodeNextFrame());
Wan-Teh Changb1825a42015-06-03 15:03:35 -0700167 bool request_key_frame = false;
168 std::vector<uint16_t> nack_list = receiver_.NackList(&request_key_frame);
169 EXPECT_FALSE(request_key_frame);
stefan@webrtc.orgef144882013-05-07 19:16:33 +0000170}
171
172TEST_F(TestVCMReceiver, NonDecodableDuration_NoKeyFrame) {
173 // Enable NACK and with no RTT thresholds for disabling retransmission delay.
174 receiver_.SetNackMode(kNack, -1, -1);
175 const size_t kMaxNackListSize = 1000;
176 const int kMaxPacketAgeToNack = 1000;
177 const int kMaxNonDecodableDuration = 500;
178 receiver_.SetNackSettings(kMaxNackListSize, kMaxPacketAgeToNack,
philipel9d3ab612015-12-21 04:12:39 -0800179 kMaxNonDecodableDuration);
stefan@webrtc.orgef144882013-05-07 19:16:33 +0000180 const int kNumFrames = kDefaultFrameRate * kMaxNonDecodableDuration / 1000;
181 for (int i = 0; i < kNumFrames; ++i) {
182 EXPECT_GE(InsertFrame(kVideoFrameDelta, true), kNoError);
183 }
Wan-Teh Changb1825a42015-06-03 15:03:35 -0700184 bool request_key_frame = false;
185 std::vector<uint16_t> nack_list = receiver_.NackList(&request_key_frame);
186 EXPECT_TRUE(request_key_frame);
stefan@webrtc.orgef144882013-05-07 19:16:33 +0000187}
188
189TEST_F(TestVCMReceiver, NonDecodableDuration_OneIncomplete) {
190 // Enable NACK and with no RTT thresholds for disabling retransmission delay.
191 receiver_.SetNackMode(kNack, -1, -1);
192 const size_t kMaxNackListSize = 1000;
193 const int kMaxPacketAgeToNack = 1000;
194 const int kMaxNonDecodableDuration = 500;
philipel9d3ab612015-12-21 04:12:39 -0800195 const int kMaxNonDecodableDurationFrames =
196 (kDefaultFrameRate * kMaxNonDecodableDuration + 500) / 1000;
stefan@webrtc.orgef144882013-05-07 19:16:33 +0000197 const int kMinDelayMs = 500;
198 receiver_.SetNackSettings(kMaxNackListSize, kMaxPacketAgeToNack,
philipel9d3ab612015-12-21 04:12:39 -0800199 kMaxNonDecodableDuration);
stefan@webrtc.orgef144882013-05-07 19:16:33 +0000200 receiver_.SetMinReceiverDelay(kMinDelayMs);
201 int64_t key_frame_inserted = clock_->TimeInMilliseconds();
202 EXPECT_GE(InsertFrame(kVideoFrameKey, true), kNoError);
203 // Insert an incomplete frame.
204 EXPECT_GE(InsertFrame(kVideoFrameDelta, false), kNoError);
205 // Insert enough frames to have too long non-decodable sequence.
philipel9d3ab612015-12-21 04:12:39 -0800206 for (int i = 0; i < kMaxNonDecodableDurationFrames; ++i) {
stefan@webrtc.orgef144882013-05-07 19:16:33 +0000207 EXPECT_GE(InsertFrame(kVideoFrameDelta, true), kNoError);
208 }
209 // Advance time until it's time to decode the key frame.
210 clock_->AdvanceTimeMilliseconds(kMinDelayMs - clock_->TimeInMilliseconds() -
philipel9d3ab612015-12-21 04:12:39 -0800211 key_frame_inserted);
stefan@webrtc.orgef144882013-05-07 19:16:33 +0000212 EXPECT_TRUE(DecodeNextFrame());
213 // Make sure we get a key frame request.
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_TRUE(request_key_frame);
stefan@webrtc.orgef144882013-05-07 19:16:33 +0000217}
218
219TEST_F(TestVCMReceiver, NonDecodableDuration_NoTrigger) {
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 all but one frame to not trigger a key frame request due to
236 // too long duration of non-decodable frames.
philipel9d3ab612015-12-21 04:12:39 -0800237 for (int i = 0; i < kMaxNonDecodableDurationFrames - 1; ++i) {
stefan@webrtc.orgef144882013-05-07 19:16:33 +0000238 EXPECT_GE(InsertFrame(kVideoFrameDelta, true), kNoError);
239 }
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 haven't generated
245 // enough frames.
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}
250
stefan@webrtc.org16734812013-05-14 12:00:47 +0000251TEST_F(TestVCMReceiver, NonDecodableDuration_NoTrigger2) {
252 // Enable NACK and with no RTT thresholds for disabling retransmission delay.
253 receiver_.SetNackMode(kNack, -1, -1);
254 const size_t kMaxNackListSize = 1000;
255 const int kMaxPacketAgeToNack = 1000;
256 const int kMaxNonDecodableDuration = 500;
philipel9d3ab612015-12-21 04:12:39 -0800257 const int kMaxNonDecodableDurationFrames =
258 (kDefaultFrameRate * kMaxNonDecodableDuration + 500) / 1000;
stefan@webrtc.org16734812013-05-14 12:00:47 +0000259 const int kMinDelayMs = 500;
260 receiver_.SetNackSettings(kMaxNackListSize, kMaxPacketAgeToNack,
philipel9d3ab612015-12-21 04:12:39 -0800261 kMaxNonDecodableDuration);
stefan@webrtc.org16734812013-05-14 12:00:47 +0000262 receiver_.SetMinReceiverDelay(kMinDelayMs);
263 int64_t key_frame_inserted = clock_->TimeInMilliseconds();
264 EXPECT_GE(InsertFrame(kVideoFrameKey, true), kNoError);
265 // Insert enough frames to have too long non-decodable sequence, except that
266 // we don't have any losses.
philipel9d3ab612015-12-21 04:12:39 -0800267 for (int i = 0; i < kMaxNonDecodableDurationFrames; ++i) {
stefan@webrtc.org16734812013-05-14 12:00:47 +0000268 EXPECT_GE(InsertFrame(kVideoFrameDelta, true), kNoError);
269 }
270 // Insert an incomplete frame.
271 EXPECT_GE(InsertFrame(kVideoFrameDelta, false), kNoError);
272 // Advance time until it's time to decode the key frame.
273 clock_->AdvanceTimeMilliseconds(kMinDelayMs - clock_->TimeInMilliseconds() -
philipel9d3ab612015-12-21 04:12:39 -0800274 key_frame_inserted);
stefan@webrtc.org16734812013-05-14 12:00:47 +0000275 EXPECT_TRUE(DecodeNextFrame());
276 // Make sure we don't get a key frame request since the non-decodable duration
277 // is only one frame.
Wan-Teh Changb1825a42015-06-03 15:03:35 -0700278 bool request_key_frame = false;
279 std::vector<uint16_t> nack_list = receiver_.NackList(&request_key_frame);
280 EXPECT_FALSE(request_key_frame);
stefan@webrtc.org16734812013-05-14 12:00:47 +0000281}
282
stefan@webrtc.orgef144882013-05-07 19:16:33 +0000283TEST_F(TestVCMReceiver, NonDecodableDuration_KeyFrameAfterIncompleteFrames) {
284 // Enable NACK and with no RTT thresholds for disabling retransmission delay.
285 receiver_.SetNackMode(kNack, -1, -1);
286 const size_t kMaxNackListSize = 1000;
287 const int kMaxPacketAgeToNack = 1000;
288 const int kMaxNonDecodableDuration = 500;
philipel9d3ab612015-12-21 04:12:39 -0800289 const int kMaxNonDecodableDurationFrames =
290 (kDefaultFrameRate * kMaxNonDecodableDuration + 500) / 1000;
stefan@webrtc.orgef144882013-05-07 19:16:33 +0000291 const int kMinDelayMs = 500;
292 receiver_.SetNackSettings(kMaxNackListSize, kMaxPacketAgeToNack,
philipel9d3ab612015-12-21 04:12:39 -0800293 kMaxNonDecodableDuration);
stefan@webrtc.orgef144882013-05-07 19:16:33 +0000294 receiver_.SetMinReceiverDelay(kMinDelayMs);
295 int64_t key_frame_inserted = clock_->TimeInMilliseconds();
296 EXPECT_GE(InsertFrame(kVideoFrameKey, true), kNoError);
297 // Insert an incomplete frame.
298 EXPECT_GE(InsertFrame(kVideoFrameDelta, false), kNoError);
299 // Insert enough frames to have too long non-decodable sequence.
philipel9d3ab612015-12-21 04:12:39 -0800300 for (int i = 0; i < kMaxNonDecodableDurationFrames; ++i) {
stefan@webrtc.orgef144882013-05-07 19:16:33 +0000301 EXPECT_GE(InsertFrame(kVideoFrameDelta, true), kNoError);
302 }
303 EXPECT_GE(InsertFrame(kVideoFrameKey, true), kNoError);
304 // Advance time until it's time to decode the key frame.
305 clock_->AdvanceTimeMilliseconds(kMinDelayMs - clock_->TimeInMilliseconds() -
philipel9d3ab612015-12-21 04:12:39 -0800306 key_frame_inserted);
stefan@webrtc.orgef144882013-05-07 19:16:33 +0000307 EXPECT_TRUE(DecodeNextFrame());
308 // Make sure we don't get a key frame request since we have a key frame
309 // in the list.
Wan-Teh Changb1825a42015-06-03 15:03:35 -0700310 bool request_key_frame = false;
311 std::vector<uint16_t> nack_list = receiver_.NackList(&request_key_frame);
312 EXPECT_FALSE(request_key_frame);
stefan@webrtc.orgef144882013-05-07 19:16:33 +0000313}
Qiang Chend4cec152015-06-19 09:17:00 -0700314
315// A simulated clock, when time elapses, will insert frames into the jitter
316// buffer, based on initial settings.
317class SimulatedClockWithFrames : public SimulatedClock {
318 public:
319 SimulatedClockWithFrames(StreamGenerator* stream_generator,
320 VCMReceiver* receiver)
321 : SimulatedClock(0),
322 stream_generator_(stream_generator),
323 receiver_(receiver) {}
324 virtual ~SimulatedClockWithFrames() {}
325
326 // If |stop_on_frame| is true and next frame arrives between now and
327 // now+|milliseconds|, the clock will be advanced to the arrival time of next
328 // frame.
329 // Otherwise, the clock will be advanced by |milliseconds|.
330 //
331 // For both cases, a frame will be inserted into the jitter buffer at the
332 // instant when the clock time is timestamps_.front().arrive_time.
333 //
334 // Return true if some frame arrives between now and now+|milliseconds|.
335 bool AdvanceTimeMilliseconds(int64_t milliseconds, bool stop_on_frame) {
336 return AdvanceTimeMicroseconds(milliseconds * 1000, stop_on_frame);
philipel9d3ab612015-12-21 04:12:39 -0800337 }
Qiang Chend4cec152015-06-19 09:17:00 -0700338
339 bool AdvanceTimeMicroseconds(int64_t microseconds, bool stop_on_frame) {
340 int64_t start_time = TimeInMicroseconds();
341 int64_t end_time = start_time + microseconds;
342 bool frame_injected = false;
343 while (!timestamps_.empty() &&
344 timestamps_.front().arrive_time <= end_time) {
henrikg91d6ede2015-09-17 00:24:34 -0700345 RTC_DCHECK(timestamps_.front().arrive_time >= start_time);
Qiang Chend4cec152015-06-19 09:17:00 -0700346
347 SimulatedClock::AdvanceTimeMicroseconds(timestamps_.front().arrive_time -
348 TimeInMicroseconds());
349 GenerateAndInsertFrame((timestamps_.front().render_time + 500) / 1000);
350 timestamps_.pop();
351 frame_injected = true;
352
353 if (stop_on_frame)
354 return frame_injected;
355 }
356
357 if (TimeInMicroseconds() < end_time) {
358 SimulatedClock::AdvanceTimeMicroseconds(end_time - TimeInMicroseconds());
359 }
360 return frame_injected;
philipel9d3ab612015-12-21 04:12:39 -0800361 }
Qiang Chend4cec152015-06-19 09:17:00 -0700362
363 // Input timestamps are in unit Milliseconds.
364 // And |arrive_timestamps| must be positive and in increasing order.
365 // |arrive_timestamps| determine when we are going to insert frames into the
366 // jitter buffer.
367 // |render_timestamps| are the timestamps on the frame.
368 void SetFrames(const int64_t* arrive_timestamps,
369 const int64_t* render_timestamps,
370 size_t size) {
371 int64_t previous_arrive_timestamp = 0;
372 for (size_t i = 0; i < size; i++) {
henrikg91d6ede2015-09-17 00:24:34 -0700373 RTC_CHECK(arrive_timestamps[i] >= previous_arrive_timestamp);
Qiang Chend4cec152015-06-19 09:17:00 -0700374 timestamps_.push(TimestampPair(arrive_timestamps[i] * 1000,
375 render_timestamps[i] * 1000));
376 previous_arrive_timestamp = arrive_timestamps[i];
377 }
378 }
379
380 private:
381 struct TimestampPair {
382 TimestampPair(int64_t arrive_timestamp, int64_t render_timestamp)
383 : arrive_time(arrive_timestamp), render_time(render_timestamp) {}
384
385 int64_t arrive_time;
386 int64_t render_time;
387 };
388
389 void GenerateAndInsertFrame(int64_t render_timestamp_ms) {
390 VCMPacket packet;
391 stream_generator_->GenerateFrame(FrameType::kVideoFrameKey,
392 1, // media packets
393 0, // empty packets
394 render_timestamp_ms);
395
396 bool packet_available = stream_generator_->PopPacket(&packet, 0);
397 EXPECT_TRUE(packet_available);
398 if (!packet_available)
399 return; // Return here to avoid crashes below.
400 receiver_->InsertPacket(packet, 640, 480);
401 }
402
403 std::queue<TimestampPair> timestamps_;
404 StreamGenerator* stream_generator_;
405 VCMReceiver* receiver_;
406};
407
408// Use a SimulatedClockWithFrames
409// Wait call will do either of these:
410// 1. If |stop_on_frame| is true, the clock will be turned to the exact instant
411// that the first frame comes and the frame will be inserted into the jitter
412// buffer, or the clock will be turned to now + |max_time| if no frame comes in
413// the window.
414// 2. If |stop_on_frame| is false, the clock will be turn to now + |max_time|,
415// and all the frames arriving between now and now + |max_time| will be
416// inserted into the jitter buffer.
417//
418// This is used to simulate the JitterBuffer getting packets from internet as
419// time elapses.
420
421class FrameInjectEvent : public EventWrapper {
422 public:
423 FrameInjectEvent(SimulatedClockWithFrames* clock, bool stop_on_frame)
424 : clock_(clock), stop_on_frame_(stop_on_frame) {}
425
426 bool Set() override { return true; }
427
philipel9d3ab612015-12-21 04:12:39 -0800428 EventTypeWrapper Wait(unsigned long max_time) override { // NOLINT
Qiang Chend4cec152015-06-19 09:17:00 -0700429 if (clock_->AdvanceTimeMilliseconds(max_time, stop_on_frame_) &&
430 stop_on_frame_) {
431 return EventTypeWrapper::kEventSignaled;
432 } else {
433 return EventTypeWrapper::kEventTimeout;
434 }
435 }
436
437 private:
438 SimulatedClockWithFrames* clock_;
439 bool stop_on_frame_;
440};
441
442class VCMReceiverTimingTest : public ::testing::Test {
443 protected:
Qiang Chend4cec152015-06-19 09:17:00 -0700444 VCMReceiverTimingTest()
445
446 : clock_(&stream_generator_, &receiver_),
447 stream_generator_(0, clock_.TimeInMilliseconds()),
448 timing_(&clock_),
449 receiver_(
450 &timing_,
451 &clock_,
452 rtc::scoped_ptr<EventWrapper>(new FrameInjectEvent(&clock_, false)),
453 rtc::scoped_ptr<EventWrapper>(
454 new FrameInjectEvent(&clock_, true))) {}
455
Qiang Chend4cec152015-06-19 09:17:00 -0700456 virtual void SetUp() { receiver_.Reset(); }
457
458 SimulatedClockWithFrames clock_;
459 StreamGenerator stream_generator_;
460 VCMTiming timing_;
461 VCMReceiver receiver_;
462};
463
464// Test whether VCMReceiver::FrameForDecoding handles parameter
465// |max_wait_time_ms| correctly:
466// 1. The function execution should never take more than |max_wait_time_ms|.
467// 2. If the function exit before now + |max_wait_time_ms|, a frame must be
468// returned.
469TEST_F(VCMReceiverTimingTest, FrameForDecoding) {
470 const size_t kNumFrames = 100;
471 const int kFramePeriod = 40;
472 int64_t arrive_timestamps[kNumFrames];
473 int64_t render_timestamps[kNumFrames];
474 int64_t next_render_time;
475
476 // Construct test samples.
477 // render_timestamps are the timestamps stored in the Frame;
478 // arrive_timestamps controls when the Frame packet got received.
479 for (size_t i = 0; i < kNumFrames; i++) {
480 // Preset frame rate to 25Hz.
481 // But we add a reasonable deviation to arrive_timestamps to mimic Internet
482 // fluctuation.
483 arrive_timestamps[i] =
484 (i + 1) * kFramePeriod + (i % 10) * ((i % 2) ? 1 : -1);
485 render_timestamps[i] = (i + 1) * kFramePeriod;
486 }
487
488 clock_.SetFrames(arrive_timestamps, render_timestamps, kNumFrames);
489
490 // Record how many frames we finally get out of the receiver.
491 size_t num_frames_return = 0;
492
493 const int64_t kMaxWaitTime = 30;
494
495 // Ideally, we should get all frames that we input in InitializeFrames.
496 // In the case that FrameForDecoding kills frames by error, we rely on the
497 // build bot to kill the test.
498 while (num_frames_return < kNumFrames) {
499 int64_t start_time = clock_.TimeInMilliseconds();
500 VCMEncodedFrame* frame =
philipel9d3ab612015-12-21 04:12:39 -0800501 receiver_.FrameForDecoding(kMaxWaitTime, &next_render_time, false);
Qiang Chend4cec152015-06-19 09:17:00 -0700502 int64_t end_time = clock_.TimeInMilliseconds();
503
504 // In any case the FrameForDecoding should not wait longer than
505 // max_wait_time.
506 // In the case that we did not get a frame, it should have been waiting for
507 // exactly max_wait_time. (By the testing samples we constructed above, we
508 // are sure there is no timing error, so the only case it returns with NULL
509 // is that it runs out of time.)
510 if (frame) {
511 receiver_.ReleaseFrame(frame);
512 ++num_frames_return;
513 EXPECT_GE(kMaxWaitTime, end_time - start_time);
514 } else {
515 EXPECT_EQ(kMaxWaitTime, end_time - start_time);
516 }
517 }
518}
519
perkj796cfaf2015-12-10 09:27:38 -0800520// Test whether VCMReceiver::FrameForDecoding handles parameter
521// |prefer_late_decoding| and |max_wait_time_ms| correctly:
522// 1. The function execution should never take more than |max_wait_time_ms|.
523// 2. If the function exit before now + |max_wait_time_ms|, a frame must be
524// returned and the end time must be equal to the render timestamp - delay
525// for decoding and rendering.
526TEST_F(VCMReceiverTimingTest, FrameForDecodingPreferLateDecoding) {
527 const size_t kNumFrames = 100;
528 const int kFramePeriod = 40;
529
530 int64_t arrive_timestamps[kNumFrames];
531 int64_t render_timestamps[kNumFrames];
532 int64_t next_render_time;
533
534 int render_delay_ms;
535 int max_decode_ms;
536 int dummy;
537 timing_.GetTimings(&dummy, &max_decode_ms, &dummy, &dummy, &dummy, &dummy,
538 &render_delay_ms);
539
540 // Construct test samples.
541 // render_timestamps are the timestamps stored in the Frame;
542 // arrive_timestamps controls when the Frame packet got received.
543 for (size_t i = 0; i < kNumFrames; i++) {
544 // Preset frame rate to 25Hz.
545 // But we add a reasonable deviation to arrive_timestamps to mimic Internet
546 // fluctuation.
547 arrive_timestamps[i] =
548 (i + 1) * kFramePeriod + (i % 10) * ((i % 2) ? 1 : -1);
549 render_timestamps[i] = (i + 1) * kFramePeriod;
550 }
551
552 clock_.SetFrames(arrive_timestamps, render_timestamps, kNumFrames);
553
554 // Record how many frames we finally get out of the receiver.
555 size_t num_frames_return = 0;
556 const int64_t kMaxWaitTime = 30;
557 bool prefer_late_decoding = true;
558 while (num_frames_return < kNumFrames) {
559 int64_t start_time = clock_.TimeInMilliseconds();
560
philipel9d3ab612015-12-21 04:12:39 -0800561 VCMEncodedFrame* frame = receiver_.FrameForDecoding(
562 kMaxWaitTime, &next_render_time, prefer_late_decoding);
perkj796cfaf2015-12-10 09:27:38 -0800563 int64_t end_time = clock_.TimeInMilliseconds();
564 if (frame) {
565 EXPECT_EQ(frame->RenderTimeMs() - max_decode_ms - render_delay_ms,
566 end_time);
567 receiver_.ReleaseFrame(frame);
568 ++num_frames_return;
569 } else {
570 EXPECT_EQ(kMaxWaitTime, end_time - start_time);
571 }
572 }
573}
574
mikhal@webrtc.org381da4b2013-04-25 21:45:29 +0000575} // namespace webrtc