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