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