1 /*
2  *  Copyright (c) 2016 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 "api/fec_controller.h"
12 
13 #include <stdint.h>
14 
15 #include <vector>
16 
17 #include "modules/include/module_fec_types.h"
18 #include "modules/video_coding/fec_controller_default.h"
19 #include "system_wrappers/include/clock.h"
20 #include "test/gtest.h"
21 
22 namespace webrtc {
23 
24 static const int kCodecBitrateBps = 100000;
25 
26 class ProtectionBitrateCalculatorTest : public ::testing::Test {
27  protected:
28   enum {
29     kSampleRate = 90000  // RTP timestamps per second.
30   };
31 
32   class ProtectionCallback : public VCMProtectionCallback {
33    public:
ProtectionRequest(const FecProtectionParams * delta_params,const FecProtectionParams * key_params,uint32_t * sent_video_rate_bps,uint32_t * sent_nack_rate_bps,uint32_t * sent_fec_rate_bps)34     int ProtectionRequest(const FecProtectionParams* delta_params,
35                           const FecProtectionParams* key_params,
36                           uint32_t* sent_video_rate_bps,
37                           uint32_t* sent_nack_rate_bps,
38                           uint32_t* sent_fec_rate_bps) override {
39       *sent_video_rate_bps = kCodecBitrateBps;
40       *sent_nack_rate_bps = nack_rate_bps_;
41       *sent_fec_rate_bps = fec_rate_bps_;
42       return 0;
43     }
44 
45     uint32_t fec_rate_bps_ = 0;
46     uint32_t nack_rate_bps_ = 0;
47   };
48 
49   // Note: simulated clock starts at 1 seconds, since parts of webrtc use 0 as
50   // a special case (e.g. frame rate in media optimization).
ProtectionBitrateCalculatorTest()51   ProtectionBitrateCalculatorTest()
52       : clock_(1000), fec_controller_(&clock_, &protection_callback_) {}
53 
54   SimulatedClock clock_;
55   ProtectionCallback protection_callback_;
56   FecControllerDefault fec_controller_;
57 };
58 
TEST_F(ProtectionBitrateCalculatorTest,ProtectsUsingFecBitrate)59 TEST_F(ProtectionBitrateCalculatorTest, ProtectsUsingFecBitrate) {
60   static const uint32_t kMaxBitrateBps = 130000;
61 
62   fec_controller_.SetProtectionMethod(true /*enable_fec*/,
63                                       false /* enable_nack */);
64   fec_controller_.SetEncodingData(640, 480, 1, 1000);
65 
66   // Using 10% of codec bitrate for FEC.
67   protection_callback_.fec_rate_bps_ = kCodecBitrateBps / 10;
68   uint32_t target_bitrate = fec_controller_.UpdateFecRates(
69       kMaxBitrateBps, 30, 0, std::vector<bool>(1, false), 0);
70 
71   EXPECT_GT(target_bitrate, 0u);
72   EXPECT_GT(kMaxBitrateBps, target_bitrate);
73 
74   // Using as much for codec bitrate as fec rate, new target rate should share
75   // both equally, but only be half of max (since that ceiling should be hit).
76   protection_callback_.fec_rate_bps_ = kCodecBitrateBps;
77   target_bitrate = fec_controller_.UpdateFecRates(
78       kMaxBitrateBps, 30, 128, std::vector<bool>(1, false), 100);
79   EXPECT_EQ(kMaxBitrateBps / 2, target_bitrate);
80 }
81 
TEST_F(ProtectionBitrateCalculatorTest,ProtectsUsingNackBitrate)82 TEST_F(ProtectionBitrateCalculatorTest, ProtectsUsingNackBitrate) {
83   static const uint32_t kMaxBitrateBps = 130000;
84 
85   fec_controller_.SetProtectionMethod(false /*enable_fec*/,
86                                       true /* enable_nack */);
87   fec_controller_.SetEncodingData(640, 480, 1, 1000);
88 
89   uint32_t target_bitrate = fec_controller_.UpdateFecRates(
90       kMaxBitrateBps, 30, 0, std::vector<bool>(1, false), 0);
91 
92   EXPECT_EQ(kMaxBitrateBps, target_bitrate);
93 
94   // Using as much for codec bitrate as nack rate, new target rate should share
95   // both equally, but only be half of max (since that ceiling should be hit).
96   protection_callback_.nack_rate_bps_ = kMaxBitrateBps;
97   target_bitrate = fec_controller_.UpdateFecRates(
98       kMaxBitrateBps, 30, 128, std::vector<bool>(1, false), 100);
99   EXPECT_EQ(kMaxBitrateBps / 2, target_bitrate);
100 }
101 
TEST_F(ProtectionBitrateCalculatorTest,NoProtection)102 TEST_F(ProtectionBitrateCalculatorTest, NoProtection) {
103   static const uint32_t kMaxBitrateBps = 130000;
104 
105   fec_controller_.SetProtectionMethod(false /*enable_fec*/,
106                                       false /* enable_nack */);
107   fec_controller_.SetEncodingData(640, 480, 1, 1000);
108 
109   uint32_t target_bitrate = fec_controller_.UpdateFecRates(
110       kMaxBitrateBps, 30, 128, std::vector<bool>(1, false), 100);
111   EXPECT_EQ(kMaxBitrateBps, target_bitrate);
112 }
113 
114 }  // namespace webrtc
115