blob: 1501f72ef680d0bdf0ae8f17607ba6f58a8fdf64 [file] [log] [blame]
niklase@google.com470e71d2011-07-07 08:21:25 +00001/*
stefan@webrtc.org8fe03af2012-01-23 14:56:14 +00002 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
niklase@google.com470e71d2011-07-07 08:21:25 +00003 *
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
pbos@webrtc.org12dc1a32013-08-05 16:22:53 +000014#include <math.h>
15#include <stdlib.h>
niklase@google.com470e71d2011-07-07 08:21:25 +000016
kwiberg3f55dea2016-02-29 05:51:59 -080017#include <memory>
18
minyue@webrtc.org74aaf292014-07-16 21:28:26 +000019#include "webrtc/base/exp_filter.h"
Henrik Kjellander2557b862015-11-18 22:00:21 +010020#include "webrtc/modules/video_coding/internal_defines.h"
21#include "webrtc/modules/video_coding/qm_select.h"
Henrik Kjellander98f53512015-10-28 18:17:40 +010022#include "webrtc/system_wrappers/include/trace.h"
stefan@webrtc.orgeb917922013-02-18 14:40:18 +000023#include "webrtc/typedefs.h"
niklase@google.com470e71d2011-07-07 08:21:25 +000024
stefan@webrtc.orga64300a2013-03-04 15:24:40 +000025namespace webrtc {
26namespace media_optimization {
27
marpan@google.com30ecda12011-09-09 17:15:12 +000028// Number of time periods used for (max) window filter for packet loss
philipel9d3ab612015-12-21 04:12:39 -080029// TODO(marpan): set reasonable window size for filtered packet loss,
marpan@google.com30ecda12011-09-09 17:15:12 +000030// adjustment should be based on logged/real data of loss stats/correlation.
31enum { kLossPrHistorySize = 10 };
32
33// 1000 ms, total filter length is (kLossPrHistorySize * 1000) ms
mikhal@google.comb29d9402011-08-01 16:39:20 +000034enum { kLossPrShortFilterWinMs = 1000 };
niklase@google.com470e71d2011-07-07 08:21:25 +000035
marpan@webrtc.org2dad3fb2012-01-09 18:18:36 +000036// The type of filter used on the received packet loss reports.
37enum FilterPacketLossMode {
philipel9d3ab612015-12-21 04:12:39 -080038 kNoFilter, // No filtering on received loss.
39 kAvgFilter, // Recursive average filter.
40 kMaxFilter // Max-window filter, over the time interval of:
41 // (kLossPrHistorySize * kLossPrShortFilterWinMs) ms.
marpan@webrtc.org2dad3fb2012-01-09 18:18:36 +000042};
43
niklase@google.com470e71d2011-07-07 08:21:25 +000044// Thresholds for hybrid NACK/FEC
45// common to media optimization and the jitter buffer.
pkasting@chromium.org16825b12015-01-12 21:51:21 +000046const int64_t kLowRttNackMs = 20;
niklase@google.com470e71d2011-07-07 08:21:25 +000047
philipel9d3ab612015-12-21 04:12:39 -080048struct VCMProtectionParameters {
49 VCMProtectionParameters()
50 : rtt(0),
51 lossPr(0.0f),
52 bitRate(0.0f),
53 packetsPerFrame(0.0f),
54 packetsPerFrameKey(0.0f),
55 frameRate(0.0f),
56 keyFrameSize(0.0f),
57 fecRateDelta(0),
58 fecRateKey(0),
59 codecWidth(0),
60 codecHeight(0),
61 numLayers(1) {}
niklase@google.com470e71d2011-07-07 08:21:25 +000062
philipel9d3ab612015-12-21 04:12:39 -080063 int64_t rtt;
64 float lossPr;
65 float bitRate;
66 float packetsPerFrame;
67 float packetsPerFrameKey;
68 float frameRate;
69 float keyFrameSize;
70 uint8_t fecRateDelta;
71 uint8_t fecRateKey;
72 uint16_t codecWidth;
73 uint16_t codecHeight;
74 int numLayers;
niklase@google.com470e71d2011-07-07 08:21:25 +000075};
76
niklase@google.com470e71d2011-07-07 08:21:25 +000077/******************************/
stefan@webrtc.orga64300a2013-03-04 15:24:40 +000078/* VCMProtectionMethod class */
79/******************************/
niklase@google.com470e71d2011-07-07 08:21:25 +000080
philipel9d3ab612015-12-21 04:12:39 -080081enum VCMProtectionMethodEnum { kNack, kFec, kNackFec, kNone };
82
83class VCMLossProbabilitySample {
84 public:
85 VCMLossProbabilitySample() : lossPr255(0), timeMs(-1) {}
86
87 uint8_t lossPr255;
88 int64_t timeMs;
niklase@google.com470e71d2011-07-07 08:21:25 +000089};
90
philipel9d3ab612015-12-21 04:12:39 -080091class VCMProtectionMethod {
92 public:
93 VCMProtectionMethod();
94 virtual ~VCMProtectionMethod();
niklase@google.com470e71d2011-07-07 08:21:25 +000095
philipel9d3ab612015-12-21 04:12:39 -080096 // Updates the efficiency of the method using the parameters provided
97 //
98 // Input:
99 // - parameters : Parameters used to calculate efficiency
100 //
101 // Return value : True if this method is recommended in
102 // the given conditions.
103 virtual bool UpdateParameters(const VCMProtectionParameters* parameters) = 0;
104
105 // Returns the protection type
106 //
107 // Return value : The protection type
108 enum VCMProtectionMethodEnum Type() const { return _type; }
109
110 // Returns the effective packet loss for ER, required by this protection
111 // method
112 //
113 // Return value : Required effective packet loss
114 virtual uint8_t RequiredPacketLossER() { return _effectivePacketLoss; }
115
116 // Extracts the FEC protection factor for Key frame, required by this
117 // protection method
118 //
119 // Return value : Required protectionFactor for Key frame
120 virtual uint8_t RequiredProtectionFactorK() { return _protectionFactorK; }
121
122 // Extracts the FEC protection factor for Delta frame, required by this
123 // protection method
124 //
125 // Return value : Required protectionFactor for delta frame
126 virtual uint8_t RequiredProtectionFactorD() { return _protectionFactorD; }
127
128 // Extracts whether the FEC Unequal protection (UEP) is used for Key frame.
129 //
130 // Return value : Required Unequal protection on/off state.
131 virtual bool RequiredUepProtectionK() { return _useUepProtectionK; }
132
133 // Extracts whether the the FEC Unequal protection (UEP) is used for Delta
134 // frame.
135 //
136 // Return value : Required Unequal protection on/off state.
137 virtual bool RequiredUepProtectionD() { return _useUepProtectionD; }
138
139 virtual int MaxFramesFec() const { return 1; }
140
philipel9d3ab612015-12-21 04:12:39 -0800141 protected:
142 uint8_t _effectivePacketLoss;
143 uint8_t _protectionFactorK;
144 uint8_t _protectionFactorD;
145 // Estimation of residual loss after the FEC
146 float _scaleProtKey;
147 int32_t _maxPayloadSize;
148
philipel9d3ab612015-12-21 04:12:39 -0800149 bool _useUepProtectionK;
150 bool _useUepProtectionD;
151 float _corrFecCost;
152 enum VCMProtectionMethodEnum _type;
niklase@google.com470e71d2011-07-07 08:21:25 +0000153};
154
philipel9d3ab612015-12-21 04:12:39 -0800155class VCMNackMethod : public VCMProtectionMethod {
156 public:
157 VCMNackMethod();
158 virtual ~VCMNackMethod();
159 virtual bool UpdateParameters(const VCMProtectionParameters* parameters);
160 // Get the effective packet loss
161 bool EffectivePacketLoss(const VCMProtectionParameters* parameter);
niklase@google.com470e71d2011-07-07 08:21:25 +0000162};
163
philipel9d3ab612015-12-21 04:12:39 -0800164class VCMFecMethod : public VCMProtectionMethod {
165 public:
166 VCMFecMethod();
167 virtual ~VCMFecMethod();
168 virtual bool UpdateParameters(const VCMProtectionParameters* parameters);
169 // Get the effective packet loss for ER
170 bool EffectivePacketLoss(const VCMProtectionParameters* parameters);
171 // Get the FEC protection factors
172 bool ProtectionFactor(const VCMProtectionParameters* parameters);
173 // Get the boost for key frame protection
174 uint8_t BoostCodeRateKey(uint8_t packetFrameDelta,
175 uint8_t packetFrameKey) const;
176 // Convert the rates: defined relative to total# packets or source# packets
177 uint8_t ConvertFECRate(uint8_t codeRate) const;
178 // Get the average effective recovery from FEC: for random loss model
179 float AvgRecoveryFEC(const VCMProtectionParameters* parameters) const;
180 // Update FEC with protectionFactorD
181 void UpdateProtectionFactorD(uint8_t protectionFactorD);
182 // Update FEC with protectionFactorK
183 void UpdateProtectionFactorK(uint8_t protectionFactorK);
184 // Compute the bits per frame. Account for temporal layers when applicable.
185 int BitsPerFrame(const VCMProtectionParameters* parameters);
186
187 protected:
188 enum { kUpperLimitFramesFec = 6 };
189 // Thresholds values for the bytes/frame and round trip time, below which we
190 // may turn off FEC, depending on |_numLayers| and |_maxFramesFec|.
191 // Max bytes/frame for VGA, corresponds to ~140k at 25fps.
192 enum { kMaxBytesPerFrameForFec = 700 };
193 // Max bytes/frame for CIF and lower: corresponds to ~80k at 25fps.
194 enum { kMaxBytesPerFrameForFecLow = 400 };
195 // Max bytes/frame for frame size larger than VGA, ~200k at 25fps.
196 enum { kMaxBytesPerFrameForFecHigh = 1000 };
niklase@google.com470e71d2011-07-07 08:21:25 +0000197};
198
philipel9d3ab612015-12-21 04:12:39 -0800199class VCMNackFecMethod : public VCMFecMethod {
200 public:
201 VCMNackFecMethod(int64_t lowRttNackThresholdMs,
202 int64_t highRttNackThresholdMs);
203 virtual ~VCMNackFecMethod();
204 virtual bool UpdateParameters(const VCMProtectionParameters* parameters);
205 // Get the effective packet loss for ER
206 bool EffectivePacketLoss(const VCMProtectionParameters* parameters);
207 // Get the protection factors
208 bool ProtectionFactor(const VCMProtectionParameters* parameters);
209 // Get the max number of frames the FEC is allowed to be based on.
210 int MaxFramesFec() const;
211 // Turn off the FEC based on low bitrate and other factors.
212 bool BitRateTooLowForFec(const VCMProtectionParameters* parameters);
stefan@webrtc.orgc35f5ce2012-04-11 07:42:25 +0000213
philipel9d3ab612015-12-21 04:12:39 -0800214 private:
215 int ComputeMaxFramesFec(const VCMProtectionParameters* parameters);
216
217 int64_t _lowRttNackMs;
218 int64_t _highRttNackMs;
219 int _maxFramesFec;
niklase@google.com470e71d2011-07-07 08:21:25 +0000220};
221
philipel9d3ab612015-12-21 04:12:39 -0800222class VCMLossProtectionLogic {
223 public:
224 explicit VCMLossProtectionLogic(int64_t nowMs);
225 ~VCMLossProtectionLogic();
niklase@google.com470e71d2011-07-07 08:21:25 +0000226
philipel9d3ab612015-12-21 04:12:39 -0800227 // Set the protection method to be used
228 //
229 // Input:
230 // - newMethodType : New requested protection method type. If one
231 // is already set, it will be deleted and replaced
232 void SetMethod(VCMProtectionMethodEnum newMethodType);
stefan@webrtc.orgc35f5ce2012-04-11 07:42:25 +0000233
philipel9d3ab612015-12-21 04:12:39 -0800234 // Update the round-trip time
235 //
236 // Input:
237 // - rtt : Round-trip time in seconds.
238 void UpdateRtt(int64_t rtt);
niklase@google.com470e71d2011-07-07 08:21:25 +0000239
philipel9d3ab612015-12-21 04:12:39 -0800240 // Update the filtered packet loss.
241 //
242 // Input:
243 // - packetLossEnc : The reported packet loss filtered
244 // (max window or average)
245 void UpdateFilteredLossPr(uint8_t packetLossEnc);
niklase@google.com470e71d2011-07-07 08:21:25 +0000246
philipel9d3ab612015-12-21 04:12:39 -0800247 // Update the current target bit rate.
248 //
249 // Input:
250 // - bitRate : The current target bit rate in kbits/s
251 void UpdateBitRate(float bitRate);
mikhal@webrtc.orga057a952011-08-26 21:17:34 +0000252
philipel9d3ab612015-12-21 04:12:39 -0800253 // Update the number of packets per frame estimate, for delta frames
254 //
255 // Input:
256 // - nPackets : Number of packets in the latest sent frame.
257 void UpdatePacketsPerFrame(float nPackets, int64_t nowMs);
niklase@google.com470e71d2011-07-07 08:21:25 +0000258
philipel9d3ab612015-12-21 04:12:39 -0800259 // Update the number of packets per frame estimate, for key frames
260 //
261 // Input:
262 // - nPackets : umber of packets in the latest sent frame.
263 void UpdatePacketsPerFrameKey(float nPackets, int64_t nowMs);
niklase@google.com470e71d2011-07-07 08:21:25 +0000264
philipel9d3ab612015-12-21 04:12:39 -0800265 // Update the keyFrameSize estimate
266 //
267 // Input:
268 // - keyFrameSize : The size of the latest sent key frame.
269 void UpdateKeyFrameSize(float keyFrameSize);
niklase@google.com470e71d2011-07-07 08:21:25 +0000270
philipel9d3ab612015-12-21 04:12:39 -0800271 // Update the frame rate
272 //
273 // Input:
274 // - frameRate : The current target frame rate.
275 void UpdateFrameRate(float frameRate) { _frameRate = frameRate; }
niklase@google.com470e71d2011-07-07 08:21:25 +0000276
philipel9d3ab612015-12-21 04:12:39 -0800277 // Update the frame size
278 //
279 // Input:
280 // - width : The codec frame width.
281 // - height : The codec frame height.
282 void UpdateFrameSize(uint16_t width, uint16_t height);
niklase@google.com470e71d2011-07-07 08:21:25 +0000283
philipel9d3ab612015-12-21 04:12:39 -0800284 // Update the number of active layers
285 //
286 // Input:
287 // - numLayers : Number of layers used.
288 void UpdateNumLayers(int numLayers);
niklase@google.com470e71d2011-07-07 08:21:25 +0000289
philipel9d3ab612015-12-21 04:12:39 -0800290 // The amount of packet loss to cover for with FEC.
291 //
292 // Input:
293 // - fecRateKey : Packet loss to cover for with FEC when
294 // sending key frames.
295 // - fecRateDelta : Packet loss to cover for with FEC when
296 // sending delta frames.
297 void UpdateFECRates(uint8_t fecRateKey, uint8_t fecRateDelta) {
298 _fecRateKey = fecRateKey;
299 _fecRateDelta = fecRateDelta;
300 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000301
philipel9d3ab612015-12-21 04:12:39 -0800302 // Update the protection methods with the current VCMProtectionParameters
303 // and set the requested protection settings.
304 // Return value : Returns true on update
305 bool UpdateMethod();
niklase@google.com470e71d2011-07-07 08:21:25 +0000306
philipel9d3ab612015-12-21 04:12:39 -0800307 // Returns the method currently selected.
308 //
309 // Return value : The protection method currently selected.
310 VCMProtectionMethod* SelectedMethod() const;
mikhal@webrtc.org0e7d9d82011-12-19 19:04:49 +0000311
philipel9d3ab612015-12-21 04:12:39 -0800312 // Return the protection type of the currently selected method
313 VCMProtectionMethodEnum SelectedType() const;
niklase@google.com470e71d2011-07-07 08:21:25 +0000314
philipel9d3ab612015-12-21 04:12:39 -0800315 // Updates the filtered loss for the average and max window packet loss,
316 // and returns the filtered loss probability in the interval [0, 255].
317 // The returned filtered loss value depends on the parameter |filter_mode|.
318 // The input parameter |lossPr255| is the received packet loss.
niklase@google.com470e71d2011-07-07 08:21:25 +0000319
philipel9d3ab612015-12-21 04:12:39 -0800320 // Return value : The filtered loss probability
321 uint8_t FilteredLoss(int64_t nowMs,
322 FilterPacketLossMode filter_mode,
323 uint8_t lossPr255);
niklase@google.com470e71d2011-07-07 08:21:25 +0000324
philipel9d3ab612015-12-21 04:12:39 -0800325 void Reset(int64_t nowMs);
mikhal@webrtc.orga057a952011-08-26 21:17:34 +0000326
philipel9d3ab612015-12-21 04:12:39 -0800327 void Release();
marpan@webrtc.org2dad3fb2012-01-09 18:18:36 +0000328
philipel9d3ab612015-12-21 04:12:39 -0800329 private:
330 // Sets the available loss protection methods.
331 void UpdateMaxLossHistory(uint8_t lossPr255, int64_t now);
332 uint8_t MaxFilteredLossPr(int64_t nowMs) const;
kwiberg3f55dea2016-02-29 05:51:59 -0800333 std::unique_ptr<VCMProtectionMethod> _selectedMethod;
philipel9d3ab612015-12-21 04:12:39 -0800334 VCMProtectionParameters _currentParameters;
335 int64_t _rtt;
336 float _lossPr;
337 float _bitRate;
338 float _frameRate;
339 float _keyFrameSize;
340 uint8_t _fecRateKey;
341 uint8_t _fecRateDelta;
342 int64_t _lastPrUpdateT;
343 int64_t _lastPacketPerFrameUpdateT;
344 int64_t _lastPacketPerFrameUpdateTKey;
345 rtc::ExpFilter _lossPr255;
346 VCMLossProbabilitySample _lossPrHistory[kLossPrHistorySize];
347 uint8_t _shortMaxLossPr255;
348 rtc::ExpFilter _packetsPerFrame;
349 rtc::ExpFilter _packetsPerFrameKey;
350 uint16_t _codecWidth;
351 uint16_t _codecHeight;
352 int _numLayers;
niklase@google.com470e71d2011-07-07 08:21:25 +0000353};
354
pbos@webrtc.orgd900e8b2013-07-03 15:12:26 +0000355} // namespace media_optimization
356} // namespace webrtc
niklase@google.com470e71d2011-07-07 08:21:25 +0000357
philipel9d3ab612015-12-21 04:12:39 -0800358#endif // WEBRTC_MODULES_VIDEO_CODING_MEDIA_OPT_UTIL_H_