| /* | |
| * Copyright (c) 2012 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. | |
| */ | |
| #ifndef MODULES_VIDEO_CODING_MEDIA_OPT_UTIL_H_ | |
| #define MODULES_VIDEO_CODING_MEDIA_OPT_UTIL_H_ | |
| #include <math.h> | |
| #include <stdlib.h> | |
| #include <memory> | |
| #include "modules/video_coding/internal_defines.h" | |
| #include "rtc_base/numerics/exp_filter.h" | |
| #include "typedefs.h" // NOLINT(build/include) | |
| namespace webrtc { | |
| namespace media_optimization { | |
| // Number of time periods used for (max) window filter for packet loss | |
| // TODO(marpan): set reasonable window size for filtered packet loss, | |
| // adjustment should be based on logged/real data of loss stats/correlation. | |
| enum { kLossPrHistorySize = 10 }; | |
| // 1000 ms, total filter length is (kLossPrHistorySize * 1000) ms | |
| enum { kLossPrShortFilterWinMs = 1000 }; | |
| // The type of filter used on the received packet loss reports. | |
| enum FilterPacketLossMode { | |
| kNoFilter, // No filtering on received loss. | |
| kAvgFilter, // Recursive average filter. | |
| kMaxFilter // Max-window filter, over the time interval of: | |
| // (kLossPrHistorySize * kLossPrShortFilterWinMs) ms. | |
| }; | |
| // Thresholds for hybrid NACK/FEC | |
| // common to media optimization and the jitter buffer. | |
| const int64_t kLowRttNackMs = 20; | |
| // If the RTT is higher than this an extra RTT wont be added to to the jitter | |
| // buffer delay. | |
| const int kMaxRttDelayThreshold = 500; | |
| struct VCMProtectionParameters { | |
| VCMProtectionParameters() | |
| : rtt(0), | |
| lossPr(0.0f), | |
| bitRate(0.0f), | |
| packetsPerFrame(0.0f), | |
| packetsPerFrameKey(0.0f), | |
| frameRate(0.0f), | |
| keyFrameSize(0.0f), | |
| fecRateDelta(0), | |
| fecRateKey(0), | |
| codecWidth(0), | |
| codecHeight(0), | |
| numLayers(1) {} | |
| int64_t rtt; | |
| float lossPr; | |
| float bitRate; | |
| float packetsPerFrame; | |
| float packetsPerFrameKey; | |
| float frameRate; | |
| float keyFrameSize; | |
| uint8_t fecRateDelta; | |
| uint8_t fecRateKey; | |
| uint16_t codecWidth; | |
| uint16_t codecHeight; | |
| int numLayers; | |
| }; | |
| /******************************/ | |
| /* VCMProtectionMethod class */ | |
| /******************************/ | |
| enum VCMProtectionMethodEnum { kNack, kFec, kNackFec, kNone }; | |
| class VCMLossProbabilitySample { | |
| public: | |
| VCMLossProbabilitySample() : lossPr255(0), timeMs(-1) {} | |
| uint8_t lossPr255; | |
| int64_t timeMs; | |
| }; | |
| class VCMProtectionMethod { | |
| public: | |
| VCMProtectionMethod(); | |
| virtual ~VCMProtectionMethod(); | |
| // Updates the efficiency of the method using the parameters provided | |
| // | |
| // Input: | |
| // - parameters : Parameters used to calculate efficiency | |
| // | |
| // Return value : True if this method is recommended in | |
| // the given conditions. | |
| virtual bool UpdateParameters(const VCMProtectionParameters* parameters) = 0; | |
| // Returns the protection type | |
| // | |
| // Return value : The protection type | |
| enum VCMProtectionMethodEnum Type() const { return _type; } | |
| // Returns the effective packet loss for ER, required by this protection | |
| // method | |
| // | |
| // Return value : Required effective packet loss | |
| virtual uint8_t RequiredPacketLossER() { return _effectivePacketLoss; } | |
| // Extracts the FEC protection factor for Key frame, required by this | |
| // protection method | |
| // | |
| // Return value : Required protectionFactor for Key frame | |
| virtual uint8_t RequiredProtectionFactorK() { return _protectionFactorK; } | |
| // Extracts the FEC protection factor for Delta frame, required by this | |
| // protection method | |
| // | |
| // Return value : Required protectionFactor for delta frame | |
| virtual uint8_t RequiredProtectionFactorD() { return _protectionFactorD; } | |
| // Extracts whether the FEC Unequal protection (UEP) is used for Key frame. | |
| // | |
| // Return value : Required Unequal protection on/off state. | |
| virtual bool RequiredUepProtectionK() { return _useUepProtectionK; } | |
| // Extracts whether the the FEC Unequal protection (UEP) is used for Delta | |
| // frame. | |
| // | |
| // Return value : Required Unequal protection on/off state. | |
| virtual bool RequiredUepProtectionD() { return _useUepProtectionD; } | |
| virtual int MaxFramesFec() const { return 1; } | |
| protected: | |
| uint8_t _effectivePacketLoss; | |
| uint8_t _protectionFactorK; | |
| uint8_t _protectionFactorD; | |
| // Estimation of residual loss after the FEC | |
| float _scaleProtKey; | |
| int32_t _maxPayloadSize; | |
| bool _useUepProtectionK; | |
| bool _useUepProtectionD; | |
| float _corrFecCost; | |
| enum VCMProtectionMethodEnum _type; | |
| }; | |
| class VCMNackMethod : public VCMProtectionMethod { | |
| public: | |
| VCMNackMethod(); | |
| virtual ~VCMNackMethod(); | |
| virtual bool UpdateParameters(const VCMProtectionParameters* parameters); | |
| // Get the effective packet loss | |
| bool EffectivePacketLoss(const VCMProtectionParameters* parameter); | |
| }; | |
| class VCMFecMethod : public VCMProtectionMethod { | |
| public: | |
| VCMFecMethod(); | |
| virtual ~VCMFecMethod(); | |
| virtual bool UpdateParameters(const VCMProtectionParameters* parameters); | |
| // Get the effective packet loss for ER | |
| bool EffectivePacketLoss(const VCMProtectionParameters* parameters); | |
| // Get the FEC protection factors | |
| bool ProtectionFactor(const VCMProtectionParameters* parameters); | |
| // Get the boost for key frame protection | |
| uint8_t BoostCodeRateKey(uint8_t packetFrameDelta, | |
| uint8_t packetFrameKey) const; | |
| // Convert the rates: defined relative to total# packets or source# packets | |
| uint8_t ConvertFECRate(uint8_t codeRate) const; | |
| // Get the average effective recovery from FEC: for random loss model | |
| float AvgRecoveryFEC(const VCMProtectionParameters* parameters) const; | |
| // Update FEC with protectionFactorD | |
| void UpdateProtectionFactorD(uint8_t protectionFactorD); | |
| // Update FEC with protectionFactorK | |
| void UpdateProtectionFactorK(uint8_t protectionFactorK); | |
| // Compute the bits per frame. Account for temporal layers when applicable. | |
| int BitsPerFrame(const VCMProtectionParameters* parameters); | |
| protected: | |
| enum { kUpperLimitFramesFec = 6 }; | |
| // Thresholds values for the bytes/frame and round trip time, below which we | |
| // may turn off FEC, depending on |_numLayers| and |_maxFramesFec|. | |
| // Max bytes/frame for VGA, corresponds to ~140k at 25fps. | |
| enum { kMaxBytesPerFrameForFec = 700 }; | |
| // Max bytes/frame for CIF and lower: corresponds to ~80k at 25fps. | |
| enum { kMaxBytesPerFrameForFecLow = 400 }; | |
| // Max bytes/frame for frame size larger than VGA, ~200k at 25fps. | |
| enum { kMaxBytesPerFrameForFecHigh = 1000 }; | |
| }; | |
| class VCMNackFecMethod : public VCMFecMethod { | |
| public: | |
| VCMNackFecMethod(int64_t lowRttNackThresholdMs, | |
| int64_t highRttNackThresholdMs); | |
| virtual ~VCMNackFecMethod(); | |
| virtual bool UpdateParameters(const VCMProtectionParameters* parameters); | |
| // Get the effective packet loss for ER | |
| bool EffectivePacketLoss(const VCMProtectionParameters* parameters); | |
| // Get the protection factors | |
| bool ProtectionFactor(const VCMProtectionParameters* parameters); | |
| // Get the max number of frames the FEC is allowed to be based on. | |
| int MaxFramesFec() const; | |
| // Turn off the FEC based on low bitrate and other factors. | |
| bool BitRateTooLowForFec(const VCMProtectionParameters* parameters); | |
| private: | |
| int ComputeMaxFramesFec(const VCMProtectionParameters* parameters); | |
| int64_t _lowRttNackMs; | |
| int64_t _highRttNackMs; | |
| int _maxFramesFec; | |
| }; | |
| class VCMLossProtectionLogic { | |
| public: | |
| explicit VCMLossProtectionLogic(int64_t nowMs); | |
| ~VCMLossProtectionLogic(); | |
| // Set the protection method to be used | |
| // | |
| // Input: | |
| // - newMethodType : New requested protection method type. If one | |
| // is already set, it will be deleted and replaced | |
| void SetMethod(VCMProtectionMethodEnum newMethodType); | |
| // Update the round-trip time | |
| // | |
| // Input: | |
| // - rtt : Round-trip time in seconds. | |
| void UpdateRtt(int64_t rtt); | |
| // Update the filtered packet loss. | |
| // | |
| // Input: | |
| // - packetLossEnc : The reported packet loss filtered | |
| // (max window or average) | |
| void UpdateFilteredLossPr(uint8_t packetLossEnc); | |
| // Update the current target bit rate. | |
| // | |
| // Input: | |
| // - bitRate : The current target bit rate in kbits/s | |
| void UpdateBitRate(float bitRate); | |
| // Update the number of packets per frame estimate, for delta frames | |
| // | |
| // Input: | |
| // - nPackets : Number of packets in the latest sent frame. | |
| void UpdatePacketsPerFrame(float nPackets, int64_t nowMs); | |
| // Update the number of packets per frame estimate, for key frames | |
| // | |
| // Input: | |
| // - nPackets : umber of packets in the latest sent frame. | |
| void UpdatePacketsPerFrameKey(float nPackets, int64_t nowMs); | |
| // Update the keyFrameSize estimate | |
| // | |
| // Input: | |
| // - keyFrameSize : The size of the latest sent key frame. | |
| void UpdateKeyFrameSize(float keyFrameSize); | |
| // Update the frame rate | |
| // | |
| // Input: | |
| // - frameRate : The current target frame rate. | |
| void UpdateFrameRate(float frameRate) { _frameRate = frameRate; } | |
| // Update the frame size | |
| // | |
| // Input: | |
| // - width : The codec frame width. | |
| // - height : The codec frame height. | |
| void UpdateFrameSize(size_t width, size_t height); | |
| // Update the number of active layers | |
| // | |
| // Input: | |
| // - numLayers : Number of layers used. | |
| void UpdateNumLayers(int numLayers); | |
| // The amount of packet loss to cover for with FEC. | |
| // | |
| // Input: | |
| // - fecRateKey : Packet loss to cover for with FEC when | |
| // sending key frames. | |
| // - fecRateDelta : Packet loss to cover for with FEC when | |
| // sending delta frames. | |
| void UpdateFECRates(uint8_t fecRateKey, uint8_t fecRateDelta) { | |
| _fecRateKey = fecRateKey; | |
| _fecRateDelta = fecRateDelta; | |
| } | |
| // Update the protection methods with the current VCMProtectionParameters | |
| // and set the requested protection settings. | |
| // Return value : Returns true on update | |
| bool UpdateMethod(); | |
| // Returns the method currently selected. | |
| // | |
| // Return value : The protection method currently selected. | |
| VCMProtectionMethod* SelectedMethod() const; | |
| // Return the protection type of the currently selected method | |
| VCMProtectionMethodEnum SelectedType() const; | |
| // Updates the filtered loss for the average and max window packet loss, | |
| // and returns the filtered loss probability in the interval [0, 255]. | |
| // The returned filtered loss value depends on the parameter |filter_mode|. | |
| // The input parameter |lossPr255| is the received packet loss. | |
| // Return value : The filtered loss probability | |
| uint8_t FilteredLoss(int64_t nowMs, | |
| FilterPacketLossMode filter_mode, | |
| uint8_t lossPr255); | |
| void Reset(int64_t nowMs); | |
| void Release(); | |
| private: | |
| // Sets the available loss protection methods. | |
| void UpdateMaxLossHistory(uint8_t lossPr255, int64_t now); | |
| uint8_t MaxFilteredLossPr(int64_t nowMs) const; | |
| std::unique_ptr<VCMProtectionMethod> _selectedMethod; | |
| VCMProtectionParameters _currentParameters; | |
| int64_t _rtt; | |
| float _lossPr; | |
| float _bitRate; | |
| float _frameRate; | |
| float _keyFrameSize; | |
| uint8_t _fecRateKey; | |
| uint8_t _fecRateDelta; | |
| int64_t _lastPrUpdateT; | |
| int64_t _lastPacketPerFrameUpdateT; | |
| int64_t _lastPacketPerFrameUpdateTKey; | |
| rtc::ExpFilter _lossPr255; | |
| VCMLossProbabilitySample _lossPrHistory[kLossPrHistorySize]; | |
| uint8_t _shortMaxLossPr255; | |
| rtc::ExpFilter _packetsPerFrame; | |
| rtc::ExpFilter _packetsPerFrameKey; | |
| size_t _codecWidth; | |
| size_t _codecHeight; | |
| int _numLayers; | |
| }; | |
| } // namespace media_optimization | |
| } // namespace webrtc | |
| #endif // MODULES_VIDEO_CODING_MEDIA_OPT_UTIL_H_ |