1 /*
2 * Copyright (c) 2011 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 <stdlib.h> // NULL
12
13 #include "testing/gtest/include/gtest/gtest.h"
14 #include "webrtc/modules/rtp_rtcp/source/vp8_partition_aggregator.h"
15
16 namespace webrtc {
17
TEST(PartitionTreeNode,CreateAndDelete)18 TEST(PartitionTreeNode, CreateAndDelete) {
19 const size_t kVector[] = {1, 2, 3};
20 const size_t kNumPartitions = GTEST_ARRAY_SIZE_(kVector);
21 PartitionTreeNode* node1 =
22 PartitionTreeNode::CreateRootNode(kVector, kNumPartitions);
23 PartitionTreeNode* node2 =
24 new PartitionTreeNode(node1, kVector, kNumPartitions, 17);
25 delete node1;
26 delete node2;
27 }
28
TEST(PartitionTreeNode,CreateChildrenAndDelete)29 TEST(PartitionTreeNode, CreateChildrenAndDelete) {
30 const size_t kVector[] = {1, 2, 3};
31 const size_t kNumPartitions = GTEST_ARRAY_SIZE_(kVector);
32 const size_t kMaxSize = 10;
33 const size_t kPenalty = 5;
34 PartitionTreeNode* root =
35 PartitionTreeNode::CreateRootNode(kVector, kNumPartitions);
36 EXPECT_TRUE(root->CreateChildren(kMaxSize));
37 ASSERT_TRUE(NULL != root->left_child());
38 ASSERT_TRUE(NULL != root->right_child());
39 EXPECT_EQ(3u, root->left_child()->this_size());
40 EXPECT_EQ(2u, root->right_child()->this_size());
41 EXPECT_EQ(11, root->right_child()->Cost(kPenalty));
42 EXPECT_FALSE(root->left_child()->packet_start());
43 EXPECT_TRUE(root->right_child()->packet_start());
44 delete root;
45 }
46
TEST(PartitionTreeNode,FindOptimalConfig)47 TEST(PartitionTreeNode, FindOptimalConfig) {
48 const size_t kVector[] = {197, 194, 213, 215, 184, 199, 197, 207};
49 const size_t kNumPartitions = GTEST_ARRAY_SIZE_(kVector);
50 const size_t kMaxSize = 1500;
51 const size_t kPenalty = 1;
52 PartitionTreeNode* root =
53 PartitionTreeNode::CreateRootNode(kVector, kNumPartitions);
54 root->set_max_parent_size(500);
55 root->set_min_parent_size(300);
56 PartitionTreeNode* opt = root->GetOptimalNode(kMaxSize, kPenalty);
57 ASSERT_TRUE(opt != NULL);
58 EXPECT_EQ(4u, opt->NumPackets());
59 // Expect optimal sequence to be {1, 0, 1, 0, 1, 0, 1, 0}, which corresponds
60 // to (right)-left-right-left-right-left-right-left, where the root node is
61 // implicitly a "right" node by definition.
62 EXPECT_TRUE(opt->parent()->parent()->parent()->parent()->parent()->
63 parent()->parent()->packet_start());
64 EXPECT_FALSE(opt->parent()->parent()->parent()->parent()->parent()->
65 parent()->packet_start());
66 EXPECT_TRUE(opt->parent()->parent()->parent()->parent()->parent()->
67 packet_start());
68 EXPECT_FALSE(opt->parent()->parent()->parent()->parent()->packet_start());
69 EXPECT_TRUE(opt->parent()->parent()->parent()->packet_start());
70 EXPECT_FALSE(opt->parent()->parent()->packet_start());
71 EXPECT_TRUE(opt->parent()->packet_start());
72 EXPECT_FALSE(opt->packet_start());
73 EXPECT_TRUE(opt == root->left_child()->right_child()->left_child()->
74 right_child()->left_child()->right_child()->left_child());
75 delete root;
76 }
77
TEST(PartitionTreeNode,FindOptimalConfigSinglePartition)78 TEST(PartitionTreeNode, FindOptimalConfigSinglePartition) {
79 const size_t kVector[] = {17};
80 const size_t kNumPartitions = GTEST_ARRAY_SIZE_(kVector);
81 const size_t kMaxSize = 1500;
82 const size_t kPenalty = 1;
83 PartitionTreeNode* root =
84 PartitionTreeNode::CreateRootNode(kVector, kNumPartitions);
85 PartitionTreeNode* opt = root->GetOptimalNode(kMaxSize, kPenalty);
86 ASSERT_TRUE(opt != NULL);
87 EXPECT_EQ(1u, opt->NumPackets());
88 EXPECT_TRUE(opt == root);
89 delete root;
90 }
91
VerifyConfiguration(const size_t * expected_config,size_t expected_config_len,const Vp8PartitionAggregator::ConfigVec & opt_config,const RTPFragmentationHeader & fragmentation)92 static void VerifyConfiguration(
93 const size_t* expected_config,
94 size_t expected_config_len,
95 const Vp8PartitionAggregator::ConfigVec& opt_config,
96 const RTPFragmentationHeader& fragmentation) {
97 ASSERT_EQ(expected_config_len, fragmentation.fragmentationVectorSize);
98 EXPECT_EQ(expected_config_len, opt_config.size());
99 for (size_t i = 0; i < expected_config_len; ++i) {
100 EXPECT_EQ(expected_config[i], opt_config[i]);
101 }
102 }
103
VerifyMinMax(const Vp8PartitionAggregator & aggregator,const Vp8PartitionAggregator::ConfigVec & opt_config,int expected_min,int expected_max)104 static void VerifyMinMax(const Vp8PartitionAggregator& aggregator,
105 const Vp8PartitionAggregator::ConfigVec& opt_config,
106 int expected_min,
107 int expected_max) {
108 int min_size = -1;
109 int max_size = -1;
110 aggregator.CalcMinMax(opt_config, &min_size, &max_size);
111 EXPECT_EQ(expected_min, min_size);
112 EXPECT_EQ(expected_max, max_size);
113 }
114
TEST(Vp8PartitionAggregator,CreateAndDelete)115 TEST(Vp8PartitionAggregator, CreateAndDelete) {
116 RTPFragmentationHeader fragmentation;
117 fragmentation.VerifyAndAllocateFragmentationHeader(3);
118 Vp8PartitionAggregator* aggregator =
119 new Vp8PartitionAggregator(fragmentation, 0, 2);
120 delete aggregator;
121 }
122
TEST(Vp8PartitionAggregator,FindOptimalConfig)123 TEST(Vp8PartitionAggregator, FindOptimalConfig) {
124 RTPFragmentationHeader fragmentation;
125 fragmentation.VerifyAndAllocateFragmentationHeader(8);
126 fragmentation.fragmentationLength[0] = 197;
127 fragmentation.fragmentationLength[1] = 194;
128 fragmentation.fragmentationLength[2] = 213;
129 fragmentation.fragmentationLength[3] = 215;
130 fragmentation.fragmentationLength[4] = 184;
131 fragmentation.fragmentationLength[5] = 199;
132 fragmentation.fragmentationLength[6] = 197;
133 fragmentation.fragmentationLength[7] = 207;
134 Vp8PartitionAggregator* aggregator =
135 new Vp8PartitionAggregator(fragmentation, 0, 7);
136 aggregator->SetPriorMinMax(300, 500);
137 size_t kMaxSize = 1500;
138 size_t kPenalty = 1;
139 Vp8PartitionAggregator::ConfigVec opt_config =
140 aggregator->FindOptimalConfiguration(kMaxSize, kPenalty);
141 const size_t kExpectedConfig[] = {0, 0, 1, 1, 2, 2, 3, 3};
142 const size_t kExpectedConfigSize = GTEST_ARRAY_SIZE_(kExpectedConfig);
143 VerifyConfiguration(kExpectedConfig, kExpectedConfigSize, opt_config,
144 fragmentation);
145 VerifyMinMax(*aggregator, opt_config, 383, 428);
146 // Change min and max and run method again. This time, we expect it to leave
147 // the values unchanged.
148 int min_size = 382;
149 int max_size = 429;
150 aggregator->CalcMinMax(opt_config, &min_size, &max_size);
151 EXPECT_EQ(382, min_size);
152 EXPECT_EQ(429, max_size);
153 delete aggregator;
154 }
155
TEST(Vp8PartitionAggregator,FindOptimalConfigEqualFragments)156 TEST(Vp8PartitionAggregator, FindOptimalConfigEqualFragments) {
157 RTPFragmentationHeader fragmentation;
158 fragmentation.VerifyAndAllocateFragmentationHeader(8);
159 fragmentation.fragmentationLength[0] = 200;
160 fragmentation.fragmentationLength[1] = 200;
161 fragmentation.fragmentationLength[2] = 200;
162 fragmentation.fragmentationLength[3] = 200;
163 fragmentation.fragmentationLength[4] = 200;
164 fragmentation.fragmentationLength[5] = 200;
165 fragmentation.fragmentationLength[6] = 200;
166 fragmentation.fragmentationLength[7] = 200;
167 Vp8PartitionAggregator* aggregator =
168 new Vp8PartitionAggregator(fragmentation, 0, 7);
169 size_t kMaxSize = 1500;
170 size_t kPenalty = 1;
171 Vp8PartitionAggregator::ConfigVec opt_config =
172 aggregator->FindOptimalConfiguration(kMaxSize, kPenalty);
173 const size_t kExpectedConfig[] = {0, 0, 0, 0, 1, 1, 1, 1};
174 const size_t kExpectedConfigSize = GTEST_ARRAY_SIZE_(kExpectedConfig);
175 VerifyConfiguration(kExpectedConfig, kExpectedConfigSize, opt_config,
176 fragmentation);
177 VerifyMinMax(*aggregator, opt_config, 800, 800);
178 delete aggregator;
179 }
180
TEST(Vp8PartitionAggregator,FindOptimalConfigSinglePartition)181 TEST(Vp8PartitionAggregator, FindOptimalConfigSinglePartition) {
182 RTPFragmentationHeader fragmentation;
183 fragmentation.VerifyAndAllocateFragmentationHeader(1);
184 fragmentation.fragmentationLength[0] = 17;
185 Vp8PartitionAggregator* aggregator =
186 new Vp8PartitionAggregator(fragmentation, 0, 0);
187 size_t kMaxSize = 1500;
188 size_t kPenalty = 1;
189 Vp8PartitionAggregator::ConfigVec opt_config =
190 aggregator->FindOptimalConfiguration(kMaxSize, kPenalty);
191 const size_t kExpectedConfig[] = {0};
192 const size_t kExpectedConfigSize = GTEST_ARRAY_SIZE_(kExpectedConfig);
193 VerifyConfiguration(kExpectedConfig, kExpectedConfigSize, opt_config,
194 fragmentation);
195 VerifyMinMax(*aggregator, opt_config, 17, 17);
196 delete aggregator;
197 }
198
TEST(Vp8PartitionAggregator,TestCalcNumberOfFragments)199 TEST(Vp8PartitionAggregator, TestCalcNumberOfFragments) {
200 const int kMTU = 1500;
201 EXPECT_EQ(2u,
202 Vp8PartitionAggregator::CalcNumberOfFragments(
203 1600, kMTU, 1, 300, 900));
204 EXPECT_EQ(3u,
205 Vp8PartitionAggregator::CalcNumberOfFragments(
206 1600, kMTU, 1, 300, 798));
207 EXPECT_EQ(2u,
208 Vp8PartitionAggregator::CalcNumberOfFragments(
209 1600, kMTU, 1, 900, 1000));
210 }
211
212 } // namespace webrtc
213