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