receiver_unittest.cc (19873B)
1 /* 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 "modules/video_coding/deprecated/receiver.h" 11 12 #include <cstdint> 13 #include <cstring> 14 #include <memory> 15 #include <queue> 16 #include <vector> 17 18 #include "api/field_trials.h" 19 #include "api/units/time_delta.h" 20 #include "api/video/video_frame_type.h" 21 #include "modules/video_coding/deprecated/event_wrapper.h" 22 #include "modules/video_coding/deprecated/jitter_buffer_common.h" 23 #include "modules/video_coding/deprecated/packet.h" 24 #include "modules/video_coding/deprecated/stream_generator.h" 25 #include "modules/video_coding/encoded_frame.h" 26 #include "modules/video_coding/timing/timing.h" 27 #include "rtc_base/checks.h" 28 #include "system_wrappers/include/clock.h" 29 #include "test/create_test_field_trials.h" 30 #include "test/gtest.h" 31 32 namespace webrtc { 33 34 class TestVCMReceiver : public ::testing::Test { 35 protected: 36 TestVCMReceiver() 37 : field_trials_(CreateTestFieldTrials()), 38 clock_(0), 39 timing_(&clock_, field_trials_), 40 receiver_(&timing_, &clock_, field_trials_), 41 stream_generator_(0, clock_.TimeInMilliseconds()) {} 42 43 int32_t InsertPacket(int index) { 44 VCMPacket packet; 45 bool packet_available = stream_generator_.GetPacket(&packet, index); 46 EXPECT_TRUE(packet_available); 47 if (!packet_available) 48 return kGeneralError; // Return here to avoid crashes below. 49 return receiver_.InsertPacket(packet); 50 } 51 52 int32_t InsertPacketAndPop(int index) { 53 VCMPacket packet; 54 bool packet_available = stream_generator_.PopPacket(&packet, index); 55 EXPECT_TRUE(packet_available); 56 if (!packet_available) 57 return kGeneralError; // Return here to avoid crashes below. 58 return receiver_.InsertPacket(packet); 59 } 60 61 int32_t InsertFrame(VideoFrameType frame_type, bool complete) { 62 int num_of_packets = complete ? 1 : 2; 63 stream_generator_.GenerateFrame( 64 frame_type, 65 (frame_type != VideoFrameType::kEmptyFrame) ? num_of_packets : 0, 66 (frame_type == VideoFrameType::kEmptyFrame) ? 1 : 0, 67 clock_.TimeInMilliseconds()); 68 int32_t ret = InsertPacketAndPop(0); 69 if (!complete) { 70 // Drop the second packet. 71 VCMPacket packet; 72 stream_generator_.PopPacket(&packet, 0); 73 } 74 clock_.AdvanceTimeMilliseconds(kDefaultFramePeriodMs); 75 return ret; 76 } 77 78 bool DecodeNextFrame() { 79 VCMEncodedFrame* frame = receiver_.FrameForDecoding(0, false); 80 if (!frame) 81 return false; 82 receiver_.ReleaseFrame(frame); 83 return true; 84 } 85 86 FieldTrials field_trials_; 87 SimulatedClock clock_; 88 VCMTiming timing_; 89 VCMReceiver receiver_; 90 StreamGenerator stream_generator_; 91 }; 92 93 TEST_F(TestVCMReceiver, NonDecodableDuration_Empty) { 94 const size_t kMaxNackListSize = 1000; 95 const int kMaxPacketAgeToNack = 1000; 96 const int kMaxNonDecodableDuration = 500; 97 const int kMinDelayMs = 500; 98 receiver_.SetNackSettings(kMaxNackListSize, kMaxPacketAgeToNack, 99 kMaxNonDecodableDuration); 100 EXPECT_GE(InsertFrame(VideoFrameType::kVideoFrameKey, true), kNoError); 101 // Advance time until it's time to decode the key frame. 102 clock_.AdvanceTimeMilliseconds(kMinDelayMs); 103 EXPECT_TRUE(DecodeNextFrame()); 104 bool request_key_frame = false; 105 std::vector<uint16_t> nack_list = receiver_.NackList(&request_key_frame); 106 EXPECT_FALSE(request_key_frame); 107 } 108 109 TEST_F(TestVCMReceiver, NonDecodableDuration_NoKeyFrame) { 110 const size_t kMaxNackListSize = 1000; 111 const int kMaxPacketAgeToNack = 1000; 112 const int kMaxNonDecodableDuration = 500; 113 receiver_.SetNackSettings(kMaxNackListSize, kMaxPacketAgeToNack, 114 kMaxNonDecodableDuration); 115 const int kNumFrames = kDefaultFrameRate * kMaxNonDecodableDuration / 1000; 116 for (int i = 0; i < kNumFrames; ++i) { 117 EXPECT_GE(InsertFrame(VideoFrameType::kVideoFrameDelta, true), kNoError); 118 } 119 bool request_key_frame = false; 120 std::vector<uint16_t> nack_list = receiver_.NackList(&request_key_frame); 121 EXPECT_TRUE(request_key_frame); 122 } 123 124 TEST_F(TestVCMReceiver, NonDecodableDuration_OneIncomplete) { 125 const size_t kMaxNackListSize = 1000; 126 const int kMaxPacketAgeToNack = 1000; 127 const int kMaxNonDecodableDuration = 500; 128 const int kMaxNonDecodableDurationFrames = 129 (kDefaultFrameRate * kMaxNonDecodableDuration + 500) / 1000; 130 const int kMinDelayMs = 500; 131 receiver_.SetNackSettings(kMaxNackListSize, kMaxPacketAgeToNack, 132 kMaxNonDecodableDuration); 133 timing_.set_min_playout_delay(TimeDelta::Millis(kMinDelayMs)); 134 int64_t key_frame_inserted = clock_.TimeInMilliseconds(); 135 EXPECT_GE(InsertFrame(VideoFrameType::kVideoFrameKey, true), kNoError); 136 // Insert an incomplete frame. 137 EXPECT_GE(InsertFrame(VideoFrameType::kVideoFrameDelta, false), kNoError); 138 // Insert enough frames to have too long non-decodable sequence. 139 for (int i = 0; i < kMaxNonDecodableDurationFrames; ++i) { 140 EXPECT_GE(InsertFrame(VideoFrameType::kVideoFrameDelta, true), kNoError); 141 } 142 // Advance time until it's time to decode the key frame. 143 clock_.AdvanceTimeMilliseconds(kMinDelayMs - clock_.TimeInMilliseconds() - 144 key_frame_inserted); 145 EXPECT_TRUE(DecodeNextFrame()); 146 // Make sure we get a key frame request. 147 bool request_key_frame = false; 148 std::vector<uint16_t> nack_list = receiver_.NackList(&request_key_frame); 149 EXPECT_TRUE(request_key_frame); 150 } 151 152 TEST_F(TestVCMReceiver, NonDecodableDuration_NoTrigger) { 153 const size_t kMaxNackListSize = 1000; 154 const int kMaxPacketAgeToNack = 1000; 155 const int kMaxNonDecodableDuration = 500; 156 const int kMaxNonDecodableDurationFrames = 157 (kDefaultFrameRate * kMaxNonDecodableDuration + 500) / 1000; 158 const int kMinDelayMs = 500; 159 receiver_.SetNackSettings(kMaxNackListSize, kMaxPacketAgeToNack, 160 kMaxNonDecodableDuration); 161 timing_.set_min_playout_delay(TimeDelta::Millis(kMinDelayMs)); 162 int64_t key_frame_inserted = clock_.TimeInMilliseconds(); 163 EXPECT_GE(InsertFrame(VideoFrameType::kVideoFrameKey, true), kNoError); 164 // Insert an incomplete frame. 165 EXPECT_GE(InsertFrame(VideoFrameType::kVideoFrameDelta, false), kNoError); 166 // Insert all but one frame to not trigger a key frame request due to 167 // too long duration of non-decodable frames. 168 for (int i = 0; i < kMaxNonDecodableDurationFrames - 1; ++i) { 169 EXPECT_GE(InsertFrame(VideoFrameType::kVideoFrameDelta, true), kNoError); 170 } 171 // Advance time until it's time to decode the key frame. 172 clock_.AdvanceTimeMilliseconds(kMinDelayMs - clock_.TimeInMilliseconds() - 173 key_frame_inserted); 174 EXPECT_TRUE(DecodeNextFrame()); 175 // Make sure we don't get a key frame request since we haven't generated 176 // enough frames. 177 bool request_key_frame = false; 178 std::vector<uint16_t> nack_list = receiver_.NackList(&request_key_frame); 179 EXPECT_FALSE(request_key_frame); 180 } 181 182 TEST_F(TestVCMReceiver, NonDecodableDuration_NoTrigger2) { 183 const size_t kMaxNackListSize = 1000; 184 const int kMaxPacketAgeToNack = 1000; 185 const int kMaxNonDecodableDuration = 500; 186 const int kMaxNonDecodableDurationFrames = 187 (kDefaultFrameRate * kMaxNonDecodableDuration + 500) / 1000; 188 const int kMinDelayMs = 500; 189 receiver_.SetNackSettings(kMaxNackListSize, kMaxPacketAgeToNack, 190 kMaxNonDecodableDuration); 191 timing_.set_min_playout_delay(TimeDelta::Millis(kMinDelayMs)); 192 int64_t key_frame_inserted = clock_.TimeInMilliseconds(); 193 EXPECT_GE(InsertFrame(VideoFrameType::kVideoFrameKey, true), kNoError); 194 // Insert enough frames to have too long non-decodable sequence, except that 195 // we don't have any losses. 196 for (int i = 0; i < kMaxNonDecodableDurationFrames; ++i) { 197 EXPECT_GE(InsertFrame(VideoFrameType::kVideoFrameDelta, true), kNoError); 198 } 199 // Insert an incomplete frame. 200 EXPECT_GE(InsertFrame(VideoFrameType::kVideoFrameDelta, false), kNoError); 201 // Advance time until it's time to decode the key frame. 202 clock_.AdvanceTimeMilliseconds(kMinDelayMs - clock_.TimeInMilliseconds() - 203 key_frame_inserted); 204 EXPECT_TRUE(DecodeNextFrame()); 205 // Make sure we don't get a key frame request since the non-decodable duration 206 // is only one frame. 207 bool request_key_frame = false; 208 std::vector<uint16_t> nack_list = receiver_.NackList(&request_key_frame); 209 EXPECT_FALSE(request_key_frame); 210 } 211 212 TEST_F(TestVCMReceiver, NonDecodableDuration_KeyFrameAfterIncompleteFrames) { 213 const size_t kMaxNackListSize = 1000; 214 const int kMaxPacketAgeToNack = 1000; 215 const int kMaxNonDecodableDuration = 500; 216 const int kMaxNonDecodableDurationFrames = 217 (kDefaultFrameRate * kMaxNonDecodableDuration + 500) / 1000; 218 const int kMinDelayMs = 500; 219 receiver_.SetNackSettings(kMaxNackListSize, kMaxPacketAgeToNack, 220 kMaxNonDecodableDuration); 221 timing_.set_min_playout_delay(TimeDelta::Millis(kMinDelayMs)); 222 int64_t key_frame_inserted = clock_.TimeInMilliseconds(); 223 EXPECT_GE(InsertFrame(VideoFrameType::kVideoFrameKey, true), kNoError); 224 // Insert an incomplete frame. 225 EXPECT_GE(InsertFrame(VideoFrameType::kVideoFrameDelta, false), kNoError); 226 // Insert enough frames to have too long non-decodable sequence. 227 for (int i = 0; i < kMaxNonDecodableDurationFrames; ++i) { 228 EXPECT_GE(InsertFrame(VideoFrameType::kVideoFrameDelta, true), kNoError); 229 } 230 EXPECT_GE(InsertFrame(VideoFrameType::kVideoFrameKey, true), kNoError); 231 // Advance time until it's time to decode the key frame. 232 clock_.AdvanceTimeMilliseconds(kMinDelayMs - clock_.TimeInMilliseconds() - 233 key_frame_inserted); 234 EXPECT_TRUE(DecodeNextFrame()); 235 // Make sure we don't get a key frame request since we have a key frame 236 // in the list. 237 bool request_key_frame = false; 238 std::vector<uint16_t> nack_list = receiver_.NackList(&request_key_frame); 239 EXPECT_FALSE(request_key_frame); 240 } 241 242 // A simulated clock, when time elapses, will insert frames into the jitter 243 // buffer, based on initial settings. 244 class SimulatedClockWithFrames : public SimulatedClock { 245 public: 246 SimulatedClockWithFrames(StreamGenerator* stream_generator, 247 VCMReceiver* receiver) 248 : SimulatedClock(0), 249 stream_generator_(stream_generator), 250 receiver_(receiver) {} 251 ~SimulatedClockWithFrames() override {} 252 253 // If `stop_on_frame` is true and next frame arrives between now and 254 // now+`milliseconds`, the clock will be advanced to the arrival time of next 255 // frame. 256 // Otherwise, the clock will be advanced by `milliseconds`. 257 // 258 // For both cases, a frame will be inserted into the jitter buffer at the 259 // instant when the clock time is timestamps_.front().arrive_time. 260 // 261 // Return true if some frame arrives between now and now+`milliseconds`. 262 bool AdvanceTimeMilliseconds(int64_t milliseconds, bool stop_on_frame) { 263 return AdvanceTimeMicroseconds(milliseconds * 1000, stop_on_frame); 264 } 265 266 bool AdvanceTimeMicroseconds(int64_t microseconds, bool stop_on_frame) { 267 int64_t start_time = TimeInMicroseconds(); 268 int64_t end_time = start_time + microseconds; 269 bool frame_injected = false; 270 while (!timestamps_.empty() && 271 timestamps_.front().arrive_time <= end_time) { 272 RTC_DCHECK_GE(timestamps_.front().arrive_time, start_time); 273 274 SimulatedClock::AdvanceTimeMicroseconds(timestamps_.front().arrive_time - 275 TimeInMicroseconds()); 276 GenerateAndInsertFrame((timestamps_.front().render_time + 500) / 1000); 277 timestamps_.pop(); 278 frame_injected = true; 279 280 if (stop_on_frame) 281 return frame_injected; 282 } 283 284 if (TimeInMicroseconds() < end_time) { 285 SimulatedClock::AdvanceTimeMicroseconds(end_time - TimeInMicroseconds()); 286 } 287 return frame_injected; 288 } 289 290 // Input timestamps are in unit Milliseconds. 291 // And `arrive_timestamps` must be positive and in increasing order. 292 // `arrive_timestamps` determine when we are going to insert frames into the 293 // jitter buffer. 294 // `render_timestamps` are the timestamps on the frame. 295 void SetFrames(const int64_t* arrive_timestamps, 296 const int64_t* render_timestamps, 297 size_t size) { 298 int64_t previous_arrive_timestamp = 0; 299 for (size_t i = 0; i < size; i++) { 300 RTC_CHECK_GE(arrive_timestamps[i], previous_arrive_timestamp); 301 timestamps_.push(TimestampPair(arrive_timestamps[i] * 1000, 302 render_timestamps[i] * 1000)); 303 previous_arrive_timestamp = arrive_timestamps[i]; 304 } 305 } 306 307 private: 308 struct TimestampPair { 309 TimestampPair(int64_t arrive_timestamp, int64_t render_timestamp) 310 : arrive_time(arrive_timestamp), render_time(render_timestamp) {} 311 312 int64_t arrive_time; 313 int64_t render_time; 314 }; 315 316 void GenerateAndInsertFrame(int64_t render_timestamp_ms) { 317 VCMPacket packet; 318 stream_generator_->GenerateFrame(VideoFrameType::kVideoFrameKey, 319 1, // media packets 320 0, // empty packets 321 render_timestamp_ms); 322 323 bool packet_available = stream_generator_->PopPacket(&packet, 0); 324 EXPECT_TRUE(packet_available); 325 if (!packet_available) 326 return; // Return here to avoid crashes below. 327 receiver_->InsertPacket(packet); 328 } 329 330 std::queue<TimestampPair> timestamps_; 331 StreamGenerator* stream_generator_; 332 VCMReceiver* receiver_; 333 }; 334 335 // Use a SimulatedClockWithFrames 336 // Wait call will do either of these: 337 // 1. If `stop_on_frame` is true, the clock will be turned to the exact instant 338 // that the first frame comes and the frame will be inserted into the jitter 339 // buffer, or the clock will be turned to now + `max_time` if no frame comes in 340 // the window. 341 // 2. If `stop_on_frame` is false, the clock will be turn to now + `max_time`, 342 // and all the frames arriving between now and now + `max_time` will be 343 // inserted into the jitter buffer. 344 // 345 // This is used to simulate the JitterBuffer getting packets from internet as 346 // time elapses. 347 348 class FrameInjectEvent : public EventWrapper { 349 public: 350 FrameInjectEvent(SimulatedClockWithFrames* clock, bool stop_on_frame) 351 : clock_(clock), stop_on_frame_(stop_on_frame) {} 352 353 bool Set() override { return true; } 354 355 EventTypeWrapper Wait(int max_time_ms) override { 356 if (clock_->AdvanceTimeMilliseconds(max_time_ms, stop_on_frame_) && 357 stop_on_frame_) { 358 return EventTypeWrapper::kEventSignaled; 359 } else { 360 return EventTypeWrapper::kEventTimeout; 361 } 362 } 363 364 private: 365 SimulatedClockWithFrames* clock_; 366 bool stop_on_frame_; 367 }; 368 369 class VCMReceiverTimingTest : public ::testing::Test { 370 protected: 371 VCMReceiverTimingTest() 372 : field_trials_(CreateTestFieldTrials()), 373 clock_(&stream_generator_, &receiver_), 374 stream_generator_(0, clock_.TimeInMilliseconds()), 375 timing_(&clock_, field_trials_), 376 receiver_( 377 &timing_, 378 &clock_, 379 std::unique_ptr<EventWrapper>(new FrameInjectEvent(&clock_, false)), 380 std::unique_ptr<EventWrapper>(new FrameInjectEvent(&clock_, true)), 381 field_trials_) {} 382 383 void SetUp() override {} 384 385 FieldTrials field_trials_; 386 SimulatedClockWithFrames clock_; 387 StreamGenerator stream_generator_; 388 VCMTiming timing_; 389 VCMReceiver receiver_; 390 }; 391 392 // Test whether VCMReceiver::FrameForDecoding handles parameter 393 // `max_wait_time_ms` correctly: 394 // 1. The function execution should never take more than `max_wait_time_ms`. 395 // 2. If the function exit before now + `max_wait_time_ms`, a frame must be 396 // returned. 397 TEST_F(VCMReceiverTimingTest, FrameForDecoding) { 398 const size_t kNumFrames = 100; 399 const int kFramePeriod = 40; 400 int64_t arrive_timestamps[kNumFrames]; 401 int64_t render_timestamps[kNumFrames]; 402 403 // Construct test samples. 404 // render_timestamps are the timestamps stored in the Frame; 405 // arrive_timestamps controls when the Frame packet got received. 406 for (size_t i = 0; i < kNumFrames; i++) { 407 // Preset frame rate to 25Hz. 408 // But we add a reasonable deviation to arrive_timestamps to mimic Internet 409 // fluctuation. 410 arrive_timestamps[i] = 411 (i + 1) * kFramePeriod + (i % 10) * ((i % 2) ? 1 : -1); 412 render_timestamps[i] = (i + 1) * kFramePeriod; 413 } 414 415 clock_.SetFrames(arrive_timestamps, render_timestamps, kNumFrames); 416 417 // Record how many frames we finally get out of the receiver. 418 size_t num_frames_return = 0; 419 420 const int64_t kMaxWaitTime = 30; 421 422 // Ideally, we should get all frames that we input in InitializeFrames. 423 // In the case that FrameForDecoding kills frames by error, we rely on the 424 // build bot to kill the test. 425 while (num_frames_return < kNumFrames) { 426 int64_t start_time = clock_.TimeInMilliseconds(); 427 VCMEncodedFrame* frame = receiver_.FrameForDecoding(kMaxWaitTime, false); 428 int64_t end_time = clock_.TimeInMilliseconds(); 429 430 // In any case the FrameForDecoding should not wait longer than 431 // max_wait_time. 432 // In the case that we did not get a frame, it should have been waiting for 433 // exactly max_wait_time. (By the testing samples we constructed above, we 434 // are sure there is no timing error, so the only case it returns with NULL 435 // is that it runs out of time.) 436 if (frame) { 437 receiver_.ReleaseFrame(frame); 438 ++num_frames_return; 439 EXPECT_GE(kMaxWaitTime, end_time - start_time); 440 } else { 441 EXPECT_EQ(kMaxWaitTime, end_time - start_time); 442 } 443 } 444 } 445 446 // Test whether VCMReceiver::FrameForDecoding handles parameter 447 // `prefer_late_decoding` and `max_wait_time_ms` correctly: 448 // 1. The function execution should never take more than `max_wait_time_ms`. 449 // 2. If the function exit before now + `max_wait_time_ms`, a frame must be 450 // returned and the end time must be equal to the render timestamp - delay 451 // for decoding and rendering. 452 TEST_F(VCMReceiverTimingTest, FrameForDecodingPreferLateDecoding) { 453 const size_t kNumFrames = 100; 454 const int kFramePeriod = 40; 455 456 int64_t arrive_timestamps[kNumFrames]; 457 int64_t render_timestamps[kNumFrames]; 458 459 auto timings = timing_.GetTimings(); 460 TimeDelta render_delay = timings.render_delay; 461 TimeDelta max_decode = timings.estimated_max_decode_time; 462 463 // Construct test samples. 464 // render_timestamps are the timestamps stored in the Frame; 465 // arrive_timestamps controls when the Frame packet got received. 466 for (size_t i = 0; i < kNumFrames; i++) { 467 // Preset frame rate to 25Hz. 468 // But we add a reasonable deviation to arrive_timestamps to mimic Internet 469 // fluctuation. 470 arrive_timestamps[i] = 471 (i + 1) * kFramePeriod + (i % 10) * ((i % 2) ? 1 : -1); 472 render_timestamps[i] = (i + 1) * kFramePeriod; 473 } 474 475 clock_.SetFrames(arrive_timestamps, render_timestamps, kNumFrames); 476 477 // Record how many frames we finally get out of the receiver. 478 size_t num_frames_return = 0; 479 const int64_t kMaxWaitTime = 30; 480 bool prefer_late_decoding = true; 481 while (num_frames_return < kNumFrames) { 482 int64_t start_time = clock_.TimeInMilliseconds(); 483 484 VCMEncodedFrame* frame = 485 receiver_.FrameForDecoding(kMaxWaitTime, prefer_late_decoding); 486 int64_t end_time = clock_.TimeInMilliseconds(); 487 if (frame) { 488 EXPECT_EQ(frame->RenderTimeMs() - max_decode.ms() - render_delay.ms(), 489 end_time); 490 receiver_.ReleaseFrame(frame); 491 ++num_frames_return; 492 } else { 493 EXPECT_EQ(kMaxWaitTime, end_time - start_time); 494 } 495 } 496 } 497 498 } // namespace webrtc