blob: a8455cb65c8e081e5670df28c35cbf9299d738b0 [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
philipelae284082016-05-09 12:14:29 +020048// If the RTT is higher than this an extra RTT wont be added to to the jitter
49// buffer delay.
50const int kMaxRttDelayThreshold = 500;
51
philipel9d3ab612015-12-21 04:12:39 -080052struct VCMProtectionParameters {
53 VCMProtectionParameters()
54 : rtt(0),
55 lossPr(0.0f),
56 bitRate(0.0f),
57 packetsPerFrame(0.0f),
58 packetsPerFrameKey(0.0f),
59 frameRate(0.0f),
60 keyFrameSize(0.0f),
61 fecRateDelta(0),
62 fecRateKey(0),
63 codecWidth(0),
64 codecHeight(0),
65 numLayers(1) {}
niklase@google.com470e71d2011-07-07 08:21:25 +000066
philipel9d3ab612015-12-21 04:12:39 -080067 int64_t rtt;
68 float lossPr;
69 float bitRate;
70 float packetsPerFrame;
71 float packetsPerFrameKey;
72 float frameRate;
73 float keyFrameSize;
74 uint8_t fecRateDelta;
75 uint8_t fecRateKey;
76 uint16_t codecWidth;
77 uint16_t codecHeight;
78 int numLayers;
niklase@google.com470e71d2011-07-07 08:21:25 +000079};
80
niklase@google.com470e71d2011-07-07 08:21:25 +000081/******************************/
stefan@webrtc.orga64300a2013-03-04 15:24:40 +000082/* VCMProtectionMethod class */
83/******************************/
niklase@google.com470e71d2011-07-07 08:21:25 +000084
philipel9d3ab612015-12-21 04:12:39 -080085enum VCMProtectionMethodEnum { kNack, kFec, kNackFec, kNone };
86
87class VCMLossProbabilitySample {
88 public:
89 VCMLossProbabilitySample() : lossPr255(0), timeMs(-1) {}
90
91 uint8_t lossPr255;
92 int64_t timeMs;
niklase@google.com470e71d2011-07-07 08:21:25 +000093};
94
philipel9d3ab612015-12-21 04:12:39 -080095class VCMProtectionMethod {
96 public:
97 VCMProtectionMethod();
98 virtual ~VCMProtectionMethod();
niklase@google.com470e71d2011-07-07 08:21:25 +000099
philipel9d3ab612015-12-21 04:12:39 -0800100 // Updates the efficiency of the method using the parameters provided
101 //
102 // Input:
103 // - parameters : Parameters used to calculate efficiency
104 //
105 // Return value : True if this method is recommended in
106 // the given conditions.
107 virtual bool UpdateParameters(const VCMProtectionParameters* parameters) = 0;
108
109 // Returns the protection type
110 //
111 // Return value : The protection type
112 enum VCMProtectionMethodEnum Type() const { return _type; }
113
114 // Returns the effective packet loss for ER, required by this protection
115 // method
116 //
117 // Return value : Required effective packet loss
118 virtual uint8_t RequiredPacketLossER() { return _effectivePacketLoss; }
119
120 // Extracts the FEC protection factor for Key frame, required by this
121 // protection method
122 //
123 // Return value : Required protectionFactor for Key frame
124 virtual uint8_t RequiredProtectionFactorK() { return _protectionFactorK; }
125
126 // Extracts the FEC protection factor for Delta frame, required by this
127 // protection method
128 //
129 // Return value : Required protectionFactor for delta frame
130 virtual uint8_t RequiredProtectionFactorD() { return _protectionFactorD; }
131
132 // Extracts whether the FEC Unequal protection (UEP) is used for Key frame.
133 //
134 // Return value : Required Unequal protection on/off state.
135 virtual bool RequiredUepProtectionK() { return _useUepProtectionK; }
136
137 // Extracts whether the the FEC Unequal protection (UEP) is used for Delta
138 // frame.
139 //
140 // Return value : Required Unequal protection on/off state.
141 virtual bool RequiredUepProtectionD() { return _useUepProtectionD; }
142
143 virtual int MaxFramesFec() const { return 1; }
144
philipel9d3ab612015-12-21 04:12:39 -0800145 protected:
146 uint8_t _effectivePacketLoss;
147 uint8_t _protectionFactorK;
148 uint8_t _protectionFactorD;
149 // Estimation of residual loss after the FEC
150 float _scaleProtKey;
151 int32_t _maxPayloadSize;
152
philipel9d3ab612015-12-21 04:12:39 -0800153 bool _useUepProtectionK;
154 bool _useUepProtectionD;
155 float _corrFecCost;
156 enum VCMProtectionMethodEnum _type;
niklase@google.com470e71d2011-07-07 08:21:25 +0000157};
158
philipel9d3ab612015-12-21 04:12:39 -0800159class VCMNackMethod : public VCMProtectionMethod {
160 public:
161 VCMNackMethod();
162 virtual ~VCMNackMethod();
163 virtual bool UpdateParameters(const VCMProtectionParameters* parameters);
164 // Get the effective packet loss
165 bool EffectivePacketLoss(const VCMProtectionParameters* parameter);
niklase@google.com470e71d2011-07-07 08:21:25 +0000166};
167
philipel9d3ab612015-12-21 04:12:39 -0800168class VCMFecMethod : public VCMProtectionMethod {
169 public:
170 VCMFecMethod();
171 virtual ~VCMFecMethod();
172 virtual bool UpdateParameters(const VCMProtectionParameters* parameters);
173 // Get the effective packet loss for ER
174 bool EffectivePacketLoss(const VCMProtectionParameters* parameters);
175 // Get the FEC protection factors
176 bool ProtectionFactor(const VCMProtectionParameters* parameters);
177 // Get the boost for key frame protection
178 uint8_t BoostCodeRateKey(uint8_t packetFrameDelta,
179 uint8_t packetFrameKey) const;
180 // Convert the rates: defined relative to total# packets or source# packets
181 uint8_t ConvertFECRate(uint8_t codeRate) const;
182 // Get the average effective recovery from FEC: for random loss model
183 float AvgRecoveryFEC(const VCMProtectionParameters* parameters) const;
184 // Update FEC with protectionFactorD
185 void UpdateProtectionFactorD(uint8_t protectionFactorD);
186 // Update FEC with protectionFactorK
187 void UpdateProtectionFactorK(uint8_t protectionFactorK);
188 // Compute the bits per frame. Account for temporal layers when applicable.
189 int BitsPerFrame(const VCMProtectionParameters* parameters);
190
191 protected:
192 enum { kUpperLimitFramesFec = 6 };
193 // Thresholds values for the bytes/frame and round trip time, below which we
194 // may turn off FEC, depending on |_numLayers| and |_maxFramesFec|.
195 // Max bytes/frame for VGA, corresponds to ~140k at 25fps.
196 enum { kMaxBytesPerFrameForFec = 700 };
197 // Max bytes/frame for CIF and lower: corresponds to ~80k at 25fps.
198 enum { kMaxBytesPerFrameForFecLow = 400 };
199 // Max bytes/frame for frame size larger than VGA, ~200k at 25fps.
200 enum { kMaxBytesPerFrameForFecHigh = 1000 };
niklase@google.com470e71d2011-07-07 08:21:25 +0000201};
202
philipel9d3ab612015-12-21 04:12:39 -0800203class VCMNackFecMethod : public VCMFecMethod {
204 public:
205 VCMNackFecMethod(int64_t lowRttNackThresholdMs,
206 int64_t highRttNackThresholdMs);
207 virtual ~VCMNackFecMethod();
208 virtual bool UpdateParameters(const VCMProtectionParameters* parameters);
209 // Get the effective packet loss for ER
210 bool EffectivePacketLoss(const VCMProtectionParameters* parameters);
211 // Get the protection factors
212 bool ProtectionFactor(const VCMProtectionParameters* parameters);
213 // Get the max number of frames the FEC is allowed to be based on.
214 int MaxFramesFec() const;
215 // Turn off the FEC based on low bitrate and other factors.
216 bool BitRateTooLowForFec(const VCMProtectionParameters* parameters);
stefan@webrtc.orgc35f5ce2012-04-11 07:42:25 +0000217
philipel9d3ab612015-12-21 04:12:39 -0800218 private:
219 int ComputeMaxFramesFec(const VCMProtectionParameters* parameters);
220
221 int64_t _lowRttNackMs;
222 int64_t _highRttNackMs;
223 int _maxFramesFec;
niklase@google.com470e71d2011-07-07 08:21:25 +0000224};
225
philipel9d3ab612015-12-21 04:12:39 -0800226class VCMLossProtectionLogic {
227 public:
228 explicit VCMLossProtectionLogic(int64_t nowMs);
229 ~VCMLossProtectionLogic();
niklase@google.com470e71d2011-07-07 08:21:25 +0000230
philipel9d3ab612015-12-21 04:12:39 -0800231 // Set the protection method to be used
232 //
233 // Input:
234 // - newMethodType : New requested protection method type. If one
235 // is already set, it will be deleted and replaced
236 void SetMethod(VCMProtectionMethodEnum newMethodType);
stefan@webrtc.orgc35f5ce2012-04-11 07:42:25 +0000237
philipel9d3ab612015-12-21 04:12:39 -0800238 // Update the round-trip time
239 //
240 // Input:
241 // - rtt : Round-trip time in seconds.
242 void UpdateRtt(int64_t rtt);
niklase@google.com470e71d2011-07-07 08:21:25 +0000243
philipel9d3ab612015-12-21 04:12:39 -0800244 // Update the filtered packet loss.
245 //
246 // Input:
247 // - packetLossEnc : The reported packet loss filtered
248 // (max window or average)
249 void UpdateFilteredLossPr(uint8_t packetLossEnc);
niklase@google.com470e71d2011-07-07 08:21:25 +0000250
philipel9d3ab612015-12-21 04:12:39 -0800251 // Update the current target bit rate.
252 //
253 // Input:
254 // - bitRate : The current target bit rate in kbits/s
255 void UpdateBitRate(float bitRate);
mikhal@webrtc.orga057a952011-08-26 21:17:34 +0000256
philipel9d3ab612015-12-21 04:12:39 -0800257 // Update the number of packets per frame estimate, for delta frames
258 //
259 // Input:
260 // - nPackets : Number of packets in the latest sent frame.
261 void UpdatePacketsPerFrame(float nPackets, int64_t nowMs);
niklase@google.com470e71d2011-07-07 08:21:25 +0000262
philipel9d3ab612015-12-21 04:12:39 -0800263 // Update the number of packets per frame estimate, for key frames
264 //
265 // Input:
266 // - nPackets : umber of packets in the latest sent frame.
267 void UpdatePacketsPerFrameKey(float nPackets, int64_t nowMs);
niklase@google.com470e71d2011-07-07 08:21:25 +0000268
philipel9d3ab612015-12-21 04:12:39 -0800269 // Update the keyFrameSize estimate
270 //
271 // Input:
272 // - keyFrameSize : The size of the latest sent key frame.
273 void UpdateKeyFrameSize(float keyFrameSize);
niklase@google.com470e71d2011-07-07 08:21:25 +0000274
philipel9d3ab612015-12-21 04:12:39 -0800275 // Update the frame rate
276 //
277 // Input:
278 // - frameRate : The current target frame rate.
279 void UpdateFrameRate(float frameRate) { _frameRate = frameRate; }
niklase@google.com470e71d2011-07-07 08:21:25 +0000280
philipel9d3ab612015-12-21 04:12:39 -0800281 // Update the frame size
282 //
283 // Input:
284 // - width : The codec frame width.
285 // - height : The codec frame height.
286 void UpdateFrameSize(uint16_t width, uint16_t height);
niklase@google.com470e71d2011-07-07 08:21:25 +0000287
philipel9d3ab612015-12-21 04:12:39 -0800288 // Update the number of active layers
289 //
290 // Input:
291 // - numLayers : Number of layers used.
292 void UpdateNumLayers(int numLayers);
niklase@google.com470e71d2011-07-07 08:21:25 +0000293
philipel9d3ab612015-12-21 04:12:39 -0800294 // The amount of packet loss to cover for with FEC.
295 //
296 // Input:
297 // - fecRateKey : Packet loss to cover for with FEC when
298 // sending key frames.
299 // - fecRateDelta : Packet loss to cover for with FEC when
300 // sending delta frames.
301 void UpdateFECRates(uint8_t fecRateKey, uint8_t fecRateDelta) {
302 _fecRateKey = fecRateKey;
303 _fecRateDelta = fecRateDelta;
304 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000305
philipel9d3ab612015-12-21 04:12:39 -0800306 // Update the protection methods with the current VCMProtectionParameters
307 // and set the requested protection settings.
308 // Return value : Returns true on update
309 bool UpdateMethod();
niklase@google.com470e71d2011-07-07 08:21:25 +0000310
philipel9d3ab612015-12-21 04:12:39 -0800311 // Returns the method currently selected.
312 //
313 // Return value : The protection method currently selected.
314 VCMProtectionMethod* SelectedMethod() const;
mikhal@webrtc.org0e7d9d82011-12-19 19:04:49 +0000315
philipel9d3ab612015-12-21 04:12:39 -0800316 // Return the protection type of the currently selected method
317 VCMProtectionMethodEnum SelectedType() const;
niklase@google.com470e71d2011-07-07 08:21:25 +0000318
philipel9d3ab612015-12-21 04:12:39 -0800319 // Updates the filtered loss for the average and max window packet loss,
320 // and returns the filtered loss probability in the interval [0, 255].
321 // The returned filtered loss value depends on the parameter |filter_mode|.
322 // The input parameter |lossPr255| is the received packet loss.
niklase@google.com470e71d2011-07-07 08:21:25 +0000323
philipel9d3ab612015-12-21 04:12:39 -0800324 // Return value : The filtered loss probability
325 uint8_t FilteredLoss(int64_t nowMs,
326 FilterPacketLossMode filter_mode,
327 uint8_t lossPr255);
niklase@google.com470e71d2011-07-07 08:21:25 +0000328
philipel9d3ab612015-12-21 04:12:39 -0800329 void Reset(int64_t nowMs);
mikhal@webrtc.orga057a952011-08-26 21:17:34 +0000330
philipel9d3ab612015-12-21 04:12:39 -0800331 void Release();
marpan@webrtc.org2dad3fb2012-01-09 18:18:36 +0000332
philipel9d3ab612015-12-21 04:12:39 -0800333 private:
334 // Sets the available loss protection methods.
335 void UpdateMaxLossHistory(uint8_t lossPr255, int64_t now);
336 uint8_t MaxFilteredLossPr(int64_t nowMs) const;
kwiberg3f55dea2016-02-29 05:51:59 -0800337 std::unique_ptr<VCMProtectionMethod> _selectedMethod;
philipel9d3ab612015-12-21 04:12:39 -0800338 VCMProtectionParameters _currentParameters;
339 int64_t _rtt;
340 float _lossPr;
341 float _bitRate;
342 float _frameRate;
343 float _keyFrameSize;
344 uint8_t _fecRateKey;
345 uint8_t _fecRateDelta;
346 int64_t _lastPrUpdateT;
347 int64_t _lastPacketPerFrameUpdateT;
348 int64_t _lastPacketPerFrameUpdateTKey;
349 rtc::ExpFilter _lossPr255;
350 VCMLossProbabilitySample _lossPrHistory[kLossPrHistorySize];
351 uint8_t _shortMaxLossPr255;
352 rtc::ExpFilter _packetsPerFrame;
353 rtc::ExpFilter _packetsPerFrameKey;
354 uint16_t _codecWidth;
355 uint16_t _codecHeight;
356 int _numLayers;
niklase@google.com470e71d2011-07-07 08:21:25 +0000357};
358
pbos@webrtc.orgd900e8b2013-07-03 15:12:26 +0000359} // namespace media_optimization
360} // namespace webrtc
niklase@google.com470e71d2011-07-07 08:21:25 +0000361
philipel9d3ab612015-12-21 04:12:39 -0800362#endif // WEBRTC_MODULES_VIDEO_CODING_MEDIA_OPT_UTIL_H_