Home | History | Annotate | Download | only in source
      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 
     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 
     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 
     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 
     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 
     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 
    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 
    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 
    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 
    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 
    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 
    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