blob: 9cac45b86b380330072f22f1811e4c9f4b65ee16 [file] [log] [blame]
andresp@webrtc.orge401c2e2013-09-16 20:29:13 +00001/*
2 * Copyright (c) 2013 The WebRTC project authors. All Rights Reserved.
3 *
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10
kwiberg3f55dea2016-02-29 05:51:59 -080011#include <memory>
andresp@webrtc.orge401c2e2013-09-16 20:29:13 +000012#include <vector>
13
Henrik Kjellander2557b862015-11-18 22:00:21 +010014#include "webrtc/modules/video_coding/include/mock/mock_vcm_callbacks.h"
kwibergac9f8762016-09-30 22:29:43 -070015#include "webrtc/modules/video_coding/include/mock/mock_video_codec_interface.h"
Henrik Kjellander2557b862015-11-18 22:00:21 +010016#include "webrtc/modules/video_coding/include/video_coding.h"
Henrik Kjellander2557b862015-11-18 22:00:21 +010017#include "webrtc/modules/video_coding/test/test_util.h"
philipel721d4022016-12-15 07:10:57 -080018#include "webrtc/modules/video_coding/timing.h"
kwibergac9f8762016-09-30 22:29:43 -070019#include "webrtc/modules/video_coding/video_coding_impl.h"
Henrik Kjellander98f53512015-10-28 18:17:40 +010020#include "webrtc/system_wrappers/include/clock.h"
kwibergac9f8762016-09-30 22:29:43 -070021#include "webrtc/test/gtest.h"
andresp@webrtc.orge401c2e2013-09-16 20:29:13 +000022
23using ::testing::_;
24using ::testing::NiceMock;
25
26namespace webrtc {
27namespace vcm {
28namespace {
29
30class TestVideoReceiver : public ::testing::Test {
31 protected:
32 static const int kUnusedPayloadType = 10;
33
34 TestVideoReceiver() : clock_(0) {}
35
36 virtual void SetUp() {
philipel721d4022016-12-15 07:10:57 -080037 timing_.reset(new VCMTiming(&clock_));
38 receiver_.reset(
39 new VideoReceiver(&clock_, &event_factory_, nullptr, timing_.get()));
perkj796cfaf2015-12-10 09:27:38 -080040 receiver_->RegisterExternalDecoder(&decoder_, kUnusedPayloadType);
andresp@webrtc.orge401c2e2013-09-16 20:29:13 +000041 const size_t kMaxNackListSize = 250;
42 const int kMaxPacketAgeToNack = 450;
43 receiver_->SetNackSettings(kMaxNackListSize, kMaxPacketAgeToNack, 0);
44
Peter Boström7776e782016-01-07 15:42:47 +010045 VideoCodingModule::Codec(kVideoCodecVP8, &settings_);
andresp@webrtc.orge401c2e2013-09-16 20:29:13 +000046 settings_.plType = kUnusedPayloadType; // Use the mocked encoder.
47 EXPECT_EQ(0, receiver_->RegisterReceiveCodec(&settings_, 1, true));
48 }
49
50 void InsertAndVerifyPaddingFrame(const uint8_t* payload,
andresp@webrtc.orge401c2e2013-09-16 20:29:13 +000051 WebRtcRTPHeader* header) {
52 ASSERT_TRUE(header != NULL);
53 for (int j = 0; j < 5; ++j) {
54 // Padding only packets are passed to the VCM with payload size 0.
55 EXPECT_EQ(0, receiver_->IncomingPacket(payload, 0, *header));
56 ++header->header.sequenceNumber;
57 }
pbosa26ac922016-02-25 04:50:01 -080058 receiver_->Process();
andresp@webrtc.orge401c2e2013-09-16 20:29:13 +000059 EXPECT_CALL(decoder_, Decode(_, _, _, _, _)).Times(0);
perkj796cfaf2015-12-10 09:27:38 -080060 EXPECT_EQ(VCM_FRAME_NOT_READY, receiver_->Decode(100));
andresp@webrtc.orge401c2e2013-09-16 20:29:13 +000061 }
62
63 void InsertAndVerifyDecodableFrame(const uint8_t* payload,
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +000064 size_t length,
andresp@webrtc.orge401c2e2013-09-16 20:29:13 +000065 WebRtcRTPHeader* header) {
66 ASSERT_TRUE(header != NULL);
67 EXPECT_EQ(0, receiver_->IncomingPacket(payload, length, *header));
68 ++header->header.sequenceNumber;
69 EXPECT_CALL(packet_request_callback_, ResendPackets(_, _)).Times(0);
pbosa26ac922016-02-25 04:50:01 -080070 receiver_->Process();;
andresp@webrtc.orge401c2e2013-09-16 20:29:13 +000071 EXPECT_CALL(decoder_, Decode(_, _, _, _, _)).Times(1);
perkj796cfaf2015-12-10 09:27:38 -080072 EXPECT_EQ(0, receiver_->Decode(100));
andresp@webrtc.orge401c2e2013-09-16 20:29:13 +000073 }
74
75 SimulatedClock clock_;
76 NullEventFactory event_factory_;
77 VideoCodec settings_;
78 NiceMock<MockVideoDecoder> decoder_;
79 NiceMock<MockPacketRequestCallback> packet_request_callback_;
80
philipel721d4022016-12-15 07:10:57 -080081 std::unique_ptr<VCMTiming> timing_;
kwiberg3f55dea2016-02-29 05:51:59 -080082 std::unique_ptr<VideoReceiver> receiver_;
andresp@webrtc.orge401c2e2013-09-16 20:29:13 +000083};
84
85TEST_F(TestVideoReceiver, PaddingOnlyFrames) {
86 EXPECT_EQ(0, receiver_->SetVideoProtection(kProtectionNack, true));
87 EXPECT_EQ(
88 0, receiver_->RegisterPacketRequestCallback(&packet_request_callback_));
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +000089 const size_t kPaddingSize = 220;
andresp@webrtc.orge401c2e2013-09-16 20:29:13 +000090 const uint8_t payload[kPaddingSize] = {0};
91 WebRtcRTPHeader header;
92 memset(&header, 0, sizeof(header));
pbos22993e12015-10-19 02:39:06 -070093 header.frameType = kEmptyFrame;
andresp@webrtc.orge401c2e2013-09-16 20:29:13 +000094 header.header.markerBit = false;
95 header.header.paddingLength = kPaddingSize;
96 header.header.payloadType = kUnusedPayloadType;
97 header.header.ssrc = 1;
98 header.header.headerLength = 12;
99 header.type.Video.codec = kRtpVideoVp8;
100 for (int i = 0; i < 10; ++i) {
101 EXPECT_CALL(packet_request_callback_, ResendPackets(_, _)).Times(0);
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +0000102 InsertAndVerifyPaddingFrame(payload, &header);
andresp@webrtc.orge401c2e2013-09-16 20:29:13 +0000103 clock_.AdvanceTimeMilliseconds(33);
104 header.header.timestamp += 3000;
105 }
106}
107
108TEST_F(TestVideoReceiver, PaddingOnlyFramesWithLosses) {
109 EXPECT_EQ(0, receiver_->SetVideoProtection(kProtectionNack, true));
110 EXPECT_EQ(
111 0, receiver_->RegisterPacketRequestCallback(&packet_request_callback_));
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +0000112 const size_t kFrameSize = 1200;
113 const size_t kPaddingSize = 220;
andresp@webrtc.orge401c2e2013-09-16 20:29:13 +0000114 const uint8_t payload[kFrameSize] = {0};
115 WebRtcRTPHeader header;
116 memset(&header, 0, sizeof(header));
pbos22993e12015-10-19 02:39:06 -0700117 header.frameType = kEmptyFrame;
andresp@webrtc.orge401c2e2013-09-16 20:29:13 +0000118 header.header.markerBit = false;
119 header.header.paddingLength = kPaddingSize;
120 header.header.payloadType = kUnusedPayloadType;
121 header.header.ssrc = 1;
122 header.header.headerLength = 12;
123 header.type.Video.codec = kRtpVideoVp8;
124 // Insert one video frame to get one frame decoded.
125 header.frameType = kVideoFrameKey;
johanefde9082016-12-19 08:32:24 -0800126 header.type.Video.is_first_packet_in_frame = true;
andresp@webrtc.orge401c2e2013-09-16 20:29:13 +0000127 header.header.markerBit = true;
128 InsertAndVerifyDecodableFrame(payload, kFrameSize, &header);
129 clock_.AdvanceTimeMilliseconds(33);
130 header.header.timestamp += 3000;
131
pbos22993e12015-10-19 02:39:06 -0700132 header.frameType = kEmptyFrame;
johanefde9082016-12-19 08:32:24 -0800133 header.type.Video.is_first_packet_in_frame = false;
andresp@webrtc.orge401c2e2013-09-16 20:29:13 +0000134 header.header.markerBit = false;
135 // Insert padding frames.
136 for (int i = 0; i < 10; ++i) {
137 // Lose one packet from the 6th frame.
138 if (i == 5) {
139 ++header.header.sequenceNumber;
140 }
141 // Lose the 4th frame.
142 if (i == 3) {
143 header.header.sequenceNumber += 5;
144 } else {
145 if (i > 3 && i < 5) {
146 EXPECT_CALL(packet_request_callback_, ResendPackets(_, 5)).Times(1);
147 } else if (i >= 5) {
148 EXPECT_CALL(packet_request_callback_, ResendPackets(_, 6)).Times(1);
149 } else {
150 EXPECT_CALL(packet_request_callback_, ResendPackets(_, _)).Times(0);
151 }
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +0000152 InsertAndVerifyPaddingFrame(payload, &header);
andresp@webrtc.orge401c2e2013-09-16 20:29:13 +0000153 }
154 clock_.AdvanceTimeMilliseconds(33);
155 header.header.timestamp += 3000;
156 }
157}
158
159TEST_F(TestVideoReceiver, PaddingOnlyAndVideo) {
160 EXPECT_EQ(0, receiver_->SetVideoProtection(kProtectionNack, true));
161 EXPECT_EQ(
162 0, receiver_->RegisterPacketRequestCallback(&packet_request_callback_));
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +0000163 const size_t kFrameSize = 1200;
164 const size_t kPaddingSize = 220;
andresp@webrtc.orge401c2e2013-09-16 20:29:13 +0000165 const uint8_t payload[kFrameSize] = {0};
166 WebRtcRTPHeader header;
167 memset(&header, 0, sizeof(header));
pbos22993e12015-10-19 02:39:06 -0700168 header.frameType = kEmptyFrame;
johanefde9082016-12-19 08:32:24 -0800169 header.type.Video.is_first_packet_in_frame = false;
andresp@webrtc.orge401c2e2013-09-16 20:29:13 +0000170 header.header.markerBit = false;
171 header.header.paddingLength = kPaddingSize;
172 header.header.payloadType = kUnusedPayloadType;
173 header.header.ssrc = 1;
174 header.header.headerLength = 12;
175 header.type.Video.codec = kRtpVideoVp8;
176 header.type.Video.codecHeader.VP8.pictureId = -1;
177 header.type.Video.codecHeader.VP8.tl0PicIdx = -1;
178 for (int i = 0; i < 3; ++i) {
179 // Insert 2 video frames.
180 for (int j = 0; j < 2; ++j) {
181 if (i == 0 && j == 0) // First frame should be a key frame.
182 header.frameType = kVideoFrameKey;
183 else
184 header.frameType = kVideoFrameDelta;
johanefde9082016-12-19 08:32:24 -0800185 header.type.Video.is_first_packet_in_frame = true;
andresp@webrtc.orge401c2e2013-09-16 20:29:13 +0000186 header.header.markerBit = true;
187 InsertAndVerifyDecodableFrame(payload, kFrameSize, &header);
188 clock_.AdvanceTimeMilliseconds(33);
189 header.header.timestamp += 3000;
190 }
191
192 // Insert 2 padding only frames.
pbos22993e12015-10-19 02:39:06 -0700193 header.frameType = kEmptyFrame;
johanefde9082016-12-19 08:32:24 -0800194 header.type.Video.is_first_packet_in_frame = false;
andresp@webrtc.orge401c2e2013-09-16 20:29:13 +0000195 header.header.markerBit = false;
196 for (int j = 0; j < 2; ++j) {
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +0000197 // InsertAndVerifyPaddingFrame(payload, &header);
andresp@webrtc.orge401c2e2013-09-16 20:29:13 +0000198 clock_.AdvanceTimeMilliseconds(33);
199 header.header.timestamp += 3000;
200 }
201 }
202}
203
204TEST_F(TestVideoReceiver, ReceiverDelay) {
205 EXPECT_EQ(0, receiver_->SetMinReceiverDelay(0));
206 EXPECT_EQ(0, receiver_->SetMinReceiverDelay(5000));
207 EXPECT_EQ(-1, receiver_->SetMinReceiverDelay(-100));
208 EXPECT_EQ(-1, receiver_->SetMinReceiverDelay(10010));
209}
210
211} // namespace
212} // namespace vcm
213} // namespace webrtc