| /* | |
| * Copyright (c) 2016 The WebRTC project authors. All Rights Reserved. | |
| * | |
| * Use of this source code is governed by a BSD-style license | |
| * that can be found in the LICENSE file in the root of the source | |
| * tree. An additional intellectual property rights grant can be found | |
| * in the file PATENTS. All contributing project authors may | |
| * be found in the AUTHORS file in the root of the source tree. | |
| */ | |
| #include "api/fec_controller.h" | |
| #include <cstdint> | |
| #include <vector> | |
| #include "modules/include/module_fec_types.h" | |
| #include "modules/video_coding/fec_controller_default.h" | |
| #include "system_wrappers/include/clock.h" | |
| #include "test/create_test_environment.h" | |
| #include "test/gtest.h" | |
| namespace webrtc { | |
| static const int kCodecBitrateBps = 100000; | |
| class ProtectionBitrateCalculatorTest : public ::testing::Test { | |
| protected: | |
| enum { | |
| kSampleRate = 90000 // RTP timestamps per second. | |
| }; | |
| class ProtectionCallback : public VCMProtectionCallback { | |
| public: | |
| int 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) override { | |
| *sent_video_rate_bps = kCodecBitrateBps; | |
| *sent_nack_rate_bps = nack_rate_bps_; | |
| *sent_fec_rate_bps = fec_rate_bps_; | |
| return 0; | |
| } | |
| void SetRetransmissionMode(int /* retransmission_mode */) override {} | |
| uint32_t fec_rate_bps_ = 0; | |
| uint32_t nack_rate_bps_ = 0; | |
| }; | |
| // Note: simulated clock starts at 1 seconds, since parts of webrtc use 0 as | |
| // a special case (e.g. frame rate in media optimization). | |
| ProtectionBitrateCalculatorTest() | |
| : clock_(1000), | |
| fec_controller_(CreateTestEnvironment({.time = &clock_}), | |
| &protection_callback_) {} | |
| SimulatedClock clock_; | |
| ProtectionCallback protection_callback_; | |
| FecControllerDefault fec_controller_; | |
| }; | |
| TEST_F(ProtectionBitrateCalculatorTest, ProtectsUsingFecBitrate) { | |
| static const uint32_t kMaxBitrateBps = 130000; | |
| fec_controller_.SetProtectionMethod(true /*enable_fec*/, | |
| false /* enable_nack */); | |
| fec_controller_.SetEncodingData(640, 480, 1, 1000); | |
| // Using 10% of codec bitrate for FEC. | |
| protection_callback_.fec_rate_bps_ = kCodecBitrateBps / 10; | |
| uint32_t target_bitrate = fec_controller_.UpdateFecRates( | |
| kMaxBitrateBps, 30, 0, std::vector<bool>(1, false), 0); | |
| EXPECT_GT(target_bitrate, 0u); | |
| EXPECT_GT(kMaxBitrateBps, target_bitrate); | |
| // Using as much for codec bitrate as fec rate, new target rate should share | |
| // both equally, but only be half of max (since that ceiling should be hit). | |
| protection_callback_.fec_rate_bps_ = kCodecBitrateBps; | |
| target_bitrate = fec_controller_.UpdateFecRates( | |
| kMaxBitrateBps, 30, 128, std::vector<bool>(1, false), 100); | |
| EXPECT_EQ(kMaxBitrateBps / 2, target_bitrate); | |
| } | |
| TEST_F(ProtectionBitrateCalculatorTest, ProtectsUsingNackBitrate) { | |
| static const uint32_t kMaxBitrateBps = 130000; | |
| fec_controller_.SetProtectionMethod(false /*enable_fec*/, | |
| true /* enable_nack */); | |
| fec_controller_.SetEncodingData(640, 480, 1, 1000); | |
| uint32_t target_bitrate = fec_controller_.UpdateFecRates( | |
| kMaxBitrateBps, 30, 0, std::vector<bool>(1, false), 0); | |
| EXPECT_EQ(kMaxBitrateBps, target_bitrate); | |
| // Using as much for codec bitrate as nack rate, new target rate should share | |
| // both equally, but only be half of max (since that ceiling should be hit). | |
| protection_callback_.nack_rate_bps_ = kMaxBitrateBps; | |
| target_bitrate = fec_controller_.UpdateFecRates( | |
| kMaxBitrateBps, 30, 128, std::vector<bool>(1, false), 100); | |
| EXPECT_EQ(kMaxBitrateBps / 2, target_bitrate); | |
| } | |
| TEST_F(ProtectionBitrateCalculatorTest, NoProtection) { | |
| static const uint32_t kMaxBitrateBps = 130000; | |
| fec_controller_.SetProtectionMethod(false /*enable_fec*/, | |
| false /* enable_nack */); | |
| fec_controller_.SetEncodingData(640, 480, 1, 1000); | |
| uint32_t target_bitrate = fec_controller_.UpdateFecRates( | |
| kMaxBitrateBps, 30, 128, std::vector<bool>(1, false), 100); | |
| EXPECT_EQ(kMaxBitrateBps, target_bitrate); | |
| } | |
| } // namespace webrtc |