Home | History | Annotate | Download | only in source
      1 /*
      2  *  Copyright (c) 2012 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 #ifndef WEBRTC_MODULES_VIDEO_CODING_MEDIA_OPT_UTIL_H_
     12 #define WEBRTC_MODULES_VIDEO_CODING_MEDIA_OPT_UTIL_H_
     13 
     14 #include <math.h>
     15 #include <stdlib.h>
     16 
     17 #include "webrtc/modules/video_coding/main/source/internal_defines.h"
     18 #include "webrtc/modules/video_coding/main/source/qm_select.h"
     19 #include "webrtc/modules/video_coding/utility/include/exp_filter.h"
     20 #include "webrtc/system_wrappers/interface/trace.h"
     21 #include "webrtc/typedefs.h"
     22 
     23 namespace webrtc {
     24 namespace media_optimization {
     25 
     26 // Number of time periods used for (max) window filter for packet loss
     27 // TODO (marpan): set reasonable window size for filtered packet loss,
     28 // adjustment should be based on logged/real data of loss stats/correlation.
     29 enum { kLossPrHistorySize = 10 };
     30 
     31 // 1000 ms, total filter length is (kLossPrHistorySize * 1000) ms
     32 enum { kLossPrShortFilterWinMs = 1000 };
     33 
     34 // The type of filter used on the received packet loss reports.
     35 enum FilterPacketLossMode {
     36   kNoFilter,    // No filtering on received loss.
     37   kAvgFilter,   // Recursive average filter.
     38   kMaxFilter    // Max-window filter, over the time interval of:
     39                 // (kLossPrHistorySize * kLossPrShortFilterWinMs) ms.
     40 };
     41 
     42 // Thresholds for hybrid NACK/FEC
     43 // common to media optimization and the jitter buffer.
     44 enum HybridNackTH {
     45     kHighRttNackMs = 100,
     46     kLowRttNackMs = 20
     47 };
     48 
     49 struct VCMProtectionParameters
     50 {
     51     VCMProtectionParameters() : rtt(0), lossPr(0.0f), bitRate(0.0f),
     52         packetsPerFrame(0.0f), packetsPerFrameKey(0.0f), frameRate(0.0f),
     53         keyFrameSize(0.0f), fecRateDelta(0), fecRateKey(0),
     54         residualPacketLossFec(0.0f), codecWidth(0), codecHeight(0),
     55         numLayers(1)
     56         {}
     57 
     58     int                 rtt;
     59     float               lossPr;
     60     float               bitRate;
     61     float               packetsPerFrame;
     62     float               packetsPerFrameKey;
     63     float               frameRate;
     64     float               keyFrameSize;
     65     uint8_t       fecRateDelta;
     66     uint8_t       fecRateKey;
     67     float               residualPacketLossFec;
     68     uint16_t      codecWidth;
     69     uint16_t      codecHeight;
     70     int                 numLayers;
     71 };
     72 
     73 
     74 /******************************/
     75 /* VCMProtectionMethod class  */
     76 /******************************/
     77 
     78 enum VCMProtectionMethodEnum
     79 {
     80     kNack,
     81     kFec,
     82     kNackFec,
     83     kNone
     84 };
     85 
     86 class VCMLossProbabilitySample
     87 {
     88 public:
     89     VCMLossProbabilitySample() : lossPr255(0), timeMs(-1) {};
     90 
     91     uint8_t     lossPr255;
     92     int64_t     timeMs;
     93 };
     94 
     95 
     96 class VCMProtectionMethod
     97 {
     98 public:
     99     VCMProtectionMethod();
    100     virtual ~VCMProtectionMethod();
    101 
    102     // Updates the efficiency of the method using the parameters provided
    103     //
    104     // Input:
    105     //         - parameters         : Parameters used to calculate efficiency
    106     //
    107     // Return value                 : True if this method is recommended in
    108     //                                the given conditions.
    109     virtual bool UpdateParameters(const VCMProtectionParameters* parameters) = 0;
    110 
    111     // Returns the protection type
    112     //
    113     // Return value                 : The protection type
    114     enum VCMProtectionMethodEnum Type() const { return _type; }
    115 
    116     // Returns the bit rate required by this protection method
    117     // during these conditions.
    118     //
    119     // Return value                 : Required bit rate
    120     virtual float RequiredBitRate() { return _efficiency; }
    121 
    122     // Returns the effective packet loss for ER, required by this protection method
    123     //
    124     // Return value                 : Required effective packet loss
    125     virtual uint8_t RequiredPacketLossER() { return _effectivePacketLoss; }
    126 
    127     // Extracts the FEC protection factor for Key frame, required by this protection method
    128     //
    129     // Return value                 : Required protectionFactor for Key frame
    130     virtual uint8_t RequiredProtectionFactorK() { return _protectionFactorK; }
    131 
    132     // Extracts the FEC protection factor for Delta frame, required by this protection method
    133     //
    134     // Return value                 : Required protectionFactor for delta frame
    135     virtual uint8_t RequiredProtectionFactorD() { return _protectionFactorD; }
    136 
    137     // Extracts whether the FEC Unequal protection (UEP) is used for Key frame.
    138     //
    139     // Return value                 : Required Unequal protection on/off state.
    140     virtual bool RequiredUepProtectionK() { return _useUepProtectionK; }
    141 
    142     // Extracts whether the the FEC Unequal protection (UEP) is used for Delta frame.
    143     //
    144     // Return value                 : Required Unequal protection on/off state.
    145     virtual bool RequiredUepProtectionD() { return _useUepProtectionD; }
    146 
    147     virtual int MaxFramesFec() const { return 1; }
    148 
    149     // Updates content metrics
    150     void UpdateContentMetrics(const VideoContentMetrics* contentMetrics);
    151 
    152 protected:
    153 
    154     uint8_t                        _effectivePacketLoss;
    155     uint8_t                        _protectionFactorK;
    156     uint8_t                        _protectionFactorD;
    157     // Estimation of residual loss after the FEC
    158     float                                _residualPacketLossFec;
    159     float                                _scaleProtKey;
    160     int32_t                        _maxPayloadSize;
    161 
    162     VCMQmRobustness*                     _qmRobustness;
    163     bool                                 _useUepProtectionK;
    164     bool                                 _useUepProtectionD;
    165     float                                _corrFecCost;
    166     enum VCMProtectionMethodEnum         _type;
    167     float                                _efficiency;
    168 };
    169 
    170 class VCMNackMethod : public VCMProtectionMethod
    171 {
    172 public:
    173     VCMNackMethod();
    174     virtual ~VCMNackMethod();
    175     virtual bool UpdateParameters(const VCMProtectionParameters* parameters);
    176     // Get the effective packet loss
    177     bool EffectivePacketLoss(const VCMProtectionParameters* parameter);
    178 };
    179 
    180 class VCMFecMethod : public VCMProtectionMethod
    181 {
    182 public:
    183     VCMFecMethod();
    184     virtual ~VCMFecMethod();
    185     virtual bool UpdateParameters(const VCMProtectionParameters* parameters);
    186     // Get the effective packet loss for ER
    187     bool EffectivePacketLoss(const VCMProtectionParameters* parameters);
    188     // Get the FEC protection factors
    189     bool ProtectionFactor(const VCMProtectionParameters* parameters);
    190     // Get the boost for key frame protection
    191     uint8_t BoostCodeRateKey(uint8_t packetFrameDelta,
    192                                    uint8_t packetFrameKey) const;
    193     // Convert the rates: defined relative to total# packets or source# packets
    194     uint8_t ConvertFECRate(uint8_t codeRate) const;
    195     // Get the average effective recovery from FEC: for random loss model
    196     float AvgRecoveryFEC(const VCMProtectionParameters* parameters) const;
    197     // Update FEC with protectionFactorD
    198     void UpdateProtectionFactorD(uint8_t protectionFactorD);
    199     // Update FEC with protectionFactorK
    200     void UpdateProtectionFactorK(uint8_t protectionFactorK);
    201     // Compute the bits per frame. Account for temporal layers when applicable.
    202     int BitsPerFrame(const VCMProtectionParameters* parameters);
    203 
    204 protected:
    205     enum { kUpperLimitFramesFec = 6 };
    206     // Thresholds values for the bytes/frame and round trip time, below which we
    207     // may turn off FEC, depending on |_numLayers| and |_maxFramesFec|.
    208     // Max bytes/frame for VGA, corresponds to ~140k at 25fps.
    209     enum { kMaxBytesPerFrameForFec = 700 };
    210     // Max bytes/frame for CIF and lower: corresponds to ~80k at 25fps.
    211     enum { kMaxBytesPerFrameForFecLow = 400 };
    212     // Max bytes/frame for frame size larger than VGA, ~200k at 25fps.
    213     enum { kMaxBytesPerFrameForFecHigh = 1000 };
    214     // Max round trip time threshold in ms.
    215     enum { kMaxRttTurnOffFec = 200 };
    216 };
    217 
    218 
    219 class VCMNackFecMethod : public VCMFecMethod
    220 {
    221 public:
    222     VCMNackFecMethod(int lowRttNackThresholdMs,
    223                      int highRttNackThresholdMs);
    224     virtual ~VCMNackFecMethod();
    225     virtual bool UpdateParameters(const VCMProtectionParameters* parameters);
    226     // Get the effective packet loss for ER
    227     bool EffectivePacketLoss(const VCMProtectionParameters* parameters);
    228     // Get the protection factors
    229     bool ProtectionFactor(const VCMProtectionParameters* parameters);
    230     // Get the max number of frames the FEC is allowed to be based on.
    231     int MaxFramesFec() const;
    232     // Turn off the FEC based on low bitrate and other factors.
    233     bool BitRateTooLowForFec(const VCMProtectionParameters* parameters);
    234 private:
    235     int ComputeMaxFramesFec(const VCMProtectionParameters* parameters);
    236 
    237     int _lowRttNackMs;
    238     int _highRttNackMs;
    239     int _maxFramesFec;
    240 };
    241 
    242 class VCMLossProtectionLogic
    243 {
    244 public:
    245     VCMLossProtectionLogic(int64_t nowMs);
    246     ~VCMLossProtectionLogic();
    247 
    248     // Set the protection method to be used
    249     //
    250     // Input:
    251     //        - newMethodType    : New requested protection method type. If one
    252     //                           is already set, it will be deleted and replaced
    253     // Return value:             Returns true on update
    254     bool SetMethod(VCMProtectionMethodEnum newMethodType);
    255 
    256     // Remove requested protection method
    257     // Input:
    258     //        - method          : method to be removed (if currently selected)
    259     //
    260     // Return value:             Returns true on update
    261     bool RemoveMethod(VCMProtectionMethodEnum method);
    262 
    263     // Return required bit rate per selected protectin method
    264     float RequiredBitRate() const;
    265 
    266     // Update the round-trip time
    267     //
    268     // Input:
    269     //          - rtt           : Round-trip time in seconds.
    270     void UpdateRtt(uint32_t rtt);
    271 
    272     // Update residual packet loss
    273     //
    274     // Input:
    275     //          - residualPacketLoss  : residual packet loss:
    276     //                                  effective loss after FEC recovery
    277     void UpdateResidualPacketLoss(float _residualPacketLoss);
    278 
    279     // Update the filtered packet loss.
    280     //
    281     // Input:
    282     //          - packetLossEnc :  The reported packet loss filtered
    283     //                             (max window or average)
    284     void UpdateFilteredLossPr(uint8_t packetLossEnc);
    285 
    286     // Update the current target bit rate.
    287     //
    288     // Input:
    289     //          - bitRate          : The current target bit rate in kbits/s
    290     void UpdateBitRate(float bitRate);
    291 
    292     // Update the number of packets per frame estimate, for delta frames
    293     //
    294     // Input:
    295     //          - nPackets         : Number of packets in the latest sent frame.
    296     void UpdatePacketsPerFrame(float nPackets, int64_t nowMs);
    297 
    298    // Update the number of packets per frame estimate, for key frames
    299     //
    300     // Input:
    301     //          - nPackets         : umber of packets in the latest sent frame.
    302     void UpdatePacketsPerFrameKey(float nPackets, int64_t nowMs);
    303 
    304     // Update the keyFrameSize estimate
    305     //
    306     // Input:
    307     //          - keyFrameSize     : The size of the latest sent key frame.
    308     void UpdateKeyFrameSize(float keyFrameSize);
    309 
    310     // Update the frame rate
    311     //
    312     // Input:
    313     //          - frameRate        : The current target frame rate.
    314     void UpdateFrameRate(float frameRate) { _frameRate = frameRate; }
    315 
    316     // Update the frame size
    317     //
    318     // Input:
    319     //          - width        : The codec frame width.
    320     //          - height       : The codec frame height.
    321     void UpdateFrameSize(uint16_t width, uint16_t height);
    322 
    323     // Update the number of active layers
    324     //
    325     // Input:
    326     //          - numLayers    : Number of layers used.
    327     void UpdateNumLayers(int numLayers);
    328 
    329     // The amount of packet loss to cover for with FEC.
    330     //
    331     // Input:
    332     //          - fecRateKey      : Packet loss to cover for with FEC when
    333     //                              sending key frames.
    334     //          - fecRateDelta    : Packet loss to cover for with FEC when
    335     //                              sending delta frames.
    336     void UpdateFECRates(uint8_t fecRateKey, uint8_t fecRateDelta)
    337                        { _fecRateKey = fecRateKey;
    338                          _fecRateDelta = fecRateDelta; }
    339 
    340     // Update the protection methods with the current VCMProtectionParameters
    341     // and set the requested protection settings.
    342     // Return value     : Returns true on update
    343     bool UpdateMethod();
    344 
    345     // Returns the method currently selected.
    346     //
    347     // Return value                 : The protection method currently selected.
    348     VCMProtectionMethod* SelectedMethod() const;
    349 
    350     // Return the protection type of the currently selected method
    351     VCMProtectionMethodEnum SelectedType() const;
    352 
    353     // Updates the filtered loss for the average and max window packet loss,
    354     // and returns the filtered loss probability in the interval [0, 255].
    355     // The returned filtered loss value depends on the parameter |filter_mode|.
    356     // The input parameter |lossPr255| is the received packet loss.
    357 
    358     // Return value                 : The filtered loss probability
    359     uint8_t FilteredLoss(int64_t nowMs, FilterPacketLossMode filter_mode,
    360                                uint8_t lossPr255);
    361 
    362     void Reset(int64_t nowMs);
    363 
    364     void Release();
    365 
    366 private:
    367     // Sets the available loss protection methods.
    368     void UpdateMaxLossHistory(uint8_t lossPr255, int64_t now);
    369     uint8_t MaxFilteredLossPr(int64_t nowMs) const;
    370     VCMProtectionMethod*      _selectedMethod;
    371     VCMProtectionParameters   _currentParameters;
    372     uint32_t            _rtt;
    373     float                     _lossPr;
    374     float                     _bitRate;
    375     float                     _frameRate;
    376     float                     _keyFrameSize;
    377     uint8_t             _fecRateKey;
    378     uint8_t             _fecRateDelta;
    379     int64_t             _lastPrUpdateT;
    380     int64_t             _lastPacketPerFrameUpdateT;
    381     int64_t             _lastPacketPerFrameUpdateTKey;
    382     VCMExpFilter              _lossPr255;
    383     VCMLossProbabilitySample  _lossPrHistory[kLossPrHistorySize];
    384     uint8_t             _shortMaxLossPr255;
    385     VCMExpFilter              _packetsPerFrame;
    386     VCMExpFilter              _packetsPerFrameKey;
    387     float                     _residualPacketLossFec;
    388     uint16_t            _codecWidth;
    389     uint16_t            _codecHeight;
    390     int                       _numLayers;
    391 };
    392 
    393 }  // namespace media_optimization
    394 }  // namespace webrtc
    395 
    396 #endif // WEBRTC_MODULES_VIDEO_CODING_MEDIA_OPT_UTIL_H_
    397