140bd7448cb81dea34512c6970864a710a75da666mikhal@webrtc.org/* Copyright (c) 2013 The WebRTC project authors. All Rights Reserved. 240bd7448cb81dea34512c6970864a710a75da666mikhal@webrtc.org * 340bd7448cb81dea34512c6970864a710a75da666mikhal@webrtc.org * Use of this source code is governed by a BSD-style license 440bd7448cb81dea34512c6970864a710a75da666mikhal@webrtc.org * that can be found in the LICENSE file in the root of the source 540bd7448cb81dea34512c6970864a710a75da666mikhal@webrtc.org * tree. An additional intellectual property rights grant can be found 640bd7448cb81dea34512c6970864a710a75da666mikhal@webrtc.org * in the file PATENTS. All contributing project authors may 740bd7448cb81dea34512c6970864a710a75da666mikhal@webrtc.org * be found in the AUTHORS file in the root of the source tree. 840bd7448cb81dea34512c6970864a710a75da666mikhal@webrtc.org */ 940bd7448cb81dea34512c6970864a710a75da666mikhal@webrtc.org 1040bd7448cb81dea34512c6970864a710a75da666mikhal@webrtc.org#include <string.h> 1140bd7448cb81dea34512c6970864a710a75da666mikhal@webrtc.org 1240bd7448cb81dea34512c6970864a710a75da666mikhal@webrtc.org#include <list> 1340bd7448cb81dea34512c6970864a710a75da666mikhal@webrtc.org 1440bd7448cb81dea34512c6970864a710a75da666mikhal@webrtc.org#include "testing/gtest/include/gtest/gtest.h" 1540bd7448cb81dea34512c6970864a710a75da666mikhal@webrtc.org#include "webrtc/modules/video_coding/main/source/packet.h" 16a557f436b9d694d5a0a045e0295e1794f2df48eapbos@webrtc.org#include "webrtc/modules/video_coding/main/source/receiver.h" 17a26a7f6b69525de3a935c79eb24be6f0bc871930andresp@webrtc.org#include "webrtc/modules/video_coding/main/source/test/stream_generator.h" 1840bd7448cb81dea34512c6970864a710a75da666mikhal@webrtc.org#include "webrtc/modules/video_coding/main/source/timing.h" 1940bd7448cb81dea34512c6970864a710a75da666mikhal@webrtc.org#include "webrtc/modules/video_coding/main/test/test_util.h" 2040bd7448cb81dea34512c6970864a710a75da666mikhal@webrtc.org#include "webrtc/system_wrappers/interface/clock.h" 2140bd7448cb81dea34512c6970864a710a75da666mikhal@webrtc.org#include "webrtc/system_wrappers/interface/critical_section_wrapper.h" 2240bd7448cb81dea34512c6970864a710a75da666mikhal@webrtc.org 2340bd7448cb81dea34512c6970864a710a75da666mikhal@webrtc.orgnamespace webrtc { 2440bd7448cb81dea34512c6970864a710a75da666mikhal@webrtc.org 2540bd7448cb81dea34512c6970864a710a75da666mikhal@webrtc.orgclass TestVCMReceiver : public ::testing::Test { 2640bd7448cb81dea34512c6970864a710a75da666mikhal@webrtc.org protected: 2740bd7448cb81dea34512c6970864a710a75da666mikhal@webrtc.org enum { kDataBufferSize = 10 }; 2840bd7448cb81dea34512c6970864a710a75da666mikhal@webrtc.org enum { kWidth = 640 }; 2940bd7448cb81dea34512c6970864a710a75da666mikhal@webrtc.org enum { kHeight = 480 }; 3040bd7448cb81dea34512c6970864a710a75da666mikhal@webrtc.org 3140bd7448cb81dea34512c6970864a710a75da666mikhal@webrtc.org TestVCMReceiver() 3240bd7448cb81dea34512c6970864a710a75da666mikhal@webrtc.org : clock_(new SimulatedClock(0)), 3340bd7448cb81dea34512c6970864a710a75da666mikhal@webrtc.org timing_(clock_.get()), 348edcccef11eabb0dd98a061c9d640b2b7743609estefan@webrtc.org receiver_(&timing_, clock_.get(), &event_factory_, true) { 3540bd7448cb81dea34512c6970864a710a75da666mikhal@webrtc.org stream_generator_.reset(new 3640bd7448cb81dea34512c6970864a710a75da666mikhal@webrtc.org StreamGenerator(0, 0, clock_->TimeInMilliseconds())); 3740bd7448cb81dea34512c6970864a710a75da666mikhal@webrtc.org memset(data_buffer_, 0, kDataBufferSize); 3840bd7448cb81dea34512c6970864a710a75da666mikhal@webrtc.org } 3940bd7448cb81dea34512c6970864a710a75da666mikhal@webrtc.org 4040bd7448cb81dea34512c6970864a710a75da666mikhal@webrtc.org virtual void SetUp() { 4140bd7448cb81dea34512c6970864a710a75da666mikhal@webrtc.org receiver_.Reset(); 4240bd7448cb81dea34512c6970864a710a75da666mikhal@webrtc.org } 4340bd7448cb81dea34512c6970864a710a75da666mikhal@webrtc.org 4440bd7448cb81dea34512c6970864a710a75da666mikhal@webrtc.org int32_t InsertPacket(int index) { 4540bd7448cb81dea34512c6970864a710a75da666mikhal@webrtc.org VCMPacket packet; 4640bd7448cb81dea34512c6970864a710a75da666mikhal@webrtc.org packet.dataPtr = data_buffer_; 4740bd7448cb81dea34512c6970864a710a75da666mikhal@webrtc.org bool packet_available = stream_generator_->GetPacket(&packet, index); 4840bd7448cb81dea34512c6970864a710a75da666mikhal@webrtc.org EXPECT_TRUE(packet_available); 4940bd7448cb81dea34512c6970864a710a75da666mikhal@webrtc.org if (!packet_available) 503740808580c6020ac61ac11a8729fa0a6a08223cstefan@webrtc.org return kGeneralError; // Return here to avoid crashes below. 5140bd7448cb81dea34512c6970864a710a75da666mikhal@webrtc.org // Arbitrary width and height. 5240bd7448cb81dea34512c6970864a710a75da666mikhal@webrtc.org return receiver_.InsertPacket(packet, 640, 480); 5340bd7448cb81dea34512c6970864a710a75da666mikhal@webrtc.org } 5440bd7448cb81dea34512c6970864a710a75da666mikhal@webrtc.org 5540bd7448cb81dea34512c6970864a710a75da666mikhal@webrtc.org int32_t InsertPacketAndPop(int index) { 5640bd7448cb81dea34512c6970864a710a75da666mikhal@webrtc.org VCMPacket packet; 5740bd7448cb81dea34512c6970864a710a75da666mikhal@webrtc.org packet.dataPtr = data_buffer_; 5840bd7448cb81dea34512c6970864a710a75da666mikhal@webrtc.org bool packet_available = stream_generator_->PopPacket(&packet, index); 5940bd7448cb81dea34512c6970864a710a75da666mikhal@webrtc.org EXPECT_TRUE(packet_available); 6040bd7448cb81dea34512c6970864a710a75da666mikhal@webrtc.org if (!packet_available) 613740808580c6020ac61ac11a8729fa0a6a08223cstefan@webrtc.org return kGeneralError; // Return here to avoid crashes below. 6240bd7448cb81dea34512c6970864a710a75da666mikhal@webrtc.org return receiver_.InsertPacket(packet, kWidth, kHeight); 6340bd7448cb81dea34512c6970864a710a75da666mikhal@webrtc.org } 6440bd7448cb81dea34512c6970864a710a75da666mikhal@webrtc.org 6540bd7448cb81dea34512c6970864a710a75da666mikhal@webrtc.org int32_t InsertFrame(FrameType frame_type, bool complete) { 6640bd7448cb81dea34512c6970864a710a75da666mikhal@webrtc.org int num_of_packets = complete ? 1 : 2; 6740bd7448cb81dea34512c6970864a710a75da666mikhal@webrtc.org stream_generator_->GenerateFrame( 6840bd7448cb81dea34512c6970864a710a75da666mikhal@webrtc.org frame_type, 6940bd7448cb81dea34512c6970864a710a75da666mikhal@webrtc.org (frame_type != kFrameEmpty) ? num_of_packets : 0, 7040bd7448cb81dea34512c6970864a710a75da666mikhal@webrtc.org (frame_type == kFrameEmpty) ? 1 : 0, 7140bd7448cb81dea34512c6970864a710a75da666mikhal@webrtc.org clock_->TimeInMilliseconds()); 7240bd7448cb81dea34512c6970864a710a75da666mikhal@webrtc.org int32_t ret = InsertPacketAndPop(0); 7306ad384100b8b493e4a3f37877caac520189fec3stefan@webrtc.org if (!complete) { 7406ad384100b8b493e4a3f37877caac520189fec3stefan@webrtc.org // Drop the second packet. 7506ad384100b8b493e4a3f37877caac520189fec3stefan@webrtc.org VCMPacket packet; 7606ad384100b8b493e4a3f37877caac520189fec3stefan@webrtc.org stream_generator_->PopPacket(&packet, 0); 7706ad384100b8b493e4a3f37877caac520189fec3stefan@webrtc.org } 7840bd7448cb81dea34512c6970864a710a75da666mikhal@webrtc.org clock_->AdvanceTimeMilliseconds(kDefaultFramePeriodMs); 7940bd7448cb81dea34512c6970864a710a75da666mikhal@webrtc.org return ret; 8040bd7448cb81dea34512c6970864a710a75da666mikhal@webrtc.org } 8140bd7448cb81dea34512c6970864a710a75da666mikhal@webrtc.org 8206ad384100b8b493e4a3f37877caac520189fec3stefan@webrtc.org bool DecodeNextFrame() { 8306ad384100b8b493e4a3f37877caac520189fec3stefan@webrtc.org int64_t render_time_ms = 0; 8406ad384100b8b493e4a3f37877caac520189fec3stefan@webrtc.org VCMEncodedFrame* frame = receiver_.FrameForDecoding(0, render_time_ms, 8506ad384100b8b493e4a3f37877caac520189fec3stefan@webrtc.org false, NULL); 8606ad384100b8b493e4a3f37877caac520189fec3stefan@webrtc.org if (!frame) 8706ad384100b8b493e4a3f37877caac520189fec3stefan@webrtc.org return false; 8806ad384100b8b493e4a3f37877caac520189fec3stefan@webrtc.org receiver_.ReleaseFrame(frame); 8906ad384100b8b493e4a3f37877caac520189fec3stefan@webrtc.org return true; 9006ad384100b8b493e4a3f37877caac520189fec3stefan@webrtc.org } 9106ad384100b8b493e4a3f37877caac520189fec3stefan@webrtc.org 9240bd7448cb81dea34512c6970864a710a75da666mikhal@webrtc.org scoped_ptr<SimulatedClock> clock_; 9340bd7448cb81dea34512c6970864a710a75da666mikhal@webrtc.org VCMTiming timing_; 9440bd7448cb81dea34512c6970864a710a75da666mikhal@webrtc.org NullEventFactory event_factory_; 9540bd7448cb81dea34512c6970864a710a75da666mikhal@webrtc.org VCMReceiver receiver_; 9640bd7448cb81dea34512c6970864a710a75da666mikhal@webrtc.org scoped_ptr<StreamGenerator> stream_generator_; 9740bd7448cb81dea34512c6970864a710a75da666mikhal@webrtc.org uint8_t data_buffer_[kDataBufferSize]; 9840bd7448cb81dea34512c6970864a710a75da666mikhal@webrtc.org}; 9940bd7448cb81dea34512c6970864a710a75da666mikhal@webrtc.org 10040bd7448cb81dea34512c6970864a710a75da666mikhal@webrtc.orgTEST_F(TestVCMReceiver, RenderBufferSize_AllComplete) { 10140bd7448cb81dea34512c6970864a710a75da666mikhal@webrtc.org EXPECT_EQ(0, receiver_.RenderBufferSizeMs()); 10240bd7448cb81dea34512c6970864a710a75da666mikhal@webrtc.org EXPECT_GE(InsertFrame(kVideoFrameKey, true), kNoError); 10306ad384100b8b493e4a3f37877caac520189fec3stefan@webrtc.org int num_of_frames = 10; 10406ad384100b8b493e4a3f37877caac520189fec3stefan@webrtc.org for (int i = 0; i < num_of_frames; ++i) { 10540bd7448cb81dea34512c6970864a710a75da666mikhal@webrtc.org EXPECT_GE(InsertFrame(kVideoFrameDelta, true), kNoError); 10640bd7448cb81dea34512c6970864a710a75da666mikhal@webrtc.org } 10706ad384100b8b493e4a3f37877caac520189fec3stefan@webrtc.org EXPECT_EQ(num_of_frames * kDefaultFramePeriodMs, 10898b201189e601aa1863085e0016e868d2db416b1pbos@webrtc.org receiver_.RenderBufferSizeMs()); 10940bd7448cb81dea34512c6970864a710a75da666mikhal@webrtc.org} 11040bd7448cb81dea34512c6970864a710a75da666mikhal@webrtc.org 11106ad384100b8b493e4a3f37877caac520189fec3stefan@webrtc.orgTEST_F(TestVCMReceiver, RenderBufferSize_SkipToKeyFrame) { 11206ad384100b8b493e4a3f37877caac520189fec3stefan@webrtc.org EXPECT_EQ(0, receiver_.RenderBufferSizeMs()); 11306ad384100b8b493e4a3f37877caac520189fec3stefan@webrtc.org const int kNumOfNonDecodableFrames = 2; 11406ad384100b8b493e4a3f37877caac520189fec3stefan@webrtc.org for (int i = 0; i < kNumOfNonDecodableFrames; ++i) { 11506ad384100b8b493e4a3f37877caac520189fec3stefan@webrtc.org EXPECT_GE(InsertFrame(kVideoFrameDelta, true), kNoError); 11606ad384100b8b493e4a3f37877caac520189fec3stefan@webrtc.org } 11706ad384100b8b493e4a3f37877caac520189fec3stefan@webrtc.org const int kNumOfFrames = 10; 11806ad384100b8b493e4a3f37877caac520189fec3stefan@webrtc.org EXPECT_GE(InsertFrame(kVideoFrameKey, true), kNoError); 11906ad384100b8b493e4a3f37877caac520189fec3stefan@webrtc.org for (int i = 0; i < kNumOfFrames - 1; ++i) { 12006ad384100b8b493e4a3f37877caac520189fec3stefan@webrtc.org EXPECT_GE(InsertFrame(kVideoFrameDelta, true), kNoError); 12106ad384100b8b493e4a3f37877caac520189fec3stefan@webrtc.org } 12206ad384100b8b493e4a3f37877caac520189fec3stefan@webrtc.org EXPECT_EQ((kNumOfFrames - 1) * kDefaultFramePeriodMs, 12306ad384100b8b493e4a3f37877caac520189fec3stefan@webrtc.org receiver_.RenderBufferSizeMs()); 12406ad384100b8b493e4a3f37877caac520189fec3stefan@webrtc.org} 12506ad384100b8b493e4a3f37877caac520189fec3stefan@webrtc.org 12640bd7448cb81dea34512c6970864a710a75da666mikhal@webrtc.orgTEST_F(TestVCMReceiver, RenderBufferSize_NotAllComplete) { 12740bd7448cb81dea34512c6970864a710a75da666mikhal@webrtc.org EXPECT_EQ(0, receiver_.RenderBufferSizeMs()); 12840bd7448cb81dea34512c6970864a710a75da666mikhal@webrtc.org EXPECT_GE(InsertFrame(kVideoFrameKey, true), kNoError); 12906ad384100b8b493e4a3f37877caac520189fec3stefan@webrtc.org int num_of_frames = 10; 13006ad384100b8b493e4a3f37877caac520189fec3stefan@webrtc.org for (int i = 0; i < num_of_frames; ++i) { 13140bd7448cb81dea34512c6970864a710a75da666mikhal@webrtc.org EXPECT_GE(InsertFrame(kVideoFrameDelta, true), kNoError); 13240bd7448cb81dea34512c6970864a710a75da666mikhal@webrtc.org } 13320eb55811a74b965c3e35fb3746b0081af84ecaestefan@webrtc.org num_of_frames++; 13440bd7448cb81dea34512c6970864a710a75da666mikhal@webrtc.org EXPECT_GE(InsertFrame(kVideoFrameDelta, false), kNoError); 13506ad384100b8b493e4a3f37877caac520189fec3stefan@webrtc.org for (int i = 0; i < num_of_frames; ++i) { 13640bd7448cb81dea34512c6970864a710a75da666mikhal@webrtc.org EXPECT_GE(InsertFrame(kVideoFrameDelta, true), kNoError); 13740bd7448cb81dea34512c6970864a710a75da666mikhal@webrtc.org } 13806ad384100b8b493e4a3f37877caac520189fec3stefan@webrtc.org EXPECT_EQ((num_of_frames - 1) * kDefaultFramePeriodMs, 13906ad384100b8b493e4a3f37877caac520189fec3stefan@webrtc.org receiver_.RenderBufferSizeMs()); 14040bd7448cb81dea34512c6970864a710a75da666mikhal@webrtc.org} 14140bd7448cb81dea34512c6970864a710a75da666mikhal@webrtc.org 14240bd7448cb81dea34512c6970864a710a75da666mikhal@webrtc.orgTEST_F(TestVCMReceiver, RenderBufferSize_NoKeyFrame) { 14340bd7448cb81dea34512c6970864a710a75da666mikhal@webrtc.org EXPECT_EQ(0, receiver_.RenderBufferSizeMs()); 14440bd7448cb81dea34512c6970864a710a75da666mikhal@webrtc.org int num_of_frames = 10; 14540bd7448cb81dea34512c6970864a710a75da666mikhal@webrtc.org for (int i = 0; i < num_of_frames; ++i) { 14640bd7448cb81dea34512c6970864a710a75da666mikhal@webrtc.org EXPECT_GE(InsertFrame(kVideoFrameDelta, true), kNoError); 14740bd7448cb81dea34512c6970864a710a75da666mikhal@webrtc.org } 148933f88591c8593007a8186f75d5e941310fb4051mikhal@webrtc.org int64_t next_render_time_ms = 0; 149933f88591c8593007a8186f75d5e941310fb4051mikhal@webrtc.org VCMEncodedFrame* frame = receiver_.FrameForDecoding(10, next_render_time_ms); 150933f88591c8593007a8186f75d5e941310fb4051mikhal@webrtc.org EXPECT_TRUE(frame == NULL); 151933f88591c8593007a8186f75d5e941310fb4051mikhal@webrtc.org receiver_.ReleaseFrame(frame); 15240bd7448cb81dea34512c6970864a710a75da666mikhal@webrtc.org EXPECT_GE(InsertFrame(kVideoFrameDelta, false), kNoError); 15340bd7448cb81dea34512c6970864a710a75da666mikhal@webrtc.org for (int i = 0; i < num_of_frames; ++i) { 15440bd7448cb81dea34512c6970864a710a75da666mikhal@webrtc.org EXPECT_GE(InsertFrame(kVideoFrameDelta, true), kNoError); 15540bd7448cb81dea34512c6970864a710a75da666mikhal@webrtc.org } 15640bd7448cb81dea34512c6970864a710a75da666mikhal@webrtc.org EXPECT_EQ(0, receiver_.RenderBufferSizeMs()); 15740bd7448cb81dea34512c6970864a710a75da666mikhal@webrtc.org} 15840bd7448cb81dea34512c6970864a710a75da666mikhal@webrtc.org 15906ad384100b8b493e4a3f37877caac520189fec3stefan@webrtc.orgTEST_F(TestVCMReceiver, NonDecodableDuration_Empty) { 16006ad384100b8b493e4a3f37877caac520189fec3stefan@webrtc.org // Enable NACK and with no RTT thresholds for disabling retransmission delay. 16106ad384100b8b493e4a3f37877caac520189fec3stefan@webrtc.org receiver_.SetNackMode(kNack, -1, -1); 16206ad384100b8b493e4a3f37877caac520189fec3stefan@webrtc.org const size_t kMaxNackListSize = 1000; 16306ad384100b8b493e4a3f37877caac520189fec3stefan@webrtc.org const int kMaxPacketAgeToNack = 1000; 16406ad384100b8b493e4a3f37877caac520189fec3stefan@webrtc.org const int kMaxNonDecodableDuration = 500; 16506ad384100b8b493e4a3f37877caac520189fec3stefan@webrtc.org const int kMinDelayMs = 500; 16606ad384100b8b493e4a3f37877caac520189fec3stefan@webrtc.org receiver_.SetNackSettings(kMaxNackListSize, kMaxPacketAgeToNack, 16706ad384100b8b493e4a3f37877caac520189fec3stefan@webrtc.org kMaxNonDecodableDuration); 16806ad384100b8b493e4a3f37877caac520189fec3stefan@webrtc.org EXPECT_GE(InsertFrame(kVideoFrameKey, true), kNoError); 16906ad384100b8b493e4a3f37877caac520189fec3stefan@webrtc.org // Advance time until it's time to decode the key frame. 17006ad384100b8b493e4a3f37877caac520189fec3stefan@webrtc.org clock_->AdvanceTimeMilliseconds(kMinDelayMs); 17106ad384100b8b493e4a3f37877caac520189fec3stefan@webrtc.org EXPECT_TRUE(DecodeNextFrame()); 17206ad384100b8b493e4a3f37877caac520189fec3stefan@webrtc.org uint16_t nack_list[kMaxNackListSize]; 17306ad384100b8b493e4a3f37877caac520189fec3stefan@webrtc.org uint16_t nack_list_length = 0; 17406ad384100b8b493e4a3f37877caac520189fec3stefan@webrtc.org VCMNackStatus ret = receiver_.NackList(nack_list, kMaxNackListSize, 17506ad384100b8b493e4a3f37877caac520189fec3stefan@webrtc.org &nack_list_length); 17606ad384100b8b493e4a3f37877caac520189fec3stefan@webrtc.org EXPECT_EQ(kNackOk, ret); 17706ad384100b8b493e4a3f37877caac520189fec3stefan@webrtc.org} 17806ad384100b8b493e4a3f37877caac520189fec3stefan@webrtc.org 17906ad384100b8b493e4a3f37877caac520189fec3stefan@webrtc.orgTEST_F(TestVCMReceiver, NonDecodableDuration_NoKeyFrame) { 18006ad384100b8b493e4a3f37877caac520189fec3stefan@webrtc.org // Enable NACK and with no RTT thresholds for disabling retransmission delay. 18106ad384100b8b493e4a3f37877caac520189fec3stefan@webrtc.org receiver_.SetNackMode(kNack, -1, -1); 18206ad384100b8b493e4a3f37877caac520189fec3stefan@webrtc.org const size_t kMaxNackListSize = 1000; 18306ad384100b8b493e4a3f37877caac520189fec3stefan@webrtc.org const int kMaxPacketAgeToNack = 1000; 18406ad384100b8b493e4a3f37877caac520189fec3stefan@webrtc.org const int kMaxNonDecodableDuration = 500; 18506ad384100b8b493e4a3f37877caac520189fec3stefan@webrtc.org receiver_.SetNackSettings(kMaxNackListSize, kMaxPacketAgeToNack, 18606ad384100b8b493e4a3f37877caac520189fec3stefan@webrtc.org kMaxNonDecodableDuration); 18706ad384100b8b493e4a3f37877caac520189fec3stefan@webrtc.org const int kNumFrames = kDefaultFrameRate * kMaxNonDecodableDuration / 1000; 18806ad384100b8b493e4a3f37877caac520189fec3stefan@webrtc.org for (int i = 0; i < kNumFrames; ++i) { 18906ad384100b8b493e4a3f37877caac520189fec3stefan@webrtc.org EXPECT_GE(InsertFrame(kVideoFrameDelta, true), kNoError); 19006ad384100b8b493e4a3f37877caac520189fec3stefan@webrtc.org } 19106ad384100b8b493e4a3f37877caac520189fec3stefan@webrtc.org uint16_t nack_list[kMaxNackListSize]; 19206ad384100b8b493e4a3f37877caac520189fec3stefan@webrtc.org uint16_t nack_list_length = 0; 19306ad384100b8b493e4a3f37877caac520189fec3stefan@webrtc.org VCMNackStatus ret = receiver_.NackList(nack_list, kMaxNackListSize, 19406ad384100b8b493e4a3f37877caac520189fec3stefan@webrtc.org &nack_list_length); 19506ad384100b8b493e4a3f37877caac520189fec3stefan@webrtc.org EXPECT_EQ(kNackKeyFrameRequest, ret); 19606ad384100b8b493e4a3f37877caac520189fec3stefan@webrtc.org} 19706ad384100b8b493e4a3f37877caac520189fec3stefan@webrtc.org 19806ad384100b8b493e4a3f37877caac520189fec3stefan@webrtc.orgTEST_F(TestVCMReceiver, NonDecodableDuration_OneIncomplete) { 19906ad384100b8b493e4a3f37877caac520189fec3stefan@webrtc.org // Enable NACK and with no RTT thresholds for disabling retransmission delay. 20006ad384100b8b493e4a3f37877caac520189fec3stefan@webrtc.org receiver_.SetNackMode(kNack, -1, -1); 20106ad384100b8b493e4a3f37877caac520189fec3stefan@webrtc.org const size_t kMaxNackListSize = 1000; 20206ad384100b8b493e4a3f37877caac520189fec3stefan@webrtc.org const int kMaxPacketAgeToNack = 1000; 20306ad384100b8b493e4a3f37877caac520189fec3stefan@webrtc.org const int kMaxNonDecodableDuration = 500; 20406ad384100b8b493e4a3f37877caac520189fec3stefan@webrtc.org const int kMaxNonDecodableDurationFrames = (kDefaultFrameRate * 20506ad384100b8b493e4a3f37877caac520189fec3stefan@webrtc.org kMaxNonDecodableDuration + 500) / 1000; 20606ad384100b8b493e4a3f37877caac520189fec3stefan@webrtc.org const int kMinDelayMs = 500; 20706ad384100b8b493e4a3f37877caac520189fec3stefan@webrtc.org receiver_.SetNackSettings(kMaxNackListSize, kMaxPacketAgeToNack, 20806ad384100b8b493e4a3f37877caac520189fec3stefan@webrtc.org kMaxNonDecodableDuration); 20906ad384100b8b493e4a3f37877caac520189fec3stefan@webrtc.org receiver_.SetMinReceiverDelay(kMinDelayMs); 21006ad384100b8b493e4a3f37877caac520189fec3stefan@webrtc.org int64_t key_frame_inserted = clock_->TimeInMilliseconds(); 21106ad384100b8b493e4a3f37877caac520189fec3stefan@webrtc.org EXPECT_GE(InsertFrame(kVideoFrameKey, true), kNoError); 21206ad384100b8b493e4a3f37877caac520189fec3stefan@webrtc.org // Insert an incomplete frame. 21306ad384100b8b493e4a3f37877caac520189fec3stefan@webrtc.org EXPECT_GE(InsertFrame(kVideoFrameDelta, false), kNoError); 21406ad384100b8b493e4a3f37877caac520189fec3stefan@webrtc.org // Insert enough frames to have too long non-decodable sequence. 21506ad384100b8b493e4a3f37877caac520189fec3stefan@webrtc.org for (int i = 0; i < kMaxNonDecodableDurationFrames; 21606ad384100b8b493e4a3f37877caac520189fec3stefan@webrtc.org ++i) { 21706ad384100b8b493e4a3f37877caac520189fec3stefan@webrtc.org EXPECT_GE(InsertFrame(kVideoFrameDelta, true), kNoError); 21806ad384100b8b493e4a3f37877caac520189fec3stefan@webrtc.org } 21906ad384100b8b493e4a3f37877caac520189fec3stefan@webrtc.org // Advance time until it's time to decode the key frame. 22006ad384100b8b493e4a3f37877caac520189fec3stefan@webrtc.org clock_->AdvanceTimeMilliseconds(kMinDelayMs - clock_->TimeInMilliseconds() - 22106ad384100b8b493e4a3f37877caac520189fec3stefan@webrtc.org key_frame_inserted); 22206ad384100b8b493e4a3f37877caac520189fec3stefan@webrtc.org EXPECT_TRUE(DecodeNextFrame()); 22306ad384100b8b493e4a3f37877caac520189fec3stefan@webrtc.org // Make sure we get a key frame request. 22406ad384100b8b493e4a3f37877caac520189fec3stefan@webrtc.org uint16_t nack_list[kMaxNackListSize]; 22506ad384100b8b493e4a3f37877caac520189fec3stefan@webrtc.org uint16_t nack_list_length = 0; 22606ad384100b8b493e4a3f37877caac520189fec3stefan@webrtc.org VCMNackStatus ret = receiver_.NackList(nack_list, kMaxNackListSize, 22706ad384100b8b493e4a3f37877caac520189fec3stefan@webrtc.org &nack_list_length); 22806ad384100b8b493e4a3f37877caac520189fec3stefan@webrtc.org EXPECT_EQ(kNackKeyFrameRequest, ret); 22906ad384100b8b493e4a3f37877caac520189fec3stefan@webrtc.org} 23006ad384100b8b493e4a3f37877caac520189fec3stefan@webrtc.org 23106ad384100b8b493e4a3f37877caac520189fec3stefan@webrtc.orgTEST_F(TestVCMReceiver, NonDecodableDuration_NoTrigger) { 23206ad384100b8b493e4a3f37877caac520189fec3stefan@webrtc.org // Enable NACK and with no RTT thresholds for disabling retransmission delay. 23306ad384100b8b493e4a3f37877caac520189fec3stefan@webrtc.org receiver_.SetNackMode(kNack, -1, -1); 23406ad384100b8b493e4a3f37877caac520189fec3stefan@webrtc.org const size_t kMaxNackListSize = 1000; 23506ad384100b8b493e4a3f37877caac520189fec3stefan@webrtc.org const int kMaxPacketAgeToNack = 1000; 23606ad384100b8b493e4a3f37877caac520189fec3stefan@webrtc.org const int kMaxNonDecodableDuration = 500; 23706ad384100b8b493e4a3f37877caac520189fec3stefan@webrtc.org const int kMaxNonDecodableDurationFrames = (kDefaultFrameRate * 23806ad384100b8b493e4a3f37877caac520189fec3stefan@webrtc.org kMaxNonDecodableDuration + 500) / 1000; 23906ad384100b8b493e4a3f37877caac520189fec3stefan@webrtc.org const int kMinDelayMs = 500; 24006ad384100b8b493e4a3f37877caac520189fec3stefan@webrtc.org receiver_.SetNackSettings(kMaxNackListSize, kMaxPacketAgeToNack, 24106ad384100b8b493e4a3f37877caac520189fec3stefan@webrtc.org kMaxNonDecodableDuration); 24206ad384100b8b493e4a3f37877caac520189fec3stefan@webrtc.org receiver_.SetMinReceiverDelay(kMinDelayMs); 24306ad384100b8b493e4a3f37877caac520189fec3stefan@webrtc.org int64_t key_frame_inserted = clock_->TimeInMilliseconds(); 24406ad384100b8b493e4a3f37877caac520189fec3stefan@webrtc.org EXPECT_GE(InsertFrame(kVideoFrameKey, true), kNoError); 24506ad384100b8b493e4a3f37877caac520189fec3stefan@webrtc.org // Insert an incomplete frame. 24606ad384100b8b493e4a3f37877caac520189fec3stefan@webrtc.org EXPECT_GE(InsertFrame(kVideoFrameDelta, false), kNoError); 24706ad384100b8b493e4a3f37877caac520189fec3stefan@webrtc.org // Insert all but one frame to not trigger a key frame request due to 24806ad384100b8b493e4a3f37877caac520189fec3stefan@webrtc.org // too long duration of non-decodable frames. 24906ad384100b8b493e4a3f37877caac520189fec3stefan@webrtc.org for (int i = 0; i < kMaxNonDecodableDurationFrames - 1; 25006ad384100b8b493e4a3f37877caac520189fec3stefan@webrtc.org ++i) { 25106ad384100b8b493e4a3f37877caac520189fec3stefan@webrtc.org EXPECT_GE(InsertFrame(kVideoFrameDelta, true), kNoError); 25206ad384100b8b493e4a3f37877caac520189fec3stefan@webrtc.org } 25306ad384100b8b493e4a3f37877caac520189fec3stefan@webrtc.org // Advance time until it's time to decode the key frame. 25406ad384100b8b493e4a3f37877caac520189fec3stefan@webrtc.org clock_->AdvanceTimeMilliseconds(kMinDelayMs - clock_->TimeInMilliseconds() - 25506ad384100b8b493e4a3f37877caac520189fec3stefan@webrtc.org key_frame_inserted); 25606ad384100b8b493e4a3f37877caac520189fec3stefan@webrtc.org EXPECT_TRUE(DecodeNextFrame()); 25706ad384100b8b493e4a3f37877caac520189fec3stefan@webrtc.org // Make sure we don't get a key frame request since we haven't generated 25806ad384100b8b493e4a3f37877caac520189fec3stefan@webrtc.org // enough frames. 25906ad384100b8b493e4a3f37877caac520189fec3stefan@webrtc.org uint16_t nack_list[kMaxNackListSize]; 26006ad384100b8b493e4a3f37877caac520189fec3stefan@webrtc.org uint16_t nack_list_length = 0; 26106ad384100b8b493e4a3f37877caac520189fec3stefan@webrtc.org VCMNackStatus ret = receiver_.NackList(nack_list, kMaxNackListSize, 26206ad384100b8b493e4a3f37877caac520189fec3stefan@webrtc.org &nack_list_length); 26306ad384100b8b493e4a3f37877caac520189fec3stefan@webrtc.org EXPECT_EQ(kNackOk, ret); 26406ad384100b8b493e4a3f37877caac520189fec3stefan@webrtc.org} 26506ad384100b8b493e4a3f37877caac520189fec3stefan@webrtc.org 2665ba433cad0d4ab117ce24862c4f0cd30015ab096stefan@webrtc.orgTEST_F(TestVCMReceiver, NonDecodableDuration_NoTrigger2) { 2675ba433cad0d4ab117ce24862c4f0cd30015ab096stefan@webrtc.org // Enable NACK and with no RTT thresholds for disabling retransmission delay. 2685ba433cad0d4ab117ce24862c4f0cd30015ab096stefan@webrtc.org receiver_.SetNackMode(kNack, -1, -1); 2695ba433cad0d4ab117ce24862c4f0cd30015ab096stefan@webrtc.org const size_t kMaxNackListSize = 1000; 2705ba433cad0d4ab117ce24862c4f0cd30015ab096stefan@webrtc.org const int kMaxPacketAgeToNack = 1000; 2715ba433cad0d4ab117ce24862c4f0cd30015ab096stefan@webrtc.org const int kMaxNonDecodableDuration = 500; 2725ba433cad0d4ab117ce24862c4f0cd30015ab096stefan@webrtc.org const int kMaxNonDecodableDurationFrames = (kDefaultFrameRate * 2735ba433cad0d4ab117ce24862c4f0cd30015ab096stefan@webrtc.org kMaxNonDecodableDuration + 500) / 1000; 2745ba433cad0d4ab117ce24862c4f0cd30015ab096stefan@webrtc.org const int kMinDelayMs = 500; 2755ba433cad0d4ab117ce24862c4f0cd30015ab096stefan@webrtc.org receiver_.SetNackSettings(kMaxNackListSize, kMaxPacketAgeToNack, 2765ba433cad0d4ab117ce24862c4f0cd30015ab096stefan@webrtc.org kMaxNonDecodableDuration); 2775ba433cad0d4ab117ce24862c4f0cd30015ab096stefan@webrtc.org receiver_.SetMinReceiverDelay(kMinDelayMs); 2785ba433cad0d4ab117ce24862c4f0cd30015ab096stefan@webrtc.org int64_t key_frame_inserted = clock_->TimeInMilliseconds(); 2795ba433cad0d4ab117ce24862c4f0cd30015ab096stefan@webrtc.org EXPECT_GE(InsertFrame(kVideoFrameKey, true), kNoError); 2805ba433cad0d4ab117ce24862c4f0cd30015ab096stefan@webrtc.org // Insert enough frames to have too long non-decodable sequence, except that 2815ba433cad0d4ab117ce24862c4f0cd30015ab096stefan@webrtc.org // we don't have any losses. 2825ba433cad0d4ab117ce24862c4f0cd30015ab096stefan@webrtc.org for (int i = 0; i < kMaxNonDecodableDurationFrames; 2835ba433cad0d4ab117ce24862c4f0cd30015ab096stefan@webrtc.org ++i) { 2845ba433cad0d4ab117ce24862c4f0cd30015ab096stefan@webrtc.org EXPECT_GE(InsertFrame(kVideoFrameDelta, true), kNoError); 2855ba433cad0d4ab117ce24862c4f0cd30015ab096stefan@webrtc.org } 2865ba433cad0d4ab117ce24862c4f0cd30015ab096stefan@webrtc.org // Insert an incomplete frame. 2875ba433cad0d4ab117ce24862c4f0cd30015ab096stefan@webrtc.org EXPECT_GE(InsertFrame(kVideoFrameDelta, false), kNoError); 2885ba433cad0d4ab117ce24862c4f0cd30015ab096stefan@webrtc.org // Advance time until it's time to decode the key frame. 2895ba433cad0d4ab117ce24862c4f0cd30015ab096stefan@webrtc.org clock_->AdvanceTimeMilliseconds(kMinDelayMs - clock_->TimeInMilliseconds() - 2905ba433cad0d4ab117ce24862c4f0cd30015ab096stefan@webrtc.org key_frame_inserted); 2915ba433cad0d4ab117ce24862c4f0cd30015ab096stefan@webrtc.org EXPECT_TRUE(DecodeNextFrame()); 2925ba433cad0d4ab117ce24862c4f0cd30015ab096stefan@webrtc.org // Make sure we don't get a key frame request since the non-decodable duration 2935ba433cad0d4ab117ce24862c4f0cd30015ab096stefan@webrtc.org // is only one frame. 2945ba433cad0d4ab117ce24862c4f0cd30015ab096stefan@webrtc.org uint16_t nack_list[kMaxNackListSize]; 2955ba433cad0d4ab117ce24862c4f0cd30015ab096stefan@webrtc.org uint16_t nack_list_length = 0; 2965ba433cad0d4ab117ce24862c4f0cd30015ab096stefan@webrtc.org VCMNackStatus ret = receiver_.NackList(nack_list, kMaxNackListSize, 2975ba433cad0d4ab117ce24862c4f0cd30015ab096stefan@webrtc.org &nack_list_length); 2985ba433cad0d4ab117ce24862c4f0cd30015ab096stefan@webrtc.org EXPECT_EQ(kNackOk, ret); 2995ba433cad0d4ab117ce24862c4f0cd30015ab096stefan@webrtc.org} 3005ba433cad0d4ab117ce24862c4f0cd30015ab096stefan@webrtc.org 30106ad384100b8b493e4a3f37877caac520189fec3stefan@webrtc.orgTEST_F(TestVCMReceiver, NonDecodableDuration_KeyFrameAfterIncompleteFrames) { 30206ad384100b8b493e4a3f37877caac520189fec3stefan@webrtc.org // Enable NACK and with no RTT thresholds for disabling retransmission delay. 30306ad384100b8b493e4a3f37877caac520189fec3stefan@webrtc.org receiver_.SetNackMode(kNack, -1, -1); 30406ad384100b8b493e4a3f37877caac520189fec3stefan@webrtc.org const size_t kMaxNackListSize = 1000; 30506ad384100b8b493e4a3f37877caac520189fec3stefan@webrtc.org const int kMaxPacketAgeToNack = 1000; 30606ad384100b8b493e4a3f37877caac520189fec3stefan@webrtc.org const int kMaxNonDecodableDuration = 500; 30706ad384100b8b493e4a3f37877caac520189fec3stefan@webrtc.org const int kMaxNonDecodableDurationFrames = (kDefaultFrameRate * 30806ad384100b8b493e4a3f37877caac520189fec3stefan@webrtc.org kMaxNonDecodableDuration + 500) / 1000; 30906ad384100b8b493e4a3f37877caac520189fec3stefan@webrtc.org const int kMinDelayMs = 500; 31006ad384100b8b493e4a3f37877caac520189fec3stefan@webrtc.org receiver_.SetNackSettings(kMaxNackListSize, kMaxPacketAgeToNack, 31106ad384100b8b493e4a3f37877caac520189fec3stefan@webrtc.org kMaxNonDecodableDuration); 31206ad384100b8b493e4a3f37877caac520189fec3stefan@webrtc.org receiver_.SetMinReceiverDelay(kMinDelayMs); 31306ad384100b8b493e4a3f37877caac520189fec3stefan@webrtc.org int64_t key_frame_inserted = clock_->TimeInMilliseconds(); 31406ad384100b8b493e4a3f37877caac520189fec3stefan@webrtc.org EXPECT_GE(InsertFrame(kVideoFrameKey, true), kNoError); 31506ad384100b8b493e4a3f37877caac520189fec3stefan@webrtc.org // Insert an incomplete frame. 31606ad384100b8b493e4a3f37877caac520189fec3stefan@webrtc.org EXPECT_GE(InsertFrame(kVideoFrameDelta, false), kNoError); 31706ad384100b8b493e4a3f37877caac520189fec3stefan@webrtc.org // Insert enough frames to have too long non-decodable sequence. 31806ad384100b8b493e4a3f37877caac520189fec3stefan@webrtc.org for (int i = 0; i < kMaxNonDecodableDurationFrames; 31906ad384100b8b493e4a3f37877caac520189fec3stefan@webrtc.org ++i) { 32006ad384100b8b493e4a3f37877caac520189fec3stefan@webrtc.org EXPECT_GE(InsertFrame(kVideoFrameDelta, true), kNoError); 32106ad384100b8b493e4a3f37877caac520189fec3stefan@webrtc.org } 32206ad384100b8b493e4a3f37877caac520189fec3stefan@webrtc.org EXPECT_GE(InsertFrame(kVideoFrameKey, true), kNoError); 32306ad384100b8b493e4a3f37877caac520189fec3stefan@webrtc.org // Advance time until it's time to decode the key frame. 32406ad384100b8b493e4a3f37877caac520189fec3stefan@webrtc.org clock_->AdvanceTimeMilliseconds(kMinDelayMs - clock_->TimeInMilliseconds() - 32506ad384100b8b493e4a3f37877caac520189fec3stefan@webrtc.org key_frame_inserted); 32606ad384100b8b493e4a3f37877caac520189fec3stefan@webrtc.org EXPECT_TRUE(DecodeNextFrame()); 32706ad384100b8b493e4a3f37877caac520189fec3stefan@webrtc.org // Make sure we don't get a key frame request since we have a key frame 32806ad384100b8b493e4a3f37877caac520189fec3stefan@webrtc.org // in the list. 32906ad384100b8b493e4a3f37877caac520189fec3stefan@webrtc.org uint16_t nack_list[kMaxNackListSize]; 33006ad384100b8b493e4a3f37877caac520189fec3stefan@webrtc.org uint16_t nack_list_length = 0; 33106ad384100b8b493e4a3f37877caac520189fec3stefan@webrtc.org VCMNackStatus ret = receiver_.NackList(nack_list, kMaxNackListSize, 33206ad384100b8b493e4a3f37877caac520189fec3stefan@webrtc.org &nack_list_length); 33306ad384100b8b493e4a3f37877caac520189fec3stefan@webrtc.org EXPECT_EQ(kNackOk, ret); 33406ad384100b8b493e4a3f37877caac520189fec3stefan@webrtc.org} 33540bd7448cb81dea34512c6970864a710a75da666mikhal@webrtc.org} // namespace webrtc 336