blob: 563116676f6f6fabc39a8c71eacc8d8faeac10b3 [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>
Yves Gerey3e707812018-11-28 16:47:49 +010011#include <cstdint>
kwiberg3f55dea2016-02-29 05:51:59 -080012#include <memory>
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
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020016#include "modules/video_coding/encoded_frame.h"
Yves Gerey3e707812018-11-28 16:47:49 +010017#include "modules/video_coding/jitter_buffer_common.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020018#include "modules/video_coding/packet.h"
19#include "modules/video_coding/receiver.h"
20#include "modules/video_coding/test/stream_generator.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020021#include "modules/video_coding/timing.h"
22#include "rtc_base/checks.h"
23#include "system_wrappers/include/clock.h"
24#include "test/gtest.h"
mikhal@webrtc.org381da4b2013-04-25 21:45:29 +000025
26namespace webrtc {
27
28class TestVCMReceiver : public ::testing::Test {
29 protected:
mikhal@webrtc.org381da4b2013-04-25 21:45:29 +000030 TestVCMReceiver()
31 : clock_(new SimulatedClock(0)),
32 timing_(clock_.get()),
Niels Möller689983f2018-11-07 16:36:22 +010033 receiver_(&timing_, clock_.get()) {
philipel9d3ab612015-12-21 04:12:39 -080034 stream_generator_.reset(
35 new StreamGenerator(0, clock_->TimeInMilliseconds()));
mikhal@webrtc.org381da4b2013-04-25 21:45:29 +000036 }
37
philipel9d3ab612015-12-21 04:12:39 -080038 virtual void SetUp() { receiver_.Reset(); }
mikhal@webrtc.org381da4b2013-04-25 21:45:29 +000039
40 int32_t InsertPacket(int index) {
41 VCMPacket packet;
mikhal@webrtc.org381da4b2013-04-25 21:45:29 +000042 bool packet_available = stream_generator_->GetPacket(&packet, index);
43 EXPECT_TRUE(packet_available);
44 if (!packet_available)
stefan@webrtc.org3417eb42013-05-21 15:25:53 +000045 return kGeneralError; // Return here to avoid crashes below.
Johan Ahlers95348f72016-06-28 11:11:28 +020046 return receiver_.InsertPacket(packet);
mikhal@webrtc.org381da4b2013-04-25 21:45:29 +000047 }
48
49 int32_t InsertPacketAndPop(int index) {
50 VCMPacket packet;
mikhal@webrtc.org381da4b2013-04-25 21:45:29 +000051 bool packet_available = stream_generator_->PopPacket(&packet, index);
52 EXPECT_TRUE(packet_available);
53 if (!packet_available)
stefan@webrtc.org3417eb42013-05-21 15:25:53 +000054 return kGeneralError; // Return here to avoid crashes below.
Johan Ahlers95348f72016-06-28 11:11:28 +020055 return receiver_.InsertPacket(packet);
mikhal@webrtc.org381da4b2013-04-25 21:45:29 +000056 }
57
Niels Möller87e2d782019-03-07 10:18:23 +010058 int32_t InsertFrame(VideoFrameType frame_type, bool complete) {
mikhal@webrtc.org381da4b2013-04-25 21:45:29 +000059 int num_of_packets = complete ? 1 : 2;
60 stream_generator_->GenerateFrame(
Niels Möller8f7ce222019-03-21 15:43:58 +010061 frame_type,
62 (frame_type != VideoFrameType::kEmptyFrame) ? num_of_packets : 0,
63 (frame_type == VideoFrameType::kEmptyFrame) ? 1 : 0,
64 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_;
mikhal@webrtc.org381da4b2013-04-25 21:45:29 +000085 VCMReceiver receiver_;
kwiberg3f55dea2016-02-29 05:51:59 -080086 std::unique_ptr<StreamGenerator> stream_generator_;
mikhal@webrtc.org381da4b2013-04-25 21:45:29 +000087};
88
stefan@webrtc.orgef144882013-05-07 19:16:33 +000089TEST_F(TestVCMReceiver, NonDecodableDuration_Empty) {
stefan@webrtc.orgef144882013-05-07 19:16:33 +000090 const size_t kMaxNackListSize = 1000;
91 const int kMaxPacketAgeToNack = 1000;
92 const int kMaxNonDecodableDuration = 500;
93 const int kMinDelayMs = 500;
94 receiver_.SetNackSettings(kMaxNackListSize, kMaxPacketAgeToNack,
philipel9d3ab612015-12-21 04:12:39 -080095 kMaxNonDecodableDuration);
Niels Möller8f7ce222019-03-21 15:43:58 +010096 EXPECT_GE(InsertFrame(VideoFrameType::kVideoFrameKey, true), kNoError);
stefan@webrtc.orgef144882013-05-07 19:16:33 +000097 // Advance time until it's time to decode the key frame.
98 clock_->AdvanceTimeMilliseconds(kMinDelayMs);
99 EXPECT_TRUE(DecodeNextFrame());
Wan-Teh Changb1825a42015-06-03 15:03:35 -0700100 bool request_key_frame = false;
101 std::vector<uint16_t> nack_list = receiver_.NackList(&request_key_frame);
102 EXPECT_FALSE(request_key_frame);
stefan@webrtc.orgef144882013-05-07 19:16:33 +0000103}
104
105TEST_F(TestVCMReceiver, NonDecodableDuration_NoKeyFrame) {
stefan@webrtc.orgef144882013-05-07 19:16:33 +0000106 const size_t kMaxNackListSize = 1000;
107 const int kMaxPacketAgeToNack = 1000;
108 const int kMaxNonDecodableDuration = 500;
109 receiver_.SetNackSettings(kMaxNackListSize, kMaxPacketAgeToNack,
philipel9d3ab612015-12-21 04:12:39 -0800110 kMaxNonDecodableDuration);
stefan@webrtc.orgef144882013-05-07 19:16:33 +0000111 const int kNumFrames = kDefaultFrameRate * kMaxNonDecodableDuration / 1000;
112 for (int i = 0; i < kNumFrames; ++i) {
Niels Möller8f7ce222019-03-21 15:43:58 +0100113 EXPECT_GE(InsertFrame(VideoFrameType::kVideoFrameDelta, true), kNoError);
stefan@webrtc.orgef144882013-05-07 19:16:33 +0000114 }
Wan-Teh Changb1825a42015-06-03 15:03:35 -0700115 bool request_key_frame = false;
116 std::vector<uint16_t> nack_list = receiver_.NackList(&request_key_frame);
117 EXPECT_TRUE(request_key_frame);
stefan@webrtc.orgef144882013-05-07 19:16:33 +0000118}
119
120TEST_F(TestVCMReceiver, NonDecodableDuration_OneIncomplete) {
stefan@webrtc.orgef144882013-05-07 19:16:33 +0000121 const size_t kMaxNackListSize = 1000;
122 const int kMaxPacketAgeToNack = 1000;
123 const int kMaxNonDecodableDuration = 500;
philipel9d3ab612015-12-21 04:12:39 -0800124 const int kMaxNonDecodableDurationFrames =
125 (kDefaultFrameRate * kMaxNonDecodableDuration + 500) / 1000;
stefan@webrtc.orgef144882013-05-07 19:16:33 +0000126 const int kMinDelayMs = 500;
127 receiver_.SetNackSettings(kMaxNackListSize, kMaxPacketAgeToNack,
philipel9d3ab612015-12-21 04:12:39 -0800128 kMaxNonDecodableDuration);
Niels Möller4eb4b052018-08-14 10:31:58 +0200129 timing_.set_min_playout_delay(kMinDelayMs);
stefan@webrtc.orgef144882013-05-07 19:16:33 +0000130 int64_t key_frame_inserted = clock_->TimeInMilliseconds();
Niels Möller8f7ce222019-03-21 15:43:58 +0100131 EXPECT_GE(InsertFrame(VideoFrameType::kVideoFrameKey, true), kNoError);
stefan@webrtc.orgef144882013-05-07 19:16:33 +0000132 // Insert an incomplete frame.
Niels Möller8f7ce222019-03-21 15:43:58 +0100133 EXPECT_GE(InsertFrame(VideoFrameType::kVideoFrameDelta, false), kNoError);
stefan@webrtc.orgef144882013-05-07 19:16:33 +0000134 // Insert enough frames to have too long non-decodable sequence.
philipel9d3ab612015-12-21 04:12:39 -0800135 for (int i = 0; i < kMaxNonDecodableDurationFrames; ++i) {
Niels Möller8f7ce222019-03-21 15:43:58 +0100136 EXPECT_GE(InsertFrame(VideoFrameType::kVideoFrameDelta, true), kNoError);
stefan@webrtc.orgef144882013-05-07 19:16:33 +0000137 }
138 // Advance time until it's time to decode the key frame.
139 clock_->AdvanceTimeMilliseconds(kMinDelayMs - clock_->TimeInMilliseconds() -
philipel9d3ab612015-12-21 04:12:39 -0800140 key_frame_inserted);
stefan@webrtc.orgef144882013-05-07 19:16:33 +0000141 EXPECT_TRUE(DecodeNextFrame());
142 // Make sure we get a key frame request.
Wan-Teh Changb1825a42015-06-03 15:03:35 -0700143 bool request_key_frame = false;
144 std::vector<uint16_t> nack_list = receiver_.NackList(&request_key_frame);
145 EXPECT_TRUE(request_key_frame);
stefan@webrtc.orgef144882013-05-07 19:16:33 +0000146}
147
148TEST_F(TestVCMReceiver, NonDecodableDuration_NoTrigger) {
stefan@webrtc.orgef144882013-05-07 19:16:33 +0000149 const size_t kMaxNackListSize = 1000;
150 const int kMaxPacketAgeToNack = 1000;
151 const int kMaxNonDecodableDuration = 500;
philipel9d3ab612015-12-21 04:12:39 -0800152 const int kMaxNonDecodableDurationFrames =
153 (kDefaultFrameRate * kMaxNonDecodableDuration + 500) / 1000;
stefan@webrtc.orgef144882013-05-07 19:16:33 +0000154 const int kMinDelayMs = 500;
155 receiver_.SetNackSettings(kMaxNackListSize, kMaxPacketAgeToNack,
philipel9d3ab612015-12-21 04:12:39 -0800156 kMaxNonDecodableDuration);
Niels Möller4eb4b052018-08-14 10:31:58 +0200157 timing_.set_min_playout_delay(kMinDelayMs);
stefan@webrtc.orgef144882013-05-07 19:16:33 +0000158 int64_t key_frame_inserted = clock_->TimeInMilliseconds();
Niels Möller8f7ce222019-03-21 15:43:58 +0100159 EXPECT_GE(InsertFrame(VideoFrameType::kVideoFrameKey, true), kNoError);
stefan@webrtc.orgef144882013-05-07 19:16:33 +0000160 // Insert an incomplete frame.
Niels Möller8f7ce222019-03-21 15:43:58 +0100161 EXPECT_GE(InsertFrame(VideoFrameType::kVideoFrameDelta, false), kNoError);
stefan@webrtc.orgef144882013-05-07 19:16:33 +0000162 // Insert all but one frame to not trigger a key frame request due to
163 // too long duration of non-decodable frames.
philipel9d3ab612015-12-21 04:12:39 -0800164 for (int i = 0; i < kMaxNonDecodableDurationFrames - 1; ++i) {
Niels Möller8f7ce222019-03-21 15:43:58 +0100165 EXPECT_GE(InsertFrame(VideoFrameType::kVideoFrameDelta, true), kNoError);
stefan@webrtc.orgef144882013-05-07 19:16:33 +0000166 }
167 // Advance time until it's time to decode the key frame.
168 clock_->AdvanceTimeMilliseconds(kMinDelayMs - clock_->TimeInMilliseconds() -
philipel9d3ab612015-12-21 04:12:39 -0800169 key_frame_inserted);
stefan@webrtc.orgef144882013-05-07 19:16:33 +0000170 EXPECT_TRUE(DecodeNextFrame());
171 // Make sure we don't get a key frame request since we haven't generated
172 // enough frames.
Wan-Teh Changb1825a42015-06-03 15:03:35 -0700173 bool request_key_frame = false;
174 std::vector<uint16_t> nack_list = receiver_.NackList(&request_key_frame);
175 EXPECT_FALSE(request_key_frame);
stefan@webrtc.orgef144882013-05-07 19:16:33 +0000176}
177
stefan@webrtc.org16734812013-05-14 12:00:47 +0000178TEST_F(TestVCMReceiver, NonDecodableDuration_NoTrigger2) {
stefan@webrtc.org16734812013-05-14 12:00:47 +0000179 const size_t kMaxNackListSize = 1000;
180 const int kMaxPacketAgeToNack = 1000;
181 const int kMaxNonDecodableDuration = 500;
philipel9d3ab612015-12-21 04:12:39 -0800182 const int kMaxNonDecodableDurationFrames =
183 (kDefaultFrameRate * kMaxNonDecodableDuration + 500) / 1000;
stefan@webrtc.org16734812013-05-14 12:00:47 +0000184 const int kMinDelayMs = 500;
185 receiver_.SetNackSettings(kMaxNackListSize, kMaxPacketAgeToNack,
philipel9d3ab612015-12-21 04:12:39 -0800186 kMaxNonDecodableDuration);
Niels Möller4eb4b052018-08-14 10:31:58 +0200187 timing_.set_min_playout_delay(kMinDelayMs);
stefan@webrtc.org16734812013-05-14 12:00:47 +0000188 int64_t key_frame_inserted = clock_->TimeInMilliseconds();
Niels Möller8f7ce222019-03-21 15:43:58 +0100189 EXPECT_GE(InsertFrame(VideoFrameType::kVideoFrameKey, true), kNoError);
stefan@webrtc.org16734812013-05-14 12:00:47 +0000190 // Insert enough frames to have too long non-decodable sequence, except that
191 // we don't have any losses.
philipel9d3ab612015-12-21 04:12:39 -0800192 for (int i = 0; i < kMaxNonDecodableDurationFrames; ++i) {
Niels Möller8f7ce222019-03-21 15:43:58 +0100193 EXPECT_GE(InsertFrame(VideoFrameType::kVideoFrameDelta, true), kNoError);
stefan@webrtc.org16734812013-05-14 12:00:47 +0000194 }
195 // Insert an incomplete frame.
Niels Möller8f7ce222019-03-21 15:43:58 +0100196 EXPECT_GE(InsertFrame(VideoFrameType::kVideoFrameDelta, false), kNoError);
stefan@webrtc.org16734812013-05-14 12:00:47 +0000197 // Advance time until it's time to decode the key frame.
198 clock_->AdvanceTimeMilliseconds(kMinDelayMs - clock_->TimeInMilliseconds() -
philipel9d3ab612015-12-21 04:12:39 -0800199 key_frame_inserted);
stefan@webrtc.org16734812013-05-14 12:00:47 +0000200 EXPECT_TRUE(DecodeNextFrame());
201 // Make sure we don't get a key frame request since the non-decodable duration
202 // is only one frame.
Wan-Teh Changb1825a42015-06-03 15:03:35 -0700203 bool request_key_frame = false;
204 std::vector<uint16_t> nack_list = receiver_.NackList(&request_key_frame);
205 EXPECT_FALSE(request_key_frame);
stefan@webrtc.org16734812013-05-14 12:00:47 +0000206}
207
stefan@webrtc.orgef144882013-05-07 19:16:33 +0000208TEST_F(TestVCMReceiver, NonDecodableDuration_KeyFrameAfterIncompleteFrames) {
stefan@webrtc.orgef144882013-05-07 19:16:33 +0000209 const size_t kMaxNackListSize = 1000;
210 const int kMaxPacketAgeToNack = 1000;
211 const int kMaxNonDecodableDuration = 500;
philipel9d3ab612015-12-21 04:12:39 -0800212 const int kMaxNonDecodableDurationFrames =
213 (kDefaultFrameRate * kMaxNonDecodableDuration + 500) / 1000;
stefan@webrtc.orgef144882013-05-07 19:16:33 +0000214 const int kMinDelayMs = 500;
215 receiver_.SetNackSettings(kMaxNackListSize, kMaxPacketAgeToNack,
philipel9d3ab612015-12-21 04:12:39 -0800216 kMaxNonDecodableDuration);
Niels Möller4eb4b052018-08-14 10:31:58 +0200217 timing_.set_min_playout_delay(kMinDelayMs);
stefan@webrtc.orgef144882013-05-07 19:16:33 +0000218 int64_t key_frame_inserted = clock_->TimeInMilliseconds();
Niels Möller8f7ce222019-03-21 15:43:58 +0100219 EXPECT_GE(InsertFrame(VideoFrameType::kVideoFrameKey, true), kNoError);
stefan@webrtc.orgef144882013-05-07 19:16:33 +0000220 // Insert an incomplete frame.
Niels Möller8f7ce222019-03-21 15:43:58 +0100221 EXPECT_GE(InsertFrame(VideoFrameType::kVideoFrameDelta, false), kNoError);
stefan@webrtc.orgef144882013-05-07 19:16:33 +0000222 // Insert enough frames to have too long non-decodable sequence.
philipel9d3ab612015-12-21 04:12:39 -0800223 for (int i = 0; i < kMaxNonDecodableDurationFrames; ++i) {
Niels Möller8f7ce222019-03-21 15:43:58 +0100224 EXPECT_GE(InsertFrame(VideoFrameType::kVideoFrameDelta, true), kNoError);
stefan@webrtc.orgef144882013-05-07 19:16:33 +0000225 }
Niels Möller8f7ce222019-03-21 15:43:58 +0100226 EXPECT_GE(InsertFrame(VideoFrameType::kVideoFrameKey, true), kNoError);
stefan@webrtc.orgef144882013-05-07 19:16:33 +0000227 // Advance time until it's time to decode the key frame.
228 clock_->AdvanceTimeMilliseconds(kMinDelayMs - clock_->TimeInMilliseconds() -
philipel9d3ab612015-12-21 04:12:39 -0800229 key_frame_inserted);
stefan@webrtc.orgef144882013-05-07 19:16:33 +0000230 EXPECT_TRUE(DecodeNextFrame());
231 // Make sure we don't get a key frame request since we have a key frame
232 // in the list.
Wan-Teh Changb1825a42015-06-03 15:03:35 -0700233 bool request_key_frame = false;
234 std::vector<uint16_t> nack_list = receiver_.NackList(&request_key_frame);
235 EXPECT_FALSE(request_key_frame);
stefan@webrtc.orgef144882013-05-07 19:16:33 +0000236}
Qiang Chend4cec152015-06-19 09:17:00 -0700237
238// A simulated clock, when time elapses, will insert frames into the jitter
239// buffer, based on initial settings.
240class SimulatedClockWithFrames : public SimulatedClock {
241 public:
242 SimulatedClockWithFrames(StreamGenerator* stream_generator,
243 VCMReceiver* receiver)
244 : SimulatedClock(0),
245 stream_generator_(stream_generator),
246 receiver_(receiver) {}
247 virtual ~SimulatedClockWithFrames() {}
248
249 // If |stop_on_frame| is true and next frame arrives between now and
250 // now+|milliseconds|, the clock will be advanced to the arrival time of next
251 // frame.
252 // Otherwise, the clock will be advanced by |milliseconds|.
253 //
254 // For both cases, a frame will be inserted into the jitter buffer at the
255 // instant when the clock time is timestamps_.front().arrive_time.
256 //
257 // Return true if some frame arrives between now and now+|milliseconds|.
258 bool AdvanceTimeMilliseconds(int64_t milliseconds, bool stop_on_frame) {
259 return AdvanceTimeMicroseconds(milliseconds * 1000, stop_on_frame);
philipel9d3ab612015-12-21 04:12:39 -0800260 }
Qiang Chend4cec152015-06-19 09:17:00 -0700261
262 bool AdvanceTimeMicroseconds(int64_t microseconds, bool stop_on_frame) {
263 int64_t start_time = TimeInMicroseconds();
264 int64_t end_time = start_time + microseconds;
265 bool frame_injected = false;
266 while (!timestamps_.empty() &&
267 timestamps_.front().arrive_time <= end_time) {
Sebastian Jansson5a000162019-04-12 11:21:32 +0200268 RTC_DCHECK_GE(timestamps_.front().arrive_time, start_time);
Qiang Chend4cec152015-06-19 09:17:00 -0700269
270 SimulatedClock::AdvanceTimeMicroseconds(timestamps_.front().arrive_time -
271 TimeInMicroseconds());
272 GenerateAndInsertFrame((timestamps_.front().render_time + 500) / 1000);
273 timestamps_.pop();
274 frame_injected = true;
275
276 if (stop_on_frame)
277 return frame_injected;
278 }
279
280 if (TimeInMicroseconds() < end_time) {
281 SimulatedClock::AdvanceTimeMicroseconds(end_time - TimeInMicroseconds());
282 }
283 return frame_injected;
philipel9d3ab612015-12-21 04:12:39 -0800284 }
Qiang Chend4cec152015-06-19 09:17:00 -0700285
286 // Input timestamps are in unit Milliseconds.
287 // And |arrive_timestamps| must be positive and in increasing order.
288 // |arrive_timestamps| determine when we are going to insert frames into the
289 // jitter buffer.
290 // |render_timestamps| are the timestamps on the frame.
291 void SetFrames(const int64_t* arrive_timestamps,
292 const int64_t* render_timestamps,
293 size_t size) {
294 int64_t previous_arrive_timestamp = 0;
295 for (size_t i = 0; i < size; i++) {
Sebastian Jansson5a000162019-04-12 11:21:32 +0200296 RTC_CHECK_GE(arrive_timestamps[i], previous_arrive_timestamp);
Qiang Chend4cec152015-06-19 09:17:00 -0700297 timestamps_.push(TimestampPair(arrive_timestamps[i] * 1000,
298 render_timestamps[i] * 1000));
299 previous_arrive_timestamp = arrive_timestamps[i];
300 }
301 }
302
303 private:
304 struct TimestampPair {
305 TimestampPair(int64_t arrive_timestamp, int64_t render_timestamp)
306 : arrive_time(arrive_timestamp), render_time(render_timestamp) {}
307
308 int64_t arrive_time;
309 int64_t render_time;
310 };
311
312 void GenerateAndInsertFrame(int64_t render_timestamp_ms) {
313 VCMPacket packet;
Niels Möller87e2d782019-03-07 10:18:23 +0100314 stream_generator_->GenerateFrame(VideoFrameType::kVideoFrameKey,
Qiang Chend4cec152015-06-19 09:17:00 -0700315 1, // media packets
316 0, // empty packets
317 render_timestamp_ms);
318
319 bool packet_available = stream_generator_->PopPacket(&packet, 0);
320 EXPECT_TRUE(packet_available);
321 if (!packet_available)
322 return; // Return here to avoid crashes below.
Johan Ahlers95348f72016-06-28 11:11:28 +0200323 receiver_->InsertPacket(packet);
Qiang Chend4cec152015-06-19 09:17:00 -0700324 }
325
326 std::queue<TimestampPair> timestamps_;
327 StreamGenerator* stream_generator_;
328 VCMReceiver* receiver_;
329};
330
331// Use a SimulatedClockWithFrames
332// Wait call will do either of these:
333// 1. If |stop_on_frame| is true, the clock will be turned to the exact instant
334// that the first frame comes and the frame will be inserted into the jitter
335// buffer, or the clock will be turned to now + |max_time| if no frame comes in
336// the window.
337// 2. If |stop_on_frame| is false, the clock will be turn to now + |max_time|,
338// and all the frames arriving between now and now + |max_time| will be
339// inserted into the jitter buffer.
340//
341// This is used to simulate the JitterBuffer getting packets from internet as
342// time elapses.
343
344class FrameInjectEvent : public EventWrapper {
345 public:
346 FrameInjectEvent(SimulatedClockWithFrames* clock, bool stop_on_frame)
347 : clock_(clock), stop_on_frame_(stop_on_frame) {}
348
349 bool Set() override { return true; }
350
philipel9d3ab612015-12-21 04:12:39 -0800351 EventTypeWrapper Wait(unsigned long max_time) override { // NOLINT
Qiang Chend4cec152015-06-19 09:17:00 -0700352 if (clock_->AdvanceTimeMilliseconds(max_time, stop_on_frame_) &&
353 stop_on_frame_) {
354 return EventTypeWrapper::kEventSignaled;
355 } else {
356 return EventTypeWrapper::kEventTimeout;
357 }
358 }
359
360 private:
361 SimulatedClockWithFrames* clock_;
362 bool stop_on_frame_;
363};
364
365class VCMReceiverTimingTest : public ::testing::Test {
366 protected:
Qiang Chend4cec152015-06-19 09:17:00 -0700367 VCMReceiverTimingTest()
368
369 : clock_(&stream_generator_, &receiver_),
370 stream_generator_(0, clock_.TimeInMilliseconds()),
371 timing_(&clock_),
372 receiver_(
373 &timing_,
374 &clock_,
kwiberg3f55dea2016-02-29 05:51:59 -0800375 std::unique_ptr<EventWrapper>(new FrameInjectEvent(&clock_, false)),
376 std::unique_ptr<EventWrapper>(
Qiang Chend4cec152015-06-19 09:17:00 -0700377 new FrameInjectEvent(&clock_, true))) {}
378
Qiang Chend4cec152015-06-19 09:17:00 -0700379 virtual void SetUp() { receiver_.Reset(); }
380
381 SimulatedClockWithFrames clock_;
382 StreamGenerator stream_generator_;
383 VCMTiming timing_;
384 VCMReceiver receiver_;
385};
386
387// Test whether VCMReceiver::FrameForDecoding handles parameter
388// |max_wait_time_ms| correctly:
389// 1. The function execution should never take more than |max_wait_time_ms|.
390// 2. If the function exit before now + |max_wait_time_ms|, a frame must be
391// returned.
392TEST_F(VCMReceiverTimingTest, FrameForDecoding) {
393 const size_t kNumFrames = 100;
394 const int kFramePeriod = 40;
395 int64_t arrive_timestamps[kNumFrames];
396 int64_t render_timestamps[kNumFrames];
Qiang Chend4cec152015-06-19 09:17:00 -0700397
398 // Construct test samples.
399 // render_timestamps are the timestamps stored in the Frame;
400 // arrive_timestamps controls when the Frame packet got received.
401 for (size_t i = 0; i < kNumFrames; i++) {
402 // Preset frame rate to 25Hz.
403 // But we add a reasonable deviation to arrive_timestamps to mimic Internet
404 // fluctuation.
405 arrive_timestamps[i] =
406 (i + 1) * kFramePeriod + (i % 10) * ((i % 2) ? 1 : -1);
407 render_timestamps[i] = (i + 1) * kFramePeriod;
408 }
409
410 clock_.SetFrames(arrive_timestamps, render_timestamps, kNumFrames);
411
412 // Record how many frames we finally get out of the receiver.
413 size_t num_frames_return = 0;
414
415 const int64_t kMaxWaitTime = 30;
416
417 // Ideally, we should get all frames that we input in InitializeFrames.
418 // In the case that FrameForDecoding kills frames by error, we rely on the
419 // build bot to kill the test.
420 while (num_frames_return < kNumFrames) {
421 int64_t start_time = clock_.TimeInMilliseconds();
Johan Ahlers31b2ec42016-06-28 13:32:49 +0200422 VCMEncodedFrame* frame = receiver_.FrameForDecoding(kMaxWaitTime, false);
Qiang Chend4cec152015-06-19 09:17:00 -0700423 int64_t end_time = clock_.TimeInMilliseconds();
424
425 // In any case the FrameForDecoding should not wait longer than
426 // max_wait_time.
427 // In the case that we did not get a frame, it should have been waiting for
428 // exactly max_wait_time. (By the testing samples we constructed above, we
429 // are sure there is no timing error, so the only case it returns with NULL
430 // is that it runs out of time.)
431 if (frame) {
432 receiver_.ReleaseFrame(frame);
433 ++num_frames_return;
434 EXPECT_GE(kMaxWaitTime, end_time - start_time);
435 } else {
436 EXPECT_EQ(kMaxWaitTime, end_time - start_time);
437 }
438 }
439}
440
perkj796cfaf2015-12-10 09:27:38 -0800441// Test whether VCMReceiver::FrameForDecoding handles parameter
442// |prefer_late_decoding| and |max_wait_time_ms| correctly:
443// 1. The function execution should never take more than |max_wait_time_ms|.
444// 2. If the function exit before now + |max_wait_time_ms|, a frame must be
445// returned and the end time must be equal to the render timestamp - delay
446// for decoding and rendering.
447TEST_F(VCMReceiverTimingTest, FrameForDecodingPreferLateDecoding) {
448 const size_t kNumFrames = 100;
449 const int kFramePeriod = 40;
450
451 int64_t arrive_timestamps[kNumFrames];
452 int64_t render_timestamps[kNumFrames];
perkj796cfaf2015-12-10 09:27:38 -0800453
454 int render_delay_ms;
455 int max_decode_ms;
456 int dummy;
457 timing_.GetTimings(&dummy, &max_decode_ms, &dummy, &dummy, &dummy, &dummy,
458 &render_delay_ms);
459
460 // Construct test samples.
461 // render_timestamps are the timestamps stored in the Frame;
462 // arrive_timestamps controls when the Frame packet got received.
463 for (size_t i = 0; i < kNumFrames; i++) {
464 // Preset frame rate to 25Hz.
465 // But we add a reasonable deviation to arrive_timestamps to mimic Internet
466 // fluctuation.
467 arrive_timestamps[i] =
468 (i + 1) * kFramePeriod + (i % 10) * ((i % 2) ? 1 : -1);
469 render_timestamps[i] = (i + 1) * kFramePeriod;
470 }
471
472 clock_.SetFrames(arrive_timestamps, render_timestamps, kNumFrames);
473
474 // Record how many frames we finally get out of the receiver.
475 size_t num_frames_return = 0;
476 const int64_t kMaxWaitTime = 30;
477 bool prefer_late_decoding = true;
478 while (num_frames_return < kNumFrames) {
479 int64_t start_time = clock_.TimeInMilliseconds();
480
Johan Ahlers31b2ec42016-06-28 13:32:49 +0200481 VCMEncodedFrame* frame =
482 receiver_.FrameForDecoding(kMaxWaitTime, prefer_late_decoding);
perkj796cfaf2015-12-10 09:27:38 -0800483 int64_t end_time = clock_.TimeInMilliseconds();
484 if (frame) {
485 EXPECT_EQ(frame->RenderTimeMs() - max_decode_ms - render_delay_ms,
486 end_time);
487 receiver_.ReleaseFrame(frame);
488 ++num_frames_return;
489 } else {
490 EXPECT_EQ(kMaxWaitTime, end_time - start_time);
491 }
492 }
493}
494
mikhal@webrtc.org381da4b2013-04-25 21:45:29 +0000495} // namespace webrtc