Upstream version 7.36.149.0
[platform/framework/web/crosswalk.git] / src / third_party / webrtc / modules / video_coding / main / source / video_receiver_unittest.cc
1 /*
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
11 #include <vector>
12
13 #include "testing/gtest/include/gtest/gtest.h"
14 #include "webrtc/modules/video_coding/codecs/interface/mock/mock_video_codec_interface.h"
15 #include "webrtc/modules/video_coding/main/interface/mock/mock_vcm_callbacks.h"
16 #include "webrtc/modules/video_coding/main/interface/video_coding.h"
17 #include "webrtc/modules/video_coding/main/source/video_coding_impl.h"
18 #include "webrtc/modules/video_coding/main/test/test_util.h"
19 #include "webrtc/system_wrappers/interface/clock.h"
20 #include "webrtc/system_wrappers/interface/scoped_ptr.h"
21
22 using ::testing::_;
23 using ::testing::NiceMock;
24
25 namespace webrtc {
26 namespace vcm {
27 namespace {
28
29 class TestVideoReceiver : public ::testing::Test {
30  protected:
31   static const int kUnusedPayloadType = 10;
32
33   TestVideoReceiver() : clock_(0) {}
34
35   virtual void SetUp() {
36     receiver_.reset(new VideoReceiver(&clock_, &event_factory_));
37     EXPECT_EQ(0, receiver_->InitializeReceiver());
38     EXPECT_EQ(0,
39               receiver_->RegisterExternalDecoder(
40                   &decoder_, kUnusedPayloadType, true));
41     const size_t kMaxNackListSize = 250;
42     const int kMaxPacketAgeToNack = 450;
43     receiver_->SetNackSettings(kMaxNackListSize, kMaxPacketAgeToNack, 0);
44
45     memset(&settings_, 0, sizeof(settings_));
46     EXPECT_EQ(0, VideoCodingModule::Codec(kVideoCodecVP8, &settings_));
47     settings_.plType = kUnusedPayloadType;  // Use the mocked encoder.
48     EXPECT_EQ(0, receiver_->RegisterReceiveCodec(&settings_, 1, true));
49   }
50
51   void InsertAndVerifyPaddingFrame(const uint8_t* payload,
52                                    int length,
53                                    WebRtcRTPHeader* header) {
54     ASSERT_TRUE(header != NULL);
55     for (int j = 0; j < 5; ++j) {
56       // Padding only packets are passed to the VCM with payload size 0.
57       EXPECT_EQ(0, receiver_->IncomingPacket(payload, 0, *header));
58       ++header->header.sequenceNumber;
59     }
60     EXPECT_EQ(0, receiver_->Process());
61     EXPECT_CALL(decoder_, Decode(_, _, _, _, _)).Times(0);
62     EXPECT_EQ(VCM_FRAME_NOT_READY, receiver_->Decode(0));
63   }
64
65   void InsertAndVerifyDecodableFrame(const uint8_t* payload,
66                                      int length,
67                                      WebRtcRTPHeader* header) {
68     ASSERT_TRUE(header != NULL);
69     EXPECT_EQ(0, receiver_->IncomingPacket(payload, length, *header));
70     ++header->header.sequenceNumber;
71     EXPECT_CALL(packet_request_callback_, ResendPackets(_, _)).Times(0);
72     EXPECT_EQ(0, receiver_->Process());
73     EXPECT_CALL(decoder_, Decode(_, _, _, _, _)).Times(1);
74     EXPECT_EQ(0, receiver_->Decode(0));
75   }
76
77   SimulatedClock clock_;
78   NullEventFactory event_factory_;
79   VideoCodec settings_;
80   NiceMock<MockVideoDecoder> decoder_;
81   NiceMock<MockPacketRequestCallback> packet_request_callback_;
82
83   scoped_ptr<VideoReceiver> receiver_;
84 };
85
86 TEST_F(TestVideoReceiver, PaddingOnlyFrames) {
87   EXPECT_EQ(0, receiver_->SetVideoProtection(kProtectionNack, true));
88   EXPECT_EQ(
89       0, receiver_->RegisterPacketRequestCallback(&packet_request_callback_));
90   const unsigned int kPaddingSize = 220;
91   const uint8_t payload[kPaddingSize] = {0};
92   WebRtcRTPHeader header;
93   memset(&header, 0, sizeof(header));
94   header.frameType = kFrameEmpty;
95   header.header.markerBit = false;
96   header.header.paddingLength = kPaddingSize;
97   header.header.payloadType = kUnusedPayloadType;
98   header.header.ssrc = 1;
99   header.header.headerLength = 12;
100   header.type.Video.codec = kRtpVideoVp8;
101   for (int i = 0; i < 10; ++i) {
102     EXPECT_CALL(packet_request_callback_, ResendPackets(_, _)).Times(0);
103     InsertAndVerifyPaddingFrame(payload, 0, &header);
104     clock_.AdvanceTimeMilliseconds(33);
105     header.header.timestamp += 3000;
106   }
107 }
108
109 TEST_F(TestVideoReceiver, PaddingOnlyFramesWithLosses) {
110   EXPECT_EQ(0, receiver_->SetVideoProtection(kProtectionNack, true));
111   EXPECT_EQ(
112       0, receiver_->RegisterPacketRequestCallback(&packet_request_callback_));
113   const unsigned int kFrameSize = 1200;
114   const unsigned int kPaddingSize = 220;
115   const uint8_t payload[kFrameSize] = {0};
116   WebRtcRTPHeader header;
117   memset(&header, 0, sizeof(header));
118   header.frameType = kFrameEmpty;
119   header.header.markerBit = false;
120   header.header.paddingLength = kPaddingSize;
121   header.header.payloadType = kUnusedPayloadType;
122   header.header.ssrc = 1;
123   header.header.headerLength = 12;
124   header.type.Video.codec = kRtpVideoVp8;
125   // Insert one video frame to get one frame decoded.
126   header.frameType = kVideoFrameKey;
127   header.type.Video.isFirstPacket = true;
128   header.header.markerBit = true;
129   InsertAndVerifyDecodableFrame(payload, kFrameSize, &header);
130   clock_.AdvanceTimeMilliseconds(33);
131   header.header.timestamp += 3000;
132
133   header.frameType = kFrameEmpty;
134   header.type.Video.isFirstPacket = false;
135   header.header.markerBit = false;
136   // Insert padding frames.
137   for (int i = 0; i < 10; ++i) {
138     // Lose one packet from the 6th frame.
139     if (i == 5) {
140       ++header.header.sequenceNumber;
141     }
142     // Lose the 4th frame.
143     if (i == 3) {
144       header.header.sequenceNumber += 5;
145     } else {
146       if (i > 3 && i < 5) {
147         EXPECT_CALL(packet_request_callback_, ResendPackets(_, 5)).Times(1);
148       } else if (i >= 5) {
149         EXPECT_CALL(packet_request_callback_, ResendPackets(_, 6)).Times(1);
150       } else {
151         EXPECT_CALL(packet_request_callback_, ResendPackets(_, _)).Times(0);
152       }
153       InsertAndVerifyPaddingFrame(payload, 0, &header);
154     }
155     clock_.AdvanceTimeMilliseconds(33);
156     header.header.timestamp += 3000;
157   }
158 }
159
160 TEST_F(TestVideoReceiver, PaddingOnlyAndVideo) {
161   EXPECT_EQ(0, receiver_->SetVideoProtection(kProtectionNack, true));
162   EXPECT_EQ(
163       0, receiver_->RegisterPacketRequestCallback(&packet_request_callback_));
164   const unsigned int kFrameSize = 1200;
165   const unsigned int kPaddingSize = 220;
166   const uint8_t payload[kFrameSize] = {0};
167   WebRtcRTPHeader header;
168   memset(&header, 0, sizeof(header));
169   header.frameType = kFrameEmpty;
170   header.type.Video.isFirstPacket = false;
171   header.header.markerBit = false;
172   header.header.paddingLength = kPaddingSize;
173   header.header.payloadType = kUnusedPayloadType;
174   header.header.ssrc = 1;
175   header.header.headerLength = 12;
176   header.type.Video.codec = kRtpVideoVp8;
177   header.type.Video.codecHeader.VP8.pictureId = -1;
178   header.type.Video.codecHeader.VP8.tl0PicIdx = -1;
179   for (int i = 0; i < 3; ++i) {
180     // Insert 2 video frames.
181     for (int j = 0; j < 2; ++j) {
182       if (i == 0 && j == 0)  // First frame should be a key frame.
183         header.frameType = kVideoFrameKey;
184       else
185         header.frameType = kVideoFrameDelta;
186       header.type.Video.isFirstPacket = true;
187       header.header.markerBit = true;
188       InsertAndVerifyDecodableFrame(payload, kFrameSize, &header);
189       clock_.AdvanceTimeMilliseconds(33);
190       header.header.timestamp += 3000;
191     }
192
193     // Insert 2 padding only frames.
194     header.frameType = kFrameEmpty;
195     header.type.Video.isFirstPacket = false;
196     header.header.markerBit = false;
197     for (int j = 0; j < 2; ++j) {
198       // InsertAndVerifyPaddingFrame(payload, 0, &header);
199       clock_.AdvanceTimeMilliseconds(33);
200       header.header.timestamp += 3000;
201     }
202   }
203 }
204
205 TEST_F(TestVideoReceiver, ReceiverDelay) {
206   EXPECT_EQ(0, receiver_->SetMinReceiverDelay(0));
207   EXPECT_EQ(0, receiver_->SetMinReceiverDelay(5000));
208   EXPECT_EQ(-1, receiver_->SetMinReceiverDelay(-100));
209   EXPECT_EQ(-1, receiver_->SetMinReceiverDelay(10010));
210 }
211
212 }  // namespace
213 }  // namespace vcm
214 }  // namespace webrtc