blob: bf77ba48ef41662a035f9cf59831f81a68d9f34c [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
Jonas Olssona4d87372019-07-05 19:08:33 +020010#include "modules/video_coding/receiver.h"
11
mikhal@webrtc.org381da4b2013-04-25 21:45:29 +000012#include <string.h>
Jonas Olssona4d87372019-07-05 19:08:33 +020013
Yves Gerey3e707812018-11-28 16:47:49 +010014#include <cstdint>
kwiberg3f55dea2016-02-29 05:51:59 -080015#include <memory>
Qiang Chend4cec152015-06-19 09:17:00 -070016#include <queue>
philipel9d3ab612015-12-21 04:12:39 -080017#include <vector>
mikhal@webrtc.org381da4b2013-04-25 21:45:29 +000018
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020019#include "modules/video_coding/encoded_frame.h"
Yves Gerey3e707812018-11-28 16:47:49 +010020#include "modules/video_coding/jitter_buffer_common.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020021#include "modules/video_coding/packet.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020022#include "modules/video_coding/test/stream_generator.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020023#include "modules/video_coding/timing.h"
24#include "rtc_base/checks.h"
25#include "system_wrappers/include/clock.h"
26#include "test/gtest.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()),
Niels Möller689983f2018-11-07 16:36:22 +010035 receiver_(&timing_, clock_.get()) {
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
Niels Möller87e2d782019-03-07 10:18:23 +010060 int32_t InsertFrame(VideoFrameType frame_type, bool complete) {
mikhal@webrtc.org381da4b2013-04-25 21:45:29 +000061 int num_of_packets = complete ? 1 : 2;
62 stream_generator_->GenerateFrame(
Niels Möller8f7ce222019-03-21 15:43:58 +010063 frame_type,
64 (frame_type != VideoFrameType::kEmptyFrame) ? num_of_packets : 0,
65 (frame_type == VideoFrameType::kEmptyFrame) ? 1 : 0,
66 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() {
Johan Ahlers31b2ec42016-06-28 13:32:49 +020078 VCMEncodedFrame* frame = receiver_.FrameForDecoding(0, false);
stefan@webrtc.orgef144882013-05-07 19:16:33 +000079 if (!frame)
80 return false;
81 receiver_.ReleaseFrame(frame);
82 return true;
83 }
84
kwiberg3f55dea2016-02-29 05:51:59 -080085 std::unique_ptr<SimulatedClock> clock_;
mikhal@webrtc.org381da4b2013-04-25 21:45:29 +000086 VCMTiming timing_;
mikhal@webrtc.org381da4b2013-04-25 21:45:29 +000087 VCMReceiver receiver_;
kwiberg3f55dea2016-02-29 05:51:59 -080088 std::unique_ptr<StreamGenerator> stream_generator_;
mikhal@webrtc.org381da4b2013-04-25 21:45:29 +000089};
90
stefan@webrtc.orgef144882013-05-07 19:16:33 +000091TEST_F(TestVCMReceiver, NonDecodableDuration_Empty) {
stefan@webrtc.orgef144882013-05-07 19:16:33 +000092 const size_t kMaxNackListSize = 1000;
93 const int kMaxPacketAgeToNack = 1000;
94 const int kMaxNonDecodableDuration = 500;
95 const int kMinDelayMs = 500;
96 receiver_.SetNackSettings(kMaxNackListSize, kMaxPacketAgeToNack,
philipel9d3ab612015-12-21 04:12:39 -080097 kMaxNonDecodableDuration);
Niels Möller8f7ce222019-03-21 15:43:58 +010098 EXPECT_GE(InsertFrame(VideoFrameType::kVideoFrameKey, true), kNoError);
stefan@webrtc.orgef144882013-05-07 19:16:33 +000099 // Advance time until it's time to decode the key frame.
100 clock_->AdvanceTimeMilliseconds(kMinDelayMs);
101 EXPECT_TRUE(DecodeNextFrame());
Wan-Teh Changb1825a42015-06-03 15:03:35 -0700102 bool request_key_frame = false;
103 std::vector<uint16_t> nack_list = receiver_.NackList(&request_key_frame);
104 EXPECT_FALSE(request_key_frame);
stefan@webrtc.orgef144882013-05-07 19:16:33 +0000105}
106
107TEST_F(TestVCMReceiver, NonDecodableDuration_NoKeyFrame) {
stefan@webrtc.orgef144882013-05-07 19:16:33 +0000108 const size_t kMaxNackListSize = 1000;
109 const int kMaxPacketAgeToNack = 1000;
110 const int kMaxNonDecodableDuration = 500;
111 receiver_.SetNackSettings(kMaxNackListSize, kMaxPacketAgeToNack,
philipel9d3ab612015-12-21 04:12:39 -0800112 kMaxNonDecodableDuration);
stefan@webrtc.orgef144882013-05-07 19:16:33 +0000113 const int kNumFrames = kDefaultFrameRate * kMaxNonDecodableDuration / 1000;
114 for (int i = 0; i < kNumFrames; ++i) {
Niels Möller8f7ce222019-03-21 15:43:58 +0100115 EXPECT_GE(InsertFrame(VideoFrameType::kVideoFrameDelta, true), kNoError);
stefan@webrtc.orgef144882013-05-07 19:16:33 +0000116 }
Wan-Teh Changb1825a42015-06-03 15:03:35 -0700117 bool request_key_frame = false;
118 std::vector<uint16_t> nack_list = receiver_.NackList(&request_key_frame);
119 EXPECT_TRUE(request_key_frame);
stefan@webrtc.orgef144882013-05-07 19:16:33 +0000120}
121
122TEST_F(TestVCMReceiver, NonDecodableDuration_OneIncomplete) {
stefan@webrtc.orgef144882013-05-07 19:16:33 +0000123 const size_t kMaxNackListSize = 1000;
124 const int kMaxPacketAgeToNack = 1000;
125 const int kMaxNonDecodableDuration = 500;
philipel9d3ab612015-12-21 04:12:39 -0800126 const int kMaxNonDecodableDurationFrames =
127 (kDefaultFrameRate * kMaxNonDecodableDuration + 500) / 1000;
stefan@webrtc.orgef144882013-05-07 19:16:33 +0000128 const int kMinDelayMs = 500;
129 receiver_.SetNackSettings(kMaxNackListSize, kMaxPacketAgeToNack,
philipel9d3ab612015-12-21 04:12:39 -0800130 kMaxNonDecodableDuration);
Niels Möller4eb4b052018-08-14 10:31:58 +0200131 timing_.set_min_playout_delay(kMinDelayMs);
stefan@webrtc.orgef144882013-05-07 19:16:33 +0000132 int64_t key_frame_inserted = clock_->TimeInMilliseconds();
Niels Möller8f7ce222019-03-21 15:43:58 +0100133 EXPECT_GE(InsertFrame(VideoFrameType::kVideoFrameKey, true), kNoError);
stefan@webrtc.orgef144882013-05-07 19:16:33 +0000134 // Insert an incomplete frame.
Niels Möller8f7ce222019-03-21 15:43:58 +0100135 EXPECT_GE(InsertFrame(VideoFrameType::kVideoFrameDelta, false), kNoError);
stefan@webrtc.orgef144882013-05-07 19:16:33 +0000136 // Insert enough frames to have too long non-decodable sequence.
philipel9d3ab612015-12-21 04:12:39 -0800137 for (int i = 0; i < kMaxNonDecodableDurationFrames; ++i) {
Niels Möller8f7ce222019-03-21 15:43:58 +0100138 EXPECT_GE(InsertFrame(VideoFrameType::kVideoFrameDelta, true), kNoError);
stefan@webrtc.orgef144882013-05-07 19:16:33 +0000139 }
140 // Advance time until it's time to decode the key frame.
141 clock_->AdvanceTimeMilliseconds(kMinDelayMs - clock_->TimeInMilliseconds() -
philipel9d3ab612015-12-21 04:12:39 -0800142 key_frame_inserted);
stefan@webrtc.orgef144882013-05-07 19:16:33 +0000143 EXPECT_TRUE(DecodeNextFrame());
144 // Make sure we get a key frame request.
Wan-Teh Changb1825a42015-06-03 15:03:35 -0700145 bool request_key_frame = false;
146 std::vector<uint16_t> nack_list = receiver_.NackList(&request_key_frame);
147 EXPECT_TRUE(request_key_frame);
stefan@webrtc.orgef144882013-05-07 19:16:33 +0000148}
149
150TEST_F(TestVCMReceiver, NonDecodableDuration_NoTrigger) {
stefan@webrtc.orgef144882013-05-07 19:16:33 +0000151 const size_t kMaxNackListSize = 1000;
152 const int kMaxPacketAgeToNack = 1000;
153 const int kMaxNonDecodableDuration = 500;
philipel9d3ab612015-12-21 04:12:39 -0800154 const int kMaxNonDecodableDurationFrames =
155 (kDefaultFrameRate * kMaxNonDecodableDuration + 500) / 1000;
stefan@webrtc.orgef144882013-05-07 19:16:33 +0000156 const int kMinDelayMs = 500;
157 receiver_.SetNackSettings(kMaxNackListSize, kMaxPacketAgeToNack,
philipel9d3ab612015-12-21 04:12:39 -0800158 kMaxNonDecodableDuration);
Niels Möller4eb4b052018-08-14 10:31:58 +0200159 timing_.set_min_playout_delay(kMinDelayMs);
stefan@webrtc.orgef144882013-05-07 19:16:33 +0000160 int64_t key_frame_inserted = clock_->TimeInMilliseconds();
Niels Möller8f7ce222019-03-21 15:43:58 +0100161 EXPECT_GE(InsertFrame(VideoFrameType::kVideoFrameKey, true), kNoError);
stefan@webrtc.orgef144882013-05-07 19:16:33 +0000162 // Insert an incomplete frame.
Niels Möller8f7ce222019-03-21 15:43:58 +0100163 EXPECT_GE(InsertFrame(VideoFrameType::kVideoFrameDelta, false), kNoError);
stefan@webrtc.orgef144882013-05-07 19:16:33 +0000164 // Insert all but one frame to not trigger a key frame request due to
165 // too long duration of non-decodable frames.
philipel9d3ab612015-12-21 04:12:39 -0800166 for (int i = 0; i < kMaxNonDecodableDurationFrames - 1; ++i) {
Niels Möller8f7ce222019-03-21 15:43:58 +0100167 EXPECT_GE(InsertFrame(VideoFrameType::kVideoFrameDelta, true), kNoError);
stefan@webrtc.orgef144882013-05-07 19:16:33 +0000168 }
169 // Advance time until it's time to decode the key frame.
170 clock_->AdvanceTimeMilliseconds(kMinDelayMs - clock_->TimeInMilliseconds() -
philipel9d3ab612015-12-21 04:12:39 -0800171 key_frame_inserted);
stefan@webrtc.orgef144882013-05-07 19:16:33 +0000172 EXPECT_TRUE(DecodeNextFrame());
173 // Make sure we don't get a key frame request since we haven't generated
174 // enough frames.
Wan-Teh Changb1825a42015-06-03 15:03:35 -0700175 bool request_key_frame = false;
176 std::vector<uint16_t> nack_list = receiver_.NackList(&request_key_frame);
177 EXPECT_FALSE(request_key_frame);
stefan@webrtc.orgef144882013-05-07 19:16:33 +0000178}
179
stefan@webrtc.org16734812013-05-14 12:00:47 +0000180TEST_F(TestVCMReceiver, NonDecodableDuration_NoTrigger2) {
stefan@webrtc.org16734812013-05-14 12:00:47 +0000181 const size_t kMaxNackListSize = 1000;
182 const int kMaxPacketAgeToNack = 1000;
183 const int kMaxNonDecodableDuration = 500;
philipel9d3ab612015-12-21 04:12:39 -0800184 const int kMaxNonDecodableDurationFrames =
185 (kDefaultFrameRate * kMaxNonDecodableDuration + 500) / 1000;
stefan@webrtc.org16734812013-05-14 12:00:47 +0000186 const int kMinDelayMs = 500;
187 receiver_.SetNackSettings(kMaxNackListSize, kMaxPacketAgeToNack,
philipel9d3ab612015-12-21 04:12:39 -0800188 kMaxNonDecodableDuration);
Niels Möller4eb4b052018-08-14 10:31:58 +0200189 timing_.set_min_playout_delay(kMinDelayMs);
stefan@webrtc.org16734812013-05-14 12:00:47 +0000190 int64_t key_frame_inserted = clock_->TimeInMilliseconds();
Niels Möller8f7ce222019-03-21 15:43:58 +0100191 EXPECT_GE(InsertFrame(VideoFrameType::kVideoFrameKey, true), kNoError);
stefan@webrtc.org16734812013-05-14 12:00:47 +0000192 // Insert enough frames to have too long non-decodable sequence, except that
193 // we don't have any losses.
philipel9d3ab612015-12-21 04:12:39 -0800194 for (int i = 0; i < kMaxNonDecodableDurationFrames; ++i) {
Niels Möller8f7ce222019-03-21 15:43:58 +0100195 EXPECT_GE(InsertFrame(VideoFrameType::kVideoFrameDelta, true), kNoError);
stefan@webrtc.org16734812013-05-14 12:00:47 +0000196 }
197 // Insert an incomplete frame.
Niels Möller8f7ce222019-03-21 15:43:58 +0100198 EXPECT_GE(InsertFrame(VideoFrameType::kVideoFrameDelta, false), kNoError);
stefan@webrtc.org16734812013-05-14 12:00:47 +0000199 // Advance time until it's time to decode the key frame.
200 clock_->AdvanceTimeMilliseconds(kMinDelayMs - clock_->TimeInMilliseconds() -
philipel9d3ab612015-12-21 04:12:39 -0800201 key_frame_inserted);
stefan@webrtc.org16734812013-05-14 12:00:47 +0000202 EXPECT_TRUE(DecodeNextFrame());
203 // Make sure we don't get a key frame request since the non-decodable duration
204 // is only one frame.
Wan-Teh Changb1825a42015-06-03 15:03:35 -0700205 bool request_key_frame = false;
206 std::vector<uint16_t> nack_list = receiver_.NackList(&request_key_frame);
207 EXPECT_FALSE(request_key_frame);
stefan@webrtc.org16734812013-05-14 12:00:47 +0000208}
209
stefan@webrtc.orgef144882013-05-07 19:16:33 +0000210TEST_F(TestVCMReceiver, NonDecodableDuration_KeyFrameAfterIncompleteFrames) {
stefan@webrtc.orgef144882013-05-07 19:16:33 +0000211 const size_t kMaxNackListSize = 1000;
212 const int kMaxPacketAgeToNack = 1000;
213 const int kMaxNonDecodableDuration = 500;
philipel9d3ab612015-12-21 04:12:39 -0800214 const int kMaxNonDecodableDurationFrames =
215 (kDefaultFrameRate * kMaxNonDecodableDuration + 500) / 1000;
stefan@webrtc.orgef144882013-05-07 19:16:33 +0000216 const int kMinDelayMs = 500;
217 receiver_.SetNackSettings(kMaxNackListSize, kMaxPacketAgeToNack,
philipel9d3ab612015-12-21 04:12:39 -0800218 kMaxNonDecodableDuration);
Niels Möller4eb4b052018-08-14 10:31:58 +0200219 timing_.set_min_playout_delay(kMinDelayMs);
stefan@webrtc.orgef144882013-05-07 19:16:33 +0000220 int64_t key_frame_inserted = clock_->TimeInMilliseconds();
Niels Möller8f7ce222019-03-21 15:43:58 +0100221 EXPECT_GE(InsertFrame(VideoFrameType::kVideoFrameKey, true), kNoError);
stefan@webrtc.orgef144882013-05-07 19:16:33 +0000222 // Insert an incomplete frame.
Niels Möller8f7ce222019-03-21 15:43:58 +0100223 EXPECT_GE(InsertFrame(VideoFrameType::kVideoFrameDelta, false), kNoError);
stefan@webrtc.orgef144882013-05-07 19:16:33 +0000224 // Insert enough frames to have too long non-decodable sequence.
philipel9d3ab612015-12-21 04:12:39 -0800225 for (int i = 0; i < kMaxNonDecodableDurationFrames; ++i) {
Niels Möller8f7ce222019-03-21 15:43:58 +0100226 EXPECT_GE(InsertFrame(VideoFrameType::kVideoFrameDelta, true), kNoError);
stefan@webrtc.orgef144882013-05-07 19:16:33 +0000227 }
Niels Möller8f7ce222019-03-21 15:43:58 +0100228 EXPECT_GE(InsertFrame(VideoFrameType::kVideoFrameKey, true), kNoError);
stefan@webrtc.orgef144882013-05-07 19:16:33 +0000229 // Advance time until it's time to decode the key frame.
230 clock_->AdvanceTimeMilliseconds(kMinDelayMs - clock_->TimeInMilliseconds() -
philipel9d3ab612015-12-21 04:12:39 -0800231 key_frame_inserted);
stefan@webrtc.orgef144882013-05-07 19:16:33 +0000232 EXPECT_TRUE(DecodeNextFrame());
233 // Make sure we don't get a key frame request since we have a key frame
234 // in the list.
Wan-Teh Changb1825a42015-06-03 15:03:35 -0700235 bool request_key_frame = false;
236 std::vector<uint16_t> nack_list = receiver_.NackList(&request_key_frame);
237 EXPECT_FALSE(request_key_frame);
stefan@webrtc.orgef144882013-05-07 19:16:33 +0000238}
Qiang Chend4cec152015-06-19 09:17:00 -0700239
240// A simulated clock, when time elapses, will insert frames into the jitter
241// buffer, based on initial settings.
242class SimulatedClockWithFrames : public SimulatedClock {
243 public:
244 SimulatedClockWithFrames(StreamGenerator* stream_generator,
245 VCMReceiver* receiver)
246 : SimulatedClock(0),
247 stream_generator_(stream_generator),
248 receiver_(receiver) {}
249 virtual ~SimulatedClockWithFrames() {}
250
251 // If |stop_on_frame| is true and next frame arrives between now and
252 // now+|milliseconds|, the clock will be advanced to the arrival time of next
253 // frame.
254 // Otherwise, the clock will be advanced by |milliseconds|.
255 //
256 // For both cases, a frame will be inserted into the jitter buffer at the
257 // instant when the clock time is timestamps_.front().arrive_time.
258 //
259 // Return true if some frame arrives between now and now+|milliseconds|.
260 bool AdvanceTimeMilliseconds(int64_t milliseconds, bool stop_on_frame) {
261 return AdvanceTimeMicroseconds(milliseconds * 1000, stop_on_frame);
philipel9d3ab612015-12-21 04:12:39 -0800262 }
Qiang Chend4cec152015-06-19 09:17:00 -0700263
264 bool AdvanceTimeMicroseconds(int64_t microseconds, bool stop_on_frame) {
265 int64_t start_time = TimeInMicroseconds();
266 int64_t end_time = start_time + microseconds;
267 bool frame_injected = false;
268 while (!timestamps_.empty() &&
269 timestamps_.front().arrive_time <= end_time) {
Sebastian Jansson5a000162019-04-12 11:21:32 +0200270 RTC_DCHECK_GE(timestamps_.front().arrive_time, start_time);
Qiang Chend4cec152015-06-19 09:17:00 -0700271
272 SimulatedClock::AdvanceTimeMicroseconds(timestamps_.front().arrive_time -
273 TimeInMicroseconds());
274 GenerateAndInsertFrame((timestamps_.front().render_time + 500) / 1000);
275 timestamps_.pop();
276 frame_injected = true;
277
278 if (stop_on_frame)
279 return frame_injected;
280 }
281
282 if (TimeInMicroseconds() < end_time) {
283 SimulatedClock::AdvanceTimeMicroseconds(end_time - TimeInMicroseconds());
284 }
285 return frame_injected;
philipel9d3ab612015-12-21 04:12:39 -0800286 }
Qiang Chend4cec152015-06-19 09:17:00 -0700287
288 // Input timestamps are in unit Milliseconds.
289 // And |arrive_timestamps| must be positive and in increasing order.
290 // |arrive_timestamps| determine when we are going to insert frames into the
291 // jitter buffer.
292 // |render_timestamps| are the timestamps on the frame.
293 void SetFrames(const int64_t* arrive_timestamps,
294 const int64_t* render_timestamps,
295 size_t size) {
296 int64_t previous_arrive_timestamp = 0;
297 for (size_t i = 0; i < size; i++) {
Sebastian Jansson5a000162019-04-12 11:21:32 +0200298 RTC_CHECK_GE(arrive_timestamps[i], previous_arrive_timestamp);
Qiang Chend4cec152015-06-19 09:17:00 -0700299 timestamps_.push(TimestampPair(arrive_timestamps[i] * 1000,
300 render_timestamps[i] * 1000));
301 previous_arrive_timestamp = arrive_timestamps[i];
302 }
303 }
304
305 private:
306 struct TimestampPair {
307 TimestampPair(int64_t arrive_timestamp, int64_t render_timestamp)
308 : arrive_time(arrive_timestamp), render_time(render_timestamp) {}
309
310 int64_t arrive_time;
311 int64_t render_time;
312 };
313
314 void GenerateAndInsertFrame(int64_t render_timestamp_ms) {
315 VCMPacket packet;
Niels Möller87e2d782019-03-07 10:18:23 +0100316 stream_generator_->GenerateFrame(VideoFrameType::kVideoFrameKey,
Qiang Chend4cec152015-06-19 09:17:00 -0700317 1, // media packets
318 0, // empty packets
319 render_timestamp_ms);
320
321 bool packet_available = stream_generator_->PopPacket(&packet, 0);
322 EXPECT_TRUE(packet_available);
323 if (!packet_available)
324 return; // Return here to avoid crashes below.
Johan Ahlers95348f72016-06-28 11:11:28 +0200325 receiver_->InsertPacket(packet);
Qiang Chend4cec152015-06-19 09:17:00 -0700326 }
327
328 std::queue<TimestampPair> timestamps_;
329 StreamGenerator* stream_generator_;
330 VCMReceiver* receiver_;
331};
332
333// Use a SimulatedClockWithFrames
334// Wait call will do either of these:
335// 1. If |stop_on_frame| is true, the clock will be turned to the exact instant
336// that the first frame comes and the frame will be inserted into the jitter
337// buffer, or the clock will be turned to now + |max_time| if no frame comes in
338// the window.
339// 2. If |stop_on_frame| is false, the clock will be turn to now + |max_time|,
340// and all the frames arriving between now and now + |max_time| will be
341// inserted into the jitter buffer.
342//
343// This is used to simulate the JitterBuffer getting packets from internet as
344// time elapses.
345
346class FrameInjectEvent : public EventWrapper {
347 public:
348 FrameInjectEvent(SimulatedClockWithFrames* clock, bool stop_on_frame)
349 : clock_(clock), stop_on_frame_(stop_on_frame) {}
350
351 bool Set() override { return true; }
352
philipel9d3ab612015-12-21 04:12:39 -0800353 EventTypeWrapper Wait(unsigned long max_time) override { // NOLINT
Qiang Chend4cec152015-06-19 09:17:00 -0700354 if (clock_->AdvanceTimeMilliseconds(max_time, stop_on_frame_) &&
355 stop_on_frame_) {
356 return EventTypeWrapper::kEventSignaled;
357 } else {
358 return EventTypeWrapper::kEventTimeout;
359 }
360 }
361
362 private:
363 SimulatedClockWithFrames* clock_;
364 bool stop_on_frame_;
365};
366
367class VCMReceiverTimingTest : public ::testing::Test {
368 protected:
Qiang Chend4cec152015-06-19 09:17:00 -0700369 VCMReceiverTimingTest()
370
371 : clock_(&stream_generator_, &receiver_),
372 stream_generator_(0, clock_.TimeInMilliseconds()),
373 timing_(&clock_),
374 receiver_(
375 &timing_,
376 &clock_,
kwiberg3f55dea2016-02-29 05:51:59 -0800377 std::unique_ptr<EventWrapper>(new FrameInjectEvent(&clock_, false)),
378 std::unique_ptr<EventWrapper>(
Qiang Chend4cec152015-06-19 09:17:00 -0700379 new FrameInjectEvent(&clock_, true))) {}
380
Qiang Chend4cec152015-06-19 09:17:00 -0700381 virtual void SetUp() { receiver_.Reset(); }
382
383 SimulatedClockWithFrames clock_;
384 StreamGenerator stream_generator_;
385 VCMTiming timing_;
386 VCMReceiver receiver_;
387};
388
389// Test whether VCMReceiver::FrameForDecoding handles parameter
390// |max_wait_time_ms| correctly:
391// 1. The function execution should never take more than |max_wait_time_ms|.
392// 2. If the function exit before now + |max_wait_time_ms|, a frame must be
393// returned.
394TEST_F(VCMReceiverTimingTest, FrameForDecoding) {
395 const size_t kNumFrames = 100;
396 const int kFramePeriod = 40;
397 int64_t arrive_timestamps[kNumFrames];
398 int64_t render_timestamps[kNumFrames];
Qiang Chend4cec152015-06-19 09:17:00 -0700399
400 // Construct test samples.
401 // render_timestamps are the timestamps stored in the Frame;
402 // arrive_timestamps controls when the Frame packet got received.
403 for (size_t i = 0; i < kNumFrames; i++) {
404 // Preset frame rate to 25Hz.
405 // But we add a reasonable deviation to arrive_timestamps to mimic Internet
406 // fluctuation.
407 arrive_timestamps[i] =
408 (i + 1) * kFramePeriod + (i % 10) * ((i % 2) ? 1 : -1);
409 render_timestamps[i] = (i + 1) * kFramePeriod;
410 }
411
412 clock_.SetFrames(arrive_timestamps, render_timestamps, kNumFrames);
413
414 // Record how many frames we finally get out of the receiver.
415 size_t num_frames_return = 0;
416
417 const int64_t kMaxWaitTime = 30;
418
419 // Ideally, we should get all frames that we input in InitializeFrames.
420 // In the case that FrameForDecoding kills frames by error, we rely on the
421 // build bot to kill the test.
422 while (num_frames_return < kNumFrames) {
423 int64_t start_time = clock_.TimeInMilliseconds();
Johan Ahlers31b2ec42016-06-28 13:32:49 +0200424 VCMEncodedFrame* frame = receiver_.FrameForDecoding(kMaxWaitTime, false);
Qiang Chend4cec152015-06-19 09:17:00 -0700425 int64_t end_time = clock_.TimeInMilliseconds();
426
427 // In any case the FrameForDecoding should not wait longer than
428 // max_wait_time.
429 // In the case that we did not get a frame, it should have been waiting for
430 // exactly max_wait_time. (By the testing samples we constructed above, we
431 // are sure there is no timing error, so the only case it returns with NULL
432 // is that it runs out of time.)
433 if (frame) {
434 receiver_.ReleaseFrame(frame);
435 ++num_frames_return;
436 EXPECT_GE(kMaxWaitTime, end_time - start_time);
437 } else {
438 EXPECT_EQ(kMaxWaitTime, end_time - start_time);
439 }
440 }
441}
442
perkj796cfaf2015-12-10 09:27:38 -0800443// Test whether VCMReceiver::FrameForDecoding handles parameter
444// |prefer_late_decoding| and |max_wait_time_ms| correctly:
445// 1. The function execution should never take more than |max_wait_time_ms|.
446// 2. If the function exit before now + |max_wait_time_ms|, a frame must be
447// returned and the end time must be equal to the render timestamp - delay
448// for decoding and rendering.
449TEST_F(VCMReceiverTimingTest, FrameForDecodingPreferLateDecoding) {
450 const size_t kNumFrames = 100;
451 const int kFramePeriod = 40;
452
453 int64_t arrive_timestamps[kNumFrames];
454 int64_t render_timestamps[kNumFrames];
perkj796cfaf2015-12-10 09:27:38 -0800455
456 int render_delay_ms;
457 int max_decode_ms;
458 int dummy;
Johannes Kronbfd343b2019-07-01 10:07:50 +0200459 timing_.GetTimings(&max_decode_ms, &dummy, &dummy, &dummy, &dummy,
perkj796cfaf2015-12-10 09:27:38 -0800460 &render_delay_ms);
461
462 // Construct test samples.
463 // render_timestamps are the timestamps stored in the Frame;
464 // arrive_timestamps controls when the Frame packet got received.
465 for (size_t i = 0; i < kNumFrames; i++) {
466 // Preset frame rate to 25Hz.
467 // But we add a reasonable deviation to arrive_timestamps to mimic Internet
468 // fluctuation.
469 arrive_timestamps[i] =
470 (i + 1) * kFramePeriod + (i % 10) * ((i % 2) ? 1 : -1);
471 render_timestamps[i] = (i + 1) * kFramePeriod;
472 }
473
474 clock_.SetFrames(arrive_timestamps, render_timestamps, kNumFrames);
475
476 // Record how many frames we finally get out of the receiver.
477 size_t num_frames_return = 0;
478 const int64_t kMaxWaitTime = 30;
479 bool prefer_late_decoding = true;
480 while (num_frames_return < kNumFrames) {
481 int64_t start_time = clock_.TimeInMilliseconds();
482
Johan Ahlers31b2ec42016-06-28 13:32:49 +0200483 VCMEncodedFrame* frame =
484 receiver_.FrameForDecoding(kMaxWaitTime, prefer_late_decoding);
perkj796cfaf2015-12-10 09:27:38 -0800485 int64_t end_time = clock_.TimeInMilliseconds();
486 if (frame) {
487 EXPECT_EQ(frame->RenderTimeMs() - max_decode_ms - render_delay_ms,
488 end_time);
489 receiver_.ReleaseFrame(frame);
490 ++num_frames_return;
491 } else {
492 EXPECT_EQ(kMaxWaitTime, end_time - start_time);
493 }
494 }
495}
496
mikhal@webrtc.org381da4b2013-04-25 21:45:29 +0000497} // namespace webrtc